Compare commits
9 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8486324e5e | |||
| e4f34833ef | |||
| 5044764a80 | |||
| c178438f06 | |||
| 22f3c8aa40 | |||
| de2e721ba7 | |||
| b94fbcb6db | |||
| 7735f64c6d | |||
| 3857313808 |
@@ -9,12 +9,12 @@ jobs:
|
||||
outputs:
|
||||
matrix: ${{ steps.set-matrix.outputs.matrix }}
|
||||
steps:
|
||||
# creates the matrix strategy from nightly_build_matrix_includes.json
|
||||
# creates the matrix strategy from nightly_build_release_matrix.json
|
||||
- uses: actions/checkout@v3
|
||||
- id: set-matrix
|
||||
uses: JoshuaTheMiller/conditional-build-matrix@main
|
||||
with:
|
||||
inputFile: '.github/workflows/nightly_build_matrix_includes.json'
|
||||
inputFile: '.github/workflows/nightly_build_release_matrix.json'
|
||||
filter: '[?runOnEvent==`${{ github.event_name }}` || runOnEvent==`always`]'
|
||||
get_release:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -174,7 +174,7 @@ jobs:
|
||||
args: --manifest-path nym-wallet/Cargo.toml --workspace --all-targets -- -D warnings
|
||||
|
||||
notification:
|
||||
needs: [build,get_release]
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Collect jobs status
|
||||
@@ -192,7 +192,7 @@ jobs:
|
||||
NYM_PROJECT_NAME: "Nym nightly build on latest release"
|
||||
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
||||
GIT_COMMIT_MESSAGE: "${{ github.event.head_commit.message }}"
|
||||
GIT_BRANCH: "https://github.com/nymtech/nym/tree/${{needs.get_release.outputs.output1}}"
|
||||
GIT_BRANCH: "${GITHUB_REF##*/}"
|
||||
KEYBASE_NYMBOT_USERNAME: "${{ secrets.KEYBASE_NYMBOT_USERNAME }}"
|
||||
KEYBASE_NYMBOT_PAPERKEY: "${{ secrets.KEYBASE_NYMBOT_PAPERKEY }}"
|
||||
KEYBASE_NYMBOT_TEAM: "${{ secrets.KEYBASE_NYMBOT_TEAM }}"
|
||||
|
||||
@@ -1,203 +0,0 @@
|
||||
name: Nightly builds on second latest release
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '24 2 * * *'
|
||||
jobs:
|
||||
matrix_prep:
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
matrix: ${{ steps.set-matrix.outputs.matrix }}
|
||||
steps:
|
||||
# creates the matrix strategy from nightly_build_matrix_includes.json
|
||||
- uses: actions/checkout@v3
|
||||
- id: set-matrix
|
||||
uses: JoshuaTheMiller/conditional-build-matrix@main
|
||||
with:
|
||||
inputFile: '.github/workflows/nightly_build_matrix_includes.json'
|
||||
filter: '[?runOnEvent==`${{ github.event_name }}` || runOnEvent==`always`]'
|
||||
get_release:
|
||||
runs-on: ubuntu-latest
|
||||
needs: matrix_prep
|
||||
outputs:
|
||||
output1: ${{ steps.step2.outputs.latest_release }}
|
||||
steps:
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v3
|
||||
- name: Fetch all branches
|
||||
run: git fetch --all
|
||||
- name: Set output variable to latest release branch
|
||||
id: step2
|
||||
run: echo "latest_release=$(git branch -r | grep -E 'release/v[0-9]+\.[0-9]+\.[0-9]+' | tail -n 2 | head -n 1 | sed 's/ origin\///')" >> $GITHUB_OUTPUT
|
||||
build:
|
||||
needs: [get_release,matrix_prep]
|
||||
strategy:
|
||||
matrix: ${{fromJson(needs.matrix_prep.outputs.matrix)}}
|
||||
runs-on: ${{ matrix.os }}
|
||||
continue-on-error: ${{ matrix.rust == 'nightly' || matrix.rust == 'beta' || matrix.rust == 'stable' }}
|
||||
steps:
|
||||
- name: Install Dependencies (Linux)
|
||||
run: sudo apt-get update && sudo apt-get install libwebkit2gtk-4.0-dev build-essential curl wget libssl-dev libgtk-3-dev libudev-dev squashfs-tools
|
||||
if: matrix.os == 'ubuntu-latest'
|
||||
|
||||
- name: Check out latest release branch
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
ref: ${{needs.get_release.outputs.output1}}
|
||||
|
||||
- name: Install rust toolchain
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: ${{ matrix.rust }}
|
||||
override: true
|
||||
components: rustfmt, clippy
|
||||
|
||||
- name: Build all binaries
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: build
|
||||
args: --workspace
|
||||
|
||||
- name: Reclaim some disk space (because Windows is being annoying)
|
||||
uses: actions-rs/cargo@v1
|
||||
if: ${{ matrix.os == 'windows-latest' }}
|
||||
with:
|
||||
command: clean
|
||||
|
||||
- name: Run all tests
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: test
|
||||
args: --workspace
|
||||
|
||||
- name: Reclaim some disk space (because Windows is being annoying)
|
||||
uses: actions-rs/cargo@v1
|
||||
if: ${{ matrix.os == 'windows-latest' }}
|
||||
with:
|
||||
command: clean
|
||||
|
||||
- name: Run expensive tests
|
||||
if: github.ref == 'refs/heads/develop' || github.event.pull_request.base.ref == 'develop' || github.event.pull_request.base.ref == 'master'
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: test
|
||||
args: --workspace --all-features -- --ignored
|
||||
|
||||
- name: Check formatting
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: fmt
|
||||
args: --all -- --check
|
||||
|
||||
- name: Reclaim some disk space (because Windows is being annoying)
|
||||
uses: actions-rs/cargo@v1
|
||||
if: ${{ matrix.os == 'windows-latest' }}
|
||||
with:
|
||||
command: clean
|
||||
|
||||
- uses: actions-rs/clippy-check@v1
|
||||
name: Clippy checks
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
args: --all-features
|
||||
|
||||
- name: Run clippy
|
||||
uses: actions-rs/cargo@v1
|
||||
if: ${{ matrix.rust != 'nightly' }}
|
||||
with:
|
||||
command: clippy
|
||||
args: --workspace --all-targets -- -D warnings
|
||||
|
||||
- name: Reclaim some disk space
|
||||
uses: actions-rs/cargo@v1
|
||||
if: ${{ matrix.os == 'windows-latest' || matrix.os == 'ubuntu-latest' }}
|
||||
with:
|
||||
command: clean
|
||||
|
||||
# COCONUT stuff
|
||||
- name: Build all binaries with coconut enabled
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: build
|
||||
args: --workspace --features=coconut
|
||||
|
||||
- name: Reclaim some disk space (because Windows is being annoying)
|
||||
uses: actions-rs/cargo@v1
|
||||
if: ${{ matrix.os == 'windows-latest' }}
|
||||
with:
|
||||
command: clean
|
||||
|
||||
- name: Run all tests with coconut enabled
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: test
|
||||
args: --workspace --features=coconut
|
||||
|
||||
- name: Reclaim some disk space (because Windows is being annoying)
|
||||
uses: actions-rs/cargo@v1
|
||||
if: ${{ matrix.os == 'windows-latest' }}
|
||||
with:
|
||||
command: clean
|
||||
|
||||
- name: Run clippy with coconut enabled
|
||||
uses: actions-rs/cargo@v1
|
||||
if: ${{ matrix.rust != 'nightly' }}
|
||||
with:
|
||||
command: clippy
|
||||
args: --workspace --all-targets --features=coconut -- -D warnings
|
||||
|
||||
# nym-wallet (the rust part)
|
||||
- name: Build nym-wallet rust code
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: build
|
||||
args: --manifest-path nym-wallet/Cargo.toml --workspace
|
||||
|
||||
- name: Run nym-wallet tests
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: test
|
||||
args: --manifest-path nym-wallet/Cargo.toml --workspace
|
||||
|
||||
- name: Check nym-wallet formatting
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: fmt
|
||||
args: --manifest-path nym-wallet/Cargo.toml --all -- --check
|
||||
|
||||
- name: Run clippy for nym-wallet
|
||||
uses: actions-rs/cargo@v1
|
||||
if: ${{ matrix.rust != 'nightly' }}
|
||||
with:
|
||||
command: clippy
|
||||
args: --manifest-path nym-wallet/Cargo.toml --workspace --all-targets -- -D warnings
|
||||
|
||||
notification:
|
||||
needs: [build,get_release]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Collect jobs status
|
||||
uses: technote-space/workflow-conclusion-action@v2
|
||||
- name: Check out repository code
|
||||
uses: actions/checkout@v3
|
||||
- name: Keybase - Node Install
|
||||
if: env.WORKFLOW_CONCLUSION == 'failure'
|
||||
run: npm install
|
||||
working-directory: .github/workflows/support-files
|
||||
- name: Keybase - Send Notification
|
||||
if: env.WORKFLOW_CONCLUSION == 'failure'
|
||||
env:
|
||||
NYM_NOTIFICATION_KIND: nightly
|
||||
NYM_PROJECT_NAME: "Nym nightly build on latest release"
|
||||
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
||||
GIT_COMMIT_MESSAGE: "${{ github.event.head_commit.message }}"
|
||||
GIT_BRANCH: "https://github.com/nymtech/nym/tree/${{needs.get_release.outputs.output1}}"
|
||||
KEYBASE_NYMBOT_USERNAME: "${{ secrets.KEYBASE_NYMBOT_USERNAME }}"
|
||||
KEYBASE_NYMBOT_PAPERKEY: "${{ secrets.KEYBASE_NYMBOT_PAPERKEY }}"
|
||||
KEYBASE_NYMBOT_TEAM: "${{ secrets.KEYBASE_NYMBOT_TEAM }}"
|
||||
KEYBASE_NYM_CHANNEL: "ci-nightly-release"
|
||||
IS_SUCCESS: "${{ env.WORKFLOW_CONCLUSION == 'success' }}"
|
||||
uses: docker://keybaseio/client:stable-node
|
||||
with:
|
||||
args: .github/workflows/support-files/notifications/entry_point.sh
|
||||
@@ -0,0 +1,50 @@
|
||||
[
|
||||
{
|
||||
"os":"ubuntu-latest",
|
||||
"rust":"stable",
|
||||
"runOnEvent":"workflow_dispatch"
|
||||
},
|
||||
|
||||
{
|
||||
"os":"windows-latest",
|
||||
"rust":"stable",
|
||||
"runOnEvent":"workflow_dispatch"
|
||||
},
|
||||
{
|
||||
"os":"macos-latest",
|
||||
"rust":"stable",
|
||||
"runOnEvent":"workflow_dispatch"
|
||||
},
|
||||
|
||||
{
|
||||
"os":"ubuntu-latest",
|
||||
"rust":"beta",
|
||||
"runOnEvent":"workflow_dispatch"
|
||||
},
|
||||
{
|
||||
"os":"windows-latest",
|
||||
"rust":"beta",
|
||||
"runOnEvent":"workflow_dispatch"
|
||||
},
|
||||
{
|
||||
"os":"macos-latest",
|
||||
"rust":"beta",
|
||||
"runOnEvent":"workflow_dispatch"
|
||||
},
|
||||
|
||||
{
|
||||
"os":"ubuntu-latest",
|
||||
"rust":"nightly",
|
||||
"runOnEvent":"workflow_dispatch"
|
||||
},
|
||||
{
|
||||
"os":"windows-latest",
|
||||
"rust":"nightly",
|
||||
"runOnEvent":"workflow_dispatch"
|
||||
},
|
||||
{
|
||||
"os":"macos-latest",
|
||||
"rust":"nightly",
|
||||
"runOnEvent":"workflow_dispatch"
|
||||
}
|
||||
]
|
||||
+1
-6
@@ -2,7 +2,7 @@
|
||||
|
||||
Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## Unreleased
|
||||
## [v1.1.1](https://github.com/nymtech/nym/tree/v1.1.1) (2022-11-29)
|
||||
|
||||
### Added
|
||||
|
||||
@@ -17,11 +17,6 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https://
|
||||
- clients,validator-api: take coconut signers from the chain instead of specifying them via CLI ([#1747])
|
||||
- multisig contract: add DKG contract to the list of addresses that can create proposals ([#1747])
|
||||
- socks5-client: wait closing inbound connection until data is sent, and throttle incoming data in general ([#1783])
|
||||
- nym-cli: improve error reporting/handling and changed `vesting-schedule` queries to use query client instead of signing client
|
||||
|
||||
### Fixed
|
||||
|
||||
- gateway-client: fix decrypting stored messages on reconnect ([#1786])
|
||||
|
||||
### Fixed
|
||||
|
||||
|
||||
Generated
+8
-10
@@ -586,7 +586,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "client-core"
|
||||
version = "1.1.0"
|
||||
version = "1.1.1"
|
||||
dependencies = [
|
||||
"client-connections",
|
||||
"config",
|
||||
@@ -1633,7 +1633,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "explorer-api"
|
||||
version = "1.1.0"
|
||||
version = "1.1.1"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"clap 3.2.8",
|
||||
@@ -3139,7 +3139,6 @@ dependencies = [
|
||||
"pretty_env_logger",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tap",
|
||||
"tokio",
|
||||
"validator-client",
|
||||
]
|
||||
@@ -3165,7 +3164,6 @@ dependencies = [
|
||||
"rand 0.6.5",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tap",
|
||||
"thiserror",
|
||||
"time 0.3.14",
|
||||
"toml",
|
||||
@@ -3176,7 +3174,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-client"
|
||||
version = "1.1.0"
|
||||
version = "1.1.1"
|
||||
dependencies = [
|
||||
"clap 3.2.8",
|
||||
"client-connections",
|
||||
@@ -3216,7 +3214,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-gateway"
|
||||
version = "1.1.0"
|
||||
version = "1.1.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
@@ -3263,7 +3261,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-mixnode"
|
||||
version = "1.1.0"
|
||||
version = "1.1.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bs58",
|
||||
@@ -3305,7 +3303,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-network-requester"
|
||||
version = "1.1.0"
|
||||
version = "1.1.1"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"clap 3.2.8",
|
||||
@@ -3353,7 +3351,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-socks5-client"
|
||||
version = "1.1.0"
|
||||
version = "1.1.1"
|
||||
dependencies = [
|
||||
"clap 3.2.8",
|
||||
"client-connections",
|
||||
@@ -3420,7 +3418,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "nym-validator-api"
|
||||
version = "1.1.0"
|
||||
version = "1.1.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "client-core"
|
||||
version = "1.1.0"
|
||||
version = "1.1.1"
|
||||
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"]
|
||||
edition = "2021"
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "nym-client"
|
||||
version = "1.1.0"
|
||||
version = "1.1.1"
|
||||
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"]
|
||||
description = "Implementation of the Nym Client"
|
||||
edition = "2021"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "nym-socks5-client"
|
||||
version = "1.1.0"
|
||||
version = "1.1.1"
|
||||
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"
|
||||
|
||||
@@ -42,28 +42,19 @@ pub struct StringMessage {
|
||||
|
||||
/// Create a new binary message with a user-specified `kind`.
|
||||
#[wasm_bindgen]
|
||||
pub fn create_binary_message(kind: u8, payload: Vec<u8>, headers: Option<String>) -> Vec<u8> {
|
||||
create_binary_message_with_headers(kind, payload, headers)
|
||||
pub fn create_binary_message(kind: u8, payload: Vec<u8>) -> Vec<u8> {
|
||||
create_binary_message_with_headers(kind, payload, "".to_string())
|
||||
}
|
||||
|
||||
/// Create a new message with a UTF-8 encoded string `payload` and a user-specified `kind`.
|
||||
#[wasm_bindgen]
|
||||
pub fn create_binary_message_from_string(
|
||||
kind: u8,
|
||||
payload: String,
|
||||
headers: Option<String>,
|
||||
) -> Vec<u8> {
|
||||
create_binary_message_with_headers(kind, payload.as_bytes().to_vec(), headers)
|
||||
pub fn create_binary_message_from_string(kind: u8, payload: String) -> Vec<u8> {
|
||||
create_binary_message_with_headers(kind, payload.as_bytes().to_vec(), "".to_string())
|
||||
}
|
||||
|
||||
/// Create a new binary message with a user-specified `kind`, and `headers` as a string.
|
||||
#[wasm_bindgen]
|
||||
pub fn create_binary_message_with_headers(
|
||||
kind: u8,
|
||||
payload: Vec<u8>,
|
||||
headers: Option<String>,
|
||||
) -> Vec<u8> {
|
||||
let headers = headers.unwrap_or_else(|| "".to_string());
|
||||
pub fn create_binary_message_with_headers(kind: u8, payload: Vec<u8>, headers: String) -> Vec<u8> {
|
||||
let headers = headers.as_bytes().to_vec();
|
||||
let size = (headers.len() as u64).to_be_bytes().to_vec();
|
||||
vec![vec![kind], size, headers, payload].concat()
|
||||
@@ -178,7 +169,7 @@ mod tests {
|
||||
let message_as_bytes = create_binary_message_with_headers(
|
||||
42u8,
|
||||
vec![0u8, 1u8, 2u8],
|
||||
Some("test headers".to_string()),
|
||||
"test headers".to_string(),
|
||||
);
|
||||
|
||||
// calculate header size
|
||||
@@ -206,7 +197,7 @@ mod tests {
|
||||
#[wasm_bindgen_test]
|
||||
fn test_binary_with_empty_headers() {
|
||||
let message_as_bytes =
|
||||
create_binary_message_with_headers(42u8, vec![0u8, 1u8, 2u8], Some("".to_string()));
|
||||
create_binary_message_with_headers(42u8, vec![0u8, 1u8, 2u8], "".to_string());
|
||||
|
||||
let expected_size = 0;
|
||||
|
||||
|
||||
@@ -9,8 +9,6 @@ pub mod binary_message_helper;
|
||||
mod client;
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
pub mod gateway_selector;
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
pub mod validation;
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn set_panic_hook() {
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
use nymsphinx::addressing::clients::Recipient;
|
||||
use wasm_bindgen::prelude::*;
|
||||
|
||||
#[wasm_bindgen]
|
||||
pub fn validate_recipient(recipient: String) -> Result<(), JsError> {
|
||||
match Recipient::try_from_base58_string(recipient) {
|
||||
Ok(_) => Ok(()),
|
||||
Err(e) => Err(JsError::new(format!("{}", e).as_str())),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::validate_recipient;
|
||||
use wasm_bindgen_test::*;
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn test_recipient_validation_ok() {
|
||||
let res = validate_recipient("DyQmXnst5NGGjzUZxRC5Bjs5bd7CBF3xMpsSmbRiizr2.GH6YTBP2NXU3AVqd8WjiTMVyeMjunXMEsp7gVCMEJqpD@336yuXAeGEgedRfqTJZsG2YV7P13QH1bHv1SjCZYarc9".to_string());
|
||||
assert!(res.is_ok())
|
||||
}
|
||||
|
||||
#[wasm_bindgen_test]
|
||||
fn test_recipient_validation_fails() {
|
||||
assert!(validate_recipient(" DyQmXnst5NGGjzUZxRC5Bjs5bd7CBF3xMpsSmbRiizr2.GH6YTBP2NXU3AVqd8WjiTMVyeMjunXMEsp7gVCMEJqpD@336yuXAeGEgedRfqTJZsG2YV7P13QH1bHv1SjCZYarc9".to_string()).is_err());
|
||||
assert!(validate_recipient(
|
||||
"DyQmXnst5NGGjzUZxRC5BjbRiizr2.GH6YTBP2NXU3AVqd8WD@336yuXAeGEgedRfqTJZQH1bHv1SjCZYarc9"
|
||||
.to_string()
|
||||
)
|
||||
.is_err());
|
||||
assert!(validate_recipient("🙀🙀🙀🙀".to_string()).is_err());
|
||||
assert!(validate_recipient("".to_string()).is_err());
|
||||
assert!(validate_recipient(" ".to_string()).is_err());
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@ use futures::{FutureExt, SinkExt, StreamExt};
|
||||
use gateway_requests::authentication::encrypted_address::EncryptedAddressBytes;
|
||||
use gateway_requests::iv::IV;
|
||||
use gateway_requests::registration::handshake::{client_handshake, SharedKeys};
|
||||
use gateway_requests::{BinaryRequest, ClientControlRequest, ServerResponse, PROTOCOL_VERSION};
|
||||
use gateway_requests::{BinaryRequest, ClientControlRequest, ServerResponse};
|
||||
use log::*;
|
||||
use network_defaults::{REMAINING_BANDWIDTH_THRESHOLD, TOKENS_TO_BURN};
|
||||
use nymsphinx::forwarding::packet::MixPacket;
|
||||
@@ -447,33 +447,6 @@ impl GatewayClient {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_gateway_protocol(
|
||||
&self,
|
||||
gateway_protocol: Option<u8>,
|
||||
) -> Result<(), GatewayClientError> {
|
||||
// right now there are no failure cases here, but this might change in the future
|
||||
match gateway_protocol {
|
||||
None => {
|
||||
warn!("the gateway we're connected to has not specified its protocol version. It's probably running version < 1.1.X, but that's still fine for now. It will become a hard error in 1.2.0");
|
||||
// note: in 1.2.0 we will have to return a hard error here
|
||||
Ok(())
|
||||
}
|
||||
Some(v) if v != PROTOCOL_VERSION => {
|
||||
let err = GatewayClientError::IncompatibleProtocol {
|
||||
gateway: Some(v),
|
||||
current: PROTOCOL_VERSION,
|
||||
};
|
||||
error!("{err}");
|
||||
Err(err)
|
||||
}
|
||||
|
||||
Some(_) => {
|
||||
info!("the gateway is using exactly the same protocol version as we are. We're good to continue!");
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn register(&mut self) -> Result<(), GatewayClientError> {
|
||||
if !self.connection.is_established() {
|
||||
return Err(GatewayClientError::ConnectionNotEstablished);
|
||||
@@ -496,20 +469,11 @@ impl GatewayClient {
|
||||
.map_err(GatewayClientError::RegistrationFailure),
|
||||
_ => unreachable!(),
|
||||
}?;
|
||||
let (authentication_status, gateway_protocol) = match self.read_control_response().await? {
|
||||
ServerResponse::Register {
|
||||
protocol_version,
|
||||
status,
|
||||
} => (status, protocol_version),
|
||||
ServerResponse::Error { message } => {
|
||||
return Err(GatewayClientError::GatewayError(message))
|
||||
}
|
||||
_ => return Err(GatewayClientError::UnexpectedResponse),
|
||||
};
|
||||
|
||||
self.check_gateway_protocol(gateway_protocol)?;
|
||||
self.authenticated = authentication_status;
|
||||
|
||||
self.authenticated = match self.read_control_response().await? {
|
||||
ServerResponse::Register { status } => Ok(status),
|
||||
ServerResponse::Error { message } => Err(GatewayClientError::GatewayError(message)),
|
||||
_ => Err(GatewayClientError::UnexpectedResponse),
|
||||
}?;
|
||||
if self.authenticated {
|
||||
self.shared_key = Some(Arc::new(shared_key));
|
||||
}
|
||||
@@ -548,11 +512,9 @@ impl GatewayClient {
|
||||
|
||||
match self.send_websocket_message(msg).await? {
|
||||
ServerResponse::Authenticate {
|
||||
protocol_version,
|
||||
status,
|
||||
bandwidth_remaining,
|
||||
} => {
|
||||
self.check_gateway_protocol(protocol_version)?;
|
||||
self.authenticated = status;
|
||||
self.bandwidth_remaining = bandwidth_remaining;
|
||||
Ok(())
|
||||
|
||||
@@ -85,9 +85,6 @@ pub enum GatewayClientError {
|
||||
|
||||
#[error("Failed to send mixnet message")]
|
||||
MixnetMsgSenderFailedToSend,
|
||||
|
||||
#[error("Attempted to negotiate connection with gateway using incompatible protocol version. Ours is {current} and the gateway reports {gateway:?}")]
|
||||
IncompatibleProtocol { gateway: Option<u8>, current: u8 },
|
||||
}
|
||||
|
||||
impl GatewayClientError {
|
||||
|
||||
@@ -22,7 +22,6 @@ thiserror = "1"
|
||||
time = { version = "0.3.6", features = ["parsing", "formatting"] }
|
||||
toml = "0.5.6"
|
||||
url = "2.2"
|
||||
tap = "1"
|
||||
|
||||
cosmrs = { git = "https://github.com/neacsu/cosmos-rust", branch = "neacsu/feegrant_support" }
|
||||
cosmwasm-std = { version = "1.0.0" }
|
||||
|
||||
@@ -15,10 +15,4 @@ pub enum ContextError {
|
||||
// TODO: improve this to return known errors
|
||||
#[error("failed to create client - {0}")]
|
||||
NymdError(String),
|
||||
|
||||
#[error("{0}")]
|
||||
NymdErrorPassthrough(#[from] validator_client::nymd::error::NymdError),
|
||||
|
||||
#[error("{0}")]
|
||||
ValidatorClientError(#[from] validator_client::ValidatorClientError),
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ use network_defaults::{
|
||||
var_names::{API_VALIDATOR, MIXNET_CONTRACT_ADDRESS, NYMD_VALIDATOR, VESTING_CONTRACT_ADDRESS},
|
||||
NymNetworkDetails,
|
||||
};
|
||||
use tap::prelude::*;
|
||||
use validator_client::nymd::{self, AccountId, NymdClient, QueryNymdClient, SigningNymdClient};
|
||||
pub use validator_client::validator_api::Client as ValidatorApiClient;
|
||||
|
||||
@@ -59,7 +58,7 @@ pub fn create_signing_client(
|
||||
network_details: &NymNetworkDetails,
|
||||
) -> Result<SigningClient, ContextError> {
|
||||
let client_config = nymd::Config::try_from_nym_network_details(network_details)
|
||||
.tap_err(|e| log::error!("Failed to get client config - {:?}", e))?;
|
||||
.expect("failed to construct valid validator client config with the provided network");
|
||||
|
||||
// get mnemonic
|
||||
let mnemonic = match std::env::var("MNEMONIC") {
|
||||
@@ -88,7 +87,7 @@ pub fn create_query_client(
|
||||
network_details: &NymNetworkDetails,
|
||||
) -> Result<QueryClient, ContextError> {
|
||||
let client_config = nymd::Config::try_from_nym_network_details(network_details)
|
||||
.tap_err(|e| log::error!("Failed to get client config - {:?}", e))?;
|
||||
.expect("failed to construct valid validator client config with the provided network");
|
||||
|
||||
let nymd_url = network_details
|
||||
.endpoints
|
||||
@@ -108,7 +107,7 @@ pub fn create_signing_client_with_validator_api(
|
||||
network_details: &NymNetworkDetails,
|
||||
) -> Result<SigningClientWithValidatorAPI, ContextError> {
|
||||
let client_config = validator_client::Config::try_from_nym_network_details(network_details)
|
||||
.tap_err(|e| log::error!("Failed to get client config - {:?}", e))?;
|
||||
.expect("failed to construct valid validator client config with the provided network");
|
||||
|
||||
// get mnemonic
|
||||
let mnemonic = match std::env::var("MNEMONIC") {
|
||||
@@ -130,7 +129,7 @@ pub fn create_query_client_with_validator_api(
|
||||
network_details: &NymNetworkDetails,
|
||||
) -> Result<QueryClientWithValidatorAPI, ContextError> {
|
||||
let client_config = validator_client::Config::try_from_nym_network_details(network_details)
|
||||
.tap_err(|e| log::error!("Failed to get client config - {:?}", e))?;
|
||||
.expect("failed to construct valid validator client config with the provided network");
|
||||
|
||||
match validator_client::client::Client::new_query(client_config) {
|
||||
Ok(client) => Ok(client),
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
|
||||
use clap::Parser;
|
||||
use cosmrs::AccountId;
|
||||
use log::{error, info};
|
||||
use log::info;
|
||||
|
||||
use validator_client::nymd::{Coin, VestingQueryClient};
|
||||
|
||||
use crate::context::QueryClient;
|
||||
use crate::context::SigningClient;
|
||||
use crate::utils::show_error;
|
||||
use crate::utils::{pretty_coin, pretty_cosmwasm_coin};
|
||||
|
||||
@@ -18,16 +18,8 @@ pub struct Args {
|
||||
pub address: Option<AccountId>,
|
||||
}
|
||||
|
||||
pub async fn balance(args: Args, client: QueryClient, address_from_mnemonic: Option<AccountId>) {
|
||||
if args.address.is_none() && address_from_mnemonic.is_none() {
|
||||
error!("Please specify an account address or a mnemonic to get the balance for");
|
||||
return;
|
||||
}
|
||||
|
||||
let account_id = args
|
||||
.address
|
||||
.unwrap_or_else(|| address_from_mnemonic.expect("please provide a mnemonic"));
|
||||
|
||||
pub async fn balance(args: Args, client: SigningClient) {
|
||||
let account_id = args.address.unwrap_or_else(|| client.address().clone());
|
||||
let vesting_address = account_id.to_string();
|
||||
let denom = client.current_chain_details().mix_denom.base.as_str();
|
||||
|
||||
|
||||
@@ -4,11 +4,11 @@
|
||||
use clap::Parser;
|
||||
use cosmrs::AccountId;
|
||||
use cosmwasm_std::Coin as CosmWasmCoin;
|
||||
use log::{error, info};
|
||||
use log::info;
|
||||
|
||||
use validator_client::nymd::{Coin, VestingQueryClient};
|
||||
|
||||
use crate::context::QueryClient;
|
||||
use crate::context::SigningClient;
|
||||
use crate::utils::show_error;
|
||||
use crate::utils::{pretty_coin, pretty_cosmwasm_coin};
|
||||
|
||||
@@ -19,18 +19,8 @@ pub struct Args {
|
||||
pub address: Option<AccountId>,
|
||||
}
|
||||
|
||||
pub async fn query(args: Args, client: QueryClient, address_from_mnemonic: Option<AccountId>) {
|
||||
if args.address.is_none() && address_from_mnemonic.is_none() {
|
||||
error!("Please specify an account address or a mnemonic to get the balance for");
|
||||
return;
|
||||
}
|
||||
|
||||
let account_id = args
|
||||
.address
|
||||
.unwrap_or_else(|| address_from_mnemonic.expect("please provide a mnemonic"));
|
||||
|
||||
info!("Checking account {} for a vesting schedule...", account_id);
|
||||
|
||||
pub async fn query(args: Args, client: SigningClient) {
|
||||
let account_id = args.address.unwrap_or_else(|| client.address().clone());
|
||||
let vesting_address = account_id.to_string();
|
||||
let denom = client.current_chain_details().mix_denom.base.as_str();
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
CONFIGURED=true
|
||||
|
||||
RUST_LOG=info
|
||||
RUST_BACKTRACE=1
|
||||
|
||||
BECH32_PREFIX=n
|
||||
MIX_DENOM=unym
|
||||
MIX_DENOM_DISPLAY=nym
|
||||
STAKE_DENOM=unyx
|
||||
STAKE_DENOM_DISPLAY=nyx
|
||||
DENOMS_EXPONENT=6
|
||||
MIXNET_CONTRACT_ADDRESS=n14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9sjyvg3g
|
||||
VESTING_CONTRACT_ADDRESS=n1nc5tatafv6eyq7llkr2gv50ff9e22mnf70qgjlv737ktmt4eswrq73f2nw
|
||||
BANDWIDTH_CLAIM_CONTRACT_ADDRESS=n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0
|
||||
COCONUT_BANDWIDTH_CONTRACT_ADDRESS=n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0
|
||||
MULTISIG_CONTRACT_ADDRESS=n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0
|
||||
REWARDING_VALIDATOR_ADDRESS=n10yyd98e2tuwu0f7ypz9dy3hhjw7v772q6287gy
|
||||
STATISTICS_SERVICE_DOMAIN_ADDRESS="http://127.0.0.1:8090"
|
||||
NYMD_VALIDATOR="https://rpc.nyx.nodes.guru/"
|
||||
API_VALIDATOR="https://validator.nymtech.net/api/"
|
||||
@@ -0,0 +1,20 @@
|
||||
CONFIGURED=true
|
||||
|
||||
RUST_LOG=info
|
||||
RUST_BACKTRACE=1
|
||||
|
||||
BECH32_PREFIX=n
|
||||
MIX_DENOM=unym
|
||||
MIX_DENOM_DISPLAY=nym
|
||||
STAKE_DENOM=unyx
|
||||
STAKE_DENOM_DISPLAY=nyx
|
||||
DENOMS_EXPONENT=6
|
||||
MIXNET_CONTRACT_ADDRESS=n1suhgf5svhu4usrurvxzlgn54ksxmn8gljarjtxqnapv8kjnp4nrsd3qaep
|
||||
VESTING_CONTRACT_ADDRESS=n1xr3rq8yvd7qplsw5yx90ftsr2zdhg4e9z60h5duusgxpv72hud3sjkxkav
|
||||
BANDWIDTH_CLAIM_CONTRACT_ADDRESS=n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0
|
||||
COCONUT_BANDWIDTH_CONTRACT_ADDRESS=n1ghd753shjuwexxywmgs4xz7x2q732vcn7ty4yw
|
||||
MULTISIG_CONTRACT_ADDRESS=n17p9rzwnnfxcjp32un9ug7yhhzgtkhvl988qccs
|
||||
REWARDING_VALIDATOR_ADDRESS=n1tfzd4qz3a45u8p4mr5zmzv66457uwjgcl05jdq
|
||||
STATISTICS_SERVICE_DOMAIN_ADDRESS="http://0.0.0.0"
|
||||
NYMD_VALIDATOR="https://qa-validator.nymtech.net"
|
||||
API_VALIDATOR="https://qa-validator-api.nymtech.net/api"
|
||||
@@ -85,10 +85,6 @@ pub fn export_to_env() {
|
||||
var_names::MULTISIG_CONTRACT_ADDRESS,
|
||||
MULTISIG_CONTRACT_ADDRESS,
|
||||
);
|
||||
set_var_to_default(
|
||||
var_names::COCONUT_DKG_CONTRACT_ADDRESS,
|
||||
COCONUT_DKG_CONTRACT_ADDRESS,
|
||||
);
|
||||
set_var_to_default(
|
||||
var_names::REWARDING_VALIDATOR_ADDRESS,
|
||||
REWARDING_VALIDATOR_ADDRESS,
|
||||
@@ -129,10 +125,6 @@ pub fn export_to_env_if_not_set() {
|
||||
var_names::MULTISIG_CONTRACT_ADDRESS,
|
||||
MULTISIG_CONTRACT_ADDRESS,
|
||||
);
|
||||
set_var_conditionally_to_default(
|
||||
var_names::COCONUT_DKG_CONTRACT_ADDRESS,
|
||||
COCONUT_DKG_CONTRACT_ADDRESS,
|
||||
);
|
||||
set_var_conditionally_to_default(
|
||||
var_names::REWARDING_VALIDATOR_ADDRESS,
|
||||
REWARDING_VALIDATOR_ADDRESS,
|
||||
|
||||
@@ -209,14 +209,18 @@ impl NymTopology {
|
||||
|
||||
#[must_use]
|
||||
pub fn filter_system_version(&self, expected_version: &str) -> Self {
|
||||
self.filter_node_versions(expected_version)
|
||||
self.filter_node_versions(expected_version, expected_version)
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
pub fn filter_node_versions(&self, expected_mix_version: &str) -> Self {
|
||||
pub fn filter_node_versions(
|
||||
&self,
|
||||
expected_mix_version: &str,
|
||||
expected_gateway_version: &str,
|
||||
) -> Self {
|
||||
NymTopology {
|
||||
mixes: self.mixes.filter_by_version(expected_mix_version),
|
||||
gateways: self.gateways.clone(),
|
||||
gateways: self.gateways.filter_by_version(expected_gateway_version),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "explorer-api"
|
||||
version = "1.1.0"
|
||||
version = "1.1.1"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
@@ -34,7 +34,7 @@ export const MobileNav: React.FC<{ children: React.ReactNode }> = ({ children }:
|
||||
const { navState, updateNavState } = useMainContext();
|
||||
const [drawerOpen, setDrawerOpen] = React.useState(false);
|
||||
// Set maintenance banner to false by default to don't display it
|
||||
const [openMaintenance, setOpenMaintenance] = React.useState(false);
|
||||
const [openMaintenance, setOpenMaintenance] = React.useState(true);
|
||||
|
||||
const toggleDrawer = () => {
|
||||
setDrawerOpen(!drawerOpen);
|
||||
|
||||
@@ -235,7 +235,7 @@ export const Nav: React.FC = ({ children }) => {
|
||||
const [drawerIsOpen, setDrawerToOpen] = React.useState(false);
|
||||
const [fixedOpen, setFixedOpen] = React.useState(false);
|
||||
// Set maintenance banner to false by default to don't display it
|
||||
const [openMaintenance, setOpenMaintenance] = React.useState(false);
|
||||
const [openMaintenance, setOpenMaintenance] = React.useState(true);
|
||||
const theme = useTheme();
|
||||
|
||||
const setToActive = (id: number) => {
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "nym-gateway"
|
||||
version = "1.1.0"
|
||||
version = "1.1.1"
|
||||
authors = [
|
||||
"Dave Hrycyszyn <futurechimp@users.noreply.github.com>",
|
||||
"Jędrzej Stuczyński <andrew@nymtech.net>",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2020-2022 - Nym Technologies SA <contact@nymtech.net>
|
||||
// Copyright 2020 - Nym Technologies SA <contact@nymtech.net>
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
pub use crypto::generic_array;
|
||||
@@ -12,10 +12,6 @@ pub mod iv;
|
||||
pub mod registration;
|
||||
pub mod types;
|
||||
|
||||
/// Defines the current version of the communication protocol between gateway and clients.
|
||||
/// It has to be incremented for any breaking change.
|
||||
pub const PROTOCOL_VERSION: u8 = 1;
|
||||
|
||||
pub type GatewayMac = HmacOutput<GatewayIntegrityHmacAlgorithm>;
|
||||
|
||||
// TODO: could using `Mac` trait here for OutputSize backfire?
|
||||
|
||||
@@ -210,10 +210,7 @@ impl<'a, S> State<'a, S> {
|
||||
match msg {
|
||||
WsMessage::Text(ws_msg) => match types::RegistrationHandshake::try_from(ws_msg) {
|
||||
Ok(reg_handshake_msg) => return match reg_handshake_msg {
|
||||
// hehe, that's a bit disgusting that the type system requires we explicitly ignore the
|
||||
// protocol_version field that we actually never attach at this point
|
||||
// yet another reason for the overdue refactor
|
||||
types::RegistrationHandshake::HandshakePayload { data, .. } => Ok(data),
|
||||
types::RegistrationHandshake::HandshakePayload { data } => Ok(data),
|
||||
types::RegistrationHandshake::HandshakeError { message } => Err(HandshakeError::RemoteError(message)),
|
||||
},
|
||||
Err(_) => error!("Received a non-handshake message during the registration handshake! It's getting dropped."),
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
use crate::authentication::encrypted_address::EncryptedAddressBytes;
|
||||
use crate::iv::IV;
|
||||
use crate::registration::handshake::SharedKeys;
|
||||
use crate::{GatewayMacSize, PROTOCOL_VERSION};
|
||||
use crate::GatewayMacSize;
|
||||
use crypto::generic_array::typenum::Unsigned;
|
||||
use crypto::hmac::recompute_keyed_hmac_and_verify_tag;
|
||||
use crypto::symmetric::stream_cipher;
|
||||
@@ -28,22 +28,13 @@ use credentials::token::bandwidth::TokenCredential;
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
#[serde(tag = "type", rename_all = "camelCase")]
|
||||
pub enum RegistrationHandshake {
|
||||
HandshakePayload {
|
||||
#[serde(default)]
|
||||
protocol_version: Option<u8>,
|
||||
data: Vec<u8>,
|
||||
},
|
||||
HandshakeError {
|
||||
message: String,
|
||||
},
|
||||
HandshakePayload { data: Vec<u8> },
|
||||
HandshakeError { message: String },
|
||||
}
|
||||
|
||||
impl RegistrationHandshake {
|
||||
pub fn new_payload(data: Vec<u8>) -> Self {
|
||||
RegistrationHandshake::HandshakePayload {
|
||||
protocol_version: Some(PROTOCOL_VERSION),
|
||||
data,
|
||||
}
|
||||
RegistrationHandshake::HandshakePayload { data }
|
||||
}
|
||||
|
||||
pub fn new_error<S: Into<String>>(message: S) -> Self {
|
||||
@@ -124,16 +115,12 @@ pub enum ClientControlRequest {
|
||||
// TODO: should this also contain a MAC considering that at this point we already
|
||||
// have the shared key derived?
|
||||
Authenticate {
|
||||
#[serde(default)]
|
||||
protocol_version: Option<u8>,
|
||||
address: String,
|
||||
enc_address: String,
|
||||
iv: String,
|
||||
},
|
||||
#[serde(alias = "handshakePayload")]
|
||||
RegisterHandshakeInitRequest {
|
||||
#[serde(default)]
|
||||
protocol_version: Option<u8>,
|
||||
data: Vec<u8>,
|
||||
},
|
||||
BandwidthCredential {
|
||||
@@ -150,7 +137,6 @@ impl ClientControlRequest {
|
||||
iv: IV,
|
||||
) -> Self {
|
||||
ClientControlRequest::Authenticate {
|
||||
protocol_version: Some(PROTOCOL_VERSION),
|
||||
address: address.as_base58_string(),
|
||||
enc_address: enc_address.to_base58_string(),
|
||||
iv: iv.to_base58_string(),
|
||||
@@ -237,14 +223,10 @@ impl TryInto<String> for ClientControlRequest {
|
||||
#[serde(tag = "type", rename_all = "camelCase")]
|
||||
pub enum ServerResponse {
|
||||
Authenticate {
|
||||
#[serde(default)]
|
||||
protocol_version: Option<u8>,
|
||||
status: bool,
|
||||
bandwidth_remaining: i64,
|
||||
},
|
||||
Register {
|
||||
#[serde(default)]
|
||||
protocol_version: Option<u8>,
|
||||
status: bool,
|
||||
},
|
||||
Bandwidth {
|
||||
@@ -399,37 +381,14 @@ mod tests {
|
||||
#[test]
|
||||
fn handshake_payload_can_be_deserialized_into_register_handshake_init_request() {
|
||||
let handshake_data = vec![1, 2, 3, 4, 5, 6];
|
||||
let handshake_payload_with_protocol = RegistrationHandshake::HandshakePayload {
|
||||
protocol_version: Some(42),
|
||||
let handshake_payload = RegistrationHandshake::HandshakePayload {
|
||||
data: handshake_data.clone(),
|
||||
};
|
||||
let serialized = serde_json::to_string(&handshake_payload_with_protocol).unwrap();
|
||||
let serialized = serde_json::to_string(&handshake_payload).unwrap();
|
||||
let deserialized = ClientControlRequest::try_from(serialized).unwrap();
|
||||
|
||||
match deserialized {
|
||||
ClientControlRequest::RegisterHandshakeInitRequest {
|
||||
protocol_version,
|
||||
data,
|
||||
} => {
|
||||
assert_eq!(protocol_version, Some(42));
|
||||
assert_eq!(data, handshake_data)
|
||||
}
|
||||
_ => unreachable!("this branch shouldn't have been reached!"),
|
||||
}
|
||||
|
||||
let handshake_payload_without_protocol = RegistrationHandshake::HandshakePayload {
|
||||
protocol_version: None,
|
||||
data: handshake_data.clone(),
|
||||
};
|
||||
let serialized = serde_json::to_string(&handshake_payload_without_protocol).unwrap();
|
||||
let deserialized = ClientControlRequest::try_from(serialized).unwrap();
|
||||
|
||||
match deserialized {
|
||||
ClientControlRequest::RegisterHandshakeInitRequest {
|
||||
protocol_version,
|
||||
data,
|
||||
} => {
|
||||
assert!(protocol_version.is_none());
|
||||
ClientControlRequest::RegisterHandshakeInitRequest { data } => {
|
||||
assert_eq!(data, handshake_data)
|
||||
}
|
||||
_ => unreachable!("this branch shouldn't have been reached!"),
|
||||
|
||||
@@ -18,7 +18,7 @@ use gateway_requests::iv::{IVConversionError, IV};
|
||||
use gateway_requests::registration::handshake::error::HandshakeError;
|
||||
use gateway_requests::registration::handshake::{gateway_handshake, SharedKeys};
|
||||
use gateway_requests::types::{ClientControlRequest, ServerResponse};
|
||||
use gateway_requests::{BinaryResponse, PROTOCOL_VERSION};
|
||||
use gateway_requests::BinaryResponse;
|
||||
use log::*;
|
||||
use mixnet_client::forwarder::MixForwardingSender;
|
||||
use nymsphinx::DestinationAddressBytes;
|
||||
@@ -55,9 +55,6 @@ enum InitialAuthenticationError {
|
||||
|
||||
#[error("Experienced connection error - {0}")]
|
||||
ConnectionError(#[from] WsError),
|
||||
|
||||
#[error("Attempted to negotiate connection with client using incompatible protocol version. Ours is {current} and the client reports {client:?}")]
|
||||
IncompatibleProtocol { client: Option<u8>, current: u8 },
|
||||
}
|
||||
|
||||
impl InitialAuthenticationError {
|
||||
@@ -282,7 +279,10 @@ where
|
||||
|
||||
// push them to the client
|
||||
if let Err(err) = self.push_packets_to_client(shared_keys, messages).await {
|
||||
warn!("We failed to send stored messages to fresh client - {err}",);
|
||||
warn!(
|
||||
"We failed to send stored messages to fresh client - {}",
|
||||
err
|
||||
);
|
||||
return Err(InitialAuthenticationError::ConnectionError(err));
|
||||
} else {
|
||||
// if it was successful - remove them from the store
|
||||
@@ -342,33 +342,6 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn check_client_protocol(
|
||||
&self,
|
||||
client_protocol: Option<u8>,
|
||||
) -> Result<(), InitialAuthenticationError> {
|
||||
// right now there are no failure cases here, but this might change in the future
|
||||
match client_protocol {
|
||||
None => {
|
||||
warn!("the client we're connected to has not specified its protocol version. It's probably running version < 1.1.X, but that's still fine for now. It will become a hard error in 1.2.0");
|
||||
// note: in 1.2.0 we will have to return a hard error here
|
||||
Ok(())
|
||||
}
|
||||
Some(v) if v != PROTOCOL_VERSION => {
|
||||
let err = InitialAuthenticationError::IncompatibleProtocol {
|
||||
client: Some(v),
|
||||
current: PROTOCOL_VERSION,
|
||||
};
|
||||
error!("{err}");
|
||||
Err(err)
|
||||
}
|
||||
|
||||
Some(_) => {
|
||||
info!("the client is using exactly the same protocol version as we are. We're good to continue!");
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Using the received challenge data, i.e. client's address as well the ciphertext of it plus
|
||||
/// a fresh IV, attempts to authenticate the client by checking whether the ciphertext matches
|
||||
/// the expected value if encrypted with the shared key.
|
||||
@@ -416,7 +389,6 @@ where
|
||||
/// * `iv`: fresh IV received with the request.
|
||||
async fn handle_authenticate(
|
||||
&mut self,
|
||||
client_protocol_version: Option<u8>,
|
||||
address: String,
|
||||
enc_address: String,
|
||||
iv: String,
|
||||
@@ -424,8 +396,6 @@ where
|
||||
where
|
||||
S: AsyncRead + AsyncWrite + Unpin,
|
||||
{
|
||||
self.check_client_protocol(client_protocol_version)?;
|
||||
|
||||
let address = DestinationAddressBytes::try_from_base58_string(address)
|
||||
.map_err(|err| InitialAuthenticationError::MalformedClientAddress(err.to_string()))?;
|
||||
let encrypted_address = EncryptedAddressBytes::try_from_base58_string(enc_address)?;
|
||||
@@ -450,7 +420,6 @@ where
|
||||
Ok(InitialAuthResult::new(
|
||||
client_details,
|
||||
ServerResponse::Authenticate {
|
||||
protocol_version: Some(PROTOCOL_VERSION),
|
||||
status,
|
||||
bandwidth_remaining,
|
||||
},
|
||||
@@ -505,14 +474,11 @@ where
|
||||
/// * `init_data`: init payload of the registration handshake.
|
||||
async fn handle_register(
|
||||
&mut self,
|
||||
client_protocol_version: Option<u8>,
|
||||
init_data: Vec<u8>,
|
||||
) -> Result<InitialAuthResult, InitialAuthenticationError>
|
||||
where
|
||||
S: AsyncRead + AsyncWrite + Unpin + Send,
|
||||
{
|
||||
self.check_client_protocol(client_protocol_version)?;
|
||||
|
||||
let remote_identity = Self::extract_remote_identity_from_register_init(&init_data)?;
|
||||
let remote_address = remote_identity.derive_destination_address();
|
||||
|
||||
@@ -527,10 +493,7 @@ where
|
||||
|
||||
Ok(InitialAuthResult::new(
|
||||
Some(client_details),
|
||||
ServerResponse::Register {
|
||||
protocol_version: Some(PROTOCOL_VERSION),
|
||||
status,
|
||||
},
|
||||
ServerResponse::Register { status },
|
||||
))
|
||||
}
|
||||
|
||||
@@ -550,18 +513,13 @@ where
|
||||
if let Ok(request) = ClientControlRequest::try_from(raw_request) {
|
||||
match request {
|
||||
ClientControlRequest::Authenticate {
|
||||
protocol_version,
|
||||
address,
|
||||
enc_address,
|
||||
iv,
|
||||
} => {
|
||||
self.handle_authenticate(protocol_version, address, enc_address, iv)
|
||||
.await
|
||||
} => self.handle_authenticate(address, enc_address, iv).await,
|
||||
ClientControlRequest::RegisterHandshakeInitRequest { data } => {
|
||||
self.handle_register(data).await
|
||||
}
|
||||
ClientControlRequest::RegisterHandshakeInitRequest {
|
||||
protocol_version,
|
||||
data,
|
||||
} => self.handle_register(protocol_version, data).await,
|
||||
// won't accept anything else (like bandwidth) without prior authentication
|
||||
_ => Err(InitialAuthenticationError::InvalidRequest),
|
||||
}
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "nym-mixnode"
|
||||
version = "1.1.0"
|
||||
version = "1.1.1"
|
||||
authors = [
|
||||
"Dave Hrycyszyn <futurechimp@users.noreply.github.com>",
|
||||
"Jędrzej Stuczyński <andrew@nymtech.net>",
|
||||
|
||||
@@ -1,3 +1,23 @@
|
||||
## [nym-connect-v1.1.1](https://github.com/nymtech/nym/tree/nym-connect-v1.1.1) (2022-11-29)
|
||||
|
||||
- socks5-client: fix multiplex concurrent connections ([#1720], [#1777])
|
||||
- socks5-client: fix wait closing inbound connection until data is sent, and throttle incoming data in general ([#1772], [#1783],[#1789])
|
||||
- socks5-client: fix shutting down all background workers if anyone of them panics or errors out. This fixes an issue where the nym-connect UI was showing connected even though the socks5 tunnel was non-functional. ([#1805])
|
||||
- gateway-libs: fix decryping messages stored on the gateway between reconnects ([#1786])
|
||||
|
||||
- nymconnect: updated UI
|
||||
- nymconnect: new help area
|
||||
- nymconnect: listen for service errors and display on frontend
|
||||
|
||||
[#1720]: https://github.com/nymtech/nym/pull/1720
|
||||
[#1772]: https://github.com/nymtech/nym/pull/1772
|
||||
[#1777]: https://github.com/nymtech/nym/pull/1777
|
||||
[#1783]: https://github.com/nymtech/nym/pull/1783
|
||||
[#1786]: https://github.com/nymtech/nym/pull/1786
|
||||
[#1789]: https://github.com/nymtech/nym/pull/1789
|
||||
[#1805]: https://github.com/nymtech/nym/pull/1805
|
||||
|
||||
|
||||
## [nym-connect-v1.1.0](https://github.com/nymtech/nym/tree/nym-connect-v1.1.0) (2022-11-09)
|
||||
|
||||
- nym-connect: rework of rewarding changes the directory data structures that describe the mixnet topology ([#1472])
|
||||
@@ -39,4 +59,4 @@
|
||||
|
||||
- nym-connect: reuse config id instead of creating a new id on each connection
|
||||
|
||||
[#1427]: https://github.com/nymtech/nym/pull/1427
|
||||
[#1427]: https://github.com/nymtech/nym/pull/1427
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nym/nym-connect",
|
||||
"version": "1.0.0",
|
||||
"version": "1.1.1",
|
||||
"main": "index.js",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
@@ -107,4 +107,4 @@
|
||||
"webpack-favicons": "^1.3.8",
|
||||
"webpack-merge": "^5.8.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "nym-connect"
|
||||
version = "1.1.0"
|
||||
version = "1.1.1"
|
||||
description = "nym-connect"
|
||||
authors = ["Nym Technologies SA"]
|
||||
license = ""
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"package": {
|
||||
"productName": "nym-connect",
|
||||
"version": "1.1.0"
|
||||
"version": "1.1.1"
|
||||
},
|
||||
"build": {
|
||||
"distDir": "../dist",
|
||||
@@ -19,7 +19,13 @@
|
||||
"active": true,
|
||||
"targets": "all",
|
||||
"identifier": "net.nymtech.connect",
|
||||
"icon": ["icons/32x32.png", "icons/128x128.png", "icons/128x128@2x.png", "icons/icon.icns", "icons/icon.ico"],
|
||||
"icon": [
|
||||
"icons/32x32.png",
|
||||
"icons/128x128.png",
|
||||
"icons/128x128@2x.png",
|
||||
"icons/icon.icns",
|
||||
"icons/icon.ico"
|
||||
],
|
||||
"resources": [],
|
||||
"externalBin": [],
|
||||
"copyright": "Copyright © 2021-2022 Nym Technologies SA",
|
||||
@@ -44,7 +50,9 @@
|
||||
},
|
||||
"updater": {
|
||||
"active": true,
|
||||
"endpoints": ["https://nymtech.net/.wellknown/connect/updater.json"],
|
||||
"endpoints": [
|
||||
"https://nymtech.net/.wellknown/connect/updater.json"
|
||||
],
|
||||
"dialog": true,
|
||||
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IENCNzQ2M0E5N0VFODE2NApSV1JrZ2U2WE9rYTNETTg1OTBKdE5uWUEra0hML2syOVUvQ2lxZmFZRzZ1T3NWbGM0eVRzUTVhVwo="
|
||||
},
|
||||
@@ -74,4 +82,4 @@
|
||||
"csp": "default-src blob: data: filesystem: ws: wss: http: https: tauri: 'unsafe-eval' 'unsafe-inline' 'self' img-src: 'self'"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,12 +5,9 @@ import {
|
||||
Chip,
|
||||
CircularProgress,
|
||||
Container,
|
||||
FormControlLabel,
|
||||
FormGroup,
|
||||
InputAdornment,
|
||||
Link,
|
||||
Stack,
|
||||
Switch,
|
||||
TextField,
|
||||
Tooltip,
|
||||
Typography,
|
||||
@@ -23,8 +20,6 @@ import CallReceivedIcon from '@mui/icons-material/CallReceived';
|
||||
import PersonIcon from '@mui/icons-material/Person';
|
||||
import PersonOffIcon from '@mui/icons-material/PersonOff';
|
||||
import ErrorIcon from '@mui/icons-material/Error';
|
||||
import VisibilityIcon from '@mui/icons-material/Visibility';
|
||||
import VisibilityOffIcon from '@mui/icons-material/VisibilityOff';
|
||||
import { NymLogo } from '@nymproject/react/logo/NymLogo';
|
||||
import { NymThemeProvider } from '@nymproject/mui-theme';
|
||||
import { useTheme } from '@mui/material/styles';
|
||||
@@ -33,10 +28,9 @@ import { DropzoneDialog } from 'react-mui-dropzone';
|
||||
import UploadFileIcon from '@mui/icons-material/UploadFile';
|
||||
import ArticleIcon from '@mui/icons-material/Article';
|
||||
import InsertDriveFileIcon from '@mui/icons-material/InsertDriveFile';
|
||||
import { Headers } from '@nymproject/sdk';
|
||||
import { ThemeToggle } from './ThemeToggle';
|
||||
import { AppContextProvider, useAppContext } from './context';
|
||||
import { BinaryMessageHeaders, MixnetContextProvider, useMixnetContext } from './context/mixnet';
|
||||
import { MixnetContextProvider, parseBinaryMessageHeaders, useMixnetContext } from './context/mixnet';
|
||||
|
||||
export const AppTheme: React.FC = ({ children }) => {
|
||||
const { mode } = useAppContext();
|
||||
@@ -51,7 +45,6 @@ interface Log {
|
||||
fileDownloadUrl?: string;
|
||||
filesize?: number;
|
||||
timestamp: Date;
|
||||
headers?: Headers;
|
||||
}
|
||||
|
||||
interface UploadState {
|
||||
@@ -59,48 +52,11 @@ interface UploadState {
|
||||
files: File[];
|
||||
}
|
||||
|
||||
const ClientAddress: React.FC<{ label?: string; tooltip?: string; address?: string }> = ({
|
||||
label,
|
||||
address,
|
||||
tooltip,
|
||||
}) => {
|
||||
const copy = useClipboard();
|
||||
|
||||
if (!address) {
|
||||
return <Chip label="Anonymous" icon={<VisibilityOffIcon />} />;
|
||||
}
|
||||
|
||||
const addressShort = `${address.slice(0, 24)}...`;
|
||||
|
||||
return (
|
||||
<Tooltip arrow title={tooltip || ''}>
|
||||
<Chip
|
||||
clickable
|
||||
label={
|
||||
label ? (
|
||||
<>
|
||||
<strong>{label}</strong> {addressShort}
|
||||
</>
|
||||
) : (
|
||||
<>{addressShort}</>
|
||||
)
|
||||
}
|
||||
onClick={() => {
|
||||
if (address) {
|
||||
copy.copy(address);
|
||||
}
|
||||
}}
|
||||
icon={<ContentCopyIcon />}
|
||||
/>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
export const Content: React.FC = () => {
|
||||
const theme = useTheme();
|
||||
const { isReady, address, connect, events, sendTextMessage, sendBinaryMessage } = useMixnetContext();
|
||||
const copy = useClipboard();
|
||||
|
||||
const [revealSenderAddress, setRevealSenderAddress] = React.useState(false);
|
||||
const [sendToSelf, setSendToSelf] = React.useState(false);
|
||||
const [recipient, setRecipient] = React.useState<string>();
|
||||
const handleRecipientChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
@@ -138,8 +94,13 @@ export const Content: React.FC = () => {
|
||||
|
||||
React.useEffect(() => {
|
||||
if (isReady) {
|
||||
const validatorApiUrl = 'https://validator.nymtech.net/api';
|
||||
const preferredGatewayIdentityKey = 'E3mvZTHQCdBvhfr178Swx9g4QG3kkRUun7YnToLMcMbM';
|
||||
// // mixnet v1
|
||||
// const validatorApiUrl = 'https://validator.nymtech.net/api';
|
||||
// const preferredGatewayIdentityKey = 'E3mvZTHQCdBvhfr178Swx9g4QG3kkRUun7YnToLMcMbM';
|
||||
|
||||
// mixnet v2
|
||||
const validatorApiUrl = 'https://qwerty-validator-api.qa.nymte.ch/api'; // "http://localhost:8081";
|
||||
const preferredGatewayIdentityKey = undefined; // '36vfvEyBzo5cWEFbnP7fqgY39kFw9PQhvwzbispeNaxL';
|
||||
|
||||
connect({
|
||||
clientId: 'Example Client',
|
||||
@@ -156,7 +117,6 @@ export const Content: React.FC = () => {
|
||||
kind: 'rx',
|
||||
timestamp: new Date(),
|
||||
message: e.args.payload,
|
||||
headers: e.args.headers,
|
||||
});
|
||||
setLogTrigger(Date.now());
|
||||
});
|
||||
@@ -182,12 +142,8 @@ export const Content: React.FC = () => {
|
||||
React.useEffect(() => {
|
||||
if (events) {
|
||||
const unsubcribe = events.subscribeToBinaryMessageReceivedEvent((e) => {
|
||||
if (!e.args.headers) {
|
||||
console.error('Expected headers, got undefined 😢', e.args);
|
||||
return;
|
||||
}
|
||||
|
||||
const headers = e.args.headers as BinaryMessageHeaders;
|
||||
// the headers will be JSON (see the mixnet context for how they are created), so parse them
|
||||
const headers = parseBinaryMessageHeaders(e.args.headers);
|
||||
|
||||
const blob = new Blob([new Uint8Array(e.args.payload)], { type: headers.mimeType });
|
||||
log.current.push({
|
||||
@@ -196,7 +152,6 @@ export const Content: React.FC = () => {
|
||||
filename: headers.filename,
|
||||
fileDownloadUrl: URL.createObjectURL(blob),
|
||||
filesize: e.args.payload.length,
|
||||
headers: e.args.headers,
|
||||
});
|
||||
setLogTrigger(Date.now());
|
||||
});
|
||||
@@ -229,8 +184,7 @@ export const Content: React.FC = () => {
|
||||
message,
|
||||
});
|
||||
setLogTrigger(Date.now());
|
||||
const senderAddress = revealSenderAddress ? address : undefined;
|
||||
await sendTextMessage({ payload: message, recipient, headers: { senderAddress } });
|
||||
await sendTextMessage({ payload: message, recipient });
|
||||
|
||||
await Promise.all(
|
||||
files.map(async (f) => {
|
||||
@@ -246,7 +200,7 @@ export const Content: React.FC = () => {
|
||||
return await sendBinaryMessage({
|
||||
payload: new Uint8Array(buffer),
|
||||
recipient,
|
||||
headers: { filename: f.name, mimeType: f.type, senderAddress },
|
||||
headers: { filename: f.name, mimeType: f.type },
|
||||
});
|
||||
} catch (e) {
|
||||
addErrorLog('Failed to send file', f.name);
|
||||
@@ -295,7 +249,20 @@ export const Content: React.FC = () => {
|
||||
) : (
|
||||
<>
|
||||
<Chip color="success" icon={<CheckCircleIcon />} label="Connected" variant="outlined" />
|
||||
<ClientAddress address={address} tooltip="Copy your client address to the clipboard" />
|
||||
{address && (
|
||||
<Tooltip arrow title="Copy your client address to the clipboard">
|
||||
<Chip
|
||||
clickable
|
||||
label={`${address.slice(0, 24)}...`}
|
||||
onClick={() => {
|
||||
if (address) {
|
||||
copy.copy(address);
|
||||
}
|
||||
}}
|
||||
icon={<ContentCopyIcon />}
|
||||
/>
|
||||
</Tooltip>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</Stack>
|
||||
@@ -380,34 +347,9 @@ export const Content: React.FC = () => {
|
||||
/>
|
||||
</Box>
|
||||
|
||||
<Stack direction="row" spacing={2}>
|
||||
<Button variant="contained" sx={{ width: 100 }} onClick={handleSend}>
|
||||
Send
|
||||
</Button>
|
||||
<FormGroup>
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Switch
|
||||
color={revealSenderAddress ? 'warning' : 'default'}
|
||||
onClick={() => setRevealSenderAddress((prevState) => !prevState)}
|
||||
/>
|
||||
}
|
||||
label={
|
||||
revealSenderAddress ? (
|
||||
<Stack direction="row" spacing={1}>
|
||||
<VisibilityIcon color="warning" />
|
||||
<Typography color={theme.palette.warning.main}>Reveal your address to the recipient</Typography>
|
||||
</Stack>
|
||||
) : (
|
||||
<Stack direction="row" spacing={1}>
|
||||
<VisibilityOffIcon />
|
||||
<Typography>Hide your address from the recipient</Typography>
|
||||
</Stack>
|
||||
)
|
||||
}
|
||||
/>
|
||||
</FormGroup>
|
||||
</Stack>
|
||||
<Button variant="contained" sx={{ width: 100 }} onClick={handleSend}>
|
||||
Send
|
||||
</Button>
|
||||
</Stack>
|
||||
)}
|
||||
</Box>
|
||||
@@ -456,16 +398,6 @@ export const Content: React.FC = () => {
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
{item.kind === 'rx' &&
|
||||
(item.headers?.senderAddress ? (
|
||||
<ClientAddress
|
||||
label="Sender"
|
||||
tooltip="Click to copy the message sender's address"
|
||||
address={item.headers?.senderAddress}
|
||||
/>
|
||||
) : (
|
||||
<ClientAddress label="Sender" />
|
||||
))}
|
||||
</Stack>
|
||||
</Box>
|
||||
))}
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
import * as React from 'react';
|
||||
import { createNymMixnetClient, IWebWorkerEvents, NymClientConfig, NymMixnetClient, Headers } from '@nymproject/sdk';
|
||||
import { createNymMixnetClient, IWebWorkerEvents, NymClientConfig, NymMixnetClient } from '@nymproject/sdk';
|
||||
|
||||
export interface BinaryMessageHeaders extends Headers {
|
||||
export interface BinaryMessageHeaders {
|
||||
filename: string;
|
||||
mimeType: string;
|
||||
}
|
||||
|
||||
export const parseBinaryMessageHeaders = (headers: string): BinaryMessageHeaders =>
|
||||
JSON.parse(headers) as BinaryMessageHeaders;
|
||||
|
||||
interface State {
|
||||
// data
|
||||
isReady: boolean;
|
||||
@@ -14,7 +17,7 @@ interface State {
|
||||
|
||||
// methods
|
||||
connect: (config: NymClientConfig) => Promise<void>;
|
||||
sendTextMessage: (args: { payload: string; recipient: string; headers?: Headers }) => Promise<void>;
|
||||
sendTextMessage: (args: { payload: string; recipient: string }) => Promise<void>;
|
||||
sendBinaryMessage: (args: { payload: Uint8Array; recipient: string; headers: BinaryMessageHeaders }) => Promise<void>;
|
||||
}
|
||||
|
||||
@@ -59,7 +62,7 @@ export const MixnetContextProvider: React.FC = ({ children }) => {
|
||||
await nym.current.client.start(config);
|
||||
};
|
||||
|
||||
const sendTextMessage = async (args: { payload: string; recipient: string; headers?: Headers }) => {
|
||||
const sendTextMessage = async (args: { payload: string; recipient: string }) => {
|
||||
if (!nym.current?.client) {
|
||||
console.error('Nym client has not initialised. Please wrap in useEffect on `isReady` prop of this context.');
|
||||
return;
|
||||
@@ -73,7 +76,8 @@ export const MixnetContextProvider: React.FC = ({ children }) => {
|
||||
return;
|
||||
}
|
||||
// convert headers to JSON
|
||||
await nym.current.client.sendBinaryMessage(args);
|
||||
const sendArgs = { ...args, headers: JSON.stringify(args.headers) };
|
||||
await nym.current.client.sendBinaryMessage(sendArgs);
|
||||
};
|
||||
|
||||
const value = React.useMemo<State>(
|
||||
|
||||
@@ -27,7 +27,7 @@ export interface NymClientConfig {
|
||||
* Optional. The identity key of the preferred gateway to connect to.
|
||||
*/
|
||||
preferredGatewayIdentityKey?: string;
|
||||
|
||||
|
||||
/**
|
||||
* Optional. The listener websocket of the preferred gateway to connect to.
|
||||
*/
|
||||
@@ -39,16 +39,11 @@ export interface NymClientConfig {
|
||||
debug?: wasm_bindgen.Debug;
|
||||
}
|
||||
|
||||
export interface Headers {
|
||||
senderAddress?: string;
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
export interface IWebWorker {
|
||||
start: (config: NymClientConfig) => void;
|
||||
selfAddress: () => string | undefined;
|
||||
sendMessage: (args: { payload: string; recipient: string; headers?: Headers }) => void;
|
||||
sendBinaryMessage: (args: { payload: Uint8Array; recipient: string; headers?: Headers }) => void;
|
||||
sendMessage: (args: { payload: string; recipient: string }) => void;
|
||||
sendBinaryMessage: (args: { payload: Uint8Array; recipient: string; headers?: string }) => void;
|
||||
}
|
||||
|
||||
export enum EventKinds {
|
||||
@@ -77,7 +72,6 @@ export interface StringMessageReceivedEvent {
|
||||
args: {
|
||||
kind: number;
|
||||
payload: string;
|
||||
headers?: Headers;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -86,7 +80,7 @@ export interface BinaryMessageReceivedEvent {
|
||||
args: {
|
||||
kind: number;
|
||||
payload: Uint8Array;
|
||||
headers?: Headers;
|
||||
headers: string;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@ import type {
|
||||
StringMessageReceivedEvent,
|
||||
BinaryMessageReceivedEvent,
|
||||
NymClientConfig,
|
||||
Headers,
|
||||
} from './types';
|
||||
import { EventKinds } from './types';
|
||||
|
||||
@@ -92,13 +91,12 @@ class ClientWrapper {
|
||||
this.client = await this.client.start();
|
||||
};
|
||||
|
||||
sendMessage = async ({ payload, recipient, headers }: { recipient: string; payload: string; headers?: Headers }) => {
|
||||
sendMessage = async ({ payload, recipient }: { recipient: string; payload: string }) => {
|
||||
if (!this.client) {
|
||||
console.error('Client has not been initialised. Please call `init` first.');
|
||||
return;
|
||||
}
|
||||
const headersAsJsonString = headers ? JSON.stringify(headers) : '';
|
||||
const message = wasm_bindgen.create_binary_message_from_string(PAYLOAD_KIND_TEXT, payload, headersAsJsonString);
|
||||
const message = wasm_bindgen.create_binary_message_from_string(PAYLOAD_KIND_TEXT, payload);
|
||||
this.client = await this.client.send_binary_message(message, recipient);
|
||||
};
|
||||
|
||||
@@ -109,14 +107,13 @@ class ClientWrapper {
|
||||
}: {
|
||||
recipient: string;
|
||||
payload: Uint8Array;
|
||||
headers?: Headers;
|
||||
headers?: string;
|
||||
}) => {
|
||||
if (!this.client) {
|
||||
console.error('Client has not been initialised. Please call `init` first.');
|
||||
return;
|
||||
}
|
||||
const headersAsJsonString = headers ? JSON.stringify(headers) : '';
|
||||
const message = wasm_bindgen.create_binary_message_with_headers(PAYLOAD_KIND_BINARY, payload, headersAsJsonString);
|
||||
const message = wasm_bindgen.create_binary_message_with_headers(PAYLOAD_KIND_BINARY, payload, headers || '');
|
||||
this.client = await this.client.send_binary_message(message, recipient);
|
||||
};
|
||||
}
|
||||
@@ -136,10 +133,11 @@ wasm_bindgen(wasmUrl)
|
||||
config.validatorApiUrl,
|
||||
config.preferredGatewayIdentityKey,
|
||||
);
|
||||
|
||||
|
||||
// set a different gatewayListener in order to avoid workaround ws over https error
|
||||
if (config.gatewayListener) gatewayEndpoint.gateway_listener = config.gatewayListener;
|
||||
|
||||
if (config.gatewayListener)
|
||||
gatewayEndpoint.gateway_listener = config.gatewayListener;
|
||||
|
||||
// create the client, passing handlers for events
|
||||
wrapper.init(
|
||||
new wasm_bindgen.Config(
|
||||
@@ -155,20 +153,19 @@ wasm_bindgen(wasmUrl)
|
||||
async (message) => {
|
||||
try {
|
||||
const { kind, payload, headers } = await wasm_bindgen.parse_binary_message_with_headers(message);
|
||||
const parsedHeaders = headers?.length > 0 ? JSON.parse(headers) : undefined;
|
||||
switch (kind) {
|
||||
case PAYLOAD_KIND_TEXT: {
|
||||
const stringMessage = await wasm_bindgen.parse_string_message_with_headers(message);
|
||||
postMessageWithType<StringMessageReceivedEvent>({
|
||||
kind: EventKinds.StringMessageReceived,
|
||||
args: { kind, payload: stringMessage.payload, headers: parsedHeaders },
|
||||
args: { kind, payload: stringMessage.payload },
|
||||
});
|
||||
break;
|
||||
}
|
||||
case PAYLOAD_KIND_BINARY:
|
||||
postMessageWithType<BinaryMessageReceivedEvent>({
|
||||
kind: EventKinds.BinaryMessageReceived,
|
||||
args: { kind, payload, headers: parsedHeaders },
|
||||
args: { kind, payload, headers: headers || '' },
|
||||
});
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "nym-network-requester"
|
||||
version = "1.1.0"
|
||||
version = "1.1.1"
|
||||
authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"]
|
||||
edition = "2021"
|
||||
rust-version = "1.65"
|
||||
|
||||
@@ -18,7 +18,6 @@ serde_json = "1"
|
||||
tokio = { version = "1.11", features = [ "net", "rt-multi-thread", "macros", "signal"] }
|
||||
bip39 = "1.0.1"
|
||||
anyhow = "1"
|
||||
tap = "1"
|
||||
|
||||
nym-cli-commands = { path = "../../common/commands" }
|
||||
logging = { path = "../../common/logging"}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
use network_defaults::NymNetworkDetails;
|
||||
use nym_cli_commands::context::{create_query_client, create_signing_client, ClientArgs};
|
||||
use nym_cli_commands::context::{create_signing_client, ClientArgs};
|
||||
|
||||
pub(crate) async fn execute(
|
||||
global_args: ClientArgs,
|
||||
@@ -19,22 +19,18 @@ pub(crate) async fn execute(
|
||||
.await
|
||||
}
|
||||
Some(nym_cli_commands::validator::vesting::VestingScheduleCommands::Query(args)) => {
|
||||
let address_from_args = args.address.clone();
|
||||
nym_cli_commands::validator::vesting::query_vesting_schedule::query(
|
||||
args,
|
||||
create_query_client(network_details)?,
|
||||
address_from_args,
|
||||
create_signing_client(global_args, network_details)?,
|
||||
)
|
||||
.await
|
||||
}
|
||||
Some(nym_cli_commands::validator::vesting::VestingScheduleCommands::VestedBalance(
|
||||
args,
|
||||
)) => {
|
||||
let address_from_args = args.address.clone();
|
||||
nym_cli_commands::validator::vesting::balance::balance(
|
||||
args,
|
||||
create_query_client(network_details)?,
|
||||
address_from_args,
|
||||
create_signing_client(global_args, network_details)?,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
[package]
|
||||
name = "nym-validator-api"
|
||||
version = "1.1.0"
|
||||
version = "1.1.1"
|
||||
authors = [
|
||||
"Dave Hrycyszyn <futurechimp@users.noreply.github.com>",
|
||||
"Jędrzej Stuczyński <andrew@nymtech.net>",
|
||||
|
||||
Reference in New Issue
Block a user