Compare commits
43 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 61610d5838 | |||
| e31d0b27d4 | |||
| 7a1a7c003e | |||
| 2953837f25 | |||
| ee98820bb4 | |||
| efd8ba5978 | |||
| 0c7181a211 | |||
| f47a111640 | |||
| ae5a9ccc50 | |||
| 40465665f0 | |||
| 8c437ac964 | |||
| f3b17ad2f8 | |||
| 9121078576 | |||
| c505a00fac | |||
| 09bad9c6b4 | |||
| 597f5e9545 | |||
| 54cb7be1e1 | |||
| 431c98e591 | |||
| 35f2e71202 | |||
| 0134030341 | |||
| 97c775bc68 | |||
| 62ba6b30ae | |||
| 24354275d3 | |||
| 76335e9adc | |||
| bab8eb746e | |||
| f298f5d4fa | |||
| 85b078a3e8 | |||
| 0115b02be3 | |||
| a4ffd135e7 | |||
| bbce67902b | |||
| e6930046c4 | |||
| 0c9402503a | |||
| 81e133b789 | |||
| 7be07c29c1 | |||
| 31bc439f65 | |||
| 6479480cf7 | |||
| 4af70ef255 | |||
| eba58f6451 | |||
| 35206655e0 | |||
| e14db00fc2 | |||
| 4caa9390cf | |||
| 92e902c81e | |||
| c47bc174bc |
@@ -19,6 +19,16 @@ jobs:
|
||||
node-version: 16
|
||||
- name: Setup yarn
|
||||
run: npm install -g yarn
|
||||
- name: Install Rust stable
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
- name: Install wasm-pack
|
||||
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
|
||||
working-directory: clients/webassembly
|
||||
- name: Build WASM
|
||||
run: wasm-pack build
|
||||
working-directory: clients/webassembly
|
||||
- name: Build dependencies
|
||||
run: yarn && yarn build
|
||||
- name: Build storybook
|
||||
|
||||
@@ -68,8 +68,10 @@ jobs:
|
||||
working-directory: nym-connect/native/android
|
||||
env:
|
||||
ANDROID_SDK_ROOT: ${{ env.ANDROID_HOME }}
|
||||
SENTRY_AUTH_TOKEN: ${{ secrets.NYMS5_ANDROID_SENTRY_AUTH_TOKEN }}
|
||||
# build for arm64 and x86_64
|
||||
run: |
|
||||
echo "auth.token=$SENTRY_AUTH_TOKEN" | tee -a sentry.properties
|
||||
./gradlew :app:assembleArch64Debug
|
||||
./gradlew :app:assembleArch64Release
|
||||
|
||||
@@ -107,4 +109,3 @@ jobs:
|
||||
files: |
|
||||
apk/nyms5-arch64-debug.apk
|
||||
apk/nyms5-arch64-release.apk
|
||||
|
||||
|
||||
@@ -36,6 +36,16 @@ jobs:
|
||||
node-version: 16
|
||||
- name: Setup yarn
|
||||
run: npm install -g yarn
|
||||
- name: Install Rust stable
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: stable
|
||||
- name: Install wasm-pack
|
||||
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
|
||||
working-directory: clients/webassembly
|
||||
- name: Build WASM
|
||||
run: wasm-pack build
|
||||
working-directory: clients/webassembly
|
||||
- name: Install
|
||||
run: yarn
|
||||
- name: Build packages
|
||||
|
||||
@@ -4,6 +4,14 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [1.1.23] (2023-06-27)
|
||||
|
||||
- nym-cli: add client identity key signing support ([#3576])
|
||||
- Don't fully turn off background task when cover traffic is disabled ([#3596])
|
||||
|
||||
[#3576]: https://github.com/nymtech/nym/issues/3576
|
||||
[#3596]: https://github.com/nymtech/nym/pull/3596
|
||||
|
||||
## [v1.1.22] (2023-06-20)
|
||||
|
||||
- CLI tool for querying network-requesters ([#3539])
|
||||
|
||||
Generated
+14
-9
@@ -1732,7 +1732,7 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
|
||||
|
||||
[[package]]
|
||||
name = "explorer-api"
|
||||
version = "1.1.22"
|
||||
version = "1.1.23"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"clap 4.2.7",
|
||||
@@ -3322,7 +3322,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-api"
|
||||
version = "1.1.23"
|
||||
version = "1.1.24"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -3459,7 +3459,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-cli"
|
||||
version = "1.1.22"
|
||||
version = "1.1.23"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base64 0.13.1",
|
||||
@@ -3507,8 +3507,10 @@ dependencies = [
|
||||
"nym-multisig-contract-common",
|
||||
"nym-name-service-common",
|
||||
"nym-network-defaults",
|
||||
"nym-pemstore",
|
||||
"nym-service-provider-directory-common",
|
||||
"nym-sphinx",
|
||||
"nym-types",
|
||||
"nym-validator-client",
|
||||
"nym-vesting-contract-common",
|
||||
"rand 0.6.5",
|
||||
@@ -3523,7 +3525,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-client"
|
||||
version = "1.1.22"
|
||||
version = "1.1.23"
|
||||
dependencies = [
|
||||
"clap 4.2.7",
|
||||
"dirs 4.0.0",
|
||||
@@ -3797,7 +3799,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-gateway"
|
||||
version = "1.1.22"
|
||||
version = "1.1.23"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -3948,7 +3950,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-mixnode"
|
||||
version = "1.1.23"
|
||||
version = "1.1.24"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bs58",
|
||||
@@ -4058,7 +4060,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-network-requester"
|
||||
version = "1.1.22"
|
||||
version = "1.1.23"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-file-watcher",
|
||||
@@ -4104,7 +4106,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-network-statistics"
|
||||
version = "1.1.22"
|
||||
version = "1.1.23"
|
||||
dependencies = [
|
||||
"dirs 4.0.0",
|
||||
"log",
|
||||
@@ -4263,7 +4265,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-socks5-client"
|
||||
version = "1.1.22"
|
||||
version = "1.1.23"
|
||||
dependencies = [
|
||||
"clap 4.2.7",
|
||||
"lazy_static",
|
||||
@@ -4402,6 +4404,7 @@ dependencies = [
|
||||
"nym-pemstore",
|
||||
"nym-sphinx-addressing",
|
||||
"nym-sphinx-params",
|
||||
"nym-sphinx-routing",
|
||||
"nym-sphinx-types",
|
||||
"nym-topology",
|
||||
"rand 0.7.3",
|
||||
@@ -4429,6 +4432,7 @@ dependencies = [
|
||||
"nym-crypto",
|
||||
"nym-sphinx-addressing",
|
||||
"nym-sphinx-params",
|
||||
"nym-sphinx-routing",
|
||||
"nym-sphinx-types",
|
||||
"nym-topology",
|
||||
"rand 0.7.3",
|
||||
@@ -4460,6 +4464,7 @@ dependencies = [
|
||||
"nym-sphinx-chunking",
|
||||
"nym-sphinx-forwarding",
|
||||
"nym-sphinx-params",
|
||||
"nym-sphinx-routing",
|
||||
"nym-sphinx-types",
|
||||
"nym-topology",
|
||||
"rand 0.7.3",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "nym-client"
|
||||
version = "1.1.22"
|
||||
version = "1.1.23"
|
||||
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"]
|
||||
description = "Implementation of the Nym Client"
|
||||
edition = "2021"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// all variable size data is always prefixed with u64 length
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// all variable size data is always prefixed with u64 length
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::error::ErrorKind;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "nym-socks5-client"
|
||||
version = "1.1.22"
|
||||
version = "1.1.23"
|
||||
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
|
||||
description = "A SOCKS5 localhost proxy that converts incoming messages to Sphinx and sends them to a Nym address"
|
||||
edition = "2021"
|
||||
|
||||
@@ -94,6 +94,7 @@ impl From<Init> for OverrideConfig {
|
||||
use_anonymous_replies: init_config.use_reply_surbs,
|
||||
fastmode: init_config.fastmode,
|
||||
no_cover: init_config.no_cover,
|
||||
medium_toggle: false,
|
||||
nyxd_urls: init_config.nyxd_urls,
|
||||
enabled_credentials_mode: init_config.enabled_credentials_mode,
|
||||
outfox: false,
|
||||
|
||||
@@ -19,7 +19,7 @@ use nym_client_core::client::key_manager::persistence::OnDiskKeys;
|
||||
use nym_client_core::config::GatewayEndpointConfig;
|
||||
use nym_client_core::error::ClientCoreError;
|
||||
use nym_config::OptionalSet;
|
||||
use nym_sphinx::params::PacketType;
|
||||
use nym_sphinx::params::{PacketSize, PacketType};
|
||||
use std::error::Error;
|
||||
|
||||
pub mod init;
|
||||
@@ -72,6 +72,7 @@ pub(crate) struct OverrideConfig {
|
||||
use_anonymous_replies: Option<bool>,
|
||||
fastmode: bool,
|
||||
no_cover: bool,
|
||||
medium_toggle: bool,
|
||||
nyxd_urls: Option<Vec<url::Url>>,
|
||||
enabled_credentials_mode: Option<bool>,
|
||||
outfox: bool,
|
||||
@@ -91,6 +92,10 @@ pub(crate) async fn execute(args: &Cli) -> Result<(), Box<dyn Error + Send + Syn
|
||||
}
|
||||
|
||||
pub(crate) fn override_config(config: Config, args: OverrideConfig) -> Config {
|
||||
let disable_cover_traffic_with_keepalive = args.medium_toggle;
|
||||
let secondary_packet_size = args.medium_toggle.then_some(PacketSize::ExtendedPacket16);
|
||||
let no_per_hop_delays = args.medium_toggle;
|
||||
|
||||
let packet_type = if args.outfox {
|
||||
PacketType::Outfox
|
||||
} else {
|
||||
@@ -101,6 +106,17 @@ pub(crate) fn override_config(config: Config, args: OverrideConfig) -> Config {
|
||||
BaseClientConfig::with_high_default_traffic_volume,
|
||||
args.fastmode,
|
||||
)
|
||||
.with_base(
|
||||
// NOTE: This interacts with disabling cover traffic fully, so we want to this to be set before
|
||||
BaseClientConfig::with_disabled_cover_traffic_with_keepalive,
|
||||
disable_cover_traffic_with_keepalive,
|
||||
)
|
||||
.with_base(
|
||||
BaseClientConfig::with_secondary_packet_size,
|
||||
secondary_packet_size,
|
||||
)
|
||||
.with_base(BaseClientConfig::with_no_per_hop_delays, no_per_hop_delays)
|
||||
// NOTE: see comment above about the order of the other disble cover traffic config
|
||||
.with_base(BaseClientConfig::with_disabled_cover_traffic, args.no_cover)
|
||||
.with_base(BaseClientConfig::with_packet_type, packet_type)
|
||||
.with_optional(Config::with_anonymous_replies, args.use_anonymous_replies)
|
||||
|
||||
@@ -60,6 +60,11 @@ pub(crate) struct Run {
|
||||
#[clap(long, hide = true)]
|
||||
no_cover: bool,
|
||||
|
||||
/// Enable medium mixnet traffic, for experiments only.
|
||||
/// This includes things like disabling cover traffic, no per hop delays, etc.
|
||||
#[clap(long, hide = true)]
|
||||
medium_toggle: bool,
|
||||
|
||||
/// Set this client to work in a enabled credentials mode that would attempt to use gateway
|
||||
/// with bandwidth credential requirement.
|
||||
#[clap(long, hide = true)]
|
||||
@@ -77,6 +82,7 @@ impl From<Run> for OverrideConfig {
|
||||
use_anonymous_replies: run_config.use_anonymous_replies,
|
||||
fastmode: run_config.fastmode,
|
||||
no_cover: run_config.no_cover,
|
||||
medium_toggle: run_config.medium_toggle,
|
||||
nyxd_urls: run_config.nyxd_urls,
|
||||
enabled_credentials_mode: run_config.enabled_credentials_mode,
|
||||
outfox: run_config.outfox,
|
||||
|
||||
Generated
+17
-3
@@ -2240,7 +2240,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-bin-common"
|
||||
version = "0.5.0"
|
||||
version = "0.6.0"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"clap",
|
||||
@@ -2255,7 +2255,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-client-core"
|
||||
version = "1.1.14"
|
||||
version = "1.1.15"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"base64 0.21.2",
|
||||
@@ -2300,7 +2300,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-client-wasm"
|
||||
version = "1.1.0"
|
||||
version = "1.1.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -2697,6 +2697,7 @@ dependencies = [
|
||||
"nym-pemstore",
|
||||
"nym-sphinx-addressing",
|
||||
"nym-sphinx-params",
|
||||
"nym-sphinx-routing",
|
||||
"nym-sphinx-types",
|
||||
"nym-topology",
|
||||
"rand 0.7.3",
|
||||
@@ -2723,6 +2724,7 @@ dependencies = [
|
||||
"nym-crypto",
|
||||
"nym-sphinx-addressing",
|
||||
"nym-sphinx-params",
|
||||
"nym-sphinx-routing",
|
||||
"nym-sphinx-types",
|
||||
"nym-topology",
|
||||
"rand 0.7.3",
|
||||
@@ -2753,6 +2755,7 @@ dependencies = [
|
||||
"nym-sphinx-chunking",
|
||||
"nym-sphinx-forwarding",
|
||||
"nym-sphinx-params",
|
||||
"nym-sphinx-routing",
|
||||
"nym-sphinx-types",
|
||||
"nym-topology",
|
||||
"rand 0.7.3",
|
||||
@@ -2884,6 +2887,7 @@ dependencies = [
|
||||
"nym-service-provider-directory-common",
|
||||
"nym-vesting-contract",
|
||||
"nym-vesting-contract-common",
|
||||
"openssl",
|
||||
"prost",
|
||||
"reqwest",
|
||||
"serde",
|
||||
@@ -2974,6 +2978,15 @@ version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-src"
|
||||
version = "111.26.0+1.1.1u"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "efc62c9f12b22b8f5208c23a7200a442b2e5999f8bdf80233852122b5a4f6f37"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.87"
|
||||
@@ -2982,6 +2995,7 @@ checksum = "8e17f59264b2809d77ae94f0e1ebabc434773f370d6ca667bd223ea10e06cc7e"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"openssl-src",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
@@ -3,3 +3,6 @@ clippy:
|
||||
|
||||
test:
|
||||
wasm-pack test --node
|
||||
|
||||
wasm-build:
|
||||
wasm-pack build
|
||||
@@ -8,6 +8,7 @@
|
||||
},
|
||||
"scripts": {
|
||||
"build": "webpack --config webpack.config.js",
|
||||
"build:wasm": "cd ../ && make wasm-build",
|
||||
"start": "webpack-dev-server --port 8001"
|
||||
},
|
||||
"repository": {
|
||||
@@ -36,4 +37,4 @@
|
||||
"dependencies": {
|
||||
"@nymproject/nym-client-wasm": "file:../pkg"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,370 +12,371 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
importScripts('nym_client_wasm.js');
|
||||
importScripts("nym_client_wasm.js");
|
||||
|
||||
console.log('Initializing worker');
|
||||
console.log("Initializing worker");
|
||||
|
||||
// wasm_bindgen creates a global variable (with the exports attached) that is in scope after `importScripts`
|
||||
const {
|
||||
NymNodeTester,
|
||||
WasmGateway,
|
||||
WasmMixNode,
|
||||
WasmNymTopology,
|
||||
default_debug,
|
||||
NymClientBuilder,
|
||||
NymClient,
|
||||
set_panic_hook,
|
||||
Config,
|
||||
GatewayEndpointConfig,
|
||||
ClientStorage,
|
||||
current_network_topology,
|
||||
make_key,
|
||||
make_key2
|
||||
NymNodeTester,
|
||||
WasmGateway,
|
||||
WasmMixNode,
|
||||
WasmNymTopology,
|
||||
default_debug,
|
||||
NymClientBuilder,
|
||||
NymClient,
|
||||
set_panic_hook,
|
||||
Config,
|
||||
GatewayEndpointConfig,
|
||||
ClientStorage,
|
||||
current_network_topology,
|
||||
make_key,
|
||||
make_key2,
|
||||
} = wasm_bindgen;
|
||||
|
||||
let client = null;
|
||||
let tester = null;
|
||||
|
||||
const preferredGateway = "336yuXAeGEgedRfqTJZsG2YV7P13QH1bHv1SjCZYarc9";
|
||||
|
||||
function dummyTopology() {
|
||||
const l1Mixnode = new WasmMixNode(
|
||||
1,
|
||||
'n1fzv4jc7fanl9s0qj02ge2ezk3kts545kjtek47',
|
||||
'178.79.143.65',
|
||||
1789,
|
||||
'4Yr4qmEHd9sgsuQ83191FR2hD88RfsbMmB4tzhhZWriz',
|
||||
'8ndjk5oZ6HxUZNScLJJ7hk39XtUqGexdKgW7hSX6kpWG',
|
||||
1,
|
||||
'1.10.0',
|
||||
);
|
||||
const l2Mixnode = new WasmMixNode(
|
||||
2,
|
||||
'n1z93z44vf8ssvdhujjvxcj4rd5e3lz0l60wdk70',
|
||||
'109.74.197.180',
|
||||
1789,
|
||||
'7sVjiMrPYZrDWRujku9QLxgE8noT7NTgBAqizCsu7AoK',
|
||||
'GepXwRnKZDd8x2nBWAajGGBVvF3mrpVMQBkgfrGuqRCN',
|
||||
2,
|
||||
'1.10.0',
|
||||
);
|
||||
const l3Mixnode = new WasmMixNode(
|
||||
3,
|
||||
'n1ptg680vnmef2cd8l0s9uyc4f0hgf3x8sed6w77',
|
||||
'176.58.101.80',
|
||||
1789,
|
||||
'FoM5Mx9Pxk1g3zEqkS3APgtBeTtTo3M8k7Yu4bV6kK1R',
|
||||
'DeYjrDC2AcQRVFshiKnbUo6bRvPyZ33QGYR2DLeFJ9qD',
|
||||
3,
|
||||
'1.10.0',
|
||||
);
|
||||
const l1Mixnode = new WasmMixNode(
|
||||
1,
|
||||
"n1fzv4jc7fanl9s0qj02ge2ezk3kts545kjtek47",
|
||||
"178.79.143.65",
|
||||
1789,
|
||||
"4Yr4qmEHd9sgsuQ83191FR2hD88RfsbMmB4tzhhZWriz",
|
||||
"8ndjk5oZ6HxUZNScLJJ7hk39XtUqGexdKgW7hSX6kpWG",
|
||||
1,
|
||||
"1.10.0"
|
||||
);
|
||||
const l2Mixnode = new WasmMixNode(
|
||||
2,
|
||||
"n1z93z44vf8ssvdhujjvxcj4rd5e3lz0l60wdk70",
|
||||
"109.74.197.180",
|
||||
1789,
|
||||
"7sVjiMrPYZrDWRujku9QLxgE8noT7NTgBAqizCsu7AoK",
|
||||
"GepXwRnKZDd8x2nBWAajGGBVvF3mrpVMQBkgfrGuqRCN",
|
||||
2,
|
||||
"1.10.0"
|
||||
);
|
||||
const l3Mixnode = new WasmMixNode(
|
||||
3,
|
||||
"n1ptg680vnmef2cd8l0s9uyc4f0hgf3x8sed6w77",
|
||||
"176.58.101.80",
|
||||
1789,
|
||||
"FoM5Mx9Pxk1g3zEqkS3APgtBeTtTo3M8k7Yu4bV6kK1R",
|
||||
"DeYjrDC2AcQRVFshiKnbUo6bRvPyZ33QGYR2DLeFJ9qD",
|
||||
3,
|
||||
"1.10.0"
|
||||
);
|
||||
|
||||
const gateway = new WasmGateway(
|
||||
'n16evnn8glr0sham3matj8rg2s24m6x56ayk87ts',
|
||||
'85.159.212.96',
|
||||
1789,
|
||||
9000,
|
||||
'336yuXAeGEgedRfqTJZsG2YV7P13QH1bHv1SjCZYarc9',
|
||||
'BtYjoWihiuFihGKQypmpSspbhmWDPxzqeTVSd8ciCpWL',
|
||||
'1.10.1',
|
||||
);
|
||||
const gateway = new WasmGateway(
|
||||
"n16evnn8glr0sham3matj8rg2s24m6x56ayk87ts",
|
||||
"85.159.212.96",
|
||||
1789,
|
||||
9000,
|
||||
"336yuXAeGEgedRfqTJZsG2YV7P13QH1bHv1SjCZYarc9",
|
||||
"BtYjoWihiuFihGKQypmpSspbhmWDPxzqeTVSd8ciCpWL",
|
||||
"1.10.1"
|
||||
);
|
||||
|
||||
const mixnodes = new Map();
|
||||
mixnodes.set(1, [l1Mixnode]);
|
||||
mixnodes.set(2, [l2Mixnode]);
|
||||
mixnodes.set(3, [l3Mixnode]);
|
||||
const mixnodes = new Map();
|
||||
mixnodes.set(1, [l1Mixnode]);
|
||||
mixnodes.set(2, [l2Mixnode]);
|
||||
mixnodes.set(3, [l3Mixnode]);
|
||||
|
||||
const gateways = [gateway];
|
||||
|
||||
const gateways = [gateway];
|
||||
|
||||
return new WasmNymTopology(mixnodes, gateways)
|
||||
return new WasmNymTopology(mixnodes, gateways);
|
||||
}
|
||||
|
||||
function printAndDisplayTestResult(result) {
|
||||
result.log_details();
|
||||
result.log_details();
|
||||
|
||||
self.postMessage({
|
||||
kind: 'DisplayTesterResults',
|
||||
args: {
|
||||
score: result.score(),
|
||||
sentPackets: result.sent_packets,
|
||||
receivedPackets: result.received_packets,
|
||||
receivedAcks: result.received_acks,
|
||||
duplicatePackets: result.duplicate_packets,
|
||||
duplicateAcks: result.duplicate_acks,
|
||||
},
|
||||
});
|
||||
self.postMessage({
|
||||
kind: "DisplayTesterResults",
|
||||
args: {
|
||||
score: result.score(),
|
||||
sentPackets: result.sent_packets,
|
||||
receivedPackets: result.received_packets,
|
||||
receivedAcks: result.received_acks,
|
||||
duplicatePackets: result.duplicate_packets,
|
||||
duplicateAcks: result.duplicate_acks,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async function testWithTester() {
|
||||
const preferredGateway = "336yuXAeGEgedRfqTJZsG2YV7P13QH1bHv1SjCZYarc9";
|
||||
// A) construct with hardcoded topology
|
||||
const topology = dummyTopology();
|
||||
const nodeTester = await new NymNodeTester(topology, preferredGateway);
|
||||
|
||||
// A) construct with hardcoded topology
|
||||
const topology = dummyTopology()
|
||||
const nodeTester = await new NymNodeTester(topology, preferredGateway);
|
||||
// B) first get topology directly from nym-api
|
||||
// const validator = 'https://qwerty-validator-api.qa.nymte.ch/api';
|
||||
// const topology = await current_network_topology(validator)
|
||||
// const nodeTester = await new NymNodeTester(topology, preferredGateway);
|
||||
//
|
||||
// C) use nym-api in the constructor (note: it does no filtering for 'good' nodes on other layers)
|
||||
// const validator = 'https://qwerty-validator-api.qa.nymte.ch/api';
|
||||
// const nodeTester = await NymNodeTester.new_with_api(validator, preferredGateway)
|
||||
|
||||
// B) first get topology directly from nym-api
|
||||
// const validator = 'https://qwerty-validator-api.qa.nymte.ch/api';
|
||||
// const topology = await current_network_topology(validator)
|
||||
// const nodeTester = await new NymNodeTester(topology, undefined, preferredGateway);
|
||||
//
|
||||
// C) use nym-api in the constructor (note: it does no filtering for 'good' nodes on other layers)
|
||||
// const validator = 'https://qwerty-validator-api.qa.nymte.ch/api';
|
||||
// const nodeTester = await NymNodeTester.new_with_api(validator, undefined, preferredGateway)
|
||||
// B) first get topology directly from nym-api
|
||||
// const validator = 'https://qwerty-validator-api.qa.nymte.ch/api';
|
||||
// const topology = await current_network_topology(validator)
|
||||
// const nodeTester = await new NymNodeTester(topology, undefined, preferredGateway);
|
||||
//
|
||||
// C) use nym-api in the constructor (note: it does no filtering for 'good' nodes on other layers)
|
||||
// const validator = 'https://qwerty-validator-api.qa.nymte.ch/api';
|
||||
// const nodeTester = await NymNodeTester.new_with_api(validator, undefined, preferredGateway)
|
||||
// D, E, F) you also don't have to specify the gateway. if you don't, a random one (from your topology) will be used
|
||||
// const topology = dummyTopology()
|
||||
// const nodeTester = await new NymNodeTester(topology);
|
||||
|
||||
// D, E, F) you also don't have to specify the gateway. if you don't, a random one (from your topology) will be used
|
||||
// const topology = dummyTopology()
|
||||
// const nodeTester = await new NymNodeTester(topology);
|
||||
self.onmessage = async (event) => {
|
||||
if (event.data && event.data.kind) {
|
||||
switch (event.data.kind) {
|
||||
case "TestPacket": {
|
||||
const { mixnodeIdentity } = event.data.args;
|
||||
console.log("starting node test...");
|
||||
|
||||
self.onmessage = async event => {
|
||||
if (event.data && event.data.kind) {
|
||||
switch (event.data.kind) {
|
||||
case 'TestPacket': {
|
||||
const {mixnodeIdentity} = event.data.args;
|
||||
console.log("starting node test...");
|
||||
|
||||
let result = await nodeTester.test_node(mixnodeIdentity);
|
||||
printAndDisplayTestResult(result)
|
||||
}
|
||||
}
|
||||
let result = await nodeTester.test_node(mixnodeIdentity);
|
||||
printAndDisplayTestResult(result);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
async function testerReconnection() {
|
||||
const validator = 'https://qwerty-validator-api.qa.nymte.ch/api';
|
||||
const nodeTester = await NymNodeTester.new_with_api(validator);
|
||||
const validator = "https://qwerty-validator-api.qa.nymte.ch/api";
|
||||
const nodeTester = await NymNodeTester.new_with_api(validator);
|
||||
|
||||
self.onmessage = async event => {
|
||||
if (event.data && event.data.kind) {
|
||||
switch (event.data.kind) {
|
||||
case 'TestPacket': {
|
||||
const {mixnodeIdentity} = event.data.args;
|
||||
console.log("starting node test...");
|
||||
self.onmessage = async (event) => {
|
||||
if (event.data && event.data.kind) {
|
||||
switch (event.data.kind) {
|
||||
case "TestPacket": {
|
||||
const { mixnodeIdentity } = event.data.args;
|
||||
console.log("starting node test...");
|
||||
|
||||
let result1 = await nodeTester.test_node(mixnodeIdentity);
|
||||
console.log("sleeping for 5s");
|
||||
await new Promise(r => setTimeout(r, 5000));
|
||||
await nodeTester.disconnect_from_gateway();
|
||||
let result1 = await nodeTester.test_node(mixnodeIdentity);
|
||||
console.log("sleeping for 5s");
|
||||
await new Promise((r) => setTimeout(r, 5000));
|
||||
await nodeTester.disconnect_from_gateway();
|
||||
|
||||
console.log("sleeping for 5s");
|
||||
await new Promise(r => setTimeout(r, 5000));
|
||||
console.log("sleeping for 5s");
|
||||
await new Promise((r) => setTimeout(r, 5000));
|
||||
|
||||
await nodeTester.reconnect_to_gateway();
|
||||
let result2 = await nodeTester.test_node(mixnodeIdentity);
|
||||
await nodeTester.reconnect_to_gateway();
|
||||
let result2 = await nodeTester.test_node(mixnodeIdentity);
|
||||
|
||||
printAndDisplayTestResult(result1)
|
||||
printAndDisplayTestResult(result2)
|
||||
}
|
||||
}
|
||||
printAndDisplayTestResult(result1);
|
||||
printAndDisplayTestResult(result2);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
async function testWithNymClient() {
|
||||
const preferredGateway = "336yuXAeGEgedRfqTJZsG2YV7P13QH1bHv1SjCZYarc9";
|
||||
const topology = dummyTopology()
|
||||
const topology = dummyTopology();
|
||||
|
||||
let received = 0
|
||||
let received = 0;
|
||||
|
||||
const onMessageHandler = (message) => {
|
||||
received += 1;
|
||||
self.postMessage({
|
||||
kind: 'ReceiveMessage',
|
||||
args: {
|
||||
message,
|
||||
senderTag: undefined,
|
||||
isTestPacket: true,
|
||||
},
|
||||
});
|
||||
|
||||
// it's really up to the user to create proper callback here...
|
||||
console.log(`received ${received} packets so far`)
|
||||
};
|
||||
|
||||
console.log('Instantiating WASM client...');
|
||||
|
||||
let clientBuilder = NymClientBuilder.new_tester(topology, onMessageHandler, preferredGateway)
|
||||
console.log('Web worker creating WASM client...');
|
||||
let local_client = await clientBuilder.start_client();
|
||||
console.log('WASM client running!');
|
||||
|
||||
const selfAddress = local_client.self_address();
|
||||
|
||||
// set the global (I guess we don't have to anymore?)
|
||||
client = local_client;
|
||||
|
||||
console.log(`Client address is ${selfAddress}`);
|
||||
const onMessageHandler = (message) => {
|
||||
received += 1;
|
||||
self.postMessage({
|
||||
kind: 'Ready',
|
||||
args: {
|
||||
selfAddress,
|
||||
},
|
||||
kind: "ReceiveMessage",
|
||||
args: {
|
||||
message,
|
||||
senderTag: undefined,
|
||||
isTestPacket: true,
|
||||
},
|
||||
});
|
||||
|
||||
// Set callback to handle messages passed to the worker.
|
||||
self.onmessage = async event => {
|
||||
console.log(event)
|
||||
if (event.data && event.data.kind) {
|
||||
switch (event.data.kind) {
|
||||
case 'SendMessage': {
|
||||
const {message, recipient} = event.data.args;
|
||||
let uint8Array = new TextEncoder().encode(message);
|
||||
await client.send_regular_message(uint8Array, recipient);
|
||||
break;
|
||||
}
|
||||
case 'TestPacket': {
|
||||
const {mixnodeIdentity} = event.data.args;
|
||||
const req = await client.try_construct_test_packet_request(mixnodeIdentity);
|
||||
await client.change_hardcoded_topology(req.injectable_topology());
|
||||
await client.try_send_test_packets(req);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// it's really up to the user to create proper callback here...
|
||||
console.log(`received ${received} packets so far`);
|
||||
};
|
||||
|
||||
console.log("Instantiating WASM client...");
|
||||
|
||||
let clientBuilder = NymClientBuilder.new_tester(
|
||||
topology,
|
||||
onMessageHandler,
|
||||
preferredGateway
|
||||
);
|
||||
|
||||
console.log("Web worker creating WASM client...");
|
||||
let local_client = await clientBuilder.start_client();
|
||||
console.log("WASM client running!");
|
||||
|
||||
const selfAddress = local_client.self_address();
|
||||
|
||||
// set the global (I guess we don't have to anymore?)
|
||||
client = local_client;
|
||||
|
||||
console.log(`Client address is ${selfAddress}`);
|
||||
self.postMessage({
|
||||
kind: "Ready",
|
||||
args: {
|
||||
selfAddress,
|
||||
},
|
||||
});
|
||||
|
||||
// Set callback to handle messages passed to the worker.
|
||||
self.onmessage = async (event) => {
|
||||
console.log(event);
|
||||
if (event.data && event.data.kind) {
|
||||
switch (event.data.kind) {
|
||||
case "SendMessage": {
|
||||
const { message, recipient } = event.data.args;
|
||||
let uint8Array = new TextEncoder().encode(message);
|
||||
await client.send_regular_message(uint8Array, recipient);
|
||||
break;
|
||||
}
|
||||
};
|
||||
case "TestPacket": {
|
||||
const { mixnodeIdentity } = event.data.args;
|
||||
const req = await client.try_construct_test_packet_request(
|
||||
mixnodeIdentity
|
||||
);
|
||||
await client.change_hardcoded_topology(req.injectable_topology());
|
||||
await client.try_send_test_packets(req);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
async function normalNymClientUsage() {
|
||||
self.postMessage({kind: 'DisableMagicTestButton'});
|
||||
self.postMessage({ kind: "DisableMagicTestButton" });
|
||||
|
||||
// only really useful if you want to adjust some settings like traffic rate
|
||||
// (if not needed you can just pass a null)
|
||||
const debug = default_debug();
|
||||
// only really useful if you want to adjust some settings like traffic rate
|
||||
// (if not needed you can just pass a null)
|
||||
const debug = default_debug();
|
||||
|
||||
debug.disable_main_poisson_packet_distribution = true;
|
||||
debug.disable_loop_cover_traffic_stream = true;
|
||||
debug.use_extended_packet_size = false;
|
||||
// debug.average_packet_delay_ms = BigInt(10);
|
||||
// debug.average_ack_delay_ms = BigInt(10);
|
||||
// debug.ack_wait_addition_ms = BigInt(3000);
|
||||
// debug.ack_wait_multiplier = 10;
|
||||
debug.disable_main_poisson_packet_distribution = true;
|
||||
debug.disable_loop_cover_traffic_stream = true;
|
||||
debug.use_extended_packet_size = false;
|
||||
// debug.average_packet_delay_ms = BigInt(10);
|
||||
// debug.average_ack_delay_ms = BigInt(10);
|
||||
// debug.ack_wait_addition_ms = BigInt(3000);
|
||||
// debug.ack_wait_multiplier = 10;
|
||||
|
||||
debug.topology_refresh_rate_ms = BigInt(60000)
|
||||
debug.topology_refresh_rate_ms = BigInt(60000);
|
||||
|
||||
const preferredGateway = "336yuXAeGEgedRfqTJZsG2YV7P13QH1bHv1SjCZYarc9";
|
||||
const validator = 'https://qwerty-validator-api.qa.nymte.ch/api';
|
||||
const preferredGateway = "336yuXAeGEgedRfqTJZsG2YV7P13QH1bHv1SjCZYarc9";
|
||||
const validator = "https://qwerty-validator-api.qa.nymte.ch/api";
|
||||
|
||||
const config = new Config('my-awesome-wasm-client', validator, debug);
|
||||
const config = new Config("my-awesome-wasm-client", validator, debug);
|
||||
|
||||
const onMessageHandler = (message) => {
|
||||
console.log(message);
|
||||
self.postMessage({
|
||||
kind: 'ReceiveMessage',
|
||||
args: {
|
||||
message,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
console.log('Instantiating WASM client...');
|
||||
|
||||
let localClient = await new NymClient(config, onMessageHandler)
|
||||
console.log('WASM client running!');
|
||||
|
||||
const selfAddress = localClient.self_address();
|
||||
|
||||
// set the global (I guess we don't have to anymore?)
|
||||
client = localClient;
|
||||
|
||||
console.log(`Client address is ${selfAddress}`);
|
||||
const onMessageHandler = (message) => {
|
||||
console.log(message);
|
||||
self.postMessage({
|
||||
kind: 'Ready',
|
||||
args: {
|
||||
selfAddress,
|
||||
},
|
||||
kind: "ReceiveMessage",
|
||||
args: {
|
||||
message,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
// Set callback to handle messages passed to the worker.
|
||||
self.onmessage = async event => {
|
||||
console.log(event)
|
||||
if (event.data && event.data.kind) {
|
||||
switch (event.data.kind) {
|
||||
case 'SendMessage': {
|
||||
const {message, recipient} = event.data.args;
|
||||
let uint8Array = new TextEncoder().encode(message);
|
||||
await client.send_regular_message(uint8Array, recipient);
|
||||
break;
|
||||
}
|
||||
}
|
||||
console.log("Instantiating WASM client...");
|
||||
|
||||
let localClient = await new NymClient(config, onMessageHandler);
|
||||
console.log("WASM client running!");
|
||||
|
||||
const selfAddress = localClient.self_address();
|
||||
|
||||
// set the global (I guess we don't have to anymore?)
|
||||
client = localClient;
|
||||
|
||||
console.log(`Client address is ${selfAddress}`);
|
||||
self.postMessage({
|
||||
kind: "Ready",
|
||||
args: {
|
||||
selfAddress,
|
||||
},
|
||||
});
|
||||
|
||||
// Set callback to handle messages passed to the worker.
|
||||
self.onmessage = async (event) => {
|
||||
console.log(event);
|
||||
if (event.data && event.data.kind) {
|
||||
switch (event.data.kind) {
|
||||
case "SendMessage": {
|
||||
const { message, recipient } = event.data.args;
|
||||
let uint8Array = new TextEncoder().encode(message);
|
||||
await client.send_regular_message(uint8Array, recipient);
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
async function messWithStorage() {
|
||||
self.onmessage = async event => {
|
||||
if (event.data && event.data.kind) {
|
||||
switch (event.data.kind) {
|
||||
case 'TestPacket': {
|
||||
const { mixnodeIdentity } = event.data.args;
|
||||
console.log("button clicked...", mixnodeIdentity);
|
||||
self.onmessage = async (event) => {
|
||||
if (event.data && event.data.kind) {
|
||||
switch (event.data.kind) {
|
||||
case "TestPacket": {
|
||||
const { mixnodeIdentity } = event.data.args;
|
||||
console.log("button clicked...", mixnodeIdentity);
|
||||
|
||||
let id1 = "one";
|
||||
let id2 = "two";
|
||||
let id1 = "one";
|
||||
let id2 = "two";
|
||||
|
||||
console.log("making store1 NO-ENC");
|
||||
let _storage1 = await ClientStorage.new_unencrypted(id1);
|
||||
console.log("making store1 NO-ENC");
|
||||
let _storage1 = await ClientStorage.new_unencrypted(id1);
|
||||
|
||||
console.log("making store2 ENC")
|
||||
let _storage2 = await new ClientStorage(id2, "my-secret-password");
|
||||
//
|
||||
//
|
||||
//
|
||||
// console.log("attempting to use store1 WITH PASSWORD")
|
||||
// let _storage1_alt = await new ClientStorage(id1, "password");
|
||||
//
|
||||
//
|
||||
//
|
||||
// console.log("attempting to use store2 WITHOUT PASSWORD")
|
||||
// let _storage2_alt = await ClientStorage.new_unencrypted(id2);
|
||||
//
|
||||
//
|
||||
//
|
||||
// console.log("attempting to use store2 with WRONG PASSWORD")
|
||||
// let _storage2_bad = await new ClientStorage(id2, "bad-password")
|
||||
console.log("making store2 ENC");
|
||||
let _storage2 = await new ClientStorage(id2, "my-secret-password");
|
||||
//
|
||||
//
|
||||
//
|
||||
// console.log("attempting to use store1 WITH PASSWORD")
|
||||
// let _storage1_alt = await new ClientStorage(id1, "password");
|
||||
//
|
||||
//
|
||||
//
|
||||
// console.log("attempting to use store2 WITHOUT PASSWORD")
|
||||
// let _storage2_alt = await ClientStorage.new_unencrypted(id2);
|
||||
//
|
||||
//
|
||||
//
|
||||
// console.log("attempting to use store2 with WRONG PASSWORD")
|
||||
// let _storage2_bad = await new ClientStorage(id2, "bad-password")
|
||||
|
||||
|
||||
//
|
||||
// console.log("read1: ", await storage1.read());
|
||||
// console.log("read2: ", await storage2.read());
|
||||
//
|
||||
// console.log("store1: ", await storage1.store("FOOMP"));
|
||||
//
|
||||
// console.log("read1: ", await storage1.read());
|
||||
// console.log("read2: ", await storage2.read());
|
||||
}
|
||||
}
|
||||
//
|
||||
// console.log("read1: ", await storage1.read());
|
||||
// console.log("read2: ", await storage2.read());
|
||||
//
|
||||
// console.log("store1: ", await storage1.store("FOOMP"));
|
||||
//
|
||||
// console.log("read1: ", await storage1.read());
|
||||
// console.log("read2: ", await storage2.read());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
async function main() {
|
||||
// load WASM package
|
||||
await wasm_bindgen('nym_client_wasm_bg.wasm');
|
||||
console.log('Loaded WASM');
|
||||
// load WASM package
|
||||
await wasm_bindgen("nym_client_wasm_bg.wasm");
|
||||
console.log("Loaded WASM");
|
||||
|
||||
// sets up better stack traces in case of in-rust panics
|
||||
set_panic_hook();
|
||||
// sets up better stack traces in case of in-rust panics
|
||||
set_panic_hook();
|
||||
|
||||
// show reconnection capabilities
|
||||
// await testerReconnection()
|
||||
// show reconnection capabilities
|
||||
// await testerReconnection()
|
||||
|
||||
// run test on simplified and dedicated tester:
|
||||
await testWithTester()
|
||||
// run test on simplified and dedicated tester:
|
||||
await testWithTester();
|
||||
|
||||
// hook-up the whole client for testing
|
||||
// await testWithNymClient()
|
||||
|
||||
// 'Normal' client setup (to send 'normal' messages)
|
||||
// await normalNymClientUsage()
|
||||
// 'Normal' client setup (to send 'normal' messages)
|
||||
// await normalNymClientUsage()
|
||||
}
|
||||
|
||||
// Let's get started!
|
||||
main();
|
||||
main();
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::client::inbound_messages::{InputMessage, InputMessageReceiver};
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use super::{
|
||||
|
||||
@@ -137,14 +137,46 @@ impl Config {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_no_cover_traffic(&mut self) {
|
||||
self.debug.cover_traffic.disable_loop_cover_traffic_stream = true;
|
||||
self.debug.traffic.disable_main_poisson_packet_distribution = true;
|
||||
}
|
||||
|
||||
pub fn with_disabled_cover_traffic_with_keepalive(mut self, disabled: bool) -> Self {
|
||||
if disabled {
|
||||
self.set_no_cover_traffic_with_keepalive()
|
||||
}
|
||||
self
|
||||
}
|
||||
pub fn set_no_cover_traffic_with_keepalive(&mut self) {
|
||||
self.debug.traffic.disable_main_poisson_packet_distribution = true;
|
||||
self.debug.cover_traffic.loop_cover_traffic_average_delay = Duration::from_secs(5);
|
||||
}
|
||||
|
||||
pub fn with_disabled_topology_refresh(mut self, disable_topology_refresh: bool) -> Self {
|
||||
self.debug.topology.disable_refreshing = disable_topology_refresh;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_no_cover_traffic(&mut self) {
|
||||
self.debug.cover_traffic.disable_loop_cover_traffic_stream = true;
|
||||
self.debug.traffic.disable_main_poisson_packet_distribution = true;
|
||||
pub fn with_no_per_hop_delays(mut self, no_per_hop_delays: bool) -> Self {
|
||||
if no_per_hop_delays {
|
||||
self.set_no_per_hop_delays()
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_no_per_hop_delays(&mut self) {
|
||||
self.debug.traffic.average_packet_delay = Duration::ZERO;
|
||||
self.debug.acknowledgements.average_ack_delay = Duration::ZERO;
|
||||
}
|
||||
|
||||
pub fn with_secondary_packet_size(mut self, secondary_packet_size: Option<PacketSize>) -> Self {
|
||||
self.set_secondary_packet_size(secondary_packet_size);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn set_secondary_packet_size(&mut self, secondary_packet_size: Option<PacketSize>) {
|
||||
self.debug.traffic.secondary_packet_size = secondary_packet_size;
|
||||
}
|
||||
|
||||
pub fn set_custom_version(&mut self, version: &str) {
|
||||
@@ -282,7 +314,7 @@ impl Client {
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)]
|
||||
#[serde(default)]
|
||||
#[serde(default, deny_unknown_fields)]
|
||||
pub struct Traffic {
|
||||
/// The parameter of Poisson distribution determining how long, on average,
|
||||
/// sent packet is going to be delayed at any given mix node.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::error::GatewayClientError;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::{nym_api, ValidatorClientError};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::nym_api::error::NymAPIError;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// TODO: There's a significant argument to pull those out of the package and make a PR on https://github.com/cosmos/cosmos-rust/
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// TODO: expose query-related capabilities to wasm client...
|
||||
|
||||
@@ -41,3 +41,6 @@ nym-multisig-contract-common = { path = "../cosmwasm-smart-contracts/multisig-co
|
||||
nym-service-provider-directory-common = { path = "../cosmwasm-smart-contracts/service-provider-directory" }
|
||||
nym-name-service-common = { path = "../cosmwasm-smart-contracts/name-service" }
|
||||
nym-sphinx = { path = "../../common/nymsphinx" }
|
||||
|
||||
nym-pemstore = { path = "../../common/pemstore", version = "0.3.0" }
|
||||
nym-types = { path = "../../common/types" }
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
use clap::{Args, Parser, Subcommand};
|
||||
use nym_bin_common::output_format::OutputFormat;
|
||||
use nym_crypto::asymmetric::identity;
|
||||
use nym_types::helpers::ConsoleSigningOutput;
|
||||
use nym_validator_client::nyxd::error::NyxdError;
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Debug, Args)]
|
||||
#[clap(args_conflicts_with_subcommands = true, subcommand_required = true)]
|
||||
pub struct MixnetOperatorsIdentityKey {
|
||||
#[clap(subcommand)]
|
||||
pub command: MixnetOperatorsIdentityKeyCommands,
|
||||
}
|
||||
|
||||
#[derive(Debug, Subcommand)]
|
||||
pub enum MixnetOperatorsIdentityKeyCommands {
|
||||
/// Register a name alias for a nym address
|
||||
Sign(SignArgs),
|
||||
}
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
pub struct SignArgs {
|
||||
/// Path to private identity key (example: private_identity_key.pem)
|
||||
#[clap(long)]
|
||||
private_key: PathBuf,
|
||||
|
||||
/// Base58 encoded message to sign
|
||||
#[clap(long)]
|
||||
base58_msg: String,
|
||||
|
||||
#[clap(short, long, default_value_t = OutputFormat::default())]
|
||||
output: OutputFormat,
|
||||
}
|
||||
|
||||
pub async fn sign(args: SignArgs) -> Result<(), NyxdError> {
|
||||
eprintln!(">>> loading: {}", args.private_key.display());
|
||||
let private_identity_key: identity::PrivateKey =
|
||||
nym_pemstore::load_key(args.private_key).expect("failed to load key");
|
||||
|
||||
print_signed_msg(&private_identity_key, &args.base58_msg, args.output);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn print_signed_msg(private_key: &identity::PrivateKey, raw_msg: &str, output: OutputFormat) {
|
||||
let trimmed = raw_msg.trim();
|
||||
eprintln!(">>> attempting to sign: {trimmed}");
|
||||
|
||||
let Ok(decoded) = bs58::decode(trimmed).into_vec() else {
|
||||
println!("failed to base58 decode the message, did you copy it correctly?");
|
||||
return;
|
||||
};
|
||||
|
||||
eprintln!(">>> decoding the message...");
|
||||
|
||||
// we don't really care about what particular information is embedded inside of it,
|
||||
// we just want to know if user correctly copied the string, i.e. whether it's a valid bs58 encoded json
|
||||
if serde_json::from_slice::<serde_json::Value>(&decoded).is_err() {
|
||||
println!("failed to parse the message after decoding, did you copy it correctly?");
|
||||
return;
|
||||
};
|
||||
|
||||
// if this is a valid json, it MUST be a valid string
|
||||
let decoded_string = String::from_utf8(decoded.clone()).unwrap();
|
||||
let signature = private_key.sign(&decoded).to_base58_string();
|
||||
|
||||
let sign_output = ConsoleSigningOutput::new(decoded_string, signature);
|
||||
println!("{}", output.format(&sign_output));
|
||||
}
|
||||
@@ -4,6 +4,7 @@
|
||||
use clap::{Args, Subcommand};
|
||||
|
||||
pub mod gateway;
|
||||
pub mod identity_key;
|
||||
pub mod mixnode;
|
||||
pub mod name;
|
||||
pub mod service;
|
||||
@@ -26,4 +27,6 @@ pub enum MixnetOperatorsCommands {
|
||||
ServiceProvider(service::MixnetOperatorsService),
|
||||
/// Manage your registered name
|
||||
Name(name::MixnetOperatorsName),
|
||||
/// Sign messages using your private identity key
|
||||
IdentityKey(identity_key::MixnetOperatorsIdentityKey),
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// due to code generated by JsonSchema
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// due to code generated by JsonSchema
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
// due to code generated by JsonSchema
|
||||
@@ -88,7 +88,7 @@ impl MixNodeDetails {
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize, JsonSchema)]
|
||||
pub struct MixNodeRewarding {
|
||||
/// Information provided by the operator that influence the cost function.
|
||||
/// Information provided by the operator that influence the cost function.
|
||||
pub cost_params: MixNodeCostParams,
|
||||
|
||||
/// Total pledge and compounded reward earned by the node operator.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::delegation::OwnerProxySubKey;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::error::MixnetContractError;
|
||||
|
||||
@@ -15,11 +15,12 @@ thiserror = { workspace = true }
|
||||
zeroize = { workspace = true }
|
||||
|
||||
nym-crypto = { path = "../../crypto", features = ["symmetric", "rand"] }
|
||||
nym-pemstore = { path = "../../pemstore" }
|
||||
nym-sphinx-addressing = { path = "../addressing" }
|
||||
nym-sphinx-params = { path = "../params" }
|
||||
nym-sphinx-routing = { path = "../routing" }
|
||||
nym-sphinx-types = { path = "../types" }
|
||||
nym-pemstore = { path = "../../pemstore" }
|
||||
nym-topology = { path = "../../topology" }
|
||||
|
||||
[features]
|
||||
serde = ["serde_crate", "generic-array"]
|
||||
serde = ["serde_crate", "generic-array"]
|
||||
|
||||
@@ -9,7 +9,7 @@ use nym_sphinx_addressing::nodes::{
|
||||
};
|
||||
use nym_sphinx_params::packet_sizes::PacketSize;
|
||||
use nym_sphinx_params::{PacketType, DEFAULT_NUM_MIX_HOPS};
|
||||
use nym_sphinx_types::delays::{self, Delay};
|
||||
use nym_sphinx_types::delays::Delay;
|
||||
use nym_sphinx_types::{NymPacket, NymPacketError, MIN_PACKET_SIZE};
|
||||
use nym_topology::{NymTopology, NymTopologyError};
|
||||
use rand::{CryptoRng, RngCore};
|
||||
@@ -51,7 +51,7 @@ impl SurbAck {
|
||||
{
|
||||
let route =
|
||||
topology.random_route_to_gateway(rng, DEFAULT_NUM_MIX_HOPS, recipient.gateway())?;
|
||||
let delays = delays::generate_from_average_duration(route.len(), average_delay);
|
||||
let delays = nym_sphinx_routing::generate_hop_delays(average_delay, route.len());
|
||||
let destination = recipient.as_sphinx_destination();
|
||||
|
||||
let surb_ack_payload = prepare_identifier(rng, ack_key, marshaled_fragment_id);
|
||||
|
||||
@@ -16,6 +16,7 @@ thiserror = "1"
|
||||
nym-crypto = { path = "../../crypto", features = ["symmetric", "rand"] }
|
||||
nym-sphinx-addressing = { path = "../addressing" }
|
||||
nym-sphinx-params = { path = "../params" }
|
||||
nym-sphinx-routing = { path = "../routing" }
|
||||
nym-sphinx-types = { path = "../types" }
|
||||
nym-topology = { path = "../../topology" }
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::encryption_key::{SurbEncryptionKey, SurbEncryptionKeyError, SurbEncryptionKeySize};
|
||||
@@ -7,7 +7,7 @@ use nym_sphinx_addressing::clients::Recipient;
|
||||
use nym_sphinx_addressing::nodes::{NymNodeRoutingAddress, MAX_NODE_ADDRESS_UNPADDED_LEN};
|
||||
use nym_sphinx_params::packet_sizes::PacketSize;
|
||||
use nym_sphinx_params::{PacketType, ReplySurbKeyDigestAlgorithm, DEFAULT_NUM_MIX_HOPS};
|
||||
use nym_sphinx_types::{delays, NymPacket, SURBMaterial, SphinxError, SURB};
|
||||
use nym_sphinx_types::{NymPacket, SURBMaterial, SphinxError, SURB};
|
||||
use nym_topology::{NymTopology, NymTopologyError};
|
||||
use rand::{CryptoRng, RngCore};
|
||||
use serde::de::{Error as SerdeError, Visitor};
|
||||
@@ -96,7 +96,7 @@ impl ReplySurb {
|
||||
{
|
||||
let route =
|
||||
topology.random_route_to_gateway(rng, DEFAULT_NUM_MIX_HOPS, recipient.gateway())?;
|
||||
let delays = delays::generate_from_average_duration(route.len(), average_delay);
|
||||
let delays = nym_sphinx_routing::generate_hop_delays(average_delay, route.len());
|
||||
let destination = recipient.as_sphinx_destination();
|
||||
|
||||
let surb_material = SURBMaterial::new(route, delays, destination);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::ChunkingError;
|
||||
|
||||
@@ -15,7 +15,8 @@ nym-crypto = { path = "../../crypto" }
|
||||
nym-sphinx-acknowledgements = { path = "../acknowledgements" }
|
||||
nym-sphinx-addressing = { path = "../addressing" }
|
||||
nym-sphinx-chunking = { path = "../chunking" }
|
||||
nym-sphinx-params = { path = "../params" }
|
||||
nym-sphinx-forwarding = { path = "../forwarding" }
|
||||
nym-sphinx-params = { path = "../params" }
|
||||
nym-sphinx-routing = { path = "../routing" }
|
||||
nym-sphinx-types = { path = "../types" }
|
||||
nym-topology = { path = "../../topology" }
|
||||
|
||||
@@ -13,7 +13,7 @@ use nym_sphinx_params::packet_sizes::PacketSize;
|
||||
use nym_sphinx_params::{
|
||||
PacketEncryptionAlgorithm, PacketHkdfAlgorithm, PacketType, DEFAULT_NUM_MIX_HOPS,
|
||||
};
|
||||
use nym_sphinx_types::{delays, NymPacket};
|
||||
use nym_sphinx_types::NymPacket;
|
||||
use nym_topology::{NymTopology, NymTopologyError};
|
||||
use rand::{CryptoRng, RngCore};
|
||||
use std::convert::TryFrom;
|
||||
@@ -120,7 +120,7 @@ where
|
||||
|
||||
let route =
|
||||
topology.random_route_to_gateway(rng, DEFAULT_NUM_MIX_HOPS, full_address.gateway())?;
|
||||
let delays = delays::generate_from_average_duration(route.len(), average_packet_delay);
|
||||
let delays = nym_sphinx_routing::generate_hop_delays(average_packet_delay, route.len());
|
||||
let destination = full_address.as_sphinx_destination();
|
||||
|
||||
let first_hop_address =
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::packet::{FramedNymPacket, Header};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#![allow(deprecated)]
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use std::time::Duration;
|
||||
|
||||
use nym_sphinx_addressing::clients::Recipient;
|
||||
use nym_sphinx_types::Node;
|
||||
use nym_sphinx_types::{delays, Delay, Node};
|
||||
use thiserror::Error;
|
||||
|
||||
pub trait SphinxRouteMaker {
|
||||
@@ -41,3 +43,11 @@ impl SphinxRouteMaker for Vec<Node> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn generate_hop_delays(average_packet_delay: Duration, num_hops: usize) -> Vec<Delay> {
|
||||
if average_packet_delay.is_zero() {
|
||||
vec![nym_sphinx_types::Delay::new_from_millis(0); num_hops]
|
||||
} else {
|
||||
delays::generate_from_average_duration(num_hops, average_packet_delay)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::message::{NymMessage, ACK_OVERHEAD, OUTFOX_ACK_OVERHEAD};
|
||||
@@ -14,7 +14,7 @@ use nym_sphinx_chunking::fragment::{Fragment, FragmentIdentifier};
|
||||
use nym_sphinx_forwarding::packet::MixPacket;
|
||||
use nym_sphinx_params::packet_sizes::PacketSize;
|
||||
use nym_sphinx_params::{PacketType, ReplySurbKeyDigestAlgorithm, DEFAULT_NUM_MIX_HOPS};
|
||||
use nym_sphinx_types::{delays, Delay, NymPacket};
|
||||
use nym_sphinx_types::{Delay, NymPacket};
|
||||
use nym_topology::{NymTopology, NymTopologyError};
|
||||
use rand::{CryptoRng, Rng};
|
||||
use std::convert::TryFrom;
|
||||
@@ -233,7 +233,7 @@ pub trait FragmentPreparer {
|
||||
|
||||
// including set of delays
|
||||
let delays =
|
||||
delays::generate_from_average_duration(route.len(), self.average_packet_delay());
|
||||
nym_sphinx_routing::generate_hop_delays(self.average_packet_delay(), route.len());
|
||||
|
||||
// create the actual sphinx packet here. With valid route and correct payload size,
|
||||
// there's absolutely no reason for this call to fail.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use super::storage;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::constants::{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use super::storage;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use super::storage;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use super::helpers::must_get_gateway_bond_by_owner;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
pub mod queries;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use super::storage;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::constants::CONTRACT_STATE_KEY;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use super::storage;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use super::storage;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use cosmwasm_std::{coin, Addr, Coin, DepsMut, Env, MessageInfo, Response, Storage};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use super::storage;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::constants::{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -61,6 +61,7 @@ The validator binary can be compiled by running the following commands:
|
||||
```
|
||||
git clone https://github.com/nymtech/nyxd.git
|
||||
cd nyxd
|
||||
git checkout release/<nyxd_version>
|
||||
|
||||
# Mainnet
|
||||
make build
|
||||
@@ -77,43 +78,17 @@ At this point, you will have a copy of the `nyxd` binary in your `build/` direct
|
||||
|
||||
You should see help text print out.
|
||||
|
||||
The `nyxd` binary and the `libwasmvm.so` shared object library binary have been compiled. `libwasmvm.so` is the wasm virtual machine which is needed to execute smart contracts.
|
||||
### Linking `nyxd` to `libwasmvm.so`
|
||||
|
||||
```admonish caution title=""
|
||||
If you have compiled these files locally and need to upload both of them to the server on which the validator will run, **or** downloaded a pre-compiled binary from Github, you need to locate and link these files in slightly different ways, outlined below. If you have instead compiled them on the server skip to the step outlining setting `LD_LIBRARY PATH` below.
|
||||
```
|
||||
`libwasmvm.so` is the wasm virtual machine which is needed to execute smart contracts in `v0.26.1`. This file is renamed in `libwasmvm.x86_64.so` in `v0.31.1`.
|
||||
|
||||
To locate these files on your system **if you downloaded a pre-compiled binary from Github** run:
|
||||
If you downloaded your `nyxd` binary from Github, you will have seen this file when un-`tar`-ing the `.tar.gz` file from the releases page.
|
||||
|
||||
```
|
||||
WASMVM_SO=$(ldd path/to/nyxd/binary | grep libwasmvm.so | awk '{ print $3 }')
|
||||
ls ${WASMVM_SO}
|
||||
```
|
||||
If you are seeing an error concerning this file when trying to run `nyxd`, then you need to move the `libwasmvm.so` file to correct location.
|
||||
|
||||
e.g. if you downloaded your `nyxd` binary to `/root` then you would replace `ldd path/to/nyxd/binary` with `ldd nyxd` in the above command.
|
||||
|
||||
|
||||
To locate these files on your system **if you uploaded your validator after compiling it on a local machine** run:
|
||||
|
||||
```
|
||||
WASMVM_SO=$(ldd build/nyxd | grep libwasmvm.so | awk '{ print $3 }')
|
||||
ls ${WASMVM_SO}
|
||||
```
|
||||
|
||||
The above commands will output something like:
|
||||
|
||||
```
|
||||
'/home/username/go/pkg/mod/github.com/!cosm!wasm/wasmvm@v0.13.0/api/libwasmvm.so'
|
||||
```
|
||||
|
||||
When you upload your `nyxd` binary, you'll need to tell it where `libwasmvm.so` is when you start your validator, or it will not run. If you have compiled them on your server then this is not necessary, as the compiled `nyxd` already has access to `libwasmvm.so`.
|
||||
|
||||
Upload both `nyxd` and `libwasmvm.so` to your validator machine. If `nyxd` can't find `libwasmvm.so` you will see an error like the following:
|
||||
|
||||
```
|
||||
./nyxd: error while loading shared libraries: libwasmvm.so: cannot open shared object file: No such file or directory
|
||||
```
|
||||
Simply `cp` or `mv` that file to `/lib/x86_64-linux-gnu/` and re-run `nyxd`.
|
||||
|
||||
### Adding `nyxd` to your `$PATH`
|
||||
You'll need to set `LD_LIBRARY_PATH` in your user's `~/.bashrc` file, and add that to our path. Replace `/home/youruser/path/to/nym/binaries` in the command below to the locations of `nyxd` and `libwasmvm.so` and run it. If you have compiled these on the server, they will be in the `build/` folder:
|
||||
|
||||
```
|
||||
@@ -616,6 +591,12 @@ nyxd tx slashing unjail
|
||||
--fees=7000unyxt
|
||||
```
|
||||
|
||||
### Upgrading your validator
|
||||
|
||||
Upgrading from `v0.26.0` -> `v0.31.1` doesn't require many modifications, simply grab a binary from the [`nyxd` releases page](https://github.com/nymtech/nyxd/releases) and once the chain has halted at the decided upon haltheight, stop your `nyxd` process, replace your binaries, and restart your process.
|
||||
|
||||
You can also use something like [Cosmovisor](https://github.com/cosmos/cosmos-sdk/tree/main/tools/cosmovisor) - grab the relevant information from the current upgrade proposal [here](https://nym.explorers.guru/proposal/8).
|
||||
|
||||
#### Common reasons for your validator being jailed
|
||||
|
||||
The most common reason for your validator being jailed is that your validator is out of memory because of bloated syslogs.
|
||||
|
||||
@@ -47,20 +47,16 @@ The example above involves ephemeral keys - if we want to create and then mainta
|
||||
As seen in the example above, the `mixnet::MixnetClientBuilder::new()` function handles checking for keys in a storage location, loading them if present, or creating them and storing them if not, making client key management very simple.
|
||||
|
||||
### Manually handling storage
|
||||
If you're integrating mixnet functionality into an existing app and want to integrate saving client configs and keys into your existing storage logic, you can manually perform the actions taken automatically above (`examples/manually_handle_keys_and_config.rs`)
|
||||
If you're integrating mixnet functionality into an existing app and want to integrate saving client configs and keys into your existing storage logic, you can manually perform the actions taken automatically above (`examples/manually_handle_storage.rs`)
|
||||
|
||||
```rust,noplayground
|
||||
{{#include ../../../../sdk/rust/nym-sdk/examples/manually_handle_keys_and_config.rs}}
|
||||
{{#include ../../../../sdk/rust/nym-sdk/examples/manually_handle_storage.rs}}
|
||||
```
|
||||
|
||||
### Anonymous replies with SURBs
|
||||
Both functions used to send messages through the mixnet (`send_str` and `send_bytes`) send a pre-determined number of SURBs along with their messages by default.
|
||||
|
||||
The number of SURBs is set [here](https://github.com/nymtech/nym/blob/release/{{platform_release_version}}/sdk/rust/nym-sdk/src/mixnet/client.rs#L35):
|
||||
|
||||
```rust,noplayground
|
||||
{{#include ../../../../sdk/rust/nym-sdk/src/mixnet/client.rs:30}}
|
||||
```
|
||||
The number of SURBs is set [here](https://github.com/nymtech/nym/blob/release/{{platform_release_version}}/sdk/rust/nym-sdk/src/mixnet/client.rs#L36).
|
||||
|
||||
You can read more about how SURBs function under the hood [here](../architecture/traffic-flow.md#private-replies-using-surbs).
|
||||
|
||||
|
||||
@@ -5,23 +5,23 @@ The Nym Desktop Wallet lets you interact with your Nym node and to delegate stak
|
||||
|
||||
You can download it for Mac, Windows, or Linux.
|
||||
|
||||
[](https://github.com/nymtech/nym/releases/tag/nym-wallet-{{platform_release_version}})
|
||||
[](https://github.com/nymtech/nym/releases/tag/nym-wallet-v1.2.4)
|
||||
|
||||
### Bypassing security warnings
|
||||
|
||||
On Windows you will see a security warning pop up when you attempt to run the wallet. We are in the process of getting app store keys from Microsoft so that this doesn't happen. See the section below for details on steps to bypass these.
|
||||
On Windows you will see a security warning pop up when you attempt to run the wallet. We are in the process of getting app store keys from Microsoft so that this doesn't happen. See the section below for details on steps to bypass these.
|
||||
|
||||
#### Linux
|
||||
#### Linux
|
||||
|
||||
You will need to `chmod +x` the AppImage in the terminal (or give it execute permission in your file browser) before it will run.
|
||||
You will need to `chmod +x` the AppImage in the terminal (or give it execute permission in your file browser) before it will run.
|
||||
|
||||
#### Windows
|
||||
#### Windows
|
||||
|
||||
_You will still encounter warnings when opening the wallet on Windows. This is because - although the wallet is approved by Microsoft - it has less than 10 thousand downloads at the current time. Once the wallet has passed this threshold, this warning will disappear._
|
||||
|
||||
Follow the steps below to bypass the warnings.
|
||||
Follow the steps below to bypass the warnings.
|
||||
|
||||
* Select more-info after clicking the msi installer app:
|
||||
* Select more-info after clicking the msi installer app:
|
||||
|
||||

|
||||
|
||||
@@ -29,7 +29,7 @@ Follow the steps below to bypass the warnings.
|
||||
|
||||

|
||||
|
||||
* Follow the installer instructions:
|
||||
* Follow the installer instructions:
|
||||
|
||||

|
||||
|
||||
@@ -39,7 +39,7 @@ Follow the steps below to bypass the warnings.
|
||||
|
||||
### For developers
|
||||
|
||||
If you would like to the compile the wallet yourself, follow the instructions below.
|
||||
If you would like to the compile the wallet yourself, follow the instructions below.
|
||||
|
||||
> Please note that the wallet has currently only been built on the operating systems for which there are binaries as listed above. If you find an issue or any additional prerequisties, please create an issue or PR against `develop` on [Github](https://github.com/nymtech/docs).
|
||||
|
||||
@@ -85,22 +85,22 @@ sudo apt install pkg-config build-essential libssl-dev curl jq
|
||||
|
||||
### Removing signing errors when building in development mode
|
||||
|
||||
If you're wanting to build the wallet yourself, you will need to make a few modifications to the file located at `nym-wallet/src-tauri/tauri.conf.json` before doing so. These relate to the wallet being accepted by Mac and Windows app stores, and so aren't relevant to you when building and running the wallet yourself.
|
||||
If you're wanting to build the wallet yourself, you will need to make a few modifications to the file located at `nym-wallet/src-tauri/tauri.conf.json` before doing so. These relate to the wallet being accepted by Mac and Windows app stores, and so aren't relevant to you when building and running the wallet yourself.
|
||||
|
||||
On **all** operating systems:
|
||||
On **all** operating systems:
|
||||
* set the value of line 49 to `false`
|
||||
* remove lines 50 to 54
|
||||
* remove lines 50 to 54
|
||||
|
||||
As well as these modifications for MacOS and Windows users:
|
||||
* MacOS users must also remove line 39
|
||||
* Windows users must remove lines 42 to 46
|
||||
As well as these modifications for MacOS and Windows users:
|
||||
* MacOS users must also remove line 39
|
||||
* Windows users must remove lines 42 to 46
|
||||
|
||||
### Installation
|
||||
Once you have made these modifications to `tauri.conf.json`, inside of the `nym-wallet` folder, run:
|
||||
|
||||
```
|
||||
yarn install
|
||||
```
|
||||
```
|
||||
|
||||
### Running in Development Mode
|
||||
|
||||
@@ -112,7 +112,7 @@ You can run the wallet without having to install it in development mode by runni
|
||||
yarn dev
|
||||
```
|
||||
|
||||
This will then start the Wallet GUI and produce a binary in `nym-wallet/target/debug/` named `nym-wallet`.
|
||||
This will then start the Wallet GUI and produce a binary in `nym-wallet/target/debug/` named `nym-wallet`.
|
||||
|
||||
### Running in Production Mode
|
||||
|
||||
@@ -165,25 +165,21 @@ To import or create a new account, first you need to create a password for your
|
||||
6. Come back to this page to import or create new accounts
|
||||
|
||||
### Importing or creating account(s) when you have signed in with mnemonic but a password already exists on your machine
|
||||
To import or create a new account, you need to log in with your existing password or create a new password.
|
||||
To import or create a new account, you need to log in with your existing password or create a new password.
|
||||
|
||||
> Creating a new password will overwrite any old one stored on your machine. Make sure you have saved any mnemonics associated with the password before creating a new one.
|
||||
|
||||
1. Log out
|
||||
2. Click on “Forgot password”
|
||||
2. Click on “Forgot password”
|
||||
3. On the next screen select “Create new password”
|
||||
4. Follow the instructions and create a new password
|
||||
5. Sign in using your new password
|
||||
|
||||
### CLI tool for wallet encrypted file (password) recovery:
|
||||
The mnemonics that are stored in the local password protected file can also be decrypted and recovered through a simple CLI tool, `nym-wallet-recovery-cli`.
|
||||
The mnemonics that are stored in the local password protected file can also be decrypted and recovered through a simple CLI tool, `nym-wallet-recovery-cli`.
|
||||
|
||||
```
|
||||
nym-wallet-recovery –file saved-wallet.json –password foo
|
||||
```
|
||||
|
||||
The saved wallet file can be found in `$XDG_DATA_HOME` or `$HOME/.local/share` on Linux, `$HOME/Library/Application Support` on Mac, and `C:\Users\username\AppData\Local` on Windows.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "explorer-api"
|
||||
version = "1.1.22"
|
||||
version = "1.1.23"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use nym_mixnet_contract_common::{MixId, MixNode};
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "nym-gateway"
|
||||
version = "1.1.22"
|
||||
version = "1.1.23"
|
||||
authors = [
|
||||
"Dave Hrycyszyn <futurechimp@users.noreply.github.com>",
|
||||
"Jędrzej Stuczyński <andrew@nymtech.net>",
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "nym-mixnode"
|
||||
version = "1.1.23"
|
||||
version = "1.1.24"
|
||||
authors = [
|
||||
"Dave Hrycyszyn <futurechimp@users.noreply.github.com>",
|
||||
"Jędrzej Stuczyński <andrew@nymtech.net>",
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "nym-api"
|
||||
version = "1.1.23"
|
||||
version = "1.1.24"
|
||||
authors = [
|
||||
"Dave Hrycyszyn <futurechimp@users.noreply.github.com>",
|
||||
"Jędrzej Stuczyński <andrew@nymtech.net>",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::node_status_api::models::ErrorResponse;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use cosmwasm_std::Decimal;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use super::helpers::_get_gateways_detailed;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::nym_contract_cache::cache::NymContractCache;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::{
|
||||
|
||||
@@ -2,6 +2,20 @@
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [v1.1.14] (2023-06-27)
|
||||
|
||||
- Nym connect fails to start when encountering an old config version ([#3588])
|
||||
- NC desktop - apps section adjustments + add monero integration ([#2977])
|
||||
- Fix medium toggle in nym-connect ([#3590])
|
||||
- [bugfix] NC: load old gateway configuration if we're not registering ([#3586])
|
||||
- nym-connect: medium speed setting ([#3585])
|
||||
|
||||
[#3588]: https://github.com/nymtech/nym/issues/3588
|
||||
[#2977]: https://github.com/nymtech/nym/issues/2977
|
||||
[#3590]: https://github.com/nymtech/nym/pull/3590
|
||||
[#3586]: https://github.com/nymtech/nym/pull/3586
|
||||
[#3585]: https://github.com/nymtech/nym/pull/3585
|
||||
|
||||
## [v1.1.13] (2023-06-20)
|
||||
|
||||
- NymConnect - add sentry.io reporting ([#3421])
|
||||
|
||||
Generated
+17
-2
@@ -3220,7 +3220,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-bin-common"
|
||||
version = "0.5.0"
|
||||
version = "0.6.0"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"clap",
|
||||
@@ -3235,7 +3235,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-client-core"
|
||||
version = "1.1.14"
|
||||
version = "1.1.15"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"base64 0.21.2",
|
||||
@@ -3365,6 +3365,7 @@ dependencies = [
|
||||
"nym-credential-storage",
|
||||
"nym-crypto",
|
||||
"nym-socks5-client-core",
|
||||
"nym-sphinx",
|
||||
"nym-task",
|
||||
"pretty_env_logger",
|
||||
"rand 0.8.5",
|
||||
@@ -3735,6 +3736,7 @@ dependencies = [
|
||||
"nym-pemstore",
|
||||
"nym-sphinx-addressing",
|
||||
"nym-sphinx-params",
|
||||
"nym-sphinx-routing",
|
||||
"nym-sphinx-types",
|
||||
"nym-topology",
|
||||
"rand 0.7.3",
|
||||
@@ -3760,6 +3762,7 @@ dependencies = [
|
||||
"nym-crypto",
|
||||
"nym-sphinx-addressing",
|
||||
"nym-sphinx-params",
|
||||
"nym-sphinx-routing",
|
||||
"nym-sphinx-types",
|
||||
"nym-topology",
|
||||
"rand 0.7.3",
|
||||
@@ -3790,6 +3793,7 @@ dependencies = [
|
||||
"nym-sphinx-chunking",
|
||||
"nym-sphinx-forwarding",
|
||||
"nym-sphinx-params",
|
||||
"nym-sphinx-routing",
|
||||
"nym-sphinx-types",
|
||||
"nym-topology",
|
||||
"rand 0.7.3",
|
||||
@@ -3906,6 +3910,7 @@ dependencies = [
|
||||
"nym-service-provider-directory-common",
|
||||
"nym-vesting-contract",
|
||||
"nym-vesting-contract-common",
|
||||
"openssl",
|
||||
"prost",
|
||||
"reqwest",
|
||||
"serde",
|
||||
@@ -4045,6 +4050,15 @@ version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-src"
|
||||
version = "111.26.0+1.1.1u"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "efc62c9f12b22b8f5208c23a7200a442b2e5999f8bdf80233852122b5a4f6f37"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.82"
|
||||
@@ -4054,6 +4068,7 @@ dependencies = [
|
||||
"autocfg",
|
||||
"cc",
|
||||
"libc",
|
||||
"openssl-src",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nym/nym-connect",
|
||||
"version": "1.1.13",
|
||||
"version": "1.1.14",
|
||||
"main": "index.js",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
|
||||
@@ -48,11 +48,12 @@ yaml-rust = "0.4"
|
||||
nym-client-core = { path = "../../../common/client-core" }
|
||||
nym-api-requests = { path = "../../../nym-api/nym-api-requests" }
|
||||
nym-contracts-common = { path = "../../../common/cosmwasm-smart-contracts/contracts-common"}
|
||||
nym-config-common = { path = "../../../common/config", package = "nym-config" }
|
||||
nym-config = { path = "../../../common/config" }
|
||||
nym-crypto = { path = "../../../common/crypto" }
|
||||
nym-credential-storage = { path = "../../../common/credential-storage" }
|
||||
nym-bin-common = { path = "../../../common/bin-common"}
|
||||
nym-socks5-client-core = { path = "../../../common/socks5-client-core" }
|
||||
nym-sphinx = { path = "../../../common/nymsphinx" }
|
||||
nym-task = { path = "../../../common/task" }
|
||||
|
||||
[dev-dependencies]
|
||||
|
||||
@@ -3,12 +3,13 @@
|
||||
|
||||
use crate::config::persistence::NymConnectPaths;
|
||||
use crate::config::template::CONFIG_TEMPLATE;
|
||||
use crate::config::upgrade::try_upgrade_config;
|
||||
use crate::error::{BackendError, Result};
|
||||
use nym_client_core::client::base_client::storage::gateway_details::OnDiskGatewayDetails;
|
||||
use nym_client_core::client::key_manager::persistence::OnDiskKeys;
|
||||
use nym_client_core::config::GatewayEndpointConfig;
|
||||
use nym_client_core::init::GatewaySetup;
|
||||
use nym_config_common::{
|
||||
use nym_config::{
|
||||
must_get_home, read_config_from_toml_file, save_formatted_config_to_file, NymConfigTemplate,
|
||||
DEFAULT_CONFIG_DIR, DEFAULT_CONFIG_FILENAME, DEFAULT_DATA_DIR, NYM_DIR,
|
||||
};
|
||||
@@ -19,8 +20,12 @@ use std::path::{Path, PathBuf};
|
||||
use std::{fs, io};
|
||||
use tap::TapFallible;
|
||||
|
||||
mod old_config_v1_1_13;
|
||||
mod old_config_v1_1_20;
|
||||
mod old_config_v1_1_20_2;
|
||||
mod persistence;
|
||||
mod template;
|
||||
mod upgrade;
|
||||
|
||||
static SOCKS5_CONFIG_ID: &str = "nym-connect";
|
||||
|
||||
@@ -138,6 +143,9 @@ pub async fn init_socks5_config(provider_address: String, chosen_gateway_id: Str
|
||||
.map_err(|_| BackendError::UnableToParseGateway)?;
|
||||
|
||||
let already_init = if default_config_filepath(&id).exists() {
|
||||
// in case we're using old config, try to upgrade it
|
||||
// (if we're using the current version, it's a no-op)
|
||||
try_upgrade_config(&id)?;
|
||||
eprintln!("SOCKS5 client \"{id}\" was already initialised before");
|
||||
true
|
||||
} else {
|
||||
@@ -156,11 +164,15 @@ pub async fn init_socks5_config(provider_address: String, chosen_gateway_id: Str
|
||||
log::trace!("Creating config for id: {id}");
|
||||
let mut config = Config::new(&id, &provider_address);
|
||||
|
||||
if let Ok(raw_validators) = std::env::var(nym_config_common::defaults::var_names::NYM_API) {
|
||||
config.core.base.client.nym_api_urls = nym_config_common::parse_urls(&raw_validators);
|
||||
if let Ok(raw_validators) = std::env::var(nym_config::defaults::var_names::NYM_API) {
|
||||
config.core.base.client.nym_api_urls = nym_config::parse_urls(&raw_validators);
|
||||
}
|
||||
|
||||
let gateway_setup = GatewaySetup::new_fresh(Some(chosen_gateway_id), None);
|
||||
let gateway_setup = if register_gateway {
|
||||
GatewaySetup::new_fresh(Some(chosen_gateway_id), None)
|
||||
} else {
|
||||
GatewaySetup::MustLoad
|
||||
};
|
||||
|
||||
// Setup gateway by either registering a new one, or reusing exiting keys
|
||||
let key_store = OnDiskKeys::new(config.storage_paths.common_paths.keys.clone());
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::config::old_config_v1_1_20::{ConfigV1_1_20, Socks5V1_1_20};
|
||||
use nym_client_core::config::old_config_v1_1_13::OldConfigV1_1_13 as OldBaseConfigV1_1_13;
|
||||
use nym_config::legacy_helpers::nym_config::MigrationNymConfig;
|
||||
use nym_config::must_get_home;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::path::PathBuf;
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct OldConfigV1_1_13 {
|
||||
#[serde(flatten)]
|
||||
pub base: OldBaseConfigV1_1_13<OldConfigV1_1_13>,
|
||||
|
||||
pub socks5: Socks5V1_1_20,
|
||||
}
|
||||
|
||||
impl MigrationNymConfig for OldConfigV1_1_13 {
|
||||
fn default_root_directory() -> PathBuf {
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
let base_dir = must_get_home();
|
||||
#[cfg(any(target_os = "android", target_os = "ios"))]
|
||||
let base_dir = PathBuf::from("/tmp");
|
||||
|
||||
base_dir.join(".nym").join("socks5-clients")
|
||||
}
|
||||
}
|
||||
|
||||
impl From<OldConfigV1_1_13> for ConfigV1_1_20 {
|
||||
fn from(value: OldConfigV1_1_13) -> Self {
|
||||
ConfigV1_1_20 {
|
||||
base: value.base.into(),
|
||||
socks5: value.socks5,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::config::old_config_v1_1_20_2::{
|
||||
ConfigV1_1_20_2, CoreConfigV1_1_20_2, SocksClientPathsV1_1_20_2,
|
||||
};
|
||||
use nym_bin_common::logging::LoggingSettings;
|
||||
use nym_client_core::config::disk_persistence::keys_paths::ClientKeysPaths;
|
||||
use nym_client_core::config::disk_persistence::old_v1_1_20_2::CommonClientPathsV1_1_20_2;
|
||||
use nym_client_core::config::old_config_v1_1_20::ConfigV1_1_20 as BaseConfigV1_1_20;
|
||||
use nym_client_core::config::old_config_v1_1_20_2::ClientV1_1_20_2;
|
||||
use nym_config::legacy_helpers::nym_config::MigrationNymConfig;
|
||||
use nym_config::must_get_home;
|
||||
use nym_socks5_client_core::config::old_config_v1_1_20_2::{
|
||||
BaseClientConfigV1_1_20_2, Socks5DebugV1_1_20_2, Socks5V1_1_20_2,
|
||||
};
|
||||
use nym_socks5_client_core::config::{ProviderInterfaceVersion, Socks5ProtocolVersion};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt::Debug;
|
||||
use std::path::PathBuf;
|
||||
|
||||
const DEFAULT_CONNECTION_START_SURBS: u32 = 20;
|
||||
const DEFAULT_PER_REQUEST_SURBS: u32 = 3;
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct ConfigV1_1_20 {
|
||||
#[serde(flatten)]
|
||||
pub base: BaseConfigV1_1_20<ConfigV1_1_20>,
|
||||
|
||||
pub socks5: Socks5V1_1_20,
|
||||
}
|
||||
|
||||
impl From<ConfigV1_1_20> for ConfigV1_1_20_2 {
|
||||
fn from(value: ConfigV1_1_20) -> Self {
|
||||
ConfigV1_1_20_2 {
|
||||
core: CoreConfigV1_1_20_2 {
|
||||
base: BaseClientConfigV1_1_20_2 {
|
||||
client: ClientV1_1_20_2 {
|
||||
version: value.base.client.version,
|
||||
id: value.base.client.id,
|
||||
disabled_credentials_mode: value.base.client.disabled_credentials_mode,
|
||||
nyxd_urls: value.base.client.nyxd_urls,
|
||||
nym_api_urls: value.base.client.nym_api_urls,
|
||||
gateway_endpoint: value.base.client.gateway_endpoint.into(),
|
||||
},
|
||||
debug: value.base.debug.into(),
|
||||
},
|
||||
socks5: value.socks5.into(),
|
||||
},
|
||||
storage_paths: SocksClientPathsV1_1_20_2 {
|
||||
common_paths: CommonClientPathsV1_1_20_2 {
|
||||
keys: ClientKeysPaths {
|
||||
private_identity_key_file: value.base.client.private_identity_key_file,
|
||||
public_identity_key_file: value.base.client.public_identity_key_file,
|
||||
private_encryption_key_file: value.base.client.private_encryption_key_file,
|
||||
public_encryption_key_file: value.base.client.public_encryption_key_file,
|
||||
gateway_shared_key_file: value.base.client.gateway_shared_key_file,
|
||||
ack_key_file: value.base.client.ack_key_file,
|
||||
},
|
||||
credentials_database: value.base.client.database_path,
|
||||
reply_surb_database: value.base.client.reply_surb_database_path,
|
||||
},
|
||||
},
|
||||
logging: LoggingSettings::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl MigrationNymConfig for ConfigV1_1_20 {
|
||||
fn default_root_directory() -> PathBuf {
|
||||
#[cfg(not(any(target_os = "android", target_os = "ios")))]
|
||||
let base_dir = must_get_home();
|
||||
#[cfg(any(target_os = "android", target_os = "ios"))]
|
||||
let base_dir = PathBuf::from("/tmp");
|
||||
|
||||
base_dir.join(".nym").join("socks5-clients")
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct Socks5V1_1_20 {
|
||||
pub listening_port: u16,
|
||||
|
||||
pub provider_mix_address: String,
|
||||
|
||||
#[serde(default = "ProviderInterfaceVersion::new_legacy")]
|
||||
pub provider_interface_version: ProviderInterfaceVersion,
|
||||
|
||||
#[serde(default = "Socks5ProtocolVersion::new_legacy")]
|
||||
pub socks5_protocol_version: Socks5ProtocolVersion,
|
||||
|
||||
#[serde(default)]
|
||||
pub send_anonymously: bool,
|
||||
|
||||
#[serde(default)]
|
||||
pub socks5_debug: Socks5DebugV1_1_20,
|
||||
}
|
||||
|
||||
impl From<Socks5V1_1_20> for Socks5V1_1_20_2 {
|
||||
fn from(value: Socks5V1_1_20) -> Self {
|
||||
Socks5V1_1_20_2 {
|
||||
listening_port: value.listening_port,
|
||||
provider_mix_address: value.provider_mix_address,
|
||||
provider_interface_version: value.provider_interface_version,
|
||||
socks5_protocol_version: value.socks5_protocol_version,
|
||||
send_anonymously: value.send_anonymously,
|
||||
socks5_debug: value.socks5_debug.into(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct Socks5DebugV1_1_20 {
|
||||
connection_start_surbs: u32,
|
||||
per_request_surbs: u32,
|
||||
}
|
||||
|
||||
impl From<Socks5DebugV1_1_20> for Socks5DebugV1_1_20_2 {
|
||||
fn from(value: Socks5DebugV1_1_20) -> Self {
|
||||
Socks5DebugV1_1_20_2 {
|
||||
connection_start_surbs: value.connection_start_surbs,
|
||||
per_request_surbs: value.per_request_surbs,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Socks5DebugV1_1_20 {
|
||||
fn default() -> Self {
|
||||
Socks5DebugV1_1_20 {
|
||||
connection_start_surbs: DEFAULT_CONNECTION_START_SURBS,
|
||||
per_request_surbs: DEFAULT_PER_REQUEST_SURBS,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::config::persistence::NymConnectPaths;
|
||||
use crate::config::{default_config_filepath, Config};
|
||||
use nym_bin_common::logging::LoggingSettings;
|
||||
use nym_client_core::config::disk_persistence::old_v1_1_20_2::CommonClientPathsV1_1_20_2;
|
||||
use nym_client_core::config::GatewayEndpointConfig;
|
||||
use nym_config::read_config_from_toml_file;
|
||||
pub use nym_socks5_client_core::config::old_config_v1_1_20_2::ConfigV1_1_20_2 as CoreConfigV1_1_20_2;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::io;
|
||||
use std::path::Path;
|
||||
|
||||
#[derive(Debug, Deserialize, PartialEq, Eq, Serialize, Clone)]
|
||||
pub struct SocksClientPathsV1_1_20_2 {
|
||||
#[serde(flatten)]
|
||||
pub common_paths: CommonClientPathsV1_1_20_2,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct ConfigV1_1_20_2 {
|
||||
pub core: CoreConfigV1_1_20_2,
|
||||
|
||||
pub storage_paths: SocksClientPathsV1_1_20_2,
|
||||
|
||||
pub logging: LoggingSettings,
|
||||
}
|
||||
|
||||
impl ConfigV1_1_20_2 {
|
||||
pub fn read_from_toml_file<P: AsRef<Path>>(path: P) -> io::Result<Self> {
|
||||
read_config_from_toml_file(path)
|
||||
}
|
||||
|
||||
pub fn read_from_default_path<P: AsRef<Path>>(id: P) -> io::Result<Self> {
|
||||
Self::read_from_toml_file(default_config_filepath(id))
|
||||
}
|
||||
|
||||
// in this upgrade, gateway endpoint configuration was moved out of the config file,
|
||||
// so its returned to be stored elsewhere.
|
||||
pub fn upgrade(self) -> (Config, GatewayEndpointConfig) {
|
||||
let gateway_details = self.core.base.client.gateway_endpoint.clone().into();
|
||||
let config = Config {
|
||||
core: self.core.into(),
|
||||
storage_paths: NymConnectPaths {
|
||||
common_paths: self.storage_paths.common_paths.upgrade_default(),
|
||||
},
|
||||
// logging: self.logging,
|
||||
};
|
||||
|
||||
(config, gateway_details)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
// Copyright 2022-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use crate::{
|
||||
config::{
|
||||
old_config_v1_1_13::OldConfigV1_1_13, old_config_v1_1_20::ConfigV1_1_20,
|
||||
old_config_v1_1_20_2::ConfigV1_1_20_2, Config,
|
||||
},
|
||||
error::{BackendError, Result},
|
||||
};
|
||||
use log::info;
|
||||
use nym_client_core::{
|
||||
client::{
|
||||
base_client::storage::gateway_details::{OnDiskGatewayDetails, PersistedGatewayDetails},
|
||||
key_manager::persistence::OnDiskKeys,
|
||||
},
|
||||
config::GatewayEndpointConfig,
|
||||
error::ClientCoreError,
|
||||
};
|
||||
|
||||
fn persist_gateway_details(config: &Config, details: GatewayEndpointConfig) -> Result<()> {
|
||||
let details_store =
|
||||
OnDiskGatewayDetails::new(&config.storage_paths.common_paths.gateway_details);
|
||||
let keys_store = OnDiskKeys::new(config.storage_paths.common_paths.keys.clone());
|
||||
let shared_keys = keys_store.ephemeral_load_gateway_keys().map_err(|source| {
|
||||
BackendError::ClientCoreError {
|
||||
source: ClientCoreError::KeyStoreError {
|
||||
source: Box::new(source),
|
||||
},
|
||||
}
|
||||
})?;
|
||||
let persisted_details = PersistedGatewayDetails::new(details, &shared_keys);
|
||||
details_store
|
||||
.store_to_disk(&persisted_details)
|
||||
.map_err(|source| BackendError::ClientCoreError {
|
||||
source: ClientCoreError::GatewayDetailsStoreError {
|
||||
source: Box::new(source),
|
||||
},
|
||||
})
|
||||
}
|
||||
fn try_upgrade_v1_1_13_config(id: &str) -> Result<bool> {
|
||||
use nym_config::legacy_helpers::nym_config::MigrationNymConfig;
|
||||
|
||||
// explicitly load it as v1.1.13 (which is incompatible with the next step, i.e. 1.1.19)
|
||||
let Ok(old_config) = OldConfigV1_1_13::load_from_file(id) else {
|
||||
// if we failed to load it, there might have been nothing to upgrade
|
||||
// or maybe it was an even older file. in either way. just ignore it and carry on with our day
|
||||
return Ok(false);
|
||||
};
|
||||
info!("It seems the client is using <= v1.1.13 config template.");
|
||||
info!("It is going to get updated to the current specification.");
|
||||
|
||||
let updated_step1: ConfigV1_1_20 = old_config.into();
|
||||
let updated_step2: ConfigV1_1_20_2 = updated_step1.into();
|
||||
let (updated, gateway_config) = updated_step2.upgrade();
|
||||
persist_gateway_details(&updated, gateway_config)?;
|
||||
|
||||
updated.save_to_default_location()?;
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
fn try_upgrade_v1_1_20_config(id: &str) -> Result<bool> {
|
||||
use nym_config::legacy_helpers::nym_config::MigrationNymConfig;
|
||||
|
||||
// explicitly load it as v1.1.20 (which is incompatible with the current one, i.e. +1.1.21)
|
||||
let Ok(old_config) = ConfigV1_1_20::load_from_file(id) else {
|
||||
// if we failed to load it, there might have been nothing to upgrade
|
||||
// or maybe it was an even older file. in either way. just ignore it and carry on with our day
|
||||
return Ok(false);
|
||||
};
|
||||
info!("It seems the client is using <= v1.1.20 config template.");
|
||||
info!("It is going to get updated to the current specification.");
|
||||
|
||||
let updated_step1: ConfigV1_1_20_2 = old_config.into();
|
||||
let (updated, gateway_config) = updated_step1.upgrade();
|
||||
persist_gateway_details(&updated, gateway_config)?;
|
||||
|
||||
updated.save_to_default_location()?;
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
fn try_upgrade_v1_1_20_2_config(id: &str) -> Result<bool> {
|
||||
// explicitly load it as v1.1.20_2 (which is incompatible with the current one, i.e. +1.1.21)
|
||||
let Ok(old_config) = ConfigV1_1_20_2::read_from_default_path(id) else {
|
||||
// if we failed to load it, there might have been nothing to upgrade
|
||||
// or maybe it was an even older file. in either way. just ignore it and carry on with our day
|
||||
return Ok(false);
|
||||
};
|
||||
info!("It seems the client is using <= v1.1.20_2 config template.");
|
||||
info!("It is going to get updated to the current specification.");
|
||||
|
||||
let (updated, gateway_config) = old_config.upgrade();
|
||||
persist_gateway_details(&updated, gateway_config)?;
|
||||
|
||||
updated.save_to_default_location()?;
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
pub fn try_upgrade_config(id: &str) -> Result<()> {
|
||||
if try_upgrade_v1_1_13_config(id)? {
|
||||
return Ok(());
|
||||
}
|
||||
if try_upgrade_v1_1_20_config(id)? {
|
||||
return Ok(());
|
||||
}
|
||||
if try_upgrade_v1_1_20_2_config(id)? {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
use nym_config_common::defaults::setup_env;
|
||||
use nym_config::defaults::setup_env;
|
||||
use tauri::Manager;
|
||||
use tokio::sync::RwLock;
|
||||
|
||||
@@ -25,6 +25,11 @@ mod tasks;
|
||||
mod window;
|
||||
|
||||
fn main() {
|
||||
if std::env::var("NYM_CONNECT_ENABLE_MEDIUM").is_ok() {
|
||||
std::env::set_var("NYM_CONNECT_DISABLE_COVER", "1");
|
||||
std::env::set_var("NYM_CONNECT_ENABLE_MIXED_SIZE_PACKETS", "1");
|
||||
std::env::set_var("NYM_CONNECT_DISABLE_PER_HOP_DELAYS", "1");
|
||||
}
|
||||
setup_env(None);
|
||||
println!("Starting up...");
|
||||
|
||||
|
||||
@@ -10,39 +10,58 @@ use nym_contracts_common::types::Percent;
|
||||
static SERVICE_PROVIDER_WELLKNOWN_URL: &str =
|
||||
"https://nymtech.net/.wellknown/connect/service-providers.json";
|
||||
|
||||
// List of network-requesters running with medium toggle enabled, for testing
|
||||
static SERVICE_PROVIDER_WELLKNOWN_URL_MEDIUM: &str =
|
||||
"https://nymtech.net/.wellknown/connect/service-providers-medium.json";
|
||||
|
||||
static HARBOUR_MASTER_URL: &str = "https://harbourmaster.nymtech.net/v1/services/?size=100";
|
||||
|
||||
static GATEWAYS_DETAILED_URL: &str =
|
||||
"https://validator.nymtech.net/api/v1/status/gateways/detailed";
|
||||
|
||||
fn get_services_url() -> &'static str {
|
||||
std::env::var("NYM_CONNECT_ENABLE_MEDIUM")
|
||||
.is_ok()
|
||||
.then(|| SERVICE_PROVIDER_WELLKNOWN_URL_MEDIUM)
|
||||
.unwrap_or(SERVICE_PROVIDER_WELLKNOWN_URL)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn get_services() -> Result<Vec<DirectoryServiceProvider>> {
|
||||
log::trace!("Fetching services");
|
||||
let services_res = reqwest::get(SERVICE_PROVIDER_WELLKNOWN_URL)
|
||||
.await?
|
||||
.json::<Vec<DirectoryService>>()
|
||||
.await?;
|
||||
log::trace!("Received: {:#?}", services_res);
|
||||
let all_services = fetch_services().await?;
|
||||
log::trace!("Received: {:#?}", all_services);
|
||||
|
||||
log::trace!("Fetching gateways");
|
||||
let gateway_res = reqwest::get(GATEWAYS_DETAILED_URL)
|
||||
.await?
|
||||
.json::<Vec<GatewayBondAnnotated>>()
|
||||
.await?;
|
||||
log::trace!("Received: {:#?}", gateway_res);
|
||||
// Early return if we're running with medium toggle enabled
|
||||
if std::env::var("NYM_CONNECT_ENABLE_MEDIUM").is_ok() {
|
||||
return Ok(all_services.into_iter().flat_map(|sp| sp.items).collect());
|
||||
}
|
||||
|
||||
// TODO: get paged
|
||||
log::trace!("Fetching active services");
|
||||
let active_services = reqwest::get(HARBOUR_MASTER_URL)
|
||||
.await?
|
||||
.json::<PagedResult<HarbourMasterService>>()
|
||||
.await?;
|
||||
let active_services = fetch_active_services().await?;
|
||||
log::trace!("Active: {:#?}", active_services);
|
||||
|
||||
let mut filtered: Vec<DirectoryService> = vec![];
|
||||
let filtered_services = filter_out_inactive(all_services, active_services);
|
||||
|
||||
for service in &services_res {
|
||||
let items = service
|
||||
log::trace!("Fetching gateways");
|
||||
let gateway_res = get_gateways_detailed().await?;
|
||||
log::trace!("Received: {:#?}", gateway_res);
|
||||
|
||||
// Use only services that are active AND have a performance of >= 90%
|
||||
let filtered_services_with_good_gateway =
|
||||
filter_out_poor_gateways(filtered_services, gateway_res);
|
||||
|
||||
Ok(filtered_services_with_good_gateway)
|
||||
}
|
||||
|
||||
fn filter_out_inactive(
|
||||
services_res: Vec<DirectoryService>,
|
||||
active_services: PagedResult<HarbourMasterService>,
|
||||
) -> Vec<DirectoryService> {
|
||||
let mut filtered: Vec<DirectoryService> = vec![];
|
||||
for service_type in &services_res {
|
||||
let items = service_type
|
||||
.items
|
||||
.clone()
|
||||
.into_iter()
|
||||
@@ -53,33 +72,48 @@ pub async fn get_services() -> Result<Vec<DirectoryServiceProvider>> {
|
||||
.any(|active| active.service_provider_client_id == sp.address)
|
||||
})
|
||||
.collect_vec();
|
||||
log::trace!("service = {} has {} items", service.id, items.len());
|
||||
log::trace!("service = {} has {} items", service_type.id, items.len());
|
||||
filtered.push(DirectoryService {
|
||||
id: service.id.clone(),
|
||||
description: service.description.clone(),
|
||||
id: service_type.id.clone(),
|
||||
description: service_type.description.clone(),
|
||||
items,
|
||||
})
|
||||
}
|
||||
filtered
|
||||
}
|
||||
|
||||
fn filter_out_poor_gateways(
|
||||
services: Vec<DirectoryService>,
|
||||
gateway_res: Vec<GatewayBondAnnotated>,
|
||||
) -> Vec<DirectoryServiceProvider> {
|
||||
let perf_threshold = Percent::from_percentage_value(90).unwrap();
|
||||
|
||||
// Use only services that are active AND have a performance of >= 90%
|
||||
let services_with_good_performance: Vec<DirectoryServiceProvider> = filtered
|
||||
.iter_mut()
|
||||
.fold(vec![], |mut acc, sp| {
|
||||
acc.append(&mut sp.items);
|
||||
acc
|
||||
})
|
||||
services
|
||||
.into_iter()
|
||||
.flat_map(|sp| sp.items)
|
||||
.filter(|sp| {
|
||||
gateway_res.iter().any(|gateway| {
|
||||
gateway.gateway_bond.gateway.identity_key == sp.gateway
|
||||
&& gateway.performance >= perf_threshold
|
||||
})
|
||||
})
|
||||
.collect();
|
||||
.collect()
|
||||
}
|
||||
|
||||
Ok(services_with_good_performance)
|
||||
async fn fetch_services() -> Result<Vec<DirectoryService>> {
|
||||
let services_url = get_services_url();
|
||||
let services_res = reqwest::get(services_url)
|
||||
.await?
|
||||
.json::<Vec<DirectoryService>>()
|
||||
.await?;
|
||||
Ok(services_res)
|
||||
}
|
||||
|
||||
async fn fetch_active_services() -> Result<PagedResult<HarbourMasterService>> {
|
||||
let active_services = reqwest::get(HARBOUR_MASTER_URL)
|
||||
.await?
|
||||
.json::<PagedResult<HarbourMasterService>>()
|
||||
.await?;
|
||||
Ok(active_services)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
|
||||
@@ -4,6 +4,7 @@ use nym_client_core::client::base_client::storage::{MixnetClientStorage, OnDiskP
|
||||
use nym_client_core::{config::GatewayEndpointConfig, error::ClientCoreStatusMessage};
|
||||
use nym_socks5_client_core::NymClient as Socks5NymClient;
|
||||
use nym_socks5_client_core::Socks5ControlMessageSender;
|
||||
use nym_sphinx::params::PacketSize;
|
||||
use nym_task::manager::TaskStatus;
|
||||
use std::sync::Arc;
|
||||
use tap::TapFallible;
|
||||
@@ -39,9 +40,31 @@ pub async fn start_nym_socks5_client(
|
||||
GatewayEndpointConfig,
|
||||
)> {
|
||||
log::info!("Loading config from file: {id}");
|
||||
let config = Config::read_from_default_path(id)
|
||||
let mut config = Config::read_from_default_path(id)
|
||||
.tap_err(|_| log::warn!("Failed to load configuration file"))?;
|
||||
|
||||
// Disable both the loop cover traffic that runs in the background as well as the Poisson
|
||||
// process that injects cover traffic into the traffic stream.
|
||||
if std::env::var("NYM_CONNECT_DISABLE_COVER").is_ok() {
|
||||
log::warn!("Disabling cover traffic");
|
||||
config.core.base.set_no_cover_traffic_with_keepalive();
|
||||
}
|
||||
|
||||
if std::env::var("NYM_CONNECT_ENABLE_MIXED_SIZE_PACKETS").is_ok() {
|
||||
log::warn!("Enabling mixed size packets");
|
||||
config
|
||||
.core
|
||||
.base
|
||||
.set_secondary_packet_size(Some(PacketSize::ExtendedPacket16));
|
||||
}
|
||||
|
||||
if std::env::var("NYM_CONNECT_DISABLE_PER_HOP_DELAYS").is_ok() {
|
||||
log::warn!("Disabling per-hop delay");
|
||||
config.core.base.set_no_per_hop_delays();
|
||||
}
|
||||
|
||||
log::trace!("Configuration used: {:#?}", config);
|
||||
|
||||
let storage =
|
||||
OnDiskPersistent::from_paths(config.storage_paths.common_paths, &config.core.base.debug)
|
||||
.await?;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"package": {
|
||||
"productName": "nym-connect",
|
||||
"version": "1.1.13"
|
||||
"version": "1.1.14"
|
||||
},
|
||||
"build": {
|
||||
"distDir": "../dist",
|
||||
@@ -28,7 +28,7 @@
|
||||
],
|
||||
"resources": [],
|
||||
"externalBin": [],
|
||||
"copyright": "Copyright © 2021-2022 Nym Technologies SA",
|
||||
"copyright": "Copyright © 2021-2023 Nym Technologies SA",
|
||||
"category": "Business",
|
||||
"shortDescription": "Browse the internet privately using the Nym Mixnet",
|
||||
"longDescription": "",
|
||||
|
||||
@@ -3,34 +3,31 @@ import { Divider, Typography } from '@mui/material';
|
||||
import { Box } from '@mui/system';
|
||||
|
||||
const appsSchema = {
|
||||
messagingApps: ['Telegram', 'Keybase'],
|
||||
wallets: ['Blockstream', 'Electrum'],
|
||||
messagingApps: ['Matrix', 'Telegram', 'Keybase'],
|
||||
wallets: ['Monero', 'Blockstream', 'Electrum'],
|
||||
};
|
||||
|
||||
export const CompatibleApps = () => (
|
||||
<Box>
|
||||
<Typography fontSize="small" color="grey.600" sx={{ mb: 2 }}>
|
||||
<Typography fontWeight="bold" variant="body2" sx={{ mb: 2 }}>
|
||||
Supported apps
|
||||
</Typography>
|
||||
<Typography color="nym.highlight" sx={{ mb: 2 }}>
|
||||
Messaging apps
|
||||
</Typography>
|
||||
|
||||
<Divider sx={{ mb: 2 }} />
|
||||
|
||||
<Box sx={{ mb: 4 }}>
|
||||
<Box sx={{ mb: 2 }}>
|
||||
{appsSchema.messagingApps.map((app) => (
|
||||
<Typography variant="body2" color="grey.400" sx={{ mb: 2 }} key={app}>
|
||||
{app}
|
||||
</Typography>
|
||||
))}
|
||||
</Box>
|
||||
<Divider sx={{ mb: 2 }} />
|
||||
<Typography color="nym.highlight" sx={{ mb: 2 }}>
|
||||
Wallets
|
||||
</Typography>
|
||||
|
||||
<Divider sx={{ mb: 2 }} />
|
||||
|
||||
<Box sx={{ mb: 4 }}>
|
||||
{appsSchema.wallets.map((wallet) => (
|
||||
<Typography variant="body2" color="grey.400" sx={{ mb: 2 }} key={wallet}>
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
],
|
||||
"resources": [],
|
||||
"externalBin": [],
|
||||
"copyright": "Copyright © 2021-2022 Nym Technologies SA",
|
||||
"copyright": "Copyright © 2021-2023 Nym Technologies SA",
|
||||
"category": "Business",
|
||||
"shortDescription": "Browse the internet privately using the Nym Mixnet",
|
||||
"longDescription": "",
|
||||
|
||||
@@ -2,6 +2,7 @@ plugins {
|
||||
id 'com.android.application'
|
||||
id 'org.jetbrains.kotlin.android'
|
||||
id 'org.jetbrains.kotlin.plugin.serialization' version '1.8.21'
|
||||
id "io.sentry.android.gradle" version "3.11.0"
|
||||
}
|
||||
|
||||
android {
|
||||
@@ -101,18 +102,20 @@ dependencies {
|
||||
|
||||
implementation 'androidx.core:core-ktx:1.10.1'
|
||||
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.1'
|
||||
implementation 'androidx.activity:activity-compose:1.5.1'
|
||||
implementation 'androidx.activity:activity-compose:1.7.2'
|
||||
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4'
|
||||
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.4'
|
||||
implementation 'org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.0'
|
||||
implementation platform('androidx.compose:compose-bom:2022.10.00')
|
||||
implementation 'androidx.lifecycle:lifecycle-viewmodel-compose:2.6.1'
|
||||
implementation 'androidx.navigation:navigation-compose:2.6.0'
|
||||
implementation 'androidx.compose.runtime:runtime-livedata'
|
||||
implementation 'androidx.compose.ui:ui'
|
||||
implementation 'androidx.compose.ui:ui-graphics'
|
||||
implementation 'androidx.compose.ui:ui-tooling-preview'
|
||||
implementation 'androidx.compose.material3:material3'
|
||||
implementation 'androidx.work:work-runtime-ktx:2.8.1'
|
||||
implementation 'androidx.datastore:datastore-preferences:1.0.0'
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.Nyms5"
|
||||
android:enableOnBackInvokedCallback="true"
|
||||
tools:targetApi="31">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
@@ -34,6 +35,20 @@
|
||||
android:name="androidx.startup.InitializationProvider"
|
||||
android:authorities="${applicationId}.androidx-startup"
|
||||
tools:node="remove" />
|
||||
|
||||
<!-- Sentry -->
|
||||
<meta-data
|
||||
android:name="io.sentry.auto-init"
|
||||
android:value="false" />
|
||||
<!-- enable screenshot for crashes -->
|
||||
<meta-data
|
||||
android:name="io.sentry.attach-screenshot"
|
||||
android:value="true" />
|
||||
<!-- enable view hierarchy for crashes -->
|
||||
<meta-data
|
||||
android:name="io.sentry.attach-view-hierarchy"
|
||||
android:value="true" />
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
||||
@@ -1,9 +1,21 @@
|
||||
package net.nymtech.nyms5
|
||||
|
||||
import android.app.Application
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import androidx.datastore.core.DataStore
|
||||
import androidx.datastore.preferences.core.Preferences
|
||||
import androidx.datastore.preferences.core.booleanPreferencesKey
|
||||
import androidx.datastore.preferences.preferencesDataStore
|
||||
import androidx.work.Configuration
|
||||
import androidx.work.DelegatingWorkerFactory
|
||||
import io.sentry.android.core.SentryAndroid
|
||||
import kotlinx.coroutines.flow.first
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.runBlocking
|
||||
|
||||
val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "settings")
|
||||
val monitoringKey = booleanPreferencesKey("monitoring")
|
||||
|
||||
class App : Application(), Configuration.Provider {
|
||||
companion object {
|
||||
@@ -13,6 +25,30 @@ class App : Application(), Configuration.Provider {
|
||||
|
||||
private val tag = "App"
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
val app = this
|
||||
|
||||
runBlocking {
|
||||
val monitoring = applicationContext.dataStore.data.map { preferences ->
|
||||
preferences[monitoringKey] ?: false
|
||||
}.first()
|
||||
|
||||
if (monitoring) {
|
||||
Log.i(tag, "Performance monitoring and error reporting enabled")
|
||||
SentryAndroid.init(app) { options ->
|
||||
options.dsn =
|
||||
"https://6872f5818bc147ef9c0fce114fcaac8a@o967446.ingest.sentry.io/4505306218102784"
|
||||
options.enableAllAutoBreadcrumbs(true)
|
||||
|
||||
// TODO should be adjusted in production env
|
||||
options.tracesSampleRate = 1.0
|
||||
options.profilesSampleRate = 1.0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getWorkManagerConfiguration(): Configuration {
|
||||
val workerFactory = DelegatingWorkerFactory()
|
||||
// pass in the NymProxy class instance
|
||||
|
||||
@@ -14,11 +14,21 @@ import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.ArrowBack
|
||||
import androidx.compose.material.icons.filled.Menu
|
||||
import androidx.compose.material3.CenterAlignedTopAppBar
|
||||
import androidx.compose.material3.DropdownMenu
|
||||
import androidx.compose.material3.DropdownMenuItem
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.LinearProgressIndicator
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Switch
|
||||
import androidx.compose.material3.Text
|
||||
@@ -34,6 +44,8 @@ import androidx.lifecycle.repeatOnLifecycle
|
||||
import kotlinx.coroutines.launch
|
||||
import net.nymtech.nyms5.ui.theme.NymTheme
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.graphics.Color
|
||||
@@ -42,8 +54,17 @@ import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import androidx.compose.ui.text.font.FontStyle
|
||||
import androidx.datastore.core.DataStore
|
||||
import androidx.datastore.preferences.core.Preferences
|
||||
import androidx.datastore.preferences.core.edit
|
||||
import androidx.navigation.compose.NavHost
|
||||
import androidx.navigation.compose.composable
|
||||
import androidx.navigation.compose.currentBackStackEntryAsState
|
||||
import androidx.navigation.compose.rememberNavController
|
||||
import androidx.work.WorkInfo
|
||||
import androidx.work.WorkManager
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
class MainActivity : ComponentActivity() {
|
||||
private val tag = "MainActivity"
|
||||
@@ -81,18 +102,16 @@ class MainActivity : ComponentActivity() {
|
||||
|
||||
lifecycleScope.launch {
|
||||
repeatOnLifecycle(Lifecycle.State.STARTED) {
|
||||
Log.d(tag, "____uiState collect")
|
||||
viewModel.uiState.collect {
|
||||
setContent {
|
||||
NymTheme {
|
||||
// A surface container using the 'background' color from the theme
|
||||
Surface(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
color = MaterialTheme.colorScheme.background
|
||||
) {
|
||||
Log.d(tag, "____UI recompose")
|
||||
applicationContext.dataStore.data.map { preferences ->
|
||||
preferences[monitoringKey] ?: false
|
||||
}.collect { monitoring ->
|
||||
viewModel.uiState.collect {
|
||||
setContent {
|
||||
NymTheme {
|
||||
val loading = it.loading
|
||||
|
||||
S5ClientSwitch(it.connected, loading, {
|
||||
HomeScreen(it, monitoring, applicationContext.dataStore) {
|
||||
if (!loading) {
|
||||
when {
|
||||
it -> {
|
||||
@@ -106,7 +125,7 @@ class MainActivity : ComponentActivity() {
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -121,6 +140,85 @@ class MainActivity : ComponentActivity() {
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun HomeScreen(
|
||||
proxyState: MainViewModel.ProxyState,
|
||||
monitoring: Boolean,
|
||||
dataStore: DataStore<Preferences>,
|
||||
onSwitch: (value: Boolean) -> Unit,
|
||||
) {
|
||||
val navController = rememberNavController()
|
||||
var expanded by remember { mutableStateOf(false) }
|
||||
val scope = rememberCoroutineScope()
|
||||
|
||||
Scaffold(topBar = {
|
||||
CenterAlignedTopAppBar(
|
||||
title = {
|
||||
Text(stringResource(R.string.app_name))
|
||||
},
|
||||
navigationIcon = {
|
||||
val navBackStackEntry by navController.currentBackStackEntryAsState()
|
||||
val currentRoute = navBackStackEntry?.destination?.route
|
||||
|
||||
if (currentRoute === "proxy") {
|
||||
IconButton(onClick = { expanded = true }) {
|
||||
Icon(
|
||||
imageVector = Icons.Filled.Menu,
|
||||
contentDescription = "Main menu"
|
||||
)
|
||||
}
|
||||
DropdownMenu(
|
||||
expanded = expanded,
|
||||
onDismissRequest = { expanded = false }
|
||||
) {
|
||||
DropdownMenuItem(onClick = {
|
||||
navController.navigate("monitoring") {
|
||||
popUpTo("proxy")
|
||||
}
|
||||
expanded = false
|
||||
}, text = {
|
||||
Text("Error reporting")
|
||||
})
|
||||
}
|
||||
} else {
|
||||
IconButton(onClick = {
|
||||
navController.navigate("proxy") {
|
||||
popUpTo("proxy")
|
||||
}
|
||||
}) {
|
||||
Icon(
|
||||
imageVector = Icons.Filled.ArrowBack,
|
||||
contentDescription = "Back home"
|
||||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
}) { contentPadding ->
|
||||
NavHost(
|
||||
navController = navController,
|
||||
startDestination = "proxy",
|
||||
modifier = Modifier.padding(contentPadding)
|
||||
) {
|
||||
composable("proxy") {
|
||||
S5ClientSwitch(
|
||||
connected = proxyState.connected,
|
||||
loading = proxyState.loading,
|
||||
onSwitch = onSwitch
|
||||
)
|
||||
}
|
||||
composable("monitoring") {
|
||||
Monitoring(initialValue = monitoring) {
|
||||
scope.launch(Dispatchers.IO) {
|
||||
dataStore.edit { settings -> settings[monitoringKey] = it }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun S5ClientSwitch(
|
||||
@@ -203,6 +301,46 @@ fun S5ClientSwitch(
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun Monitoring(
|
||||
modifier: Modifier = Modifier,
|
||||
initialValue: Boolean,
|
||||
onSwitch: (value: Boolean) -> Unit,
|
||||
) {
|
||||
var monitoring by remember { mutableStateOf(initialValue) }
|
||||
|
||||
Column(
|
||||
modifier = modifier
|
||||
.padding(16.dp)
|
||||
.verticalScroll(rememberScrollState())
|
||||
) {
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Text("Enable error reporting")
|
||||
Spacer(modifier = modifier.width(16.dp))
|
||||
Switch(checked = monitoring, onCheckedChange = {
|
||||
monitoring = it
|
||||
onSwitch(it)
|
||||
})
|
||||
}
|
||||
Spacer(modifier = modifier.height(18.dp))
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.warning_24),
|
||||
contentDescription = "copy to clipboard",
|
||||
tint = Color.Yellow
|
||||
)
|
||||
Spacer(modifier = modifier.width(16.dp))
|
||||
Text(stringResource(R.string.monitoring_desc_3), color = Color.Yellow)
|
||||
}
|
||||
Spacer(modifier = modifier.height(18.dp))
|
||||
Text(stringResource(R.string.monitoring_desc_1))
|
||||
Spacer(modifier = modifier.height(18.dp))
|
||||
Text(stringResource(R.string.monitoring_desc_2))
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun PreviewSocks5Client() {
|
||||
@@ -225,3 +363,18 @@ fun PreviewSocks5Client() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun PreviewMonitoring() {
|
||||
NymTheme {
|
||||
Surface(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
color = MaterialTheme.colorScheme.background
|
||||
) {
|
||||
Monitoring(initialValue = false) {
|
||||
Log.d("Monitoring", "switch $it")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ class MainViewModel(
|
||||
private val workManager: WorkManager,
|
||||
private val nymProxy: NymProxy
|
||||
) : ViewModel() {
|
||||
private val tag = "viewModel"
|
||||
private val tag = "MainViewModel"
|
||||
|
||||
private val workRequest: OneTimeWorkRequest =
|
||||
OneTimeWorkRequestBuilder<ProxyWorker>()
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<vector android:height="24dp" android:tint="#000000"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M1,21h22L12,2 1,21zM13,18h-2v-2h2v2zM13,14h-2v-4h2v4z"/>
|
||||
</vector>
|
||||
@@ -11,4 +11,8 @@
|
||||
<string name="sp_url">https://harbourmaster.nymtech.net/v1/services?size=100</string>
|
||||
<string name="default_sp">DpB3cHAchJiNBQi5FrZx2csXb1mrHkpYh9Wzf8Rjsuko.ANNWrvHqMYuertHGHUrZdBntQhpzfbWekB39qez9U2Vx@2BuMSfMW3zpeAjKXyKLhmY4QW1DXurrtSPEJ6CjX3SEh</string>
|
||||
<string name="connected_text">Connected to the mixnet</string>
|
||||
<string name="monitoring_desc_1">Help Nym developers to fix errors, crashes and improve the application by enabling this option. If errors occur or if the app crashes, it will automatically send a report. Also it tracks various performance metrics. We use sentry.io service to handle this.</string>
|
||||
<string name="monitoring_desc_2">Note: A report can include your external IP, this can be useful to catch issues related to IP location.
|
||||
All recorded data is used by Nym developers and for app development purposes only.</string>
|
||||
<string name="monitoring_desc_3">You must restart the application for the change to take effect.</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,3 @@
|
||||
defaults.project=nym-connect-android
|
||||
defaults.org=nymtech
|
||||
# auth.token=xxx
|
||||
@@ -2,6 +2,12 @@
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [v1.2.5] (2023-06-27)
|
||||
|
||||
- Wallet - add "Test my node" in the Node Settings and show its results ([#2314])
|
||||
|
||||
[#2314]: https://github.com/nymtech/nym/issues/2314
|
||||
|
||||
## [v1.2.4] (2023-06-06)
|
||||
|
||||
- Wallet - Bonding page does not load the node info automatically unless you navigate back and forth from it! ([#3478])
|
||||
|
||||
Generated
+13
-2
@@ -2915,7 +2915,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-bin-common"
|
||||
version = "0.5.0"
|
||||
version = "0.6.0"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"clap",
|
||||
@@ -3220,6 +3220,7 @@ dependencies = [
|
||||
"nym-service-provider-directory-common",
|
||||
"nym-vesting-contract",
|
||||
"nym-vesting-contract-common",
|
||||
"openssl",
|
||||
"prost",
|
||||
"reqwest",
|
||||
"serde",
|
||||
@@ -3297,7 +3298,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym_wallet"
|
||||
version = "1.2.4"
|
||||
version = "1.2.5"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"base64 0.13.1",
|
||||
@@ -3447,6 +3448,15 @@ version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-src"
|
||||
version = "111.26.0+1.1.1u"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "efc62c9f12b22b8f5208c23a7200a442b2e5999f8bdf80233852122b5a4f6f37"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.80"
|
||||
@@ -3456,6 +3466,7 @@ dependencies = [
|
||||
"autocfg",
|
||||
"cc",
|
||||
"libc",
|
||||
"openssl-src",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2021-2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use nym_mixnet_contract_common::{EpochId, Interval as ContractInterval, IntervalId};
|
||||
|
||||
@@ -10,27 +10,30 @@ pub(crate) const STAKE_DENOM: DenomDetails = DenomDetails::new("unyx", "nyx", 6)
|
||||
// -- Contract addresses --
|
||||
|
||||
pub(crate) const MIXNET_CONTRACT_ADDRESS: &str =
|
||||
"n14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9sjyvg3g";
|
||||
"n10qt8wg0n7z740ssvf3urmvgtjhxpyp74hxqvqt7z226gykuus7eq5u9pvq";
|
||||
pub(crate) const VESTING_CONTRACT_ADDRESS: &str =
|
||||
"n1nc5tatafv6eyq7llkr2gv50ff9e22mnf70qgjlv737ktmt4eswrq73f2nw";
|
||||
"n1vguuxez2h5ekltfj9gjd62fs5k4rl2zy5hfrncasykzw08rezpfstk9xtk";
|
||||
pub(crate) const BANDWIDTH_CLAIM_CONTRACT_ADDRESS: &str =
|
||||
"n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0";
|
||||
pub(crate) const COCONUT_BANDWIDTH_CONTRACT_ADDRESS: &str =
|
||||
"n1ghd753shjuwexxywmgs4xz7x2q732vcn7ty4yw";
|
||||
pub(crate) const GROUP_CONTRACT_ADDRESS: &str = "n17p9rzwnnfxcjp32un9ug7yhhzgtkhvl988qccs";
|
||||
pub(crate) const MULTISIG_CONTRACT_ADDRESS: &str = "n17p9rzwnnfxcjp32un9ug7yhhzgtkhvl988qccs";
|
||||
pub(crate) const COCONUT_DKG_CONTRACT_ADDRESS: &str = "n17p9rzwnnfxcjp32un9ug7yhhzgtkhvl988qccs";
|
||||
pub(crate) const GROUP_CONTRACT_ADDRESS: &str =
|
||||
"n1g4xlpqy29m50j5y69reguae328tc9y83l4299pf2wmjn0xczq5js3704ql";
|
||||
pub(crate) const MULTISIG_CONTRACT_ADDRESS: &str =
|
||||
"n1p54qvfde6mpnqvz3dnpa78x2qyyr5k4sgw9qr97mxjgklc5gze9sv6t964";
|
||||
pub(crate) const COCONUT_DKG_CONTRACT_ADDRESS: &str =
|
||||
"n1xqkp8x4gqwjnhemtemc5dqhwll6w6rrgpywvhka7sh8vz8swul9sp3lv3w";
|
||||
pub(crate) const SERVICE_PROVIDER_DIRECTORY_CONTRACT_ADDRESS: &str =
|
||||
"n1ryt076cufyddallg5x0gz3qjz0pd3wg0m4cwkg9njhmlnp6u88qq6nczgj";
|
||||
"n1nhdr07kmjns2x8dnp53tdk4qxreze8zdxj6xucyvkdj9tta73rjqa96wps";
|
||||
pub(crate) const NAME_SERVICE_CONTRACT_ADDRESS: &str =
|
||||
"n1cm2u5vfjd3zalfw0p65xyh4tcrw3hjlm0960gzhewga449h4mgas77mjkl";
|
||||
"n1uz24lsnwxvhep8m3gjec7ev86twlhlqrf5rphlgn3rda3zu048ssjqr5w9";
|
||||
|
||||
// -- Constructor functions --
|
||||
|
||||
pub(crate) fn validators() -> Vec<ValidatorDetails> {
|
||||
vec![ValidatorDetails::new(
|
||||
"https://qwerty-validator.qa.nymte.ch/",
|
||||
Some("https://qwerty-validator-api.qa.nymte.ch/api"),
|
||||
"https://qa-validator.qa.nymte.ch/",
|
||||
Some("https://qa-nym-api.qa.nymte.ch/api"),
|
||||
)]
|
||||
}
|
||||
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
"lodash": "^4.17.21",
|
||||
"notistack": "^2.0.3",
|
||||
"npm-run-all": "^4.1.5",
|
||||
"nym-client-wasm": "1.1.1",
|
||||
"qrcode.react": "^1.0.1",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
|
||||
@@ -37,7 +37,7 @@ serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
serde_repr = "0.1"
|
||||
strum = { version = "0.23", features = ["derive"] }
|
||||
tauri = { version = "=1.2.3", features = ["clipboard-all", "shell-open", "updater", "window-maximize"] }
|
||||
tauri = { version = "=1.2.3", features = ["clipboard-all", "shell-open", "updater", "window-maximize", "window-print"] }
|
||||
tendermint-rpc = "0.23.0"
|
||||
time = { version = "0.3.17", features = ["local-offset"] }
|
||||
thiserror = "1.0"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user