Compare commits
31 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f838ddffe2 | |||
| 7f7c33d10b | |||
| e7fdd3d076 | |||
| 4dc89bd65f | |||
| 9aa3b9507d | |||
| 61e88f304b | |||
| 7ff043d8df | |||
| c904d245d2 | |||
| d315a2a91b | |||
| 0741d05ab3 | |||
| 61aa920362 | |||
| 24b9b17e64 | |||
| 5e3e633c4b | |||
| f3cff902ba | |||
| 4fe1b4c26f | |||
| cb24a08b06 | |||
| 597a53d11a | |||
| 639deeb502 | |||
| e263a4a21f | |||
| 17d258d094 | |||
| 8288d38257 | |||
| 1cd560c85e | |||
| 9018642992 | |||
| ad35c4006e | |||
| 2ec790e851 | |||
| 8f8cec0785 | |||
| 4a80cd301b | |||
| 63524eceff | |||
| a477b007e1 | |||
| 5b81510325 | |||
| 3bef973326 |
@@ -43,3 +43,4 @@ Cargo.lock
|
|||||||
nym-connect/Cargo.lock
|
nym-connect/Cargo.lock
|
||||||
.parcel-cache
|
.parcel-cache
|
||||||
**/.DS_Store
|
**/.DS_Store
|
||||||
|
cpu-cycles/libcpucycles/build
|
||||||
Generated
+230
-341
File diff suppressed because it is too large
Load Diff
+1
-2
@@ -22,7 +22,6 @@ members = [
|
|||||||
"clients/native",
|
"clients/native",
|
||||||
"clients/native/websocket-requests",
|
"clients/native/websocket-requests",
|
||||||
"clients/socks5",
|
"clients/socks5",
|
||||||
"common/bandwidth-claim-contract",
|
|
||||||
"common/bin-common",
|
"common/bin-common",
|
||||||
"common/client-libs/gateway-client",
|
"common/client-libs/gateway-client",
|
||||||
"common/client-libs/mixnet-client",
|
"common/client-libs/mixnet-client",
|
||||||
@@ -107,7 +106,7 @@ license = "Apache-2.0"
|
|||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
async-trait = "0.1.64"
|
async-trait = "0.1.64"
|
||||||
cfg-if = "1.0.0"
|
cfg-if = "1.0.0"
|
||||||
dotenv = "0.15.0"
|
dotenvy = "0.15.6"
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
once_cell = "1.7.2"
|
once_cell = "1.7.2"
|
||||||
|
|||||||
@@ -1,13 +1,22 @@
|
|||||||
test: clippy-all cargo-test wasm fmt
|
test: clippy-all cargo-test wasm fmt
|
||||||
|
test-no-mobile: clippy-all-no-mobile cargo-test-no-mobile wasm fmt-no-mobile
|
||||||
test-all: test cargo-test-expensive
|
test-all: test cargo-test-expensive
|
||||||
|
test-all-no-mobile: test-no-mobile cargo-test-expensive
|
||||||
no-clippy: build cargo-test wasm fmt
|
no-clippy: build cargo-test wasm fmt
|
||||||
|
no-clippy-no-mobile: build-no-mobile cargo-test-no-mobile wasm fmt-no-mobile
|
||||||
happy: fmt clippy-happy test
|
happy: fmt clippy-happy test
|
||||||
clippy-all: clippy-main clippy-main-examples clippy-all-contracts clippy-all-wallet clippy-all-connect clippy-all-connect-mobile clippy-all-wasm-client
|
happy-no-mobile: fmt-no-mobile clippy-happy-no-mobile test-no-mobile
|
||||||
clippy-happy: clippy-happy-main clippy-happy-contracts clippy-happy-wallet clippy-happy-connect clippy-happy-connect-mobile
|
clippy-all: clippy-all-no-mobile clippy-all-connect-mobile
|
||||||
cargo-test: test-main test-contracts test-wallet test-connect test-connect-mobile
|
clippy-all-no-mobile: clippy-main clippy-main-examples clippy-all-contracts clippy-all-wallet clippy-all-connect clippy-all-wasm-client
|
||||||
|
clippy-happy: clippy-happy-no-mobile clippy-happy-connect-mobile
|
||||||
|
clippy-happy-no-mobile: clippy-happy-main clippy-happy-contracts clippy-happy-wallet clippy-happy-connect
|
||||||
|
cargo-test: cargo-test-no-mobile test-connect-mobile
|
||||||
|
cargo-test-no-mobile: test-main test-contracts test-wallet test-connect
|
||||||
cargo-test-expensive: test-main-expensive test-contracts-expensive test-wallet-expensive test-connect-expensive
|
cargo-test-expensive: test-main-expensive test-contracts-expensive test-wallet-expensive test-connect-expensive
|
||||||
build: build-contracts build-wallet build-main build-main-examples build-connect build-connect-mobile build-wasm-client
|
build: build-no-mobile build-connect-mobile
|
||||||
fmt: fmt-main fmt-contracts fmt-wallet fmt-connect fmt-connect-mobile fmt-wasm-client
|
build-no-mobile: build-contracts build-wallet build-main build-main-examples build-connect build-wasm-client
|
||||||
|
fmt: fmt-no-mobile fmt-connect-mobile
|
||||||
|
fmt-no-mobile: fmt-main fmt-contracts fmt-wallet fmt-connect fmt-wasm-client
|
||||||
|
|
||||||
clippy-happy-main:
|
clippy-happy-main:
|
||||||
cargo clippy
|
cargo clippy
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ The platform is composed of multiple Rust crates. Top-level executable binary cr
|
|||||||
* nym-wallet - a desktop wallet implemented using the [Tauri](https://tauri.studio/en/docs/about/intro) framework.
|
* nym-wallet - a desktop wallet implemented using the [Tauri](https://tauri.studio/en/docs/about/intro) framework.
|
||||||
|
|
||||||
[](https://opensource.org/licenses/Apache-2.0)
|
[](https://opensource.org/licenses/Apache-2.0)
|
||||||
[](https://github.com/nymtech/nym/actions?query=branch%3Adevelop)
|
[](https://github.com/nymtech/nym/actions?query=branch%3Adevelop)
|
||||||
|
|
||||||
|
|
||||||
### Building
|
### Building
|
||||||
|
|||||||
@@ -37,6 +37,10 @@ nym-topology = { path = "../../common/topology" }
|
|||||||
validator-client = { path = "../../common/client-libs/validator-client", default-features = false }
|
validator-client = { path = "../../common/client-libs/validator-client", default-features = false }
|
||||||
nym-task = { path = "../../common/task" }
|
nym-task = { path = "../../common/task" }
|
||||||
|
|
||||||
|
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.validator-client]
|
||||||
|
path = "../../common/client-libs/validator-client"
|
||||||
|
features = ["nyxd-client"]
|
||||||
|
|
||||||
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.tokio-stream]
|
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.tokio-stream]
|
||||||
version = "0.1.11"
|
version = "0.1.11"
|
||||||
features = ["time"]
|
features = ["time"]
|
||||||
|
|||||||
@@ -155,18 +155,21 @@ impl Backend {
|
|||||||
// (assuming no key rotation has happened)
|
// (assuming no key rotation has happened)
|
||||||
// but the way it's currently coded, everyone will purge old data
|
// but the way it's currently coded, everyone will purge old data
|
||||||
let since_last_flush = OffsetDateTime::now_utc() - last_flush;
|
let since_last_flush = OffsetDateTime::now_utc() - last_flush;
|
||||||
if since_last_flush.whole_days() > 0 {
|
let days = since_last_flush.whole_days();
|
||||||
info!("it's been over {} days and {} hours since we last used our data store. our reply surbs are already outdated - we're going to purge them now.", since_last_flush.whole_days(), since_last_flush.whole_hours());
|
let hours = since_last_flush.whole_hours() % 24;
|
||||||
|
|
||||||
|
if days > 0 {
|
||||||
|
info!("it's been over {days} days and {hours} hours since we last used our data store. our reply surbs are already outdated - we're going to purge them now.");
|
||||||
manager.delete_all_reply_surb_data().await?;
|
manager.delete_all_reply_surb_data().await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if since_last_flush.whole_days() > 1 {
|
if days > 1 {
|
||||||
info!("it's been over {} days and {} hours since we last used our data store. our reply keys are already outdated - we're going to purge them now.", since_last_flush.whole_days(), since_last_flush.whole_hours());
|
info!("it's been over {days} days and {hours} hours since we last used our data store. our reply keys are already outdated - we're going to purge them now.");
|
||||||
manager.delete_all_reply_keys().await?;
|
manager.delete_all_reply_keys().await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
if since_last_flush.whole_days() > 2 {
|
if days > 2 {
|
||||||
info!("it's been over {} days and {} hours since we last used our data store. our used sender tags are already outdated - we're going to purge them now.", since_last_flush.whole_days(), since_last_flush.whole_hours());
|
info!("it's been over {days} days and {hours} hours since we last used our data store. our used sender tags are already outdated - we're going to purge them now.");
|
||||||
manager.delete_all_tags().await?;
|
manager.delete_all_tags().await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,10 +15,10 @@ thiserror = "1.0"
|
|||||||
url = "2.2"
|
url = "2.2"
|
||||||
tokio = { version = "1.24.1", features = ["rt-multi-thread", "net", "signal", "macros"] } # async runtime
|
tokio = { version = "1.24.1", features = ["rt-multi-thread", "net", "signal", "macros"] } # async runtime
|
||||||
|
|
||||||
coconut-interface = { path = "../../common/coconut-interface" }
|
nym-coconut-interface = { path = "../../common/coconut-interface" }
|
||||||
nym-config = { path = "../../common/config" }
|
nym-config = { path = "../../common/config" }
|
||||||
credentials = { path = "../../common/credentials" }
|
nym-credentials = { path = "../../common/credentials" }
|
||||||
credential-storage = { path = "../../common/credential-storage" }
|
nym-credential-storage = { path = "../../common/credential-storage" }
|
||||||
nym-crypto = { path = "../../common/crypto", features = ["rand", "asymmetric", "symmetric", "aes", "hashing"] }
|
nym-crypto = { path = "../../common/crypto", features = ["rand", "asymmetric", "symmetric", "aes", "hashing"] }
|
||||||
nym-bin-common = { path = "../../common/bin-common"}
|
nym-bin-common = { path = "../../common/bin-common"}
|
||||||
nym-network-defaults = { path = "../../common/network-defaults" }
|
nym-network-defaults = { path = "../../common/network-defaults" }
|
||||||
|
|||||||
@@ -7,11 +7,11 @@ use nym_bin_common::completions::ArgShell;
|
|||||||
use rand::rngs::OsRng;
|
use rand::rngs::OsRng;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use coconut_interface::{Base58, Parameters};
|
use nym_coconut_interface::{Base58, Parameters};
|
||||||
use credential_storage::storage::Storage;
|
use nym_credential_storage::storage::Storage;
|
||||||
use credential_storage::PersistentStorage;
|
use nym_credential_storage::PersistentStorage;
|
||||||
use credentials::coconut::bandwidth::{BandwidthVoucher, TOTAL_ATTRIBUTES};
|
use nym_credentials::coconut::bandwidth::{BandwidthVoucher, TOTAL_ATTRIBUTES};
|
||||||
use credentials::coconut::utils::obtain_aggregate_signature;
|
use nym_credentials::coconut::utils::obtain_aggregate_signature;
|
||||||
use nym_crypto::asymmetric::{encryption, identity};
|
use nym_crypto::asymmetric::{encryption, identity};
|
||||||
use nym_network_defaults::VOUCHER_INFO;
|
use nym_network_defaults::VOUCHER_INFO;
|
||||||
use validator_client::nyxd::traits::DkgQueryClient;
|
use validator_client::nyxd::traits::DkgQueryClient;
|
||||||
|
|||||||
@@ -4,8 +4,8 @@
|
|||||||
use std::time::SystemTimeError;
|
use std::time::SystemTimeError;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
use credential_storage::error::StorageError;
|
use nym_credential_storage::error::StorageError;
|
||||||
use credentials::error::Error as CredentialError;
|
use nym_credentials::error::Error as CredentialError;
|
||||||
use nym_crypto::asymmetric::encryption::KeyRecoveryError;
|
use nym_crypto::asymmetric::encryption::KeyRecoveryError;
|
||||||
use nym_crypto::asymmetric::identity::Ed25519RecoveryError;
|
use nym_crypto::asymmetric::identity::Ed25519RecoveryError;
|
||||||
use validator_client::nyxd::error::NyxdError;
|
use validator_client::nyxd::error::NyxdError;
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ async fn main() -> Result<()> {
|
|||||||
.client_home_directory
|
.client_home_directory
|
||||||
.join(DATA_DIR)
|
.join(DATA_DIR)
|
||||||
.join(CRED_DB_FILE_NAME);
|
.join(CRED_DB_FILE_NAME);
|
||||||
let shared_storage = credential_storage::initialise_storage(db_path).await;
|
let shared_storage = nym_credential_storage::initialise_storage(db_path).await;
|
||||||
let recovery_storage = recovery_storage::RecoveryStorage::new(r.recovery_dir)?;
|
let recovery_storage = recovery_storage::RecoveryStorage::new(r.recovery_dir)?;
|
||||||
|
|
||||||
let network_details = NymNetworkDetails::new_from_env();
|
let network_details = NymNetworkDetails::new_from_env();
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use credentials::coconut::bandwidth::BandwidthVoucher;
|
use nym_credentials::coconut::bandwidth::BandwidthVoucher;
|
||||||
use std::fs::{create_dir_all, read_dir, File};
|
use std::fs::{create_dir_all, read_dir, File};
|
||||||
use std::io::{Read, Write};
|
use std::io::{Read, Write};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use coconut_interface::Parameters;
|
use nym_coconut_interface::Parameters;
|
||||||
use credentials::coconut::bandwidth::BandwidthVoucher;
|
use nym_credentials::coconut::bandwidth::BandwidthVoucher;
|
||||||
|
|
||||||
use nym_crypto::asymmetric::{encryption, identity};
|
use nym_crypto::asymmetric::{encryption, identity};
|
||||||
|
|
||||||
|
|||||||
@@ -36,10 +36,10 @@ tokio-tungstenite = "0.14" # websocket
|
|||||||
## internal
|
## internal
|
||||||
nym-bin-common = { path = "../../common/bin-common" }
|
nym-bin-common = { path = "../../common/bin-common" }
|
||||||
client-core = { path = "../client-core", features = ["fs-surb-storage"] }
|
client-core = { path = "../client-core", features = ["fs-surb-storage"] }
|
||||||
coconut-interface = { path = "../../common/coconut-interface" }
|
nym-coconut-interface = { path = "../../common/coconut-interface" }
|
||||||
nym-config = { path = "../../common/config" }
|
nym-config = { path = "../../common/config" }
|
||||||
credential-storage = { path = "../../common/credential-storage" }
|
nym-credential-storage = { path = "../../common/credential-storage" }
|
||||||
credentials = { path = "../../common/credentials" }
|
nym-credentials = { path = "../../common/credentials" }
|
||||||
nym-crypto = { path = "../../common/crypto" }
|
nym-crypto = { path = "../../common/crypto" }
|
||||||
gateway-client = { path = "../../common/client-libs/gateway-client" }
|
gateway-client = { path = "../../common/client-libs/gateway-client" }
|
||||||
gateway-requests = { path = "../../gateway/gateway-requests" }
|
gateway-requests = { path = "../../gateway/gateway-requests" }
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ impl SocketClient {
|
|||||||
let client = validator_client::Client::new_query(client_config)
|
let client = validator_client::Client::new_query(client_config)
|
||||||
.expect("Could not construct query client");
|
.expect("Could not construct query client");
|
||||||
BandwidthController::new(
|
BandwidthController::new(
|
||||||
credential_storage::initialise_storage(config.get_base().get_database_path()).await,
|
nym_credential_storage::initialise_storage(config.get_base().get_database_path()).await,
|
||||||
client,
|
client,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,26 +29,26 @@ url = "2.2"
|
|||||||
# internal
|
# internal
|
||||||
nym-bin-common = { path = "../../common/bin-common" }
|
nym-bin-common = { path = "../../common/bin-common" }
|
||||||
client-core = { path = "../client-core", features = ["fs-surb-storage"] }
|
client-core = { path = "../client-core", features = ["fs-surb-storage"] }
|
||||||
coconut-interface = { path = "../../common/coconut-interface" }
|
nym-coconut-interface = { path = "../../common/coconut-interface" }
|
||||||
nym-config = { path = "../../common/config" }
|
nym-config = { path = "../../common/config" }
|
||||||
credential-storage = { path = "../../common/credential-storage", optional = true }
|
nym-credential-storage = { path = "../../common/credential-storage", optional = true }
|
||||||
mobile-storage = { path = "../../common/mobile-storage", optional = true }
|
mobile-storage = { path = "../../common/mobile-storage", optional = true }
|
||||||
credentials = { path = "../../common/credentials" }
|
nym-credentials = { path = "../../common/credentials" }
|
||||||
nym-crypto = { path = "../../common/crypto" }
|
nym-crypto = { path = "../../common/crypto" }
|
||||||
gateway-client = { path = "../../common/client-libs/gateway-client" }
|
gateway-client = { path = "../../common/client-libs/gateway-client" }
|
||||||
gateway-requests = { path = "../../gateway/gateway-requests" }
|
gateway-requests = { path = "../../gateway/gateway-requests" }
|
||||||
nym-network-defaults = { path = "../../common/network-defaults" }
|
nym-network-defaults = { path = "../../common/network-defaults" }
|
||||||
nym-sphinx = { path = "../../common/nymsphinx" }
|
nym-sphinx = { path = "../../common/nymsphinx" }
|
||||||
ordered-buffer = { path = "../../common/socks5/ordered-buffer" }
|
nym-ordered-buffer = { path = "../../common/socks5/ordered-buffer" }
|
||||||
nym-pemstore = { path = "../../common/pemstore" }
|
nym-pemstore = { path = "../../common/pemstore" }
|
||||||
proxy-helpers = { path = "../../common/socks5/proxy-helpers" }
|
nym-socks5-proxy-helpers = { path = "../../common/socks5/proxy-helpers" }
|
||||||
service-providers-common = { path = "../../service-providers/common" }
|
nym-service-providers-common = { path = "../../service-providers/common" }
|
||||||
socks5-requests = { path = "../../common/socks5/requests" }
|
nym-socks5-requests = { path = "../../common/socks5/requests" }
|
||||||
nym-task = { path = "../../common/task" }
|
nym-task = { path = "../../common/task" }
|
||||||
nym-topology = { path = "../../common/topology" }
|
nym-topology = { path = "../../common/topology" }
|
||||||
validator-client = { path = "../../common/client-libs/validator-client", features = ["nyxd-client"] }
|
validator-client = { path = "../../common/client-libs/validator-client", features = ["nyxd-client"] }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["credential-storage"]
|
default = ["nym-credential-storage"]
|
||||||
eth = []
|
eth = []
|
||||||
mobile = ["mobile-storage", "gateway-client/mobile"]
|
mobile = ["mobile-storage", "gateway-client/mobile"]
|
||||||
|
|||||||
@@ -7,10 +7,10 @@ pub use client_core::config::MISSING_VALUE;
|
|||||||
use client_core::config::{ClientCoreConfigTrait, DebugConfig};
|
use client_core::config::{ClientCoreConfigTrait, DebugConfig};
|
||||||
use nym_config::defaults::DEFAULT_SOCKS5_LISTENING_PORT;
|
use nym_config::defaults::DEFAULT_SOCKS5_LISTENING_PORT;
|
||||||
use nym_config::{NymConfig, OptionalSet};
|
use nym_config::{NymConfig, OptionalSet};
|
||||||
|
use nym_service_providers_common::interface::ProviderInterfaceVersion;
|
||||||
|
use nym_socks5_requests::Socks5ProtocolVersion;
|
||||||
use nym_sphinx::addressing::clients::Recipient;
|
use nym_sphinx::addressing::clients::Recipient;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use service_providers_common::interface::ProviderInterfaceVersion;
|
|
||||||
use socks5_requests::Socks5ProtocolVersion;
|
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ impl NymClient {
|
|||||||
|
|
||||||
#[cfg(not(feature = "mobile"))]
|
#[cfg(not(feature = "mobile"))]
|
||||||
let storage =
|
let storage =
|
||||||
credential_storage::initialise_storage(config.get_base().get_database_path()).await;
|
nym_credential_storage::initialise_storage(config.get_base().get_database_path()).await;
|
||||||
|
|
||||||
#[cfg(feature = "mobile")]
|
#[cfg(feature = "mobile")]
|
||||||
let storage = mobile_storage::PersistentStorage {};
|
let storage = mobile_storage::PersistentStorage {};
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use crate::socks::types::SocksProxyError;
|
use crate::socks::types::SocksProxyError;
|
||||||
use client_core::error::ClientCoreError;
|
use client_core::error::ClientCoreError;
|
||||||
use socks5_requests::{ConnectionError, ConnectionId};
|
use nym_socks5_requests::{ConnectionError, ConnectionId};
|
||||||
|
|
||||||
#[derive(thiserror::Error, Debug)]
|
#[derive(thiserror::Error, Debug)]
|
||||||
pub enum Socks5ClientError {
|
pub enum Socks5ClientError {
|
||||||
|
|||||||
@@ -8,19 +8,19 @@ use client_core::client::inbound_messages::{InputMessage, InputMessageSender};
|
|||||||
use futures::channel::mpsc;
|
use futures::channel::mpsc;
|
||||||
use futures::task::{Context, Poll};
|
use futures::task::{Context, Poll};
|
||||||
use log::*;
|
use log::*;
|
||||||
|
use nym_service_providers_common::interface::{ProviderInterfaceVersion, RequestVersion};
|
||||||
|
use nym_socks5_proxy_helpers::connection_controller::{
|
||||||
|
ConnectionReceiver, ControllerCommand, ControllerSender,
|
||||||
|
};
|
||||||
|
use nym_socks5_proxy_helpers::proxy_runner::ProxyRunner;
|
||||||
|
use nym_socks5_requests::{
|
||||||
|
ConnectionId, RemoteAddress, Socks5ProtocolVersion, Socks5ProviderRequest, Socks5Request,
|
||||||
|
};
|
||||||
use nym_sphinx::addressing::clients::Recipient;
|
use nym_sphinx::addressing::clients::Recipient;
|
||||||
use nym_task::connections::{LaneQueueLengths, TransmissionLane};
|
use nym_task::connections::{LaneQueueLengths, TransmissionLane};
|
||||||
use nym_task::TaskClient;
|
use nym_task::TaskClient;
|
||||||
use pin_project::pin_project;
|
use pin_project::pin_project;
|
||||||
use proxy_helpers::connection_controller::{
|
|
||||||
ConnectionReceiver, ControllerCommand, ControllerSender,
|
|
||||||
};
|
|
||||||
use proxy_helpers::proxy_runner::ProxyRunner;
|
|
||||||
use rand::RngCore;
|
use rand::RngCore;
|
||||||
use service_providers_common::interface::{ProviderInterfaceVersion, RequestVersion};
|
|
||||||
use socks5_requests::{
|
|
||||||
ConnectionId, RemoteAddress, Socks5ProtocolVersion, Socks5ProviderRequest, Socks5Request,
|
|
||||||
};
|
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ use log::*;
|
|||||||
|
|
||||||
use client_core::client::received_buffer::ReconstructedMessagesReceiver;
|
use client_core::client::received_buffer::ReconstructedMessagesReceiver;
|
||||||
use client_core::client::received_buffer::{ReceivedBufferMessage, ReceivedBufferRequestSender};
|
use client_core::client::received_buffer::{ReceivedBufferMessage, ReceivedBufferRequestSender};
|
||||||
|
use nym_service_providers_common::interface::{ControlResponse, ResponseContent};
|
||||||
|
use nym_socks5_proxy_helpers::connection_controller::ControllerSender;
|
||||||
|
use nym_socks5_requests::{Socks5ProviderResponse, Socks5Response, Socks5ResponseContent};
|
||||||
use nym_sphinx::receiver::ReconstructedMessage;
|
use nym_sphinx::receiver::ReconstructedMessage;
|
||||||
use nym_task::TaskClient;
|
use nym_task::TaskClient;
|
||||||
use proxy_helpers::connection_controller::ControllerSender;
|
|
||||||
use service_providers_common::interface::{ControlResponse, ResponseContent};
|
|
||||||
use socks5_requests::{Socks5ProviderResponse, Socks5Response, Socks5ResponseContent};
|
|
||||||
|
|
||||||
use crate::error::Socks5ClientError;
|
use crate::error::Socks5ClientError;
|
||||||
|
|
||||||
|
|||||||
@@ -8,10 +8,10 @@ use client_core::client::{
|
|||||||
inbound_messages::InputMessageSender, received_buffer::ReceivedBufferRequestSender,
|
inbound_messages::InputMessageSender, received_buffer::ReceivedBufferRequestSender,
|
||||||
};
|
};
|
||||||
use log::*;
|
use log::*;
|
||||||
|
use nym_socks5_proxy_helpers::connection_controller::Controller;
|
||||||
use nym_sphinx::addressing::clients::Recipient;
|
use nym_sphinx::addressing::clients::Recipient;
|
||||||
use nym_task::connections::{ConnectionCommandSender, LaneQueueLengths};
|
use nym_task::connections::{ConnectionCommandSender, LaneQueueLengths};
|
||||||
use nym_task::TaskClient;
|
use nym_task::TaskClient;
|
||||||
use proxy_helpers::connection_controller::Controller;
|
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use tap::TapFallible;
|
use tap::TapFallible;
|
||||||
use tokio::net::TcpListener;
|
use tokio::net::TcpListener;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use socks5_requests::Socks5RequestError;
|
use nym_socks5_requests::Socks5RequestError;
|
||||||
use std::string::FromUtf8Error;
|
use std::string::FromUtf8Error;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
|
|||||||
@@ -1,83 +1,71 @@
|
|||||||
{
|
{
|
||||||
"root": true,
|
"root": true,
|
||||||
"env": {
|
"env": {
|
||||||
"browser": true,
|
"browser": true,
|
||||||
"es6": true,
|
"es6": true,
|
||||||
"node": true
|
"node": true
|
||||||
},
|
},
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
"ecmaVersion": 2019,
|
"ecmaVersion": 2019,
|
||||||
"sourceType": "module"
|
"sourceType": "module"
|
||||||
},
|
},
|
||||||
"globals": {
|
"globals": {
|
||||||
"Atomics": "readonly",
|
"Atomics": "readonly",
|
||||||
"SharedArrayBuffer": "readonly"
|
"SharedArrayBuffer": "readonly"
|
||||||
},
|
},
|
||||||
"plugins": ["prettier", "mocha"],
|
"plugins": ["prettier", "mocha"],
|
||||||
"extends": [
|
"extends": ["airbnb-base", "airbnb-typescript/base", "prettier"],
|
||||||
"airbnb-base",
|
"rules": {
|
||||||
"airbnb-typescript/base",
|
"prettier/prettier": "error",
|
||||||
"prettier"],
|
"import/prefer-default-export": "off",
|
||||||
"rules": {
|
"import/no-extraneous-dependencies": [
|
||||||
"prettier/prettier": "error",
|
"error",
|
||||||
"import/prefer-default-export": "off",
|
{
|
||||||
"import/no-extraneous-dependencies": [
|
"devDependencies": ["**/*.test.[jt]s", "**/*.spec.[jt]s"]
|
||||||
"error",
|
}
|
||||||
{
|
],
|
||||||
"devDependencies": [
|
"import/extensions": [
|
||||||
"**/*.test.[jt]s",
|
"error",
|
||||||
"**/*.spec.[jt]s"
|
"ignorePackages",
|
||||||
]
|
{
|
||||||
}
|
"ts": "never",
|
||||||
],
|
"js": "never"
|
||||||
"import/extensions": [
|
}
|
||||||
"error",
|
|
||||||
"ignorePackages",
|
|
||||||
{
|
|
||||||
"ts": "never",
|
|
||||||
"js": "never"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"overrides": [
|
|
||||||
{
|
|
||||||
"files": "**/*.ts",
|
|
||||||
"parser": "@typescript-eslint/parser",
|
|
||||||
"parserOptions": {
|
|
||||||
"project": "./tsconfig.json"
|
|
||||||
},
|
|
||||||
"plugins": ["@typescript-eslint/eslint-plugin"],
|
|
||||||
"extends": [
|
|
||||||
"plugin:@typescript-eslint/eslint-recommended",
|
|
||||||
"plugin:@typescript-eslint/recommended",
|
|
||||||
"prettier"
|
|
||||||
],
|
|
||||||
"rules": {
|
|
||||||
"@typescript-eslint/explicit-function-return-type": "off",
|
|
||||||
"@typescript-eslint/no-explicit-any": "off",
|
|
||||||
"@typescript-eslint/no-var-requires": "off",
|
|
||||||
"no-use-before-define": [0],
|
|
||||||
"@typescript-eslint/no-use-before-define": [1],
|
|
||||||
"import/no-unresolved": 0,
|
|
||||||
"import/no-extraneous-dependencies": [
|
|
||||||
"error",
|
|
||||||
{
|
|
||||||
"devDependencies": [
|
|
||||||
"**/*.test.ts",
|
|
||||||
"**/*.spec.ts"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"quotes": "off",
|
|
||||||
"@typescript-eslint/quotes": [
|
|
||||||
2,
|
|
||||||
"single",
|
|
||||||
{
|
|
||||||
"avoidEscape": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"@typescript-eslint/no-unused-vars": [2, { "argsIgnorePattern": "^_" }]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"overrides": [
|
||||||
|
{
|
||||||
|
"files": "**/*.ts",
|
||||||
|
"parser": "@typescript-eslint/parser",
|
||||||
|
"parserOptions": {
|
||||||
|
"project": "./tsconfig.json"
|
||||||
|
},
|
||||||
|
"plugins": ["@typescript-eslint/eslint-plugin"],
|
||||||
|
"extends": ["plugin:@typescript-eslint/eslint-recommended", "plugin:@typescript-eslint/recommended", "prettier"],
|
||||||
|
"rules": {
|
||||||
|
"@typescript-eslint/explicit-function-return-type": "off",
|
||||||
|
"@typescript-eslint/no-explicit-any": "off",
|
||||||
|
"@typescript-eslint/no-var-requires": "off",
|
||||||
|
"no-use-before-define": [0],
|
||||||
|
"@typescript-eslint/no-use-before-define": [1],
|
||||||
|
"import/no-unresolved": 0,
|
||||||
|
"import/no-extraneous-dependencies": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
"devDependencies": ["**/*.test.ts", "**/*.spec.ts"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"quotes": "off",
|
||||||
|
"@typescript-eslint/quotes": [
|
||||||
|
2,
|
||||||
|
"single",
|
||||||
|
{
|
||||||
|
"avoidEscape": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"@typescript-eslint/no-unused-vars": [2, { "argsIgnorePattern": "^_" }]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"ignorePatterns": ["tsconfig.json", "*.d.ts", "dist/**/*", "dist", "node_modules"]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,4 +4,5 @@ coverage
|
|||||||
dist
|
dist
|
||||||
docs
|
docs
|
||||||
examples/accounts
|
examples/accounts
|
||||||
node_modules
|
node_modules
|
||||||
|
.env
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
coverage
|
coverage
|
||||||
node_modules
|
node_modules
|
||||||
tests
|
tests
|
||||||
|
src
|
||||||
|
type
|
||||||
|
|||||||
+24
-25
@@ -1,40 +1,39 @@
|
|||||||
Nym Validator Client
|
# Nym Validator Client (Typescript)
|
||||||
====================
|
|
||||||
|
|
||||||
A TypeScript client for interacting with CosmWasm smart contracts in Nym validators.
|
A TypeScript client for interacting with CosmWasm smart contracts in Nym validators.
|
||||||
|
|
||||||
Running examples
|
Include the Nym Validator in your project:
|
||||||
-----------------
|
|
||||||
|
|
||||||
With the code checked out, `cd examples`. This folder contains runnable example code that will set up a blockchain and allow you to interact with it through the client.
|
|
||||||
|
|
||||||
Running tests
|
|
||||||
-------------
|
|
||||||
|
|
||||||
```
|
```
|
||||||
npm test
|
yarn add @nymproject/nym-validator-client
|
||||||
```
|
```
|
||||||
|
|
||||||
You can also trigger test execution with a test watcher. I don't have the centuries of life left to me that are needed to fight through the arcana of wiring up a working TypeScript mocha triggered execution setup, so for now my Cargo-based hack is:
|
Connect to validator and make queries
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
cargo watch -s "cd clients/validator && npm test"
|
import Validator from '@nymproject/nym-validator-client'
|
||||||
|
|
||||||
|
const main = async () => {
|
||||||
|
|
||||||
|
const client = await Validator.connectForQuery(rpcAddress, validatorAddress, prefix, mixnetContractAddress, vestingContractAddress, denom)
|
||||||
|
|
||||||
|
client.getBalance(address)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
It's ugly but works fine if you have Cargo installed. TypeScript setup help happily accepted here.
|
Connect to validator for performing actions
|
||||||
|
|
||||||
Generating Documentation
|
```
|
||||||
------------------------
|
import Validator from '@nymproject/nym-validator-client'
|
||||||
|
|
||||||
You can generate docs by running `npm run docs`. Generated output will appear in the `docs` directory.
|
const main = async () => {
|
||||||
|
|
||||||
Packaging
|
const client = await Validator.connect(mnemonic, rpcAddress, validatorAddress, prefix, mixnetContractAddress, vestingContractAddress, denom)
|
||||||
------------------------
|
|
||||||
|
|
||||||
If you're a Nym platform developer who's made changes to the client and wants to re-publish the package to NPM, here's how you do it:
|
const res = await client.send(address, [{ amount: '10000000', denom: 'unym' }]);
|
||||||
|
|
||||||
1. Bump the version number (use SemVer)
|
}
|
||||||
1. `npm run build`
|
|
||||||
1. `npm login` (if you haven't already)
|
```
|
||||||
1. `npm publish`
|
|
||||||
|
|||||||
@@ -4,15 +4,23 @@
|
|||||||
"description": "A TypeScript client for interacting with smart contracts in Nym validators",
|
"description": "A TypeScript client for interacting with smart contracts in Nym validators",
|
||||||
"repository": "https://github.com/nymtech/nym",
|
"repository": "https://github.com/nymtech/nym",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"types": "dist/index.d.ts",
|
"types": "./dist/index.d.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc",
|
"build": "rollup -c ./rollup.config.mjs",
|
||||||
"test": "ts-mocha tests/**/*.test.ts",
|
"build:types": "rollup-type-bundler --dist ./dist/nym-validator-client",
|
||||||
|
"build:prod": "sh ./scripts/build-prod.sh",
|
||||||
|
"test": "ts-mocha -p ./tsconfig.test.json ./src/tests/**/*.test.ts",
|
||||||
|
"testmock": "ts-mocha -p ./tsconfig.test.json ./src/tests/mock/*.test.ts",
|
||||||
"coverage": "nyc npm test",
|
"coverage": "nyc npm test",
|
||||||
"lint": "eslint src",
|
"clean": "rm -rf ./dist",
|
||||||
"lint:fix": "eslint src --fix",
|
"lint": "eslint",
|
||||||
|
"lint:fix": "eslint --fix",
|
||||||
|
"lint:tsc": "tsc --noEmit",
|
||||||
"docs": "typedoc --out docs src/index.ts"
|
"docs": "typedoc --out docs src/index.ts"
|
||||||
},
|
},
|
||||||
|
"files": [
|
||||||
|
"./dist/*"
|
||||||
|
],
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
"author": "Nym Technologies SA (https://nymtech.net)",
|
"author": "Nym Technologies SA (https://nymtech.net)",
|
||||||
"contributors": [
|
"contributors": [
|
||||||
@@ -21,6 +29,14 @@
|
|||||||
],
|
],
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@favware/rollup-type-bundler": "^2.0.0",
|
||||||
|
"@nymproject/types": "^1.0.0",
|
||||||
|
"@rollup/plugin-commonjs": "^24.0.1",
|
||||||
|
"@rollup/plugin-json": "^6.0.0",
|
||||||
|
"@rollup/plugin-typescript": "^11.0.0",
|
||||||
|
"@rollup/plugin-node-resolve": "^15.0.1",
|
||||||
|
"rollup": "^3.17.2",
|
||||||
|
"rollup-plugin-dts": "^5.2.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.7.0",
|
"@typescript-eslint/eslint-plugin": "^5.7.0",
|
||||||
"@typescript-eslint/parser": "^5.7.0",
|
"@typescript-eslint/parser": "^5.7.0",
|
||||||
"eslint": "^7.18.0",
|
"eslint": "^7.18.0",
|
||||||
@@ -31,21 +47,21 @@
|
|||||||
"eslint-plugin-import": "^2.25.4",
|
"eslint-plugin-import": "^2.25.4",
|
||||||
"eslint-plugin-mocha": "^10.0.3",
|
"eslint-plugin-mocha": "^10.0.3",
|
||||||
"eslint-plugin-prettier": "^4.0.0",
|
"eslint-plugin-prettier": "^4.0.0",
|
||||||
"expect": "^28.1.3",
|
|
||||||
"mocha": "^10.0.0",
|
"mocha": "^10.0.0",
|
||||||
"prettier": "^2.5.1",
|
"prettier": "^2.5.1",
|
||||||
"typedoc": "^0.22.13",
|
|
||||||
"ts-mocha": "^10.0.0",
|
"ts-mocha": "^10.0.0",
|
||||||
"typescript": "^4.6.2"
|
"typedoc": "^0.22.13",
|
||||||
},
|
"typescript": "^4.6.2",
|
||||||
"dependencies": {
|
"cosmjs-types": "^0.4.1",
|
||||||
"@cosmjs/cosmwasm-stargate": "^0.28.0",
|
"dotenv": "^16.0.3",
|
||||||
"@cosmjs/crypto": "^0.28.0",
|
"expect": "^28.1.3",
|
||||||
"@cosmjs/math": "^0.28.0",
|
"moq.ts": "^7.3.4",
|
||||||
"@cosmjs/proto-signing": "^0.28.0",
|
"@cosmjs/cosmwasm-stargate": "^0.29.5",
|
||||||
"@cosmjs/stargate": "^0.28.0",
|
"@cosmjs/crypto": "^0.29.5",
|
||||||
"@cosmjs/tendermint-rpc": "^0.28.0",
|
"@cosmjs/math": "^0.29.5",
|
||||||
"axios": "^0.26.1",
|
"@cosmjs/proto-signing": "^0.29.5",
|
||||||
"cosmjs-types": "^0.4.1"
|
"@cosmjs/stargate": "^0.29.5",
|
||||||
|
"@cosmjs/tendermint-rpc": "^0.29.5",
|
||||||
|
"axios": "^1.3.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import typescript from '@rollup/plugin-typescript';
|
||||||
|
import resolve from '@rollup/plugin-node-resolve';
|
||||||
|
import json from '@rollup/plugin-json';
|
||||||
|
import commonjs from '@rollup/plugin-commonjs';
|
||||||
|
|
||||||
|
export default [
|
||||||
|
{
|
||||||
|
input: './src/index.ts',
|
||||||
|
output: {
|
||||||
|
dir: 'dist/nym-validator-client',
|
||||||
|
format: 'cjs',
|
||||||
|
},
|
||||||
|
plugins: [resolve(), typescript(), commonjs(), json()],
|
||||||
|
},
|
||||||
|
];
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -o errexit
|
||||||
|
set -o nounset
|
||||||
|
|
||||||
|
rm -rf ./dist || true
|
||||||
|
rm -rf ../../dist || true
|
||||||
|
|
||||||
|
|
||||||
|
# Bundle application
|
||||||
|
|
||||||
|
yarn build
|
||||||
|
|
||||||
|
# Bundle types
|
||||||
|
|
||||||
|
yarn build:types
|
||||||
|
|
||||||
|
# Build package.json for bundle
|
||||||
|
|
||||||
|
node ./scripts/buildPackageJson.mjs
|
||||||
|
|
||||||
|
# Copy README
|
||||||
|
|
||||||
|
cp README.md dist/nym-validator-client
|
||||||
|
|
||||||
|
# move the output outside of the yarn/npm workspaces
|
||||||
|
|
||||||
|
mv ./dist ../../
|
||||||
|
|
||||||
|
echo "Output can be found in:"
|
||||||
|
realpath ../../dist
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import * as fs from 'fs';
|
||||||
|
|
||||||
|
// parse the package.json from the SDK, so we can keep fields like the name and version
|
||||||
|
const json = JSON.parse(fs.readFileSync('./package.json').toString());
|
||||||
|
|
||||||
|
// defaults (NB: these are in the output file locations)
|
||||||
|
const main = 'index.js';
|
||||||
|
const types = 'index.d.ts';
|
||||||
|
|
||||||
|
// make a package.json for the bundle
|
||||||
|
const packageJson = {
|
||||||
|
name: json.name,
|
||||||
|
version: json.version,
|
||||||
|
license: json.license,
|
||||||
|
author: json.author,
|
||||||
|
main,
|
||||||
|
types,
|
||||||
|
};
|
||||||
|
|
||||||
|
fs.writeFileSync('./dist/nym-validator-client/package.json', JSON.stringify(packageJson, null, 2));
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
import { Decimal } from '@cosmjs/math';
|
import { Decimal } from '@cosmjs/math';
|
||||||
import { Coin } from '@cosmjs/stargate';
|
import { Coin } from '@cosmjs/stargate';
|
||||||
|
import { CoinMap } from './types/shared';
|
||||||
|
|
||||||
// NARROW NO-BREAK SPACE (U+202F)
|
// NARROW NO-BREAK SPACE (U+202F)
|
||||||
const thinSpace = '\u202F';
|
const thinSpace = '\u202F';
|
||||||
@@ -34,15 +35,6 @@ export function nativeToPrintable(nativeValue: string): string {
|
|||||||
return Decimal.fromAtomics(nativeValue, 6).toString();
|
return Decimal.fromAtomics(nativeValue, 6).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MappedCoin {
|
|
||||||
readonly denom: string;
|
|
||||||
readonly fractionalDigits: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface CoinMap {
|
|
||||||
readonly [key: string]: MappedCoin;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function nativeCoinToDisplay(coin: Coin, coinMap: CoinMap): Coin {
|
export function nativeCoinToDisplay(coin: Coin, coinMap: CoinMap): Coin {
|
||||||
if (!coinMap) return coin;
|
if (!coinMap) return coin;
|
||||||
|
|
||||||
|
|||||||
+133
-75
@@ -1,6 +1,3 @@
|
|||||||
import { Bip39, Random } from '@cosmjs/crypto';
|
|
||||||
import { DirectSecp256k1HdWallet, EncodeObject } from '@cosmjs/proto-signing';
|
|
||||||
import { coin as cosmosCoin, Coin, DeliverTxResponse, isDeliverTxFailure, StdFee } from '@cosmjs/stargate';
|
|
||||||
import {
|
import {
|
||||||
ExecuteResult,
|
ExecuteResult,
|
||||||
InstantiateOptions,
|
InstantiateOptions,
|
||||||
@@ -8,45 +5,37 @@ import {
|
|||||||
MigrateResult,
|
MigrateResult,
|
||||||
UploadResult,
|
UploadResult,
|
||||||
} from '@cosmjs/cosmwasm-stargate';
|
} from '@cosmjs/cosmwasm-stargate';
|
||||||
import SigningClient, { ISigningClient } from './signing-client';
|
import { Bip39, Random } from '@cosmjs/crypto';
|
||||||
|
import { DirectSecp256k1HdWallet, EncodeObject } from '@cosmjs/proto-signing';
|
||||||
|
import { Coin, coin as cosmosCoin, DeliverTxResponse, isDeliverTxFailure, StdFee } from '@cosmjs/stargate';
|
||||||
import {
|
import {
|
||||||
ContractStateParams,
|
ContractStateParams,
|
||||||
Delegation,
|
Delegation,
|
||||||
Gateway,
|
Gateway,
|
||||||
GatewayBond,
|
GatewayBond,
|
||||||
|
GatewayOwnershipResponse,
|
||||||
|
LayerDistribution,
|
||||||
MixnetContractVersion,
|
MixnetContractVersion,
|
||||||
MixNode,
|
MixNode,
|
||||||
MixNodeBond,
|
MixNodeBond,
|
||||||
|
MixNodeCostParams,
|
||||||
|
MixNodeDetails,
|
||||||
|
MixNodeRewarding,
|
||||||
|
MixOwnershipResponse,
|
||||||
PagedAllDelegationsResponse,
|
PagedAllDelegationsResponse,
|
||||||
PagedDelegatorDelegationsResponse,
|
PagedDelegatorDelegationsResponse,
|
||||||
PagedGatewayResponse,
|
PagedGatewayResponse,
|
||||||
PagedMixDelegationsResponse,
|
PagedMixDelegationsResponse,
|
||||||
PagedMixnodeResponse,
|
PagedMixNodeBondResponse,
|
||||||
} from './types';
|
PagedMixNodeDetailsResponse,
|
||||||
import {
|
PagedUnbondedMixnodesResponse,
|
||||||
CoinMap,
|
RewardingParams,
|
||||||
displayAmountToNative,
|
StakeSaturationResponse,
|
||||||
MappedCoin,
|
UnbondedMixnodeResponse,
|
||||||
nativeCoinToDisplay,
|
} from '@nymproject/types';
|
||||||
nativeToPrintable,
|
|
||||||
printableBalance,
|
|
||||||
printableCoin,
|
|
||||||
} from './currency';
|
|
||||||
import QueryClient from './query-client';
|
import QueryClient from './query-client';
|
||||||
import { nymGasPrice } from './stargate-helper';
|
import SigningClient, { ISigningClient } from './signing-client';
|
||||||
|
import { ContractState } from './types/shared';
|
||||||
export { coins, coin } from '@cosmjs/stargate';
|
|
||||||
export { Coin };
|
|
||||||
export {
|
|
||||||
displayAmountToNative,
|
|
||||||
nativeCoinToDisplay,
|
|
||||||
printableCoin,
|
|
||||||
printableBalance,
|
|
||||||
nativeToPrintable,
|
|
||||||
MappedCoin,
|
|
||||||
CoinMap,
|
|
||||||
};
|
|
||||||
export { nymGasPrice };
|
|
||||||
|
|
||||||
export interface INymClient {
|
export interface INymClient {
|
||||||
readonly mixnetContract: string;
|
readonly mixnetContract: string;
|
||||||
@@ -147,7 +136,7 @@ export default class ValidatorClient implements INymClient {
|
|||||||
return DirectSecp256k1HdWallet.fromMnemonic(mnemonic, signerOptions);
|
return DirectSecp256k1HdWallet.fromMnemonic(mnemonic, signerOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
getBalance(address: string): Promise<Coin> {
|
async getBalance(address: string): Promise<Coin> {
|
||||||
return this.client.getBalance(address, this.denom);
|
return this.client.getBalance(address, this.denom);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -159,15 +148,39 @@ export default class ValidatorClient implements INymClient {
|
|||||||
return this.client.getCachedMixnodes();
|
return this.client.getCachedMixnodes();
|
||||||
}
|
}
|
||||||
|
|
||||||
async getActiveMixnodes(): Promise<MixNodeBond[]> {
|
async getStakeSaturation(mixId: number): Promise<StakeSaturationResponse> {
|
||||||
|
return this.client.getStakeSaturation(this.mixnetContract, mixId);
|
||||||
|
}
|
||||||
|
|
||||||
|
async getActiveMixnodes(): Promise<MixNodeDetails[]> {
|
||||||
return this.client.getActiveMixnodes();
|
return this.client.getActiveMixnodes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getUnbondedMixNodeInformation(mixId: number): Promise<UnbondedMixnodeResponse> {
|
||||||
|
return this.client.getUnbondedMixNodeInformation(this.mixnetContract, mixId);
|
||||||
|
}
|
||||||
|
|
||||||
async getRewardedMixnodes(): Promise<MixNodeBond[]> {
|
async getRewardedMixnodes(): Promise<MixNodeBond[]> {
|
||||||
return this.client.getRewardedMixnodes();
|
return this.client.getRewardedMixnodes();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getMixnetContractSettings(): Promise<ContractStateParams> {
|
async getMixnodeRewardingDetails(mixId: number): Promise<MixNodeRewarding> {
|
||||||
|
return this.client.getMixnodeRewardingDetails(this.mixnetContract, mixId);
|
||||||
|
}
|
||||||
|
|
||||||
|
async getOwnedMixnode(address: string): Promise<MixOwnershipResponse> {
|
||||||
|
return this.client.getOwnedMixnode(this.mixnetContract, address);
|
||||||
|
}
|
||||||
|
|
||||||
|
async ownsGateway(address: string): Promise<GatewayOwnershipResponse> {
|
||||||
|
return this.client.ownsGateway(this.mixnetContract, address);
|
||||||
|
}
|
||||||
|
|
||||||
|
async getLayerDistribution(): Promise<LayerDistribution> {
|
||||||
|
return this.client.getLayerDistribution(this.mixnetContract);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getMixnetContractSettings(): Promise<ContractState> {
|
||||||
return this.client.getStateParams(this.mixnetContract);
|
return this.client.getStateParams(this.mixnetContract);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,29 +188,74 @@ export default class ValidatorClient implements INymClient {
|
|||||||
return this.client.getContractVersion(this.mixnetContract);
|
return this.client.getContractVersion(this.mixnetContract);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getRewardPool(): Promise<string> {
|
public async getVestingContractVersion(): Promise<MixnetContractVersion> {
|
||||||
return this.client.getRewardPool(this.mixnetContract);
|
return this.client.getContractVersion(this.vestingContract);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getCirculatingSupply(): Promise<string> {
|
public async getSpendableCoins(vestingAccountAddress: string): Promise<MixnetContractVersion> {
|
||||||
return this.client.getCirculatingSupply(this.mixnetContract);
|
return this.client.getSpendableCoins(this.vestingContract, vestingAccountAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getSybilResistancePercent(): Promise<number> {
|
public async getRewardParams(): Promise<RewardingParams> {
|
||||||
return this.client.getSybilResistancePercent(this.mixnetContract);
|
return this.client.getRewardParams(this.mixnetContract);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getIntervalRewardPercent(): Promise<number> {
|
async getUnbondedMixNodes(): Promise<UnbondedMixnodeResponse[]> {
|
||||||
return this.client.getIntervalRewardPercent(this.mixnetContract);
|
let mixNodes: UnbondedMixnodeResponse[] = [];
|
||||||
|
const limit = 50;
|
||||||
|
let startAfter;
|
||||||
|
for (;;) {
|
||||||
|
// eslint-disable-next-line no-await-in-loop
|
||||||
|
const pagedResponse: PagedUnbondedMixnodesResponse = await this.client.getUnbondedMixNodes(
|
||||||
|
this.mixnetContract,
|
||||||
|
limit,
|
||||||
|
startAfter,
|
||||||
|
);
|
||||||
|
|
||||||
|
mixNodes = mixNodes.concat(pagedResponse.nodes);
|
||||||
|
startAfter = pagedResponse.start_next_after;
|
||||||
|
// if `start_next_after` is not set, we're done
|
||||||
|
if (!startAfter) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mixNodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getAllNyxdMixnodes(): Promise<MixNodeBond[]> {
|
public async getMixNodeBonds(): Promise<MixNodeBond[]> {
|
||||||
let mixNodes: MixNodeBond[] = [];
|
let mixNodes: MixNodeBond[] = [];
|
||||||
const limit = 50;
|
const limit = 50;
|
||||||
let startAfter;
|
let startAfter;
|
||||||
for (; ;) {
|
for (;;) {
|
||||||
// eslint-disable-next-line no-await-in-loop
|
// eslint-disable-next-line no-await-in-loop
|
||||||
const pagedResponse: PagedMixnodeResponse = await this.client.getMixNodesPaged(this.mixnetContract, limit);
|
const pagedResponse: PagedMixNodeBondResponse = await this.client.getMixNodeBonds(
|
||||||
|
this.mixnetContract,
|
||||||
|
limit,
|
||||||
|
startAfter,
|
||||||
|
);
|
||||||
|
mixNodes = mixNodes.concat(pagedResponse.nodes);
|
||||||
|
startAfter = pagedResponse.start_next_after;
|
||||||
|
// if `start_next_after` is not set, we're done
|
||||||
|
if (!startAfter) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mixNodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async getMixNodesDetailed(): Promise<MixNodeDetails[]> {
|
||||||
|
let mixNodes: MixNodeDetails[] = [];
|
||||||
|
const limit = 50;
|
||||||
|
let startAfter;
|
||||||
|
for (;;) {
|
||||||
|
// eslint-disable-next-line no-await-in-loop
|
||||||
|
const pagedResponse: PagedMixNodeDetailsResponse = await this.client.getMixNodesDetailed(
|
||||||
|
this.mixnetContract,
|
||||||
|
limit,
|
||||||
|
startAfter,
|
||||||
|
);
|
||||||
mixNodes = mixNodes.concat(pagedResponse.nodes);
|
mixNodes = mixNodes.concat(pagedResponse.nodes);
|
||||||
startAfter = pagedResponse.start_next_after;
|
startAfter = pagedResponse.start_next_after;
|
||||||
// if `start_next_after` is not set, we're done
|
// if `start_next_after` is not set, we're done
|
||||||
@@ -210,37 +268,24 @@ export default class ValidatorClient implements INymClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async getAllNyxdGateways(): Promise<GatewayBond[]> {
|
public async getAllNyxdGateways(): Promise<GatewayBond[]> {
|
||||||
let gateways: GatewayBond[] = [];
|
const pagedResponse: PagedGatewayResponse = await this.client.getGatewaysPaged(this.mixnetContract);
|
||||||
const limit = 50;
|
return pagedResponse.nodes;
|
||||||
let startAfter;
|
|
||||||
for (; ;) {
|
|
||||||
// eslint-disable-next-line no-await-in-loop
|
|
||||||
const pagedResponse: PagedGatewayResponse = await this.client.getGatewaysPaged(this.mixnetContract, limit);
|
|
||||||
gateways = gateways.concat(pagedResponse.nodes);
|
|
||||||
startAfter = pagedResponse.start_next_after;
|
|
||||||
// if `start_next_after` is not set, we're done
|
|
||||||
if (!startAfter) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return gateways;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets list of all delegations towards particular mixnode.
|
* Gets list of all delegations towards particular mixnode.
|
||||||
*
|
*
|
||||||
* @param mixIdentity identity of the node to which the delegation was sent
|
* @param mix_id identity of the node to which the delegation was sent
|
||||||
*/
|
*/
|
||||||
public async getAllNyxdSingleMixnodeDelegations(mixIdentity: string): Promise<Delegation[]> {
|
public async getAllNyxdSingleMixnodeDelegations(mix_id: number): Promise<Delegation[]> {
|
||||||
let delegations: Delegation[] = [];
|
let delegations: Delegation[] = [];
|
||||||
const limit = 250;
|
const limit = 250;
|
||||||
let startAfter;
|
let startAfter;
|
||||||
for (; ;) {
|
for (;;) {
|
||||||
// eslint-disable-next-line no-await-in-loop
|
// eslint-disable-next-line no-await-in-loop
|
||||||
const pagedResponse: PagedMixDelegationsResponse = await this.client.getMixNodeDelegationsPaged(
|
const pagedResponse: PagedMixDelegationsResponse = await this.client.getMixNodeDelegationsPaged(
|
||||||
this.mixnetContract,
|
this.mixnetContract,
|
||||||
mixIdentity,
|
mix_id,
|
||||||
limit,
|
limit,
|
||||||
startAfter,
|
startAfter,
|
||||||
);
|
);
|
||||||
@@ -259,7 +304,7 @@ export default class ValidatorClient implements INymClient {
|
|||||||
let delegations: Delegation[] = [];
|
let delegations: Delegation[] = [];
|
||||||
const limit = 250;
|
const limit = 250;
|
||||||
let startAfter;
|
let startAfter;
|
||||||
for (; ;) {
|
for (;;) {
|
||||||
// eslint-disable-next-line no-await-in-loop
|
// eslint-disable-next-line no-await-in-loop
|
||||||
const pagedResponse: PagedDelegatorDelegationsResponse = await this.client.getDelegatorDelegationsPaged(
|
const pagedResponse: PagedDelegatorDelegationsResponse = await this.client.getDelegatorDelegationsPaged(
|
||||||
this.mixnetContract,
|
this.mixnetContract,
|
||||||
@@ -278,13 +323,13 @@ export default class ValidatorClient implements INymClient {
|
|||||||
return delegations;
|
return delegations;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getAllNyxdNetworkDelegations(): Promise<Delegation[]> {
|
public async getAllNyxdDelegations(): Promise<Delegation[]> {
|
||||||
let delegations: Delegation[] = [];
|
let delegations: Delegation[] = [];
|
||||||
const limit = 250;
|
const limit = 250;
|
||||||
let startAfter;
|
let startAfter;
|
||||||
for (; ;) {
|
for (;;) {
|
||||||
// eslint-disable-next-line no-await-in-loop
|
// eslint-disable-next-line no-await-in-loop
|
||||||
const pagedResponse: PagedAllDelegationsResponse = await this.client.getAllNetworkDelegationsPaged(
|
const pagedResponse: PagedAllDelegationsResponse = await this.client.getAllDelegationsPaged(
|
||||||
this.mixnetContract,
|
this.mixnetContract,
|
||||||
limit,
|
limit,
|
||||||
startAfter,
|
startAfter,
|
||||||
@@ -300,6 +345,10 @@ export default class ValidatorClient implements INymClient {
|
|||||||
return delegations;
|
return delegations;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async getDelegationDetails(mix_id: number, delegator: string): Promise<Delegation> {
|
||||||
|
return this.client.getDelegationDetails(this.mixnetContract, mix_id, delegator);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a minimum gateway bond required to create a fresh mixnode.
|
* Generate a minimum gateway bond required to create a fresh mixnode.
|
||||||
*
|
*
|
||||||
@@ -308,7 +357,7 @@ export default class ValidatorClient implements INymClient {
|
|||||||
public async minimumMixnodePledge(): Promise<Coin> {
|
public async minimumMixnodePledge(): Promise<Coin> {
|
||||||
const stateParams = await this.getMixnetContractSettings();
|
const stateParams = await this.getMixnetContractSettings();
|
||||||
// we trust the contract to return a valid number
|
// we trust the contract to return a valid number
|
||||||
return cosmosCoin(stateParams.minimum_mixnode_pledge, this.prefix);
|
return cosmosCoin(stateParams.params.minimum_mixnode_pledge, this.prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -319,7 +368,7 @@ export default class ValidatorClient implements INymClient {
|
|||||||
public async minimumGatewayPledge(): Promise<Coin> {
|
public async minimumGatewayPledge(): Promise<Coin> {
|
||||||
const stateParams = await this.getMixnetContractSettings();
|
const stateParams = await this.getMixnetContractSettings();
|
||||||
// we trust the contract to return a valid number
|
// we trust the contract to return a valid number
|
||||||
return cosmosCoin(stateParams.minimum_gateway_pledge, this.prefix);
|
return cosmosCoin(stateParams.params.minimum_gateway_pledge, this.prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async send(
|
public async send(
|
||||||
@@ -393,12 +442,21 @@ export default class ValidatorClient implements INymClient {
|
|||||||
public async bondMixNode(
|
public async bondMixNode(
|
||||||
mixNode: MixNode,
|
mixNode: MixNode,
|
||||||
ownerSignature: string,
|
ownerSignature: string,
|
||||||
|
costParams: MixNodeCostParams,
|
||||||
pledge: Coin,
|
pledge: Coin,
|
||||||
fee?: StdFee | 'auto' | number,
|
fee?: StdFee | 'auto' | number,
|
||||||
memo?: string,
|
memo?: string,
|
||||||
): Promise<ExecuteResult> {
|
): Promise<ExecuteResult> {
|
||||||
this.assertSigning();
|
this.assertSigning();
|
||||||
return (this.client as ISigningClient).bondMixNode(this.mixnetContract, mixNode, ownerSignature, pledge, fee, memo);
|
return (this.client as ISigningClient).bondMixNode(
|
||||||
|
this.mixnetContract,
|
||||||
|
mixNode,
|
||||||
|
costParams,
|
||||||
|
ownerSignature,
|
||||||
|
pledge,
|
||||||
|
fee,
|
||||||
|
memo,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async unbondMixNode(fee?: StdFee | 'auto' | number, memo?: string): Promise<ExecuteResult> {
|
public async unbondMixNode(fee?: StdFee | 'auto' | number, memo?: string): Promise<ExecuteResult> {
|
||||||
@@ -423,29 +481,29 @@ export default class ValidatorClient implements INymClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async delegateToMixNode(
|
public async delegateToMixNode(
|
||||||
mixIdentity: string,
|
mixId: number,
|
||||||
amount: Coin,
|
amount: Coin,
|
||||||
fee?: StdFee | 'auto' | number,
|
fee?: StdFee | 'auto' | number,
|
||||||
memo?: string,
|
memo?: string,
|
||||||
): Promise<ExecuteResult> {
|
): Promise<ExecuteResult> {
|
||||||
this.assertSigning();
|
this.assertSigning();
|
||||||
return (this.client as ISigningClient).delegateToMixNode(this.mixnetContract, mixIdentity, amount, fee, memo);
|
return (this.client as ISigningClient).delegateToMixNode(this.mixnetContract, mixId, amount, fee, memo);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async undelegateFromMixNode(
|
public async undelegateFromMixNode(
|
||||||
mixIdentity: string,
|
mixId: number,
|
||||||
fee?: StdFee | 'auto' | number,
|
fee?: StdFee | 'auto' | number,
|
||||||
memo?: string,
|
memo?: string,
|
||||||
): Promise<ExecuteResult> {
|
): Promise<ExecuteResult> {
|
||||||
return (this.client as ISigningClient).undelegateFromMixNode(this.mixnetContract, mixIdentity, fee, memo);
|
return (this.client as ISigningClient).undelegateFromMixNode(this.mixnetContract, mixId, fee, memo);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async updateMixnodeConfig(
|
public async updateMixnodeConfig(
|
||||||
mixIdentity: string,
|
mixId: number,
|
||||||
fee: StdFee | 'auto' | number,
|
fee: StdFee | 'auto' | number,
|
||||||
profitPercentage: number,
|
profitPercentage: number,
|
||||||
): Promise<ExecuteResult> {
|
): Promise<ExecuteResult> {
|
||||||
return (this.client as ISigningClient).updateMixnodeConfig(this.mixnetContract, mixIdentity, profitPercentage, fee);
|
return (this.client as ISigningClient).updateMixnodeConfig(this.mixnetContract, mixId, profitPercentage, fee);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async updateContractStateParams(
|
public async updateContractStateParams(
|
||||||
|
|||||||
@@ -2,9 +2,8 @@
|
|||||||
* Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
* Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
import { GatewayBond, MixNodeBond } from './types';
|
import { GatewayBond, MixNodeBond, MixNodeDetails } from '@nymproject/types';
|
||||||
|
|
||||||
export const NYM_API_VERSION = '/v1';
|
export const NYM_API_VERSION = '/v1';
|
||||||
export const NYM_API_GATEWAYS_PATH = `${NYM_API_VERSION}/gateways`;
|
export const NYM_API_GATEWAYS_PATH = `${NYM_API_VERSION}/gateways`;
|
||||||
@@ -17,7 +16,7 @@ export interface INymApiQuery {
|
|||||||
|
|
||||||
getCachedGateways(): Promise<GatewayBond[]>;
|
getCachedGateways(): Promise<GatewayBond[]>;
|
||||||
|
|
||||||
getActiveMixnodes(): Promise<MixNodeBond[]>;
|
getActiveMixnodes(): Promise<MixNodeDetails[]>;
|
||||||
|
|
||||||
getRewardedMixnodes(): Promise<MixNodeBond[]>;
|
getRewardedMixnodes(): Promise<MixNodeBond[]>;
|
||||||
}
|
}
|
||||||
@@ -51,7 +50,7 @@ export default class NymApiQuerier implements INymApiQuery {
|
|||||||
throw new Error('None of the provided validator APIs seem to be alive');
|
throw new Error('None of the provided validator APIs seem to be alive');
|
||||||
}
|
}
|
||||||
|
|
||||||
async getActiveMixnodes(): Promise<MixNodeBond[]> {
|
async getActiveMixnodes(): Promise<MixNodeDetails[]> {
|
||||||
const url = new URL(this.nymApiUrl);
|
const url = new URL(this.nymApiUrl);
|
||||||
url.pathname += NYM_API_ACTIVE_MIXNODES_PATH;
|
url.pathname += NYM_API_ACTIVE_MIXNODES_PATH;
|
||||||
|
|
||||||
|
|||||||
@@ -2,28 +2,24 @@
|
|||||||
* Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
* Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
||||||
* SPDX-License-Identifier: Apache-2.0
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { JsonObject } from '@cosmjs/cosmwasm-stargate';
|
|
||||||
// eslint-disable-next-line import/no-cycle
|
// eslint-disable-next-line import/no-cycle
|
||||||
import { INyxdQuery } from './query-client';
|
import { INyxdQuery } from './query-client';
|
||||||
|
import { Delegation, RewardingParams, StakeSaturationResponse } from '@nymproject/types';
|
||||||
import {
|
import {
|
||||||
ContractStateParams,
|
UnbondedMixnodeResponse,
|
||||||
Delegation,
|
|
||||||
GatewayOwnershipResponse,
|
GatewayOwnershipResponse,
|
||||||
LayerDistribution,
|
|
||||||
MixnetContractVersion,
|
MixnetContractVersion,
|
||||||
MixOwnershipResponse,
|
MixOwnershipResponse,
|
||||||
PagedAllDelegationsResponse,
|
PagedAllDelegationsResponse,
|
||||||
PagedDelegatorDelegationsResponse,
|
PagedDelegatorDelegationsResponse,
|
||||||
PagedGatewayResponse,
|
PagedGatewayResponse,
|
||||||
PagedMixDelegationsResponse,
|
PagedMixDelegationsResponse,
|
||||||
PagedMixnodeResponse,
|
PagedMixNodeBondResponse,
|
||||||
RewardingStatus,
|
PagedMixNodeDetailsResponse,
|
||||||
} from './types';
|
PagedUnbondedMixnodesResponse,
|
||||||
|
LayerDistribution,
|
||||||
interface SmartContractQuery {
|
} from '@nymproject/types';
|
||||||
queryContractSmart(address: string, queryMsg: Record<string, unknown>): Promise<JsonObject>;
|
import { ContractState, SmartContractQuery } from './types/shared';
|
||||||
}
|
|
||||||
|
|
||||||
export default class NyxdQuerier implements INyxdQuery {
|
export default class NyxdQuerier implements INyxdQuery {
|
||||||
client: SmartContractQuery;
|
client: SmartContractQuery;
|
||||||
@@ -38,15 +34,44 @@ export default class NyxdQuerier implements INyxdQuery {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getMixNodesPaged(mixnetContractAddress: string, limit?: number, startAfter?: string): Promise<PagedMixnodeResponse> {
|
getMixNodeBonds(
|
||||||
|
mixnetContractAddress: string,
|
||||||
|
limit?: number,
|
||||||
|
startAfter?: string,
|
||||||
|
): Promise<PagedMixNodeBondResponse> {
|
||||||
return this.client.queryContractSmart(mixnetContractAddress, {
|
return this.client.queryContractSmart(mixnetContractAddress, {
|
||||||
get_mix_nodes: {
|
get_mix_node_bonds: {
|
||||||
limit,
|
limit,
|
||||||
start_after: startAfter,
|
start_after: startAfter,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getMixNodesDetailed(
|
||||||
|
mixnetContractAddress: string,
|
||||||
|
limit?: number,
|
||||||
|
startAfter?: string,
|
||||||
|
): Promise<PagedMixNodeDetailsResponse> {
|
||||||
|
return this.client.queryContractSmart(mixnetContractAddress, {
|
||||||
|
get_mix_nodes_detailed: {
|
||||||
|
limit,
|
||||||
|
start_after: startAfter,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getStakeSaturation(mixnetContractAddress: string, mixId: number): Promise<StakeSaturationResponse> {
|
||||||
|
return this.client.queryContractSmart(mixnetContractAddress, {
|
||||||
|
get_stake_saturation: { mix_id: mixId },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getMixnodeRewardingDetails(mixnetContractAddress: string, mixId: number): Promise<any> {
|
||||||
|
return this.client.queryContractSmart(mixnetContractAddress, {
|
||||||
|
get_mixnode_rewarding_details: { mix_id: mixId },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
getGatewaysPaged(mixnetContractAddress: string, limit?: number, startAfter?: string): Promise<PagedGatewayResponse> {
|
getGatewaysPaged(mixnetContractAddress: string, limit?: number, startAfter?: string): Promise<PagedGatewayResponse> {
|
||||||
return this.client.queryContractSmart(mixnetContractAddress, {
|
return this.client.queryContractSmart(mixnetContractAddress, {
|
||||||
get_gateways: {
|
get_gateways: {
|
||||||
@@ -56,35 +81,51 @@ export default class NyxdQuerier implements INyxdQuery {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
ownsMixNode(mixnetContractAddress: string, address: string): Promise<MixOwnershipResponse> {
|
getOwnedMixnode(mixnetContractAddress: string, address: string): Promise<MixOwnershipResponse> {
|
||||||
return this.client.queryContractSmart(mixnetContractAddress, {
|
return this.client.queryContractSmart(mixnetContractAddress, {
|
||||||
owns_mixnode: {
|
get_owned_mixnode: {
|
||||||
address,
|
address,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getUnbondedMixNodes(
|
||||||
|
mixnetContractAddress: string,
|
||||||
|
limit?: number,
|
||||||
|
startAfter?: string,
|
||||||
|
): Promise<PagedUnbondedMixnodesResponse> {
|
||||||
|
return this.client.queryContractSmart(mixnetContractAddress, {
|
||||||
|
get_unbonded_mix_nodes: { limit, start_after: startAfter },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getUnbondedMixNodeInformation(mixnetContractAddress: string, mixId: number): Promise<UnbondedMixnodeResponse> {
|
||||||
|
return this.client.queryContractSmart(mixnetContractAddress, {
|
||||||
|
get_unbonded_mix_node_information: { mix_id: mixId },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
ownsGateway(mixnetContractAddress: string, address: string): Promise<GatewayOwnershipResponse> {
|
ownsGateway(mixnetContractAddress: string, address: string): Promise<GatewayOwnershipResponse> {
|
||||||
return this.client.queryContractSmart(mixnetContractAddress, {
|
return this.client.queryContractSmart(mixnetContractAddress, {
|
||||||
owns_gateway: {
|
get_owned_gateway: {
|
||||||
address,
|
address,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getStateParams(mixnetContractAddress: string): Promise<ContractStateParams> {
|
getStateParams(mixnetContractAddress: string): Promise<ContractState> {
|
||||||
return this.client.queryContractSmart(mixnetContractAddress, {
|
return this.client.queryContractSmart(mixnetContractAddress, {
|
||||||
state_params: {},
|
get_state: {},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getAllNetworkDelegationsPaged(
|
getAllDelegationsPaged(
|
||||||
mixnetContractAddress: string,
|
mixnetContractAddress: string,
|
||||||
limit?: number,
|
limit?: number,
|
||||||
startAfter?: [string, string],
|
startAfter?: [string, string],
|
||||||
): Promise<PagedAllDelegationsResponse> {
|
): Promise<PagedAllDelegationsResponse> {
|
||||||
return this.client.queryContractSmart(mixnetContractAddress, {
|
return this.client.queryContractSmart(mixnetContractAddress, {
|
||||||
get_all_network_delegations: {
|
get_all_delegations: {
|
||||||
start_after: startAfter,
|
start_after: startAfter,
|
||||||
limit,
|
limit,
|
||||||
},
|
},
|
||||||
@@ -93,13 +134,13 @@ export default class NyxdQuerier implements INyxdQuery {
|
|||||||
|
|
||||||
getMixNodeDelegationsPaged(
|
getMixNodeDelegationsPaged(
|
||||||
mixnetContractAddress: string,
|
mixnetContractAddress: string,
|
||||||
mixIdentity: string,
|
mix_id: number,
|
||||||
limit?: number,
|
limit?: number,
|
||||||
startAfter?: string,
|
startAfter?: string,
|
||||||
): Promise<PagedMixDelegationsResponse> {
|
): Promise<PagedMixDelegationsResponse> {
|
||||||
return this.client.queryContractSmart(mixnetContractAddress, {
|
return this.client.queryContractSmart(mixnetContractAddress, {
|
||||||
get_mixnode_delegations: {
|
get_mixnode_delegations: {
|
||||||
mix_identity: mixIdentity,
|
mix_id: mix_id,
|
||||||
start_after: startAfter,
|
start_after: startAfter,
|
||||||
limit,
|
limit,
|
||||||
},
|
},
|
||||||
@@ -121,10 +162,10 @@ export default class NyxdQuerier implements INyxdQuery {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getDelegationDetails(mixnetContractAddress: string, mixIdentity: string, delegator: string): Promise<Delegation> {
|
getDelegationDetails(mixnetContractAddress: string, mix_id: number, delegator: string): Promise<Delegation> {
|
||||||
return this.client.queryContractSmart(mixnetContractAddress, {
|
return this.client.queryContractSmart(mixnetContractAddress, {
|
||||||
get_delegation_details: {
|
get_delegation_details: {
|
||||||
mix_identity: mixIdentity,
|
mix_id: mix_id,
|
||||||
delegator,
|
delegator,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
@@ -132,44 +173,19 @@ export default class NyxdQuerier implements INyxdQuery {
|
|||||||
|
|
||||||
getLayerDistribution(mixnetContractAddress: string): Promise<LayerDistribution> {
|
getLayerDistribution(mixnetContractAddress: string): Promise<LayerDistribution> {
|
||||||
return this.client.queryContractSmart(mixnetContractAddress, {
|
return this.client.queryContractSmart(mixnetContractAddress, {
|
||||||
layer_distribution: {},
|
get_layer_distribution: {},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getRewardPool(mixnetContractAddress: string): Promise<string> {
|
getRewardParams(mixnetContractAddress: string): Promise<RewardingParams> {
|
||||||
return this.client.queryContractSmart(mixnetContractAddress, {
|
return this.client.queryContractSmart(mixnetContractAddress, {
|
||||||
get_reward_pool: {},
|
get_rewarding_params: {},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
getCirculatingSupply(mixnetContractAddress: string): Promise<string> {
|
getSpendableCoins(vestingContractAddress: string, vestingAccountAddress: string): Promise<any> {
|
||||||
return this.client.queryContractSmart(mixnetContractAddress, {
|
return this.client.queryContractSmart(vestingContractAddress, {
|
||||||
get_circulating_supply: {},
|
vesting_account_address: vestingAccountAddress,
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
getIntervalRewardPercent(mixnetContractAddress: string): Promise<number> {
|
|
||||||
return this.client.queryContractSmart(mixnetContractAddress, {
|
|
||||||
get_interval_reward_percent: {},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
getSybilResistancePercent(mixnetContractAddress: string): Promise<number> {
|
|
||||||
return this.client.queryContractSmart(mixnetContractAddress, {
|
|
||||||
get_sybil_resistance_percent: {},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
getRewardingStatus(
|
|
||||||
mixnetContractAddress: string,
|
|
||||||
mixIdentity: string,
|
|
||||||
rewardingIntervalNonce: number,
|
|
||||||
): Promise<RewardingStatus> {
|
|
||||||
return this.client.queryContractSmart(mixnetContractAddress, {
|
|
||||||
get_rewarding_status: {
|
|
||||||
mix_identity: mixIdentity,
|
|
||||||
rewarding_interval_nonce: rewardingIntervalNonce,
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,75 +1,56 @@
|
|||||||
import { CosmWasmClient, JsonObject } from '@cosmjs/cosmwasm-stargate';
|
import { CosmWasmClient } from '@cosmjs/cosmwasm-stargate';
|
||||||
import { Tendermint34Client } from '@cosmjs/tendermint-rpc';
|
|
||||||
import {
|
|
||||||
Account,
|
|
||||||
Block,
|
|
||||||
Coin,
|
|
||||||
DeliverTxResponse,
|
|
||||||
IndexedTx,
|
|
||||||
SearchTxFilter,
|
|
||||||
SearchTxQuery,
|
|
||||||
SequenceResponse,
|
|
||||||
} from '@cosmjs/stargate';
|
|
||||||
import { Code, CodeDetails, Contract, ContractCodeHistoryEntry } from '@cosmjs/cosmwasm-stargate/build/cosmwasmclient';
|
|
||||||
// eslint-disable-next-line import/no-cycle
|
// eslint-disable-next-line import/no-cycle
|
||||||
import NyxdQuerier from './nyxd-querier';
|
import NyxdQuerier from './nyxd-querier';
|
||||||
import {
|
import {
|
||||||
ContractStateParams,
|
|
||||||
Delegation,
|
Delegation,
|
||||||
GatewayBond,
|
GatewayBond,
|
||||||
GatewayOwnershipResponse,
|
GatewayOwnershipResponse,
|
||||||
LayerDistribution,
|
LayerDistribution,
|
||||||
MixnetContractVersion,
|
MixnetContractVersion,
|
||||||
MixNodeBond,
|
MixNodeDetails,
|
||||||
MixOwnershipResponse,
|
MixOwnershipResponse,
|
||||||
PagedAllDelegationsResponse,
|
PagedAllDelegationsResponse,
|
||||||
PagedDelegatorDelegationsResponse,
|
PagedDelegatorDelegationsResponse,
|
||||||
PagedGatewayResponse,
|
PagedGatewayResponse,
|
||||||
PagedMixDelegationsResponse,
|
PagedMixDelegationsResponse,
|
||||||
PagedMixnodeResponse,
|
PagedMixNodeBondResponse,
|
||||||
RewardingStatus,
|
PagedMixNodeDetailsResponse,
|
||||||
} from './types';
|
PagedUnbondedMixnodesResponse,
|
||||||
import NymApiQuerier, { INymApiQuery as INymApiQuery } from './nym-api-querier';
|
StakeSaturationResponse,
|
||||||
|
UnbondedMixnodeResponse,
|
||||||
export interface ICosmWasmQuery {
|
MixNodeBond,
|
||||||
// methods exposed by `CosmWasmClient`
|
MixNodeRewarding,
|
||||||
getChainId(): Promise<string>;
|
} from '@nymproject/types';
|
||||||
getHeight(): Promise<number>;
|
import NymApiQuerier, { INymApiQuery } from './nym-api-querier';
|
||||||
getAccount(searchAddress: string): Promise<Account | null>;
|
import { ContractState, ICosmWasmQuery } from './types/shared';
|
||||||
getSequence(address: string): Promise<SequenceResponse>;
|
import { RewardingParams } from '@nymproject/types';
|
||||||
getBlock(height?: number): Promise<Block>;
|
import { Tendermint34Client } from '@cosmjs/tendermint-rpc';
|
||||||
getBalance(address: string, searchDenom: string): Promise<Coin>;
|
|
||||||
getTx(id: string): Promise<IndexedTx | null>;
|
|
||||||
searchTx(query: SearchTxQuery, filter?: SearchTxFilter): Promise<readonly IndexedTx[]>;
|
|
||||||
disconnect(): void;
|
|
||||||
broadcastTx(tx: Uint8Array, timeoutMs?: number, pollIntervalMs?: number): Promise<DeliverTxResponse>;
|
|
||||||
getCodes(): Promise<readonly Code[]>;
|
|
||||||
getCodeDetails(codeId: number): Promise<CodeDetails>;
|
|
||||||
getContracts(codeId: number): Promise<readonly string[]>;
|
|
||||||
getContract(address: string): Promise<Contract>;
|
|
||||||
getContractCodeHistory(address: string): Promise<readonly ContractCodeHistoryEntry[]>;
|
|
||||||
queryContractRaw(address: string, key: Uint8Array): Promise<Uint8Array | null>;
|
|
||||||
queryContractSmart(address: string, queryMsg: Record<string, unknown>): Promise<JsonObject>;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface INyxdQuery {
|
export interface INyxdQuery {
|
||||||
// nym-specific implemented inside NymQuerier
|
// nym-specific implemented inside NymQuerier
|
||||||
getContractVersion(mixnetContractAddress: string): Promise<MixnetContractVersion>;
|
getContractVersion(mixnetContractAddress: string): Promise<MixnetContractVersion>;
|
||||||
|
getMixNodeBonds(
|
||||||
getMixNodesPaged(mixnetContractAddress: string, limit?: number, startAfter?: string): Promise<PagedMixnodeResponse>;
|
mixnetContractAddress: string,
|
||||||
|
limit?: number,
|
||||||
|
startAfter?: string,
|
||||||
|
): Promise<PagedMixNodeBondResponse>;
|
||||||
|
getMixNodesDetailed(
|
||||||
|
mixnetContractAddress: string,
|
||||||
|
limit?: number,
|
||||||
|
startAfter?: string,
|
||||||
|
): Promise<PagedMixNodeDetailsResponse>;
|
||||||
getGatewaysPaged(mixnetContractAddress: string, limit?: number, startAfter?: string): Promise<PagedGatewayResponse>;
|
getGatewaysPaged(mixnetContractAddress: string, limit?: number, startAfter?: string): Promise<PagedGatewayResponse>;
|
||||||
ownsMixNode(mixnetContractAddress: string, address: string): Promise<MixOwnershipResponse>;
|
getOwnedMixnode(mixnetContractAddress: string, address: string): Promise<MixOwnershipResponse>;
|
||||||
ownsGateway(mixnetContractAddress: string, address: string): Promise<GatewayOwnershipResponse>;
|
ownsGateway(mixnetContractAddress: string, address: string): Promise<GatewayOwnershipResponse>;
|
||||||
getStateParams(mixnetContractAddress: string): Promise<ContractStateParams>;
|
getStateParams(mixnetContractAddress: string): Promise<ContractState>;
|
||||||
|
getAllDelegationsPaged(
|
||||||
getAllNetworkDelegationsPaged(
|
|
||||||
mixnetContractAddress: string,
|
mixnetContractAddress: string,
|
||||||
limit?: number,
|
limit?: number,
|
||||||
startAfter?: [string, string],
|
startAfter?: [string, string],
|
||||||
): Promise<PagedAllDelegationsResponse>;
|
): Promise<PagedAllDelegationsResponse>;
|
||||||
getMixNodeDelegationsPaged(
|
getMixNodeDelegationsPaged(
|
||||||
mixnetContractAddress: string,
|
mixnetContractAddress: string,
|
||||||
mixIdentity: string,
|
mix_id: number,
|
||||||
limit?: number,
|
limit?: number,
|
||||||
startAfter?: string,
|
startAfter?: string,
|
||||||
): Promise<PagedMixDelegationsResponse>;
|
): Promise<PagedMixDelegationsResponse>;
|
||||||
@@ -79,21 +60,15 @@ export interface INyxdQuery {
|
|||||||
limit?: number,
|
limit?: number,
|
||||||
startAfter?: string,
|
startAfter?: string,
|
||||||
): Promise<PagedDelegatorDelegationsResponse>;
|
): Promise<PagedDelegatorDelegationsResponse>;
|
||||||
getDelegationDetails(mixnetContractAddress: string, mixIdentity: string, delegator: string): Promise<Delegation>;
|
getDelegationDetails(mixnetContractAddress: string, mix_id: number, delegator: string): Promise<Delegation>;
|
||||||
|
|
||||||
getLayerDistribution(mixnetContractAddress: string): Promise<LayerDistribution>;
|
getLayerDistribution(mixnetContractAddress: string): Promise<LayerDistribution>;
|
||||||
getRewardPool(mixnetContractAddress: string): Promise<string>;
|
getRewardParams(mixnetContractAddress: string): Promise<RewardingParams>;
|
||||||
getCirculatingSupply(mixnetContractAddress: string): Promise<string>;
|
getStakeSaturation(mixnetContractAddress: string, mixId: number): Promise<StakeSaturationResponse>;
|
||||||
getIntervalRewardPercent(mixnetContractAddress: string): Promise<number>;
|
getUnbondedMixNodeInformation(mixnetContractAddress: string, mixId: number): Promise<UnbondedMixnodeResponse>;
|
||||||
getSybilResistancePercent(mixnetContractAddress: string): Promise<number>;
|
getMixnodeRewardingDetails(mixnetContractAddress: string, mixId: number): Promise<MixNodeRewarding>;
|
||||||
getRewardingStatus(
|
|
||||||
mixnetContractAddress: string,
|
|
||||||
mixIdentity: string,
|
|
||||||
rewardingIntervalNonce: number,
|
|
||||||
): Promise<RewardingStatus>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IQueryClient extends ICosmWasmQuery, INyxdQuery, INymApiQuery { }
|
export interface IQueryClient extends ICosmWasmQuery, INyxdQuery, INymApiQuery {}
|
||||||
|
|
||||||
export default class QueryClient extends CosmWasmClient implements IQueryClient {
|
export default class QueryClient extends CosmWasmClient implements IQueryClient {
|
||||||
private nyxdQuerier: NyxdQuerier;
|
private nyxdQuerier: NyxdQuerier;
|
||||||
@@ -115,41 +90,73 @@ export default class QueryClient extends CosmWasmClient implements IQueryClient
|
|||||||
return this.nyxdQuerier.getContractVersion(mixnetContractAddress);
|
return this.nyxdQuerier.getContractVersion(mixnetContractAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
getMixNodesPaged(mixnetContractAddress: string, limit?: number, startAfter?: string): Promise<PagedMixnodeResponse> {
|
getMixNodeBonds(
|
||||||
return this.nyxdQuerier.getMixNodesPaged(mixnetContractAddress, limit, startAfter);
|
mixnetContractAddress: string,
|
||||||
|
limit?: number,
|
||||||
|
startAfter?: string,
|
||||||
|
): Promise<PagedMixNodeBondResponse> {
|
||||||
|
return this.nyxdQuerier.getMixNodeBonds(mixnetContractAddress, limit, startAfter);
|
||||||
|
}
|
||||||
|
|
||||||
|
getMixNodesDetailed(
|
||||||
|
mixnetContractAddress: string,
|
||||||
|
limit?: number,
|
||||||
|
startAfter?: string,
|
||||||
|
): Promise<PagedMixNodeDetailsResponse> {
|
||||||
|
return this.nyxdQuerier.getMixNodesDetailed(mixnetContractAddress, limit, startAfter);
|
||||||
|
}
|
||||||
|
|
||||||
|
getStakeSaturation(mixnetContractAddress: string, mixId: number): Promise<StakeSaturationResponse> {
|
||||||
|
return this.nyxdQuerier.getStakeSaturation(mixnetContractAddress, mixId);
|
||||||
|
}
|
||||||
|
|
||||||
|
getMixnodeRewardingDetails(mixnetContractAddress: string, mixId: number): Promise<MixNodeRewarding> {
|
||||||
|
return this.nyxdQuerier.getMixnodeRewardingDetails(mixnetContractAddress, mixId);
|
||||||
}
|
}
|
||||||
|
|
||||||
getGatewaysPaged(mixnetContractAddress: string, limit?: number, startAfter?: string): Promise<PagedGatewayResponse> {
|
getGatewaysPaged(mixnetContractAddress: string, limit?: number, startAfter?: string): Promise<PagedGatewayResponse> {
|
||||||
return this.nyxdQuerier.getGatewaysPaged(mixnetContractAddress, limit, startAfter);
|
return this.nyxdQuerier.getGatewaysPaged(mixnetContractAddress, limit, startAfter);
|
||||||
}
|
}
|
||||||
|
|
||||||
ownsMixNode(mixnetContractAddress: string, address: string): Promise<MixOwnershipResponse> {
|
getOwnedMixnode(mixnetContractAddress: string, address: string): Promise<MixOwnershipResponse> {
|
||||||
return this.nyxdQuerier.ownsMixNode(mixnetContractAddress, address);
|
return this.nyxdQuerier.getOwnedMixnode(mixnetContractAddress, address);
|
||||||
}
|
}
|
||||||
|
|
||||||
ownsGateway(mixnetContractAddress: string, address: string): Promise<GatewayOwnershipResponse> {
|
ownsGateway(mixnetContractAddress: string, address: string): Promise<GatewayOwnershipResponse> {
|
||||||
return this.nyxdQuerier.ownsGateway(mixnetContractAddress, address);
|
return this.nyxdQuerier.ownsGateway(mixnetContractAddress, address);
|
||||||
}
|
}
|
||||||
|
|
||||||
getStateParams(mixnetContractAddress: string): Promise<ContractStateParams> {
|
getUnbondedMixNodes(
|
||||||
|
mixnetContractAddress: string,
|
||||||
|
limit?: number,
|
||||||
|
startAfter?: string,
|
||||||
|
): Promise<PagedUnbondedMixnodesResponse> {
|
||||||
|
return this.nyxdQuerier.getUnbondedMixNodes(mixnetContractAddress, limit, startAfter);
|
||||||
|
}
|
||||||
|
|
||||||
|
getUnbondedMixNodeInformation(mixnetContractAddress: string, mixId: number): Promise<UnbondedMixnodeResponse> {
|
||||||
|
return this.nyxdQuerier.getUnbondedMixNodeInformation(mixnetContractAddress, mixId);
|
||||||
|
}
|
||||||
|
|
||||||
|
getStateParams(mixnetContractAddress: string): Promise<ContractState> {
|
||||||
return this.nyxdQuerier.getStateParams(mixnetContractAddress);
|
return this.nyxdQuerier.getStateParams(mixnetContractAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
getAllNetworkDelegationsPaged(
|
getAllDelegationsPaged(
|
||||||
mixnetContractAddress: string,
|
mixnetContractAddress: string,
|
||||||
limit?: number,
|
limit?: number,
|
||||||
startAfter?: [string, string],
|
startAfter?: [string, string],
|
||||||
): Promise<PagedAllDelegationsResponse> {
|
): Promise<PagedAllDelegationsResponse> {
|
||||||
return this.nyxdQuerier.getAllNetworkDelegationsPaged(mixnetContractAddress, limit, startAfter);
|
return this.nyxdQuerier.getAllDelegationsPaged(mixnetContractAddress, limit, startAfter);
|
||||||
}
|
}
|
||||||
|
|
||||||
getMixNodeDelegationsPaged(
|
getMixNodeDelegationsPaged(
|
||||||
mixnetContractAddress: string,
|
mixnetContractAddress: string,
|
||||||
mixIdentity: string,
|
mix_id: number,
|
||||||
limit?: number,
|
limit?: number,
|
||||||
startAfter?: string,
|
startAfter?: string,
|
||||||
): Promise<PagedMixDelegationsResponse> {
|
): Promise<PagedMixDelegationsResponse> {
|
||||||
return this.nyxdQuerier.getMixNodeDelegationsPaged(mixnetContractAddress, mixIdentity, limit, startAfter);
|
return this.nyxdQuerier.getMixNodeDelegationsPaged(mixnetContractAddress, mix_id, limit, startAfter);
|
||||||
}
|
}
|
||||||
|
|
||||||
getDelegatorDelegationsPaged(
|
getDelegatorDelegationsPaged(
|
||||||
@@ -161,36 +168,16 @@ export default class QueryClient extends CosmWasmClient implements IQueryClient
|
|||||||
return this.nyxdQuerier.getDelegatorDelegationsPaged(mixnetContractAddress, delegator, limit, startAfter);
|
return this.nyxdQuerier.getDelegatorDelegationsPaged(mixnetContractAddress, delegator, limit, startAfter);
|
||||||
}
|
}
|
||||||
|
|
||||||
getDelegationDetails(mixnetContractAddress: string, mixIdentity: string, delegator: string): Promise<Delegation> {
|
getDelegationDetails(mixnetContractAddress: string, mix_id: number, delegator: string): Promise<Delegation> {
|
||||||
return this.nyxdQuerier.getDelegationDetails(mixnetContractAddress, mixIdentity, delegator);
|
return this.nyxdQuerier.getDelegationDetails(mixnetContractAddress, mix_id, delegator);
|
||||||
}
|
}
|
||||||
|
|
||||||
getLayerDistribution(mixnetContractAddress: string): Promise<LayerDistribution> {
|
getLayerDistribution(mixnetContractAddress: string): Promise<LayerDistribution> {
|
||||||
return this.nyxdQuerier.getLayerDistribution(mixnetContractAddress);
|
return this.nyxdQuerier.getLayerDistribution(mixnetContractAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
getRewardPool(mixnetContractAddress: string): Promise<string> {
|
getRewardParams(mixnetContractAddress: string): Promise<RewardingParams> {
|
||||||
return this.nyxdQuerier.getRewardPool(mixnetContractAddress);
|
return this.nyxdQuerier.getRewardParams(mixnetContractAddress);
|
||||||
}
|
|
||||||
|
|
||||||
getCirculatingSupply(mixnetContractAddress: string): Promise<string> {
|
|
||||||
return this.nyxdQuerier.getCirculatingSupply(mixnetContractAddress);
|
|
||||||
}
|
|
||||||
|
|
||||||
getIntervalRewardPercent(mixnetContractAddress: string): Promise<number> {
|
|
||||||
return this.nyxdQuerier.getIntervalRewardPercent(mixnetContractAddress);
|
|
||||||
}
|
|
||||||
|
|
||||||
getSybilResistancePercent(mixnetContractAddress: string): Promise<number> {
|
|
||||||
return this.nyxdQuerier.getSybilResistancePercent(mixnetContractAddress);
|
|
||||||
}
|
|
||||||
|
|
||||||
getRewardingStatus(
|
|
||||||
mixnetContractAddress: string,
|
|
||||||
mixIdentity: string,
|
|
||||||
rewardingIntervalNonce: number,
|
|
||||||
): Promise<RewardingStatus> {
|
|
||||||
return this.nyxdQuerier.getRewardingStatus(mixnetContractAddress, mixIdentity, rewardingIntervalNonce);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getCachedGateways(): Promise<GatewayBond[]> {
|
getCachedGateways(): Promise<GatewayBond[]> {
|
||||||
@@ -201,11 +188,15 @@ export default class QueryClient extends CosmWasmClient implements IQueryClient
|
|||||||
return this.nymApiQuerier.getCachedMixnodes();
|
return this.nymApiQuerier.getCachedMixnodes();
|
||||||
}
|
}
|
||||||
|
|
||||||
getActiveMixnodes(): Promise<MixNodeBond[]> {
|
getActiveMixnodes(): Promise<MixNodeDetails[]> {
|
||||||
return this.nymApiQuerier.getActiveMixnodes();
|
return this.nymApiQuerier.getActiveMixnodes();
|
||||||
}
|
}
|
||||||
|
|
||||||
getRewardedMixnodes(): Promise<MixNodeBond[]> {
|
getRewardedMixnodes(): Promise<MixNodeBond[]> {
|
||||||
return this.nymApiQuerier.getRewardedMixnodes();
|
return this.nymApiQuerier.getRewardedMixnodes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getSpendableCoins(vestingContractAddress: string, vestingAccountAddress: string): Promise<any> {
|
||||||
|
return this.nyxdQuerier.getSpendableCoins(vestingContractAddress, vestingAccountAddress);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,15 +25,22 @@ import {
|
|||||||
MixnetContractVersion,
|
MixnetContractVersion,
|
||||||
MixNode,
|
MixNode,
|
||||||
MixNodeBond,
|
MixNodeBond,
|
||||||
|
MixNodeCostParams,
|
||||||
|
MixNodeDetails,
|
||||||
|
MixNodeRewarding,
|
||||||
MixOwnershipResponse,
|
MixOwnershipResponse,
|
||||||
PagedAllDelegationsResponse,
|
PagedAllDelegationsResponse,
|
||||||
PagedDelegatorDelegationsResponse,
|
PagedDelegatorDelegationsResponse,
|
||||||
PagedGatewayResponse,
|
PagedGatewayResponse,
|
||||||
PagedMixDelegationsResponse,
|
PagedMixDelegationsResponse,
|
||||||
PagedMixnodeResponse,
|
PagedMixNodeBondResponse,
|
||||||
RewardingStatus,
|
PagedMixNodeDetailsResponse,
|
||||||
} from './types';
|
PagedUnbondedMixnodesResponse,
|
||||||
|
RewardingParams,
|
||||||
|
UnbondedMixnodeResponse,
|
||||||
|
} from '@nymproject/types';
|
||||||
import NymApiQuerier from './nym-api-querier';
|
import NymApiQuerier from './nym-api-querier';
|
||||||
|
import { ContractState } from './types/shared';
|
||||||
|
|
||||||
// methods exposed by `SigningCosmWasmClient`
|
// methods exposed by `SigningCosmWasmClient`
|
||||||
export interface ICosmWasmSigning {
|
export interface ICosmWasmSigning {
|
||||||
@@ -143,6 +150,7 @@ export interface ISigningClient extends IQueryClient, ICosmWasmSigning, INymSign
|
|||||||
bondMixNode(
|
bondMixNode(
|
||||||
mixnetContractAddress: string,
|
mixnetContractAddress: string,
|
||||||
mixNode: MixNode,
|
mixNode: MixNode,
|
||||||
|
costParams: MixNodeCostParams,
|
||||||
ownerSignature: string,
|
ownerSignature: string,
|
||||||
pledge: Coin,
|
pledge: Coin,
|
||||||
fee?: StdFee | 'auto' | number,
|
fee?: StdFee | 'auto' | number,
|
||||||
@@ -164,7 +172,7 @@ export interface ISigningClient extends IQueryClient, ICosmWasmSigning, INymSign
|
|||||||
|
|
||||||
delegateToMixNode(
|
delegateToMixNode(
|
||||||
mixnetContractAddress: string,
|
mixnetContractAddress: string,
|
||||||
mixIdentity: string,
|
mixId: number,
|
||||||
amount: Coin,
|
amount: Coin,
|
||||||
fee?: StdFee | 'auto' | number,
|
fee?: StdFee | 'auto' | number,
|
||||||
memo?: string,
|
memo?: string,
|
||||||
@@ -172,14 +180,14 @@ export interface ISigningClient extends IQueryClient, ICosmWasmSigning, INymSign
|
|||||||
|
|
||||||
undelegateFromMixNode(
|
undelegateFromMixNode(
|
||||||
mixnetContractAddress: string,
|
mixnetContractAddress: string,
|
||||||
mixIdentity: string,
|
mixId: number,
|
||||||
fee?: StdFee | 'auto' | number,
|
fee?: StdFee | 'auto' | number,
|
||||||
memo?: string,
|
memo?: string,
|
||||||
): Promise<ExecuteResult>;
|
): Promise<ExecuteResult>;
|
||||||
|
|
||||||
updateMixnodeConfig(
|
updateMixnodeConfig(
|
||||||
mixnetContractAddress: string,
|
mixnetContractAddress: string,
|
||||||
mixIdentity: string,
|
mixId: number,
|
||||||
profitMarginPercent: number,
|
profitMarginPercent: number,
|
||||||
fee: StdFee | 'auto' | number,
|
fee: StdFee | 'auto' | number,
|
||||||
): Promise<ExecuteResult>;
|
): Promise<ExecuteResult>;
|
||||||
@@ -235,44 +243,76 @@ export default class SigningClient extends SigningCosmWasmClient implements ISig
|
|||||||
// query related:
|
// query related:
|
||||||
|
|
||||||
getContractVersion(mixnetContractAddress: string): Promise<MixnetContractVersion> {
|
getContractVersion(mixnetContractAddress: string): Promise<MixnetContractVersion> {
|
||||||
return this.nyxdQuerier.getContractVersion(mixnetContractAddress);
|
return this.getContractVersion(mixnetContractAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
getMixNodesPaged(mixnetContractAddress: string, limit?: number, startAfter?: string): Promise<PagedMixnodeResponse> {
|
getMixNodeBonds(
|
||||||
return this.nyxdQuerier.getMixNodesPaged(mixnetContractAddress, limit, startAfter);
|
mixnetContractAddress: string,
|
||||||
|
limit?: number,
|
||||||
|
startAfter?: string,
|
||||||
|
): Promise<PagedMixNodeBondResponse> {
|
||||||
|
return this.nyxdQuerier.getMixNodeBonds(mixnetContractAddress, limit, startAfter);
|
||||||
|
}
|
||||||
|
|
||||||
|
getMixNodesDetailed(
|
||||||
|
mixnetContractAddress: string,
|
||||||
|
limit?: number,
|
||||||
|
startAfter?: string,
|
||||||
|
): Promise<PagedMixNodeDetailsResponse> {
|
||||||
|
return this.nyxdQuerier.getMixNodesDetailed(mixnetContractAddress, limit, startAfter);
|
||||||
|
}
|
||||||
|
|
||||||
|
getStakeSaturation(mixnetContractAddress: string, mixId: number) {
|
||||||
|
return this.nyxdQuerier.getStakeSaturation(mixnetContractAddress, mixId);
|
||||||
|
}
|
||||||
|
|
||||||
|
getUnbondedMixNodeInformation(mixnetContractAddress: string, mixId: number): Promise<UnbondedMixnodeResponse> {
|
||||||
|
return this.nyxdQuerier.getUnbondedMixNodeInformation(mixnetContractAddress, mixId);
|
||||||
|
}
|
||||||
|
|
||||||
|
getMixnodeRewardingDetails(mixnetContractAddress: string, mixId: number): Promise<MixNodeRewarding> {
|
||||||
|
return this.nyxdQuerier.getMixnodeRewardingDetails(mixnetContractAddress, mixId);
|
||||||
}
|
}
|
||||||
|
|
||||||
getGatewaysPaged(mixnetContractAddress: string, limit?: number, startAfter?: string): Promise<PagedGatewayResponse> {
|
getGatewaysPaged(mixnetContractAddress: string, limit?: number, startAfter?: string): Promise<PagedGatewayResponse> {
|
||||||
return this.nyxdQuerier.getGatewaysPaged(mixnetContractAddress, limit, startAfter);
|
return this.nyxdQuerier.getGatewaysPaged(mixnetContractAddress, limit, startAfter);
|
||||||
}
|
}
|
||||||
|
|
||||||
ownsMixNode(mixnetContractAddress: string, address: string): Promise<MixOwnershipResponse> {
|
getOwnedMixnode(mixnetContractAddress: string, address: string): Promise<MixOwnershipResponse> {
|
||||||
return this.nyxdQuerier.ownsMixNode(mixnetContractAddress, address);
|
return this.nyxdQuerier.getOwnedMixnode(mixnetContractAddress, address);
|
||||||
}
|
}
|
||||||
|
|
||||||
ownsGateway(mixnetContractAddress: string, address: string): Promise<GatewayOwnershipResponse> {
|
ownsGateway(mixnetContractAddress: string, address: string): Promise<GatewayOwnershipResponse> {
|
||||||
return this.nyxdQuerier.ownsGateway(mixnetContractAddress, address);
|
return this.nyxdQuerier.ownsGateway(mixnetContractAddress, address);
|
||||||
}
|
}
|
||||||
|
|
||||||
getStateParams(mixnetContractAddress: string): Promise<ContractStateParams> {
|
getStateParams(mixnetContractAddress: string): Promise<ContractState> {
|
||||||
return this.nyxdQuerier.getStateParams(mixnetContractAddress);
|
return this.nyxdQuerier.getStateParams(mixnetContractAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
getAllNetworkDelegationsPaged(
|
getAllDelegationsPaged(
|
||||||
mixnetContractAddress: string,
|
mixnetContractAddress: string,
|
||||||
limit?: number,
|
limit?: number,
|
||||||
startAfter?: [string, string],
|
startAfter?: [string, string],
|
||||||
): Promise<PagedAllDelegationsResponse> {
|
): Promise<PagedAllDelegationsResponse> {
|
||||||
return this.nyxdQuerier.getAllNetworkDelegationsPaged(mixnetContractAddress, limit, startAfter);
|
return this.getAllDelegationsPaged(mixnetContractAddress, limit, startAfter);
|
||||||
|
}
|
||||||
|
|
||||||
|
getUnbondedMixNodes(
|
||||||
|
mixnetContractAddress: string,
|
||||||
|
limit?: number,
|
||||||
|
startAfter?: string,
|
||||||
|
): Promise<PagedUnbondedMixnodesResponse> {
|
||||||
|
return this.nyxdQuerier.getUnbondedMixNodes(mixnetContractAddress, limit, startAfter);
|
||||||
}
|
}
|
||||||
|
|
||||||
getMixNodeDelegationsPaged(
|
getMixNodeDelegationsPaged(
|
||||||
mixnetContractAddress: string,
|
mixnetContractAddress: string,
|
||||||
mixIdentity: string,
|
mix_id: number,
|
||||||
limit?: number,
|
limit?: number,
|
||||||
startAfter?: string,
|
startAfter?: string,
|
||||||
): Promise<PagedMixDelegationsResponse> {
|
): Promise<PagedMixDelegationsResponse> {
|
||||||
return this.nyxdQuerier.getMixNodeDelegationsPaged(mixnetContractAddress, mixIdentity, limit, startAfter);
|
return this.nyxdQuerier.getMixNodeDelegationsPaged(mixnetContractAddress, mix_id, limit, startAfter);
|
||||||
}
|
}
|
||||||
|
|
||||||
getDelegatorDelegationsPaged(
|
getDelegatorDelegationsPaged(
|
||||||
@@ -284,36 +324,16 @@ export default class SigningClient extends SigningCosmWasmClient implements ISig
|
|||||||
return this.nyxdQuerier.getDelegatorDelegationsPaged(mixnetContractAddress, delegator, limit, startAfter);
|
return this.nyxdQuerier.getDelegatorDelegationsPaged(mixnetContractAddress, delegator, limit, startAfter);
|
||||||
}
|
}
|
||||||
|
|
||||||
getDelegationDetails(mixnetContractAddress: string, mixIdentity: string, delegator: string): Promise<Delegation> {
|
getDelegationDetails(mixnetContractAddress: string, mix_id: number, delegator: string): Promise<Delegation> {
|
||||||
return this.nyxdQuerier.getDelegationDetails(mixnetContractAddress, mixIdentity, delegator);
|
return this.nyxdQuerier.getDelegationDetails(mixnetContractAddress, mix_id, delegator);
|
||||||
}
|
}
|
||||||
|
|
||||||
getLayerDistribution(mixnetContractAddress: string): Promise<LayerDistribution> {
|
getLayerDistribution(mixnetContractAddress: string): Promise<LayerDistribution> {
|
||||||
return this.nyxdQuerier.getLayerDistribution(mixnetContractAddress);
|
return this.nyxdQuerier.getLayerDistribution(mixnetContractAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
getRewardPool(mixnetContractAddress: string): Promise<string> {
|
getRewardParams(mixnetContractAddress: string): Promise<RewardingParams> {
|
||||||
return this.nyxdQuerier.getRewardPool(mixnetContractAddress);
|
return this.nyxdQuerier.getRewardParams(mixnetContractAddress);
|
||||||
}
|
|
||||||
|
|
||||||
getCirculatingSupply(mixnetContractAddress: string): Promise<string> {
|
|
||||||
return this.nyxdQuerier.getCirculatingSupply(mixnetContractAddress);
|
|
||||||
}
|
|
||||||
|
|
||||||
getIntervalRewardPercent(mixnetContractAddress: string): Promise<number> {
|
|
||||||
return this.nyxdQuerier.getIntervalRewardPercent(mixnetContractAddress);
|
|
||||||
}
|
|
||||||
|
|
||||||
getSybilResistancePercent(mixnetContractAddress: string): Promise<number> {
|
|
||||||
return this.nyxdQuerier.getSybilResistancePercent(mixnetContractAddress);
|
|
||||||
}
|
|
||||||
|
|
||||||
getRewardingStatus(
|
|
||||||
mixnetContractAddress: string,
|
|
||||||
mixIdentity: string,
|
|
||||||
rewardingIntervalNonce: number,
|
|
||||||
): Promise<RewardingStatus> {
|
|
||||||
return this.nyxdQuerier.getRewardingStatus(mixnetContractAddress, mixIdentity, rewardingIntervalNonce);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getCachedGateways(): Promise<GatewayBond[]> {
|
getCachedGateways(): Promise<GatewayBond[]> {
|
||||||
@@ -324,7 +344,7 @@ export default class SigningClient extends SigningCosmWasmClient implements ISig
|
|||||||
return this.nymApiQuerier.getCachedMixnodes();
|
return this.nymApiQuerier.getCachedMixnodes();
|
||||||
}
|
}
|
||||||
|
|
||||||
getActiveMixnodes(): Promise<MixNodeBond[]> {
|
getActiveMixnodes(): Promise<MixNodeDetails[]> {
|
||||||
return this.nymApiQuerier.getActiveMixnodes();
|
return this.nymApiQuerier.getActiveMixnodes();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -332,11 +352,16 @@ export default class SigningClient extends SigningCosmWasmClient implements ISig
|
|||||||
return this.nymApiQuerier.getRewardedMixnodes();
|
return this.nymApiQuerier.getRewardedMixnodes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getSpendableCoins(vestingContractAddress: string, vestingAccountAddress: string): Promise<any> {
|
||||||
|
return this.nyxdQuerier.getSpendableCoins(vestingContractAddress, vestingAccountAddress);
|
||||||
|
}
|
||||||
|
|
||||||
// signing related:
|
// signing related:
|
||||||
|
|
||||||
bondMixNode(
|
bondMixNode(
|
||||||
mixnetContractAddress: string,
|
mixnetContractAddress: string,
|
||||||
mixNode: MixNode,
|
mixNode: MixNode,
|
||||||
|
costParams: MixNodeCostParams,
|
||||||
ownerSignature: string,
|
ownerSignature: string,
|
||||||
pledge: Coin,
|
pledge: Coin,
|
||||||
fee: StdFee | 'auto' | number = 'auto',
|
fee: StdFee | 'auto' | number = 'auto',
|
||||||
@@ -348,6 +373,7 @@ export default class SigningClient extends SigningCosmWasmClient implements ISig
|
|||||||
{
|
{
|
||||||
bond_mixnode: {
|
bond_mixnode: {
|
||||||
mix_node: mixNode,
|
mix_node: mixNode,
|
||||||
|
cost_params: costParams,
|
||||||
owner_signature: ownerSignature,
|
owner_signature: ownerSignature,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -414,7 +440,7 @@ export default class SigningClient extends SigningCosmWasmClient implements ISig
|
|||||||
|
|
||||||
delegateToMixNode(
|
delegateToMixNode(
|
||||||
mixnetContractAddress: string,
|
mixnetContractAddress: string,
|
||||||
mixIdentity: string,
|
mixId: number,
|
||||||
amount: Coin,
|
amount: Coin,
|
||||||
fee: StdFee | 'auto' | number = 'auto',
|
fee: StdFee | 'auto' | number = 'auto',
|
||||||
memo = 'Default MixNode Delegation from Typescript',
|
memo = 'Default MixNode Delegation from Typescript',
|
||||||
@@ -424,7 +450,7 @@ export default class SigningClient extends SigningCosmWasmClient implements ISig
|
|||||||
mixnetContractAddress,
|
mixnetContractAddress,
|
||||||
{
|
{
|
||||||
delegate_to_mixnode: {
|
delegate_to_mixnode: {
|
||||||
mix_identity: mixIdentity,
|
mix_id: mixId,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
fee,
|
fee,
|
||||||
@@ -435,7 +461,7 @@ export default class SigningClient extends SigningCosmWasmClient implements ISig
|
|||||||
|
|
||||||
undelegateFromMixNode(
|
undelegateFromMixNode(
|
||||||
mixnetContractAddress: string,
|
mixnetContractAddress: string,
|
||||||
mixIdentity: string,
|
mixId: number,
|
||||||
fee: StdFee | 'auto' | number = 'auto',
|
fee: StdFee | 'auto' | number = 'auto',
|
||||||
memo = 'Default MixNode Undelegation from Typescript',
|
memo = 'Default MixNode Undelegation from Typescript',
|
||||||
): Promise<ExecuteResult> {
|
): Promise<ExecuteResult> {
|
||||||
@@ -444,7 +470,7 @@ export default class SigningClient extends SigningCosmWasmClient implements ISig
|
|||||||
mixnetContractAddress,
|
mixnetContractAddress,
|
||||||
{
|
{
|
||||||
undelegate_from_mixnode: {
|
undelegate_from_mixnode: {
|
||||||
mix_identity: mixIdentity,
|
mix_id: mixId,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
fee,
|
fee,
|
||||||
@@ -454,14 +480,14 @@ export default class SigningClient extends SigningCosmWasmClient implements ISig
|
|||||||
|
|
||||||
updateMixnodeConfig(
|
updateMixnodeConfig(
|
||||||
mixnetContractAddress: string,
|
mixnetContractAddress: string,
|
||||||
mixIdentity: string,
|
mixId: number,
|
||||||
profitMarginPercent: number,
|
profitMarginPercent: number,
|
||||||
fee: StdFee | 'auto' | number,
|
fee: StdFee | 'auto' | number,
|
||||||
): Promise<ExecuteResult> {
|
): Promise<ExecuteResult> {
|
||||||
return this.execute(
|
return this.execute(
|
||||||
this.clientAddress,
|
this.clientAddress,
|
||||||
mixnetContractAddress,
|
mixnetContractAddress,
|
||||||
{ update_mixnode_config: { profit_margin_percent: profitMarginPercent, mix_identity: mixIdentity } },
|
{ update_mixnode_config: { profit_margin_percent: profitMarginPercent, mix_id: mixId } },
|
||||||
fee,
|
fee,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,178 @@
|
|||||||
|
import expect from 'expect';
|
||||||
|
|
||||||
|
export const amountDemon = {
|
||||||
|
amount: expect.any(String),
|
||||||
|
denom: expect.any(String)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const delegation = {
|
||||||
|
owner: expect.any(String),
|
||||||
|
mix_id: expect.any(Number),
|
||||||
|
cumulative_reward_ratio: expect.any(String),
|
||||||
|
amount: amountDemon,
|
||||||
|
height: expect.any(Number || BigInt),
|
||||||
|
proxy: expect.any(String || null)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const detailedDelegation = {
|
||||||
|
delegation: delegation,
|
||||||
|
mixnode_still_bonded: expect.any(Boolean)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const gateway = {
|
||||||
|
pledge_amount: amountDemon,
|
||||||
|
owner: expect.any(String),
|
||||||
|
block_height: expect.any(Number || BigInt),
|
||||||
|
gateway: {
|
||||||
|
host: expect.any(String),
|
||||||
|
mix_port: expect.any(Number),
|
||||||
|
clients_port: expect.any(Number),
|
||||||
|
location: expect.any(String),
|
||||||
|
sphinx_key: expect.any(String),
|
||||||
|
identity_key: expect.any(String),
|
||||||
|
version: expect.any(String),
|
||||||
|
},
|
||||||
|
proxy: expect.any(String || null)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const pagedGateway = {
|
||||||
|
nodes: gateway,
|
||||||
|
per_page: expect.any(Number),
|
||||||
|
start_next_after: expect.any(Number)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ownGateway = {
|
||||||
|
address: expect.any(String),
|
||||||
|
gateway: gateway
|
||||||
|
}
|
||||||
|
|
||||||
|
export const rewardingdetails = {
|
||||||
|
cost_params: {
|
||||||
|
profit_margin_percent: expect.any(String),
|
||||||
|
interval_operating_cost: {
|
||||||
|
denom: expect.any(String),
|
||||||
|
amount: expect.any(String)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
operator: expect.any(String),
|
||||||
|
delegates: expect.any(String),
|
||||||
|
total_unit_reward: expect.any(String),
|
||||||
|
unit_delegation: expect.any(String),
|
||||||
|
last_rewarded_epoch: expect.any(Number),
|
||||||
|
unique_delegations: expect.any(Number)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const mix_node = {
|
||||||
|
host: expect.any(String),
|
||||||
|
mix_port: expect.any(Number),
|
||||||
|
verloc_port: expect.any(Number),
|
||||||
|
http_api_port: expect.any(Number),
|
||||||
|
sphinx_key: expect.any(String),
|
||||||
|
identity_key: expect.any(String),
|
||||||
|
version: expect.any(String)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const mixnodebond = {
|
||||||
|
mix_id: expect.any(Number),
|
||||||
|
owner: expect.any(String),
|
||||||
|
original_pledge: {
|
||||||
|
denom: expect.any(String),
|
||||||
|
amount: expect.any(String)
|
||||||
|
},
|
||||||
|
layer: expect.any(String),
|
||||||
|
mix_node: mix_node,
|
||||||
|
proxy: expect.any(String) || null,
|
||||||
|
bonding_height: expect.any(Number || BigInt),
|
||||||
|
is_unbonding: expect.any(Boolean)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const mixnode = {
|
||||||
|
bond_information: mixnodebond,
|
||||||
|
rewarding_details: rewardingdetails
|
||||||
|
}
|
||||||
|
|
||||||
|
export const ownedNode = {
|
||||||
|
address: expect.any(String),
|
||||||
|
mixnode_details: {
|
||||||
|
bond_information: mixnodebond,
|
||||||
|
rewarding_details: rewardingdetails
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const saturation = {
|
||||||
|
mix_id: expect.any(Number),
|
||||||
|
current_saturation: expect.any(String),
|
||||||
|
uncapped_saturation: expect.any(String)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const contractVersion = {
|
||||||
|
build_timestamp: expect.any(String),
|
||||||
|
build_version: expect.any(String),
|
||||||
|
commit_sha: expect.any(String),
|
||||||
|
commit_timestamp: expect.any(String),
|
||||||
|
commit_branch: expect.any(String),
|
||||||
|
rustc_version: expect.any(String)
|
||||||
|
};
|
||||||
|
|
||||||
|
export const stateParams = {
|
||||||
|
minimum_gateway_pledge: amountDemon,
|
||||||
|
minimum_mixnode_pledge: expect.any(String),
|
||||||
|
mixnode_rewarded_set_size: expect.any(Number),
|
||||||
|
mixnode_active_set_size: expect.any(Number)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const contract = {
|
||||||
|
owner: expect.any(Number),
|
||||||
|
rewarding_validator_address: expect.any(Number),
|
||||||
|
vesting_contract_address: expect.any(Number),
|
||||||
|
rewarding_denom: expect.any(String),
|
||||||
|
params: stateParams
|
||||||
|
}
|
||||||
|
|
||||||
|
export const rewardingnode = {
|
||||||
|
mix_id: expect.any(Number),
|
||||||
|
rewarding_details: rewardingdetails
|
||||||
|
}
|
||||||
|
|
||||||
|
export const unbondednode = {
|
||||||
|
mix_id: expect.any(Number),
|
||||||
|
unbonded_info: {
|
||||||
|
identity_key: expect.any(String),
|
||||||
|
owner: expect.any(String),
|
||||||
|
proxy: expect.any(String) || null,
|
||||||
|
unbonding_height: expect.any(Number)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const allunbondednodes = [
|
||||||
|
expect.any(Number), {
|
||||||
|
identity_key: expect.any(String),
|
||||||
|
owner: expect.any(String),
|
||||||
|
proxy: expect.any(String) || null,
|
||||||
|
unbonding_height: expect.any(Number)
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
export const layerDistribution = {
|
||||||
|
layer1: expect.any(Number),
|
||||||
|
layer2: expect.any(Number),
|
||||||
|
layer3: expect.any(Number)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export const intervalRewardParams = {
|
||||||
|
reward_pool: expect.any(Number),
|
||||||
|
staking_supply: expect.any(Number),
|
||||||
|
staking_supply_scale_factor: expect.any(Number),
|
||||||
|
epoch_reward_budget: expect.any(Number),
|
||||||
|
stake_saturation_point: expect.any(Number),
|
||||||
|
sybil_resistance: expect.any(Number),
|
||||||
|
active_set_work_factor: expect.any(Number),
|
||||||
|
interval_pool_emission: expect.any(Number)
|
||||||
|
}
|
||||||
|
|
||||||
|
export const rewardingParams = {
|
||||||
|
interval: intervalRewardParams,
|
||||||
|
rewarded_set_size: expect.any(Number),
|
||||||
|
active_set_size: expect.any(Number)
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import { Mock, Times } from 'moq.ts';
|
||||||
|
import expect from 'expect';
|
||||||
|
import { INyxdQuery } from '../../query-client';
|
||||||
|
|
||||||
|
export class TestHelper {
|
||||||
|
buildMethod = async <T>(methodName: string, args: any[], expectedResult: any): Promise<T> => {
|
||||||
|
const client = new Mock<INyxdQuery>()
|
||||||
|
.setup((nym) => nym[methodName](...args))
|
||||||
|
.returns(Promise.resolve(expectedResult));
|
||||||
|
const obj = client.object();
|
||||||
|
const actualDetails = await obj[methodName](...args);
|
||||||
|
|
||||||
|
client.verify((nym) => nym[methodName](...args), Times.Exactly(1));
|
||||||
|
expect(Object.keys([actualDetails])).toEqual(Object.keys(expectedResult));
|
||||||
|
expect(actualDetails).toBeDefined();
|
||||||
|
|
||||||
|
return actualDetails;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
import expect from 'expect';
|
||||||
|
import { Delegation } from '@nymproject/types';
|
||||||
|
import { PagedAllDelegationsResponse, PagedDelegatorDelegationsResponse } from '../../types/shared-types';
|
||||||
|
import { TestHelper } from './client';
|
||||||
|
import { mixnet, mixnodeowneraddress, mix_id } from './testData';
|
||||||
|
|
||||||
|
describe('Delegation mock tests', () => {
|
||||||
|
const testHelper = new TestHelper();
|
||||||
|
|
||||||
|
it('get Delegation Details', () => {
|
||||||
|
const execute = testHelper.buildMethod('getDelegationDetails', [mixnet, mix_id, mixnodeowneraddress], <Delegation>{
|
||||||
|
owner: mixnodeowneraddress,
|
||||||
|
mix_id: 0,
|
||||||
|
cumulative_reward_ratio: '',
|
||||||
|
amount: {
|
||||||
|
denom: 'nym',
|
||||||
|
amount: '10',
|
||||||
|
},
|
||||||
|
height: 1314134144132n,
|
||||||
|
proxy: 'null',
|
||||||
|
});
|
||||||
|
expect(execute).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('get All Delegations Paged', () => {
|
||||||
|
const execute = testHelper.buildMethod('getAllDelegationsPaged', [mixnet], <PagedAllDelegationsResponse>{
|
||||||
|
delegations: [],
|
||||||
|
});
|
||||||
|
expect(execute).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('get Delegator Delegations Paged', () => {
|
||||||
|
const execute = testHelper.buildMethod('getDelegatorDelegationsPaged', [mixnet, mixnodeowneraddress], <
|
||||||
|
PagedDelegatorDelegationsResponse
|
||||||
|
>{
|
||||||
|
delegations: [],
|
||||||
|
});
|
||||||
|
expect(execute).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import expect from 'expect';
|
||||||
|
import { GatewayOwnershipResponse, PagedGatewayResponse } from '../../types/shared-types';
|
||||||
|
import { TestHelper } from './client';
|
||||||
|
import { gatewayowneraddress, mixnet } from './testData';
|
||||||
|
|
||||||
|
describe('Gateway mock tests', () => {
|
||||||
|
const testHelper = new TestHelper();
|
||||||
|
|
||||||
|
it('get Gateways Paged', () => {
|
||||||
|
const execute = testHelper.buildMethod('getGatewaysPaged', [mixnet], <PagedGatewayResponse>{
|
||||||
|
nodes: [],
|
||||||
|
per_page: 25,
|
||||||
|
});
|
||||||
|
expect(execute).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('owns Gateway', () => {
|
||||||
|
const execute = testHelper.buildMethod('ownsGateway', [mixnet, gatewayowneraddress], <GatewayOwnershipResponse>{
|
||||||
|
address: gatewayowneraddress,
|
||||||
|
gateway: {},
|
||||||
|
});
|
||||||
|
expect(execute).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
import expect from 'expect';
|
||||||
|
import { LayerDistribution, MixnetContractVersion, StakeSaturationResponse } from '@nymproject/types';
|
||||||
|
import { TestHelper } from './client';
|
||||||
|
import { mixnet, mix_id } from './testData';
|
||||||
|
import { RewardingParams } from '@nymproject/types';
|
||||||
|
import { ContractState } from '../../types/shared';
|
||||||
|
|
||||||
|
describe('Mixnet mock tests', () => {
|
||||||
|
const testHelper = new TestHelper();
|
||||||
|
|
||||||
|
it('get Layer Distribution', () => {
|
||||||
|
const execute = testHelper.buildMethod('getLayerDistribution', [mixnet], <LayerDistribution>{
|
||||||
|
layer1: 2,
|
||||||
|
layer2: 2,
|
||||||
|
layer3: 5,
|
||||||
|
});
|
||||||
|
expect(execute).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('get Reward Params', () => {
|
||||||
|
const execute = testHelper.buildMethod('getRewardParams', [mixnet], <RewardingParams>{
|
||||||
|
interval: {},
|
||||||
|
rewarded_set_size: 0,
|
||||||
|
active_set_size: 0,
|
||||||
|
});
|
||||||
|
expect(execute).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('get Stake Saturation', () => {
|
||||||
|
const execute = testHelper.buildMethod('getStakeSaturation', [mixnet, mix_id], <StakeSaturationResponse>{
|
||||||
|
mix_id: 0,
|
||||||
|
current_saturation: '',
|
||||||
|
uncapped_saturation: '',
|
||||||
|
});
|
||||||
|
expect(execute).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('get State Params', () => {
|
||||||
|
const execute = testHelper.buildMethod('getStateParams', [mixnet], <ContractState>{
|
||||||
|
owner: '',
|
||||||
|
rewarding_validator_address: '',
|
||||||
|
vesting_contract_address: '',
|
||||||
|
rewarding_denom: 'unym',
|
||||||
|
params: {
|
||||||
|
minimum_mixnode_pledge: '',
|
||||||
|
minimum_gateway_pledge: '',
|
||||||
|
mixnode_rewarded_set_size: 240,
|
||||||
|
mixnode_active_set_size: 240,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
expect(execute).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('get Contract Version', () => {
|
||||||
|
const execute = testHelper.buildMethod('getContractVersion', [mixnet], <MixnetContractVersion>{
|
||||||
|
build_timestamp: 'test',
|
||||||
|
commit_branch: 'test',
|
||||||
|
build_version: 'test',
|
||||||
|
rustc_version: 'test',
|
||||||
|
commit_sha: 'test',
|
||||||
|
commit_timestamp: 'test',
|
||||||
|
});
|
||||||
|
expect(execute).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
import expect from 'expect';
|
||||||
|
import {
|
||||||
|
MixNodeRewarding,
|
||||||
|
MixOwnershipResponse,
|
||||||
|
PagedMixDelegationsResponse,
|
||||||
|
PagedMixNodeBondResponse,
|
||||||
|
PagedMixNodeDetailsResponse,
|
||||||
|
UnbondedMixnodeResponse,
|
||||||
|
} from '@nymproject/types';
|
||||||
|
import { TestHelper } from './client';
|
||||||
|
import { mixnet, mixnodeowneraddress, mix_id } from './testData';
|
||||||
|
|
||||||
|
describe('Mixnode mock tests', () => {
|
||||||
|
const testHelper = new TestHelper();
|
||||||
|
|
||||||
|
it('get Mixnode Bonds', () => {
|
||||||
|
const execute = testHelper.buildMethod('getMixNodeBonds', [mixnet], <PagedMixNodeBondResponse>{
|
||||||
|
nodes: [],
|
||||||
|
per_page: 25,
|
||||||
|
});
|
||||||
|
expect(execute).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('get Mixnode Delegations Paged', () => {
|
||||||
|
const execute = testHelper.buildMethod('getMixNodeDelegationsPaged', [mixnet, mix_id], <
|
||||||
|
PagedMixDelegationsResponse
|
||||||
|
>{
|
||||||
|
delegations: [],
|
||||||
|
per_page: 25,
|
||||||
|
});
|
||||||
|
expect(execute).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('get Mixnodes Detailed', () => {
|
||||||
|
const execute = testHelper.buildMethod('getMixNodesDetailed', [mixnet], <PagedMixNodeDetailsResponse>{
|
||||||
|
nodes: [],
|
||||||
|
per_page: 25,
|
||||||
|
});
|
||||||
|
expect(execute).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('get Mixnode Rewarding Details', () => {
|
||||||
|
const execute = testHelper.buildMethod('getMixnodeRewardingDetails', [mixnet, mix_id], <MixNodeRewarding>{
|
||||||
|
cost_params: {},
|
||||||
|
operator: '',
|
||||||
|
delegates: '',
|
||||||
|
total_unit_reward: '',
|
||||||
|
unit_delegation: '',
|
||||||
|
last_rewarded_epoch: 1,
|
||||||
|
unique_delegations: 1,
|
||||||
|
});
|
||||||
|
expect(execute).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('get Owned Mixnode', () => {
|
||||||
|
const execute = testHelper.buildMethod('getOwnedMixnode', [mixnet, mixnodeowneraddress], <MixOwnershipResponse>{
|
||||||
|
address: '',
|
||||||
|
mixnode: {},
|
||||||
|
});
|
||||||
|
expect(execute).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('get Unbonded Mixnode Information', () => {
|
||||||
|
const execute = testHelper.buildMethod(
|
||||||
|
'getUnbondedMixNodeInformation',
|
||||||
|
[mixnet, mix_id],
|
||||||
|
<UnbondedMixnodeResponse>{},
|
||||||
|
);
|
||||||
|
expect(execute).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
export const mixnet = 'n14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9sjyvg3g';
|
||||||
|
export const gatewayowneraddress = 'n16evnn8glr0sham3matj8rg2s24m6x56ayk87ts';
|
||||||
|
// export const mixId = 436207616;
|
||||||
|
export const mix_id = 26;
|
||||||
|
export const nodeIdentityKey = 'ATmVJknZarDF6Yj53M7h8NS9LLCUvWuToXpk3pDvYUH1';
|
||||||
|
export const mixnodeowneraddress = 'n1fzv4jc7fanl9s0qj02ge2ezk3kts545kjtek47';
|
||||||
|
export const delegatorAddress = 'n1lemst75va9700tsrxq58adzujrh6h9s5x60h9h';
|
||||||
|
export const rewardingIntervalNonce = 1;
|
||||||
@@ -0,0 +1,180 @@
|
|||||||
|
import expect from 'expect';
|
||||||
|
import ValidatorClient from '../../index';
|
||||||
|
|
||||||
|
import {
|
||||||
|
allunbondednodes,
|
||||||
|
contract,
|
||||||
|
delegation,
|
||||||
|
gateway,
|
||||||
|
layerDistribution,
|
||||||
|
mixnode,
|
||||||
|
mixnodebond,
|
||||||
|
ownedNode,
|
||||||
|
ownGateway,
|
||||||
|
rewardingnode,
|
||||||
|
saturation,
|
||||||
|
unbondednode,
|
||||||
|
} from '../expectedResponses';
|
||||||
|
import { delegatorAddress, gatewayowneraddress } from '../mock/testData';
|
||||||
|
|
||||||
|
const dotenv = require('dotenv');
|
||||||
|
|
||||||
|
dotenv.config();
|
||||||
|
|
||||||
|
describe('Mixnet queries', () => {
|
||||||
|
let client: ValidatorClient;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
client = await ValidatorClient.connectForQuery(
|
||||||
|
process.env.rpcAddress || '',
|
||||||
|
process.env.validatorAddress || '',
|
||||||
|
process.env.prefix || '',
|
||||||
|
process.env.mixnetContractAddress || '',
|
||||||
|
process.env.vestingContractAddress || '',
|
||||||
|
process.env.denom || '',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
//
|
||||||
|
// CONTRACT
|
||||||
|
//
|
||||||
|
|
||||||
|
it('can query for an account balance', async () => {
|
||||||
|
const balance = await client.getBalance('n1ptg680vnmef2cd8l0s9uyc4f0hgf3x8sed6w77');
|
||||||
|
expect(Number.parseFloat(balance.amount)).toBeGreaterThan(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can query for stake saturation', async () => {
|
||||||
|
const stakeSaturation = await client.getStakeSaturation(7);
|
||||||
|
expect(Object.keys(stakeSaturation)).toEqual(Object.keys(saturation));
|
||||||
|
expect(stakeSaturation).toBeTruthy();
|
||||||
|
expect(stakeSaturation?.current_saturation).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can query for contract version', async () => {
|
||||||
|
const contractV = await client.getMixnetContractVersion();
|
||||||
|
expect(contractV).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can query for mixnet contract settings', async () => {
|
||||||
|
const settings = await client.getMixnetContractSettings();
|
||||||
|
expect(Object.keys(settings)).toEqual(Object.keys(contract));
|
||||||
|
expect(settings).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can query for reward pool', async () => {
|
||||||
|
const rewardPool = await client.getRewardParams();
|
||||||
|
// TODO add velidation here
|
||||||
|
expect(rewardPool).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can query for layer distribution', async () => {
|
||||||
|
const layer = await client.getLayerDistribution();
|
||||||
|
expect(Object.keys(layer)).toEqual(Object.keys(layerDistribution));
|
||||||
|
expect(layer).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
//
|
||||||
|
// MIXNODES
|
||||||
|
//
|
||||||
|
|
||||||
|
it('can query for unbonded mixnodes', async () => {
|
||||||
|
const unbondedNodes = await client.getUnbondedMixNodes();
|
||||||
|
for (let i = 0; i < unbondedNodes.length; i++) {
|
||||||
|
expect(Object.keys(unbondedNodes[0])).toEqual(Object.keys(allunbondednodes));
|
||||||
|
expect(unbondedNodes).toBeTruthy();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can query for unbonded mixnode information', async () => {
|
||||||
|
const unbondedMixnodeInfo = await client.getUnbondedMixNodeInformation(1);
|
||||||
|
expect(Object.keys(unbondedMixnodeInfo)).toEqual(Object.keys(unbondednode));
|
||||||
|
expect(unbondedMixnodeInfo).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can query for mixnode rewarding details', async () => {
|
||||||
|
const rewardingDetails = await client.getMixnodeRewardingDetails(1);
|
||||||
|
expect(Object.keys(rewardingDetails)).toEqual(Object.keys(rewardingnode));
|
||||||
|
expect(rewardingDetails).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can query for owned mixnode', async () => {
|
||||||
|
const ownedMixnode = await client.getOwnedMixnode('n1ptg680vnmef2cd8l0s9uyc4f0hgf3x8sed6w77');
|
||||||
|
expect(Object.keys(ownedMixnode)).toEqual(Object.keys(ownedNode));
|
||||||
|
expect(ownedMixnode).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can query for all mixnode bonds', async () => {
|
||||||
|
const mixnodeBonds = await client.getMixNodeBonds();
|
||||||
|
expect(Object.keys(mixnodeBonds[0])).toEqual(Object.keys(mixnodebond));
|
||||||
|
expect(mixnodeBonds).toBeTruthy();
|
||||||
|
expect(Array.isArray(mixnodeBonds)).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can query for all mixnode details', async () => {
|
||||||
|
const mixnodeDetails = await client.getMixNodesDetailed();
|
||||||
|
expect(Object.keys(mixnodeDetails[0])).toEqual(Object.keys(mixnode));
|
||||||
|
expect(mixnodeDetails).toBeTruthy();
|
||||||
|
expect(Array.isArray(mixnodeDetails)).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can query for all active mixnodes', async () => {
|
||||||
|
const activeNodes = await client.getActiveMixnodes();
|
||||||
|
expect(Object.keys(activeNodes[0])).toEqual(Object.keys(mixnode));
|
||||||
|
expect(activeNodes).toBeTruthy();
|
||||||
|
expect(Array.isArray(activeNodes)).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can query for rewarded mixnodes', async () => {
|
||||||
|
const rewardNodes = await client.getRewardedMixnodes();
|
||||||
|
expect(Object.keys(rewardNodes[0])).toEqual(Object.keys(mixnode));
|
||||||
|
expect(rewardNodes).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
//
|
||||||
|
// DELEGATIONS
|
||||||
|
//
|
||||||
|
|
||||||
|
it('can query for account delegations', async () => {
|
||||||
|
const delegations = await client.getAllNyxdDelegatorDelegations('n1fzv4jc7fanl9s0qj02ge2ezk3kts545kjtek47');
|
||||||
|
expect(Object.keys(delegations[0])).toEqual(Object.keys(delegation));
|
||||||
|
expect(delegations).toBeTruthy();
|
||||||
|
expect(Array.isArray(delegations)).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can query for all delegations', async () => {
|
||||||
|
const allDelegations = await client.getAllNyxdDelegations();
|
||||||
|
expect(Object.keys(allDelegations[0])).toEqual(Object.keys(delegation));
|
||||||
|
expect(allDelegations).toBeTruthy();
|
||||||
|
expect(Array.isArray(allDelegations)).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can query for all delegations on a node', async () => {
|
||||||
|
const mixnodeDelegations = await client.getAllNyxdSingleMixnodeDelegations(1);
|
||||||
|
expect(Object.keys(mixnodeDelegations[0])).toEqual(Object.keys(delegation));
|
||||||
|
expect(mixnodeDelegations).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can query for detailed delegations', async () => {
|
||||||
|
const detailedDelegation = await client.getDelegationDetails(7, delegatorAddress);
|
||||||
|
expect(Object.keys(detailedDelegation)).toEqual(Object.keys(detailedDelegation));
|
||||||
|
expect(detailedDelegation).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
//
|
||||||
|
// GATEWAYS
|
||||||
|
//
|
||||||
|
|
||||||
|
it('can query for all gateways', async () => {
|
||||||
|
const gateways = await client.getAllNyxdGateways();
|
||||||
|
expect(Object.keys(gateways[0])).toEqual(Object.keys(gateway));
|
||||||
|
expect(gateways).toBeTruthy();
|
||||||
|
expect(Array.isArray(gateways)).toBeTruthy();
|
||||||
|
}).timeout(10000);
|
||||||
|
|
||||||
|
it('can query for owned gateway', async () => {
|
||||||
|
const gateway = await client.ownsGateway(gatewayowneraddress);
|
||||||
|
expect(Object.keys(gateway)).toEqual(Object.keys(ownGateway));
|
||||||
|
expect(gateway).toBeTruthy();
|
||||||
|
}).timeout(10000);
|
||||||
|
});
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import expect from 'expect';
|
||||||
|
import ValidatorClient from '../../index';
|
||||||
|
|
||||||
|
const dotenv = require('dotenv');
|
||||||
|
|
||||||
|
dotenv.config();
|
||||||
|
|
||||||
|
describe('Vesting queries', () => {
|
||||||
|
let client: ValidatorClient;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
client = await ValidatorClient.connectForQuery(
|
||||||
|
process.env.rpcAddress || '',
|
||||||
|
process.env.validatorAddress || '',
|
||||||
|
process.env.prefix || '',
|
||||||
|
process.env.mixnetContractAddress || '',
|
||||||
|
process.env.vestingContractAddress || '',
|
||||||
|
process.env.denom || '',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can query for contract version', async () => {
|
||||||
|
const contract = await client.getVestingContractVersion();
|
||||||
|
expect(contract).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can get the balance on the account', () => {});
|
||||||
|
});
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
import expect from 'expect';
|
||||||
|
import ValidatorClient from '../../';
|
||||||
|
|
||||||
|
const dotenv = require('dotenv');
|
||||||
|
|
||||||
|
dotenv.config();
|
||||||
|
|
||||||
|
// TODO: implement for QA with .env for mnemonics
|
||||||
|
describe('Mixnet actions', () => {
|
||||||
|
let client: ValidatorClient;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
client = await ValidatorClient.connect(
|
||||||
|
process.env.mnemonic || '',
|
||||||
|
process.env.rpcAddress || '',
|
||||||
|
process.env.validatorAddress || '',
|
||||||
|
process.env.prefix || '',
|
||||||
|
process.env.mixnetContractAddress || '',
|
||||||
|
process.env.vestingContractAddress || '',
|
||||||
|
process.env.denom || '',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('can send tokens', async () => {
|
||||||
|
const res = await client.send(client.address, [{ amount: '10000000', denom: 'unym' }]);
|
||||||
|
expect(res.transactionHash).toBeDefined();
|
||||||
|
}).timeout(10000);
|
||||||
|
|
||||||
|
it.skip('can delegate tokens', async () => {
|
||||||
|
const [_, secondMixnode] = await client.getActiveMixnodes();
|
||||||
|
|
||||||
|
if (secondMixnode) {
|
||||||
|
const res = await client.delegateToMixNode(
|
||||||
|
secondMixnode.bond_information.mix_id,
|
||||||
|
{
|
||||||
|
amount: '15000000',
|
||||||
|
denom: 'unym',
|
||||||
|
},
|
||||||
|
{ gas: '1000000', amount: [{ amount: '100000', denom: 'unym' }] },
|
||||||
|
);
|
||||||
|
expect(res.transactionHash).toBeDefined();
|
||||||
|
}
|
||||||
|
}).timeout(10000);
|
||||||
|
|
||||||
|
// Need to provide a mix id that can be undelegated from
|
||||||
|
it.skip('can undelegate from a mixnode', async () => {
|
||||||
|
const mixId = 8;
|
||||||
|
const res = await client.undelegateFromMixNode(mixId);
|
||||||
|
expect(res.transactionHash).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it.skip('Can unbond a mixnode', async () => {
|
||||||
|
const res = await client.unbondMixNode();
|
||||||
|
expect(res.transactionHash).toBeDefined();
|
||||||
|
}).timeout(10000);
|
||||||
|
|
||||||
|
it.skip('Can bond a mixnode', async () => {
|
||||||
|
const res = await client.bondMixNode(
|
||||||
|
{
|
||||||
|
identity_key: '3P6pAcF2p3pYMqWdpHqhbavu3ifyaBs5Qw5UmmCGwimx',
|
||||||
|
sphinx_key: 'GQMQKwUThaggatA6oZteSWTsCQoUfmLtamJ7o9YkP9aE',
|
||||||
|
host: '109.74.195.67',
|
||||||
|
mix_port: 1789,
|
||||||
|
verloc_port: 1790,
|
||||||
|
http_api_port: 8000,
|
||||||
|
version: '1.1.4',
|
||||||
|
},
|
||||||
|
'3rXWCQBUj5JQB3UBUkZcXhCk9Zh3cjduMF8aFHPTG7KTkkhZzDJTNmE2p2Ph1g6iQW5vRGTpQzjXF33WDwvhzHk6',
|
||||||
|
{ profit_margin_percent: '0.1', interval_operating_cost: { amount: '40', denom: 'nym' } },
|
||||||
|
{ amount: '100_000_000', denom: 'unym' },
|
||||||
|
{ gas: '1000000', amount: [{ amount: '100000', denom: 'unym' }] },
|
||||||
|
);
|
||||||
|
expect(res.transactionHash).toBeDefined();
|
||||||
|
}).timeout(10000);
|
||||||
|
|
||||||
|
it.skip('can unbond a gateway', async () => {
|
||||||
|
const res = await client.unbondGateway();
|
||||||
|
expect(res.transactionHash).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it.skip('can bond a gateway', async () => {
|
||||||
|
const res = await client.bondGateway(
|
||||||
|
{
|
||||||
|
identity_key: '36vfvEyBzo5cWEFbnP7fqgY39kFw9PQhvwzbispeNaxL',
|
||||||
|
sphinx_key: 'G65Fwc2JNAotuHQFqmDKhQNQL5rn3r9pupUdmxMygNUZ',
|
||||||
|
host: '151.236.220.82',
|
||||||
|
version: '1.1.4',
|
||||||
|
mix_port: 1789,
|
||||||
|
clients_port: 9000,
|
||||||
|
location: 'Cuba',
|
||||||
|
},
|
||||||
|
'3ipSJksWHehZm1YfuH5Ahtg7b22NnrP9hEs6iEDXfUS5uiUhpWmCjGR3b3NDHuxeGjpZYJNYJ52D8WCPK5ZR7Szj',
|
||||||
|
{ amount: '100_000_000', denom: 'unym' },
|
||||||
|
);
|
||||||
|
expect(res.transactionHash).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it.skip('can update contract state params', async () => {
|
||||||
|
const res = await client.updateContractStateParams({
|
||||||
|
minimum_mixnode_pledge: '',
|
||||||
|
minimum_gateway_pledge: '',
|
||||||
|
mixnode_rewarded_set_size: 2,
|
||||||
|
mixnode_active_set_size: 2,
|
||||||
|
});
|
||||||
|
expect(res.transactionHash).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"target": "es6",
|
|
||||||
"module": "commonjs",
|
|
||||||
"esModuleInterop": true,
|
|
||||||
"strict": true,
|
|
||||||
"declaration": true,
|
|
||||||
"outDir": "./dist"
|
|
||||||
},
|
|
||||||
"exclude": [
|
|
||||||
"tests",
|
|
||||||
"dist",
|
|
||||||
"node_modules"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,157 +0,0 @@
|
|||||||
import { Coin } from '@cosmjs/stargate';
|
|
||||||
|
|
||||||
// TODO: ideally we'd have re-exported those using that fancy crate that builds ts types from rust
|
|
||||||
|
|
||||||
export type MixnetContractVersion = {
|
|
||||||
build_timestamp: string;
|
|
||||||
build_version: string;
|
|
||||||
commit_sha: string;
|
|
||||||
commit_timestamp: string;
|
|
||||||
commit_branch: string;
|
|
||||||
rustc_version: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type PagedMixnodeResponse = {
|
|
||||||
nodes: MixNodeBond[];
|
|
||||||
per_page: number;
|
|
||||||
start_next_after?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type PagedGatewayResponse = {
|
|
||||||
nodes: GatewayBond[];
|
|
||||||
per_page: number;
|
|
||||||
start_next_after?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type MixOwnershipResponse = {
|
|
||||||
address: string;
|
|
||||||
mixnode?: MixNodeBond;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type GatewayOwnershipResponse = {
|
|
||||||
address: string;
|
|
||||||
gateway?: GatewayBond;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type ContractStateParams = {
|
|
||||||
// ideally I'd want to define those as `number` rather than `string`, but
|
|
||||||
// rust-side they are defined as Uint128 and that don't have
|
|
||||||
// native javascript representations and therefore are interpreted as strings after deserialization
|
|
||||||
minimum_mixnode_pledge: string;
|
|
||||||
minimum_gateway_pledge: string;
|
|
||||||
mixnode_rewarded_set_size: number;
|
|
||||||
mixnode_active_set_size: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type LayerDistribution = {
|
|
||||||
gateways: number;
|
|
||||||
layer1: number;
|
|
||||||
layer2: number;
|
|
||||||
layer3: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type Delegation = {
|
|
||||||
owner: string;
|
|
||||||
node_identity: string;
|
|
||||||
amount: Coin;
|
|
||||||
block_height: number;
|
|
||||||
proxy?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type PagedMixDelegationsResponse = {
|
|
||||||
delegations: Delegation[];
|
|
||||||
start_next_after?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type PagedDelegatorDelegationsResponse = {
|
|
||||||
delegations: Delegation[];
|
|
||||||
start_next_after?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type PagedAllDelegationsResponse = {
|
|
||||||
delegations: Delegation[];
|
|
||||||
start_next_after?: [string, string];
|
|
||||||
};
|
|
||||||
|
|
||||||
export type RewardingResult = {
|
|
||||||
operator_reward: string;
|
|
||||||
total_delegator_reward: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type NodeRewardParams = {
|
|
||||||
period_reward_pool: string;
|
|
||||||
k: string;
|
|
||||||
reward_blockstamp: number;
|
|
||||||
circulating_supply: string;
|
|
||||||
uptime: string;
|
|
||||||
sybil_resistance_percent: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type DelegatorRewardParams = {
|
|
||||||
node_reward_params: NodeRewardParams;
|
|
||||||
sigma: number;
|
|
||||||
profit_margin: number;
|
|
||||||
node_profit: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type PendingDelegatorRewarding = {
|
|
||||||
running_results: RewardingResult;
|
|
||||||
next_start: string;
|
|
||||||
rewarding_params: DelegatorRewardParams;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type RewardingStatus = { Complete: RewardingResult } | { PendingNextDelegatorPage: PendingDelegatorRewarding };
|
|
||||||
|
|
||||||
export type MixnodeRewardingStatusResponse = {
|
|
||||||
status?: RewardingStatus;
|
|
||||||
};
|
|
||||||
|
|
||||||
export enum Layer {
|
|
||||||
Gateway,
|
|
||||||
One,
|
|
||||||
Two,
|
|
||||||
Three,
|
|
||||||
}
|
|
||||||
|
|
||||||
export type MixNodeBond = {
|
|
||||||
owner: string;
|
|
||||||
mix_node: MixNode;
|
|
||||||
layer: Layer;
|
|
||||||
bond_amount: Coin;
|
|
||||||
total_delegation: Coin;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type MixNode = {
|
|
||||||
host: string;
|
|
||||||
mix_port: number;
|
|
||||||
verloc_port: number;
|
|
||||||
http_api_port: number;
|
|
||||||
sphinx_key: string;
|
|
||||||
identity_key: string;
|
|
||||||
version: string;
|
|
||||||
profit_margin_percent: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type GatewayBond = {
|
|
||||||
owner: string;
|
|
||||||
gateway: Gateway;
|
|
||||||
|
|
||||||
bond_amount: Coin;
|
|
||||||
total_delegation: Coin;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type Gateway = {
|
|
||||||
host: string;
|
|
||||||
mix_port: number;
|
|
||||||
clients_port: number;
|
|
||||||
location: string;
|
|
||||||
sphinx_key: string;
|
|
||||||
identity_key: string;
|
|
||||||
version: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type SendRequest = {
|
|
||||||
senderAddress: string;
|
|
||||||
recipientAddress: string;
|
|
||||||
transferAmount: readonly Coin[];
|
|
||||||
};
|
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
declare namespace NodeJS {
|
||||||
|
interface ProcessEnv {
|
||||||
|
rpcAddress: string;
|
||||||
|
validatorAddress: string;
|
||||||
|
prefix: string;
|
||||||
|
mixnetContractAddress: string;
|
||||||
|
vestingContractAddress: string;
|
||||||
|
denom: string;
|
||||||
|
mnemonic: string;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,259 @@
|
|||||||
|
import { JsonObject } from '@cosmjs/cosmwasm-stargate';
|
||||||
|
import { Code, CodeDetails, Contract, ContractCodeHistoryEntry } from '@cosmjs/cosmwasm-stargate/build/cosmwasmclient';
|
||||||
|
import {
|
||||||
|
Account,
|
||||||
|
Block,
|
||||||
|
Coin,
|
||||||
|
DeliverTxResponse,
|
||||||
|
IndexedTx,
|
||||||
|
SearchTxFilter,
|
||||||
|
SearchTxQuery,
|
||||||
|
SequenceResponse,
|
||||||
|
} from '@cosmjs/stargate';
|
||||||
|
import {
|
||||||
|
MixNodeRewarding,
|
||||||
|
PagedMixNodeBondResponse,
|
||||||
|
PagedMixNodeDetailsResponse,
|
||||||
|
StakeSaturationResponse,
|
||||||
|
UnbondedMixnodeResponse,
|
||||||
|
} from '@nymproject/types';
|
||||||
|
|
||||||
|
export type MixnetContractVersion = {
|
||||||
|
build_timestamp: string;
|
||||||
|
build_version: string;
|
||||||
|
commit_sha: string;
|
||||||
|
commit_timestamp: string;
|
||||||
|
commit_branch: string;
|
||||||
|
rustc_version: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type PagedMixnodeResponse = {
|
||||||
|
nodes: MixNodeBond[];
|
||||||
|
per_page: number;
|
||||||
|
start_next_after?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type PagedGatewayResponse = {
|
||||||
|
nodes: GatewayBond[];
|
||||||
|
per_page: number;
|
||||||
|
start_next_after?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type MixOwnershipResponse = {
|
||||||
|
address: string;
|
||||||
|
mixnode?: MixNodeBond;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type GatewayOwnershipResponse = {
|
||||||
|
address: string;
|
||||||
|
gateway?: GatewayBond;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ContractStateParams = {
|
||||||
|
// ideally I'd want to define those as `number` rather than `string`, but
|
||||||
|
// rust-side they are defined as Uint128 and that don't have
|
||||||
|
// native javascript representations and therefore are interpreted as strings after deserialization
|
||||||
|
minimum_mixnode_pledge: string;
|
||||||
|
minimum_gateway_pledge: string;
|
||||||
|
mixnode_rewarded_set_size: number;
|
||||||
|
mixnode_active_set_size: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type LayerDistribution = {
|
||||||
|
gateways: number;
|
||||||
|
layer1: number;
|
||||||
|
layer2: number;
|
||||||
|
layer3: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Delegation = {
|
||||||
|
owner: string;
|
||||||
|
node_identity: string;
|
||||||
|
amount: Coin;
|
||||||
|
block_height: number;
|
||||||
|
proxy?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type PagedMixDelegationsResponse = {
|
||||||
|
delegations: Delegation[];
|
||||||
|
start_next_after?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type PagedDelegatorDelegationsResponse = {
|
||||||
|
delegations: Delegation[];
|
||||||
|
start_next_after?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type PagedAllDelegationsResponse = {
|
||||||
|
delegations: Delegation[];
|
||||||
|
start_next_after?: [string, string];
|
||||||
|
};
|
||||||
|
|
||||||
|
export type RewardingResult = {
|
||||||
|
operator_reward: string;
|
||||||
|
total_delegator_reward: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type NodeRewardParams = {
|
||||||
|
period_reward_pool: string;
|
||||||
|
k: string;
|
||||||
|
reward_blockstamp: number;
|
||||||
|
circulating_supply: string;
|
||||||
|
uptime: string;
|
||||||
|
sybil_resistance_percent: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type DelegatorRewardParams = {
|
||||||
|
node_reward_params: NodeRewardParams;
|
||||||
|
sigma: number;
|
||||||
|
profit_margin: number;
|
||||||
|
node_profit: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type PendingDelegatorRewarding = {
|
||||||
|
running_results: RewardingResult;
|
||||||
|
next_start: string;
|
||||||
|
rewarding_params: DelegatorRewardParams;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type RewardingStatus = { Complete: RewardingResult } | { PendingNextDelegatorPage: PendingDelegatorRewarding };
|
||||||
|
|
||||||
|
export type MixnodeRewardingStatusResponse = {
|
||||||
|
status?: RewardingStatus;
|
||||||
|
};
|
||||||
|
|
||||||
|
export enum Layer {
|
||||||
|
Gateway,
|
||||||
|
One,
|
||||||
|
Two,
|
||||||
|
Three,
|
||||||
|
}
|
||||||
|
|
||||||
|
export type MixNodeBond = {
|
||||||
|
owner: string;
|
||||||
|
mix_node: MixNode;
|
||||||
|
layer: Layer;
|
||||||
|
bond_amount: Coin;
|
||||||
|
total_delegation: Coin;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type MixNode = {
|
||||||
|
host: string;
|
||||||
|
mix_port: number;
|
||||||
|
verloc_port: number;
|
||||||
|
http_api_port: number;
|
||||||
|
sphinx_key: string;
|
||||||
|
identity_key: string;
|
||||||
|
version: string;
|
||||||
|
profit_margin_percent: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type GatewayBond = {
|
||||||
|
owner: string;
|
||||||
|
gateway: Gateway;
|
||||||
|
|
||||||
|
bond_amount: Coin;
|
||||||
|
total_delegation: Coin;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type Gateway = {
|
||||||
|
host: string;
|
||||||
|
mix_port: number;
|
||||||
|
clients_port: number;
|
||||||
|
location: string;
|
||||||
|
sphinx_key: string;
|
||||||
|
identity_key: string;
|
||||||
|
version: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type SendRequest = {
|
||||||
|
senderAddress: string;
|
||||||
|
recipientAddress: string;
|
||||||
|
transferAmount: readonly Coin[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface SmartContractQuery {
|
||||||
|
queryContractSmart(address: string, queryMsg: Record<string, unknown>): Promise<JsonObject>;
|
||||||
|
}
|
||||||
|
export interface ICosmWasmQuery {
|
||||||
|
// methods exposed by `CosmWasmClient`
|
||||||
|
getChainId(): Promise<string>;
|
||||||
|
getHeight(): Promise<number>;
|
||||||
|
getAccount(searchAddress: string): Promise<Account | null>;
|
||||||
|
getSequence(address: string): Promise<SequenceResponse>;
|
||||||
|
getBlock(height?: number): Promise<Block>;
|
||||||
|
getBalance(address: string, searchDenom: string): Promise<Coin>;
|
||||||
|
getTx(id: string): Promise<IndexedTx | null>;
|
||||||
|
searchTx(query: SearchTxQuery, filter?: SearchTxFilter): Promise<readonly IndexedTx[]>;
|
||||||
|
disconnect(): void;
|
||||||
|
broadcastTx(tx: Uint8Array, timeoutMs?: number, pollIntervalMs?: number): Promise<DeliverTxResponse>;
|
||||||
|
getCodes(): Promise<readonly Code[]>;
|
||||||
|
getCodeDetails(codeId: number): Promise<CodeDetails>;
|
||||||
|
getContracts(codeId: number): Promise<readonly string[]>;
|
||||||
|
getContract(address: string): Promise<Contract>;
|
||||||
|
getContractCodeHistory(address: string): Promise<readonly ContractCodeHistoryEntry[]>;
|
||||||
|
queryContractRaw(address: string, key: Uint8Array): Promise<Uint8Array | null>;
|
||||||
|
queryContractSmart(address: string, queryMsg: Record<string, unknown>): Promise<JsonObject>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface INymdQuery {
|
||||||
|
// nym-specific implemented inside NymQuerier
|
||||||
|
getContractVersion(mixnetContractAddress: string): Promise<MixnetContractVersion>;
|
||||||
|
getMixNodeBonds(
|
||||||
|
mixnetContractAddress: string,
|
||||||
|
limit?: number,
|
||||||
|
startAfter?: string,
|
||||||
|
): Promise<PagedMixNodeBondResponse>;
|
||||||
|
getMixNodesDetailed(
|
||||||
|
mixnetContractAddress: string,
|
||||||
|
limit?: number,
|
||||||
|
startAfter?: string,
|
||||||
|
): Promise<PagedMixNodeDetailsResponse>;
|
||||||
|
getGatewaysPaged(mixnetContractAddress: string, limit?: number, startAfter?: string): Promise<PagedGatewayResponse>;
|
||||||
|
getOwnedMixnode(mixnetContractAddress: string, address: string): Promise<MixOwnershipResponse>;
|
||||||
|
ownsGateway(mixnetContractAddress: string, address: string): Promise<GatewayOwnershipResponse>;
|
||||||
|
getStateParams(mixnetContractAddress: string): Promise<ContractState>;
|
||||||
|
getAllNetworkDelegationsPaged(
|
||||||
|
mixnetContractAddress: string,
|
||||||
|
limit?: number,
|
||||||
|
startAfter?: [string, string],
|
||||||
|
): Promise<PagedAllDelegationsResponse>;
|
||||||
|
getMixNodeDelegationsPaged(
|
||||||
|
mixnetContractAddress: string,
|
||||||
|
mix_id: number,
|
||||||
|
limit?: number,
|
||||||
|
startAfter?: string,
|
||||||
|
): Promise<PagedMixDelegationsResponse>;
|
||||||
|
getDelegatorDelegationsPaged(
|
||||||
|
mixnetContractAddress: string,
|
||||||
|
delegator: string,
|
||||||
|
limit?: number,
|
||||||
|
startAfter?: string,
|
||||||
|
): Promise<PagedDelegatorDelegationsResponse>;
|
||||||
|
getDelegationDetails(mixnetContractAddress: string, mix_id: number, delegator: string): Promise<Delegation>;
|
||||||
|
getLayerDistribution(mixnetContractAddress: string): Promise<LayerDistribution>;
|
||||||
|
getStakeSaturation(mixnetContractAddress: string, mixId: number): Promise<StakeSaturationResponse>;
|
||||||
|
getUnbondedMixNodeInformation(mixnetContractAddress: string, mixId: number): Promise<UnbondedMixnodeResponse>;
|
||||||
|
getMixnodeRewardingDetails(mixnetContractAddress: string, mixId: number): Promise<MixNodeRewarding>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IVestingQuerier {
|
||||||
|
getVestingContractVersion(mixnetContractAddress: string): Promise<MixnetContractVersion>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MappedCoin {
|
||||||
|
readonly denom: string;
|
||||||
|
readonly fractionalDigits: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CoinMap {
|
||||||
|
readonly [key: string]: MappedCoin;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ContractState {
|
||||||
|
owner: string;
|
||||||
|
rewarding_validator_address: string;
|
||||||
|
vesting_contract_address: string;
|
||||||
|
rewarding_denom: string;
|
||||||
|
params: ContractStateParams;
|
||||||
|
}
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
import ValidatorClient from '../../validator/index';
|
|
||||||
import expect from 'expect';
|
|
||||||
|
|
||||||
describe('Query: balances', () => {
|
|
||||||
it('can query for an account balance', async () => {
|
|
||||||
const client = await ValidatorClient.connectForQuery(
|
|
||||||
'https://rpc.nymtech.net/', 'https://validator.nymtech.net/api/', 'n', 'n14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9sjyvg3g', 'n1nc5tatafv6eyq7llkr2gv50ff9e22mnf70qgjlv737ktmt4eswrq73f2nw', 'nym');
|
|
||||||
const balance = await client.getBalance('n10yyd98e2tuwu0f7ypz9dy3hhjw7v772q6287gy');
|
|
||||||
expect(Number.parseFloat(balance.amount)).toBeGreaterThan(0);
|
|
||||||
}).timeout(5000);
|
|
||||||
})
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
import ValidatorClient from '../../dist';
|
|
||||||
import expect from 'expect';
|
|
||||||
|
|
||||||
// TODO: implement for QA with .env for mnemonics
|
|
||||||
// describe('Sign: send', () => {
|
|
||||||
// it('can send tokens', async () => {
|
|
||||||
// const client = await ValidatorClient.connect(
|
|
||||||
// '<ADD MNEMONIC HERE>',
|
|
||||||
// 'https://rpc.nyx.nodes.guru/', 'https://validator.nymtech.net/api/', 'n', 'n14hj2tavq8fpesdwxxcu44rty3hh90vhujrvcmstl4zr3txmfvw9sjyvg3g', 'n1nc5tatafv6eyq7llkr2gv50ff9e22mnf70qgjlv737ktmt4eswrq73f2nw', 'nym');
|
|
||||||
// await client.send('<ADD ADDRESS HERE>')
|
|
||||||
// const balance = await client.getBalance('n10yyd98e2tuwu0f7ypz9dy3hhjw7v772q6287gy');
|
|
||||||
// expect(Number.parseFloat(balance.amount)).toBeGreaterThan(0);
|
|
||||||
// }).timeout(5000);
|
|
||||||
// })
|
|
||||||
@@ -1,23 +1,22 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "es6",
|
"outDir": "./dist/nym-validator-client",
|
||||||
"module": "commonjs",
|
"module": "ES2020",
|
||||||
"esModuleInterop": true,
|
"target": "es2021",
|
||||||
"strict": true,
|
"allowJs": false,
|
||||||
"declaration": true,
|
"strict": true,
|
||||||
"outDir": "./dist",
|
"lib": ["es2021", "dom", "dom.iterable", "esnext"],
|
||||||
"skipLibCheck": true
|
"moduleResolution": "node",
|
||||||
},
|
"skipDefaultLibCheck": true,
|
||||||
"typedocOptions": {
|
"esModuleInterop": true,
|
||||||
"entryPoints": [
|
"declaration": true,
|
||||||
"src/index.ts"
|
"skipLibCheck": true,
|
||||||
],
|
"noImplicitAny": true,
|
||||||
"out": "docs"
|
"typeRoots": ["./src/types/global.d.ts"]
|
||||||
},
|
},
|
||||||
"exclude": [
|
"typedocOptions": {
|
||||||
"dist",
|
"entryPoints": ["./src/index.ts"],
|
||||||
"examples",
|
"out": "docs"
|
||||||
"tests",
|
},
|
||||||
"node_modules"
|
"exclude": ["dist", "./src/tests/**/*", "node_module"]
|
||||||
]
|
}
|
||||||
}
|
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"extends": "./tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"module": "CommonJS"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -31,8 +31,8 @@ wasm-bindgen-futures = "0.4"
|
|||||||
|
|
||||||
# internal
|
# internal
|
||||||
client-core = { path = "../client-core", default-features = false, features = ["wasm"] }
|
client-core = { path = "../client-core", default-features = false, features = ["wasm"] }
|
||||||
coconut-interface = { path = "../../common/coconut-interface" }
|
nym-coconut-interface = { path = "../../common/coconut-interface" }
|
||||||
credentials = { path = "../../common/credentials" }
|
nym-credentials = { path = "../../common/credentials" }
|
||||||
nym-crypto = { path = "../../common/crypto" }
|
nym-crypto = { path = "../../common/crypto" }
|
||||||
nym-sphinx = { path = "../../common/nymsphinx" }
|
nym-sphinx = { path = "../../common/nymsphinx" }
|
||||||
gateway-client = { path = "../../common/client-libs/gateway-client", default-features = false, features = ["wasm"] }
|
gateway-client = { path = "../../common/client-libs/gateway-client", default-features = false, features = ["wasm"] }
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "bandwidth-claim-contract"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
schemars = "0.8"
|
|
||||||
serde = { version = "1.0.103", default-features = false, features = ["derive"] }
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
use schemars::JsonSchema;
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
// Serializable structures for what we find in common/crypto
|
|
||||||
#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq, Eq, JsonSchema)]
|
|
||||||
pub struct PublicKey([u8; 32]);
|
|
||||||
|
|
||||||
impl PublicKey {
|
|
||||||
pub fn new(bytes: [u8; 32]) -> Self {
|
|
||||||
PublicKey(bytes)
|
|
||||||
}
|
|
||||||
pub fn to_bytes(&self) -> [u8; 32] {
|
|
||||||
self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl AsRef<[u8]> for PublicKey {
|
|
||||||
#[inline]
|
|
||||||
fn as_ref(&self) -> &[u8] {
|
|
||||||
&self.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
|
|
||||||
pub struct Signature([u8; 32], [u8; 32]);
|
|
||||||
|
|
||||||
impl Signature {
|
|
||||||
pub fn new(bytes: [u8; 64]) -> Self {
|
|
||||||
let mut sig1 = [0u8; 32];
|
|
||||||
let mut sig2 = [0u8; 32];
|
|
||||||
sig1.copy_from_slice(&bytes[..32]);
|
|
||||||
sig2.copy_from_slice(&bytes[32..]);
|
|
||||||
|
|
||||||
Signature(sig1, sig2)
|
|
||||||
}
|
|
||||||
pub fn to_bytes(&self) -> [u8; 64] {
|
|
||||||
let mut res = [0u8; 64];
|
|
||||||
res[..32].copy_from_slice(&self.0);
|
|
||||||
res[32..].copy_from_slice(&self.1);
|
|
||||||
res
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
pub mod keys;
|
|
||||||
pub mod msg;
|
|
||||||
pub mod payment;
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
use schemars::JsonSchema;
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
use crate::keys::PublicKey;
|
|
||||||
use crate::payment::LinkPaymentData;
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
|
|
||||||
pub struct InstantiateMsg {}
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
|
|
||||||
#[serde(rename_all = "snake_case")]
|
|
||||||
pub enum ExecuteMsg {
|
|
||||||
LinkPayment { data: LinkPaymentData },
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
|
|
||||||
#[serde(rename_all = "snake_case")]
|
|
||||||
pub enum QueryMsg {
|
|
||||||
GetPayments {
|
|
||||||
limit: Option<u32>,
|
|
||||||
start_after: Option<PublicKey>,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
|
|
||||||
#[serde(rename_all = "snake_case")]
|
|
||||||
pub struct MigrateMsg {}
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
use schemars::JsonSchema;
|
|
||||||
use serde::{Deserialize, Serialize};
|
|
||||||
|
|
||||||
use crate::keys::{PublicKey, Signature};
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)]
|
|
||||||
pub struct Payment {
|
|
||||||
verification_key: PublicKey,
|
|
||||||
gateway_identity: PublicKey,
|
|
||||||
bandwidth: u64,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Payment {
|
|
||||||
pub fn new(verification_key: PublicKey, gateway_identity: PublicKey, bandwidth: u64) -> Self {
|
|
||||||
Payment {
|
|
||||||
verification_key,
|
|
||||||
gateway_identity,
|
|
||||||
bandwidth,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn verification_key(&self) -> PublicKey {
|
|
||||||
self.verification_key
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq, JsonSchema)]
|
|
||||||
pub struct LinkPaymentData {
|
|
||||||
pub verification_key: PublicKey,
|
|
||||||
pub gateway_identity: PublicKey,
|
|
||||||
pub bandwidth: u64,
|
|
||||||
pub signature: Signature,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl LinkPaymentData {
|
|
||||||
pub fn new(
|
|
||||||
verification_key: [u8; 32],
|
|
||||||
gateway_identity: [u8; 32],
|
|
||||||
bandwidth: u64,
|
|
||||||
signature: [u8; 64],
|
|
||||||
) -> Self {
|
|
||||||
LinkPaymentData {
|
|
||||||
verification_key: PublicKey::new(verification_key),
|
|
||||||
gateway_identity: PublicKey::new(gateway_identity),
|
|
||||||
bandwidth,
|
|
||||||
signature: Signature::new(signature),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, JsonSchema)]
|
|
||||||
pub struct PagedPaymentResponse {
|
|
||||||
pub payments: Vec<Payment>,
|
|
||||||
pub per_page: usize,
|
|
||||||
pub start_next_after: Option<PublicKey>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PagedPaymentResponse {
|
|
||||||
pub fn new(
|
|
||||||
payments: Vec<Payment>,
|
|
||||||
per_page: usize,
|
|
||||||
start_next_after: Option<PublicKey>,
|
|
||||||
) -> Self {
|
|
||||||
PagedPaymentResponse {
|
|
||||||
payments,
|
|
||||||
per_page,
|
|
||||||
start_next_after,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -17,7 +17,7 @@ semver = "0.11"
|
|||||||
serde = { workspace = true, features = ["derive"], optional = true }
|
serde = { workspace = true, features = ["derive"], optional = true }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
vergen = { version = "7", default-features = false, features = ["build", "git", "rustc", "cargo"] }
|
vergen = { version = "=7.4.3", default-features = false, features = ["build", "git", "rustc", "cargo"] }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = []
|
default = []
|
||||||
|
|||||||
@@ -4,5 +4,10 @@
|
|||||||
use vergen::{vergen, Config};
|
use vergen::{vergen, Config};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
vergen(Config::default()).expect("failed to extract build metadata")
|
let mut config = Config::default();
|
||||||
|
if std::env::var("DOCS_RS").is_ok() {
|
||||||
|
// If we don't have access to git information, such as in a docs.rs build, don't error
|
||||||
|
*config.git_mut().skip_if_error_mut() = true;
|
||||||
|
}
|
||||||
|
vergen(config).expect("failed to extract build metadata");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ async-trait = { workspace = true }
|
|||||||
tokio = { version = "1.24.1", features = ["macros"] }
|
tokio = { version = "1.24.1", features = ["macros"] }
|
||||||
|
|
||||||
# internal
|
# internal
|
||||||
coconut-interface = { path = "../../coconut-interface" }
|
nym-coconut-interface = { path = "../../coconut-interface" }
|
||||||
credentials = { path = "../../credentials" }
|
nym-credentials = { path = "../../credentials" }
|
||||||
nym-crypto = { path = "../../crypto" }
|
nym-crypto = { path = "../../crypto" }
|
||||||
gateway-requests = { path = "../../../gateway/gateway-requests" }
|
gateway-requests = { path = "../../../gateway/gateway-requests" }
|
||||||
nym-network-defaults = { path = "../../network-defaults" }
|
nym-network-defaults = { path = "../../network-defaults" }
|
||||||
@@ -47,7 +47,7 @@ features = ["net", "sync", "time"]
|
|||||||
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.tokio-tungstenite]
|
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.tokio-tungstenite]
|
||||||
version = "0.14"
|
version = "0.14"
|
||||||
|
|
||||||
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.credential-storage]
|
[target."cfg(not(target_arch = \"wasm32\"))".dependencies.nym-credential-storage]
|
||||||
path = "../../credential-storage"
|
path = "../../credential-storage"
|
||||||
|
|
||||||
# wasm-only dependencies
|
# wasm-only dependencies
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use crate::error::GatewayClientError;
|
|||||||
use crate::wasm_mockups::Storage;
|
use crate::wasm_mockups::Storage;
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
#[cfg(not(feature = "mobile"))]
|
#[cfg(not(feature = "mobile"))]
|
||||||
use credential_storage::storage::Storage;
|
use nym_credential_storage::storage::Storage;
|
||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
#[cfg(feature = "mobile")]
|
#[cfg(feature = "mobile")]
|
||||||
@@ -22,7 +22,7 @@ use crate::wasm_mockups::StorageError;
|
|||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
#[cfg(not(feature = "mobile"))]
|
#[cfg(not(feature = "mobile"))]
|
||||||
use credential_storage::error::StorageError;
|
use nym_credential_storage::error::StorageError;
|
||||||
|
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
use crate::wasm_mockups::{Client, CosmWasmClient};
|
use crate::wasm_mockups::{Client, CosmWasmClient};
|
||||||
@@ -30,8 +30,8 @@ use std::str::FromStr;
|
|||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
use validator_client::{nyxd::CosmWasmClient, Client};
|
use validator_client::{nyxd::CosmWasmClient, Client};
|
||||||
use {
|
use {
|
||||||
coconut_interface::Base58,
|
nym_coconut_interface::Base58,
|
||||||
credentials::coconut::{
|
nym_credentials::coconut::{
|
||||||
bandwidth::prepare_for_spending, utils::obtain_aggregate_verification_key,
|
bandwidth::prepare_for_spending, utils::obtain_aggregate_verification_key,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -42,7 +42,7 @@ use crate::wasm_mockups::PersistentStorage;
|
|||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
#[cfg(not(feature = "mobile"))]
|
#[cfg(not(feature = "mobile"))]
|
||||||
use credential_storage::PersistentStorage;
|
use nym_credential_storage::PersistentStorage;
|
||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
#[cfg(feature = "mobile")]
|
#[cfg(feature = "mobile")]
|
||||||
@@ -69,17 +69,17 @@ where
|
|||||||
|
|
||||||
pub async fn prepare_coconut_credential(
|
pub async fn prepare_coconut_credential(
|
||||||
&self,
|
&self,
|
||||||
) -> Result<(coconut_interface::Credential, i64), GatewayClientError> {
|
) -> Result<(nym_coconut_interface::Credential, i64), GatewayClientError> {
|
||||||
let bandwidth_credential = self.storage.get_next_coconut_credential().await?;
|
let bandwidth_credential = self.storage.get_next_coconut_credential().await?;
|
||||||
let voucher_value = u64::from_str(&bandwidth_credential.voucher_value)
|
let voucher_value = u64::from_str(&bandwidth_credential.voucher_value)
|
||||||
.map_err(|_| StorageError::InconsistentData)?;
|
.map_err(|_| StorageError::InconsistentData)?;
|
||||||
let voucher_info = bandwidth_credential.voucher_info.clone();
|
let voucher_info = bandwidth_credential.voucher_info.clone();
|
||||||
let serial_number =
|
let serial_number =
|
||||||
coconut_interface::Attribute::try_from_bs58(bandwidth_credential.serial_number)?;
|
nym_coconut_interface::Attribute::try_from_bs58(bandwidth_credential.serial_number)?;
|
||||||
let binding_number =
|
let binding_number =
|
||||||
coconut_interface::Attribute::try_from_bs58(bandwidth_credential.binding_number)?;
|
nym_coconut_interface::Attribute::try_from_bs58(bandwidth_credential.binding_number)?;
|
||||||
let signature =
|
let signature =
|
||||||
coconut_interface::Signature::try_from_bs58(bandwidth_credential.signature)?;
|
nym_coconut_interface::Signature::try_from_bs58(bandwidth_credential.signature)?;
|
||||||
let epoch_id = u64::from_str(&bandwidth_credential.epoch_id)
|
let epoch_id = u64::from_str(&bandwidth_credential.epoch_id)
|
||||||
.map_err(|_| StorageError::InconsistentData)?;
|
.map_err(|_| StorageError::InconsistentData)?;
|
||||||
|
|
||||||
|
|||||||
@@ -9,13 +9,13 @@ pub use crate::packet_router::{
|
|||||||
};
|
};
|
||||||
use crate::socket_state::{PartiallyDelegated, SocketState};
|
use crate::socket_state::{PartiallyDelegated, SocketState};
|
||||||
use crate::{cleanup_socket_message, try_decrypt_binary_message};
|
use crate::{cleanup_socket_message, try_decrypt_binary_message};
|
||||||
use coconut_interface::Credential;
|
|
||||||
use futures::{SinkExt, StreamExt};
|
use futures::{SinkExt, StreamExt};
|
||||||
use gateway_requests::authentication::encrypted_address::EncryptedAddressBytes;
|
use gateway_requests::authentication::encrypted_address::EncryptedAddressBytes;
|
||||||
use gateway_requests::iv::IV;
|
use gateway_requests::iv::IV;
|
||||||
use gateway_requests::registration::handshake::{client_handshake, SharedKeys};
|
use gateway_requests::registration::handshake::{client_handshake, SharedKeys};
|
||||||
use gateway_requests::{BinaryRequest, ClientControlRequest, ServerResponse, PROTOCOL_VERSION};
|
use gateway_requests::{BinaryRequest, ClientControlRequest, ServerResponse, PROTOCOL_VERSION};
|
||||||
use log::*;
|
use log::*;
|
||||||
|
use nym_coconut_interface::Credential;
|
||||||
use nym_crypto::asymmetric::identity;
|
use nym_crypto::asymmetric::identity;
|
||||||
use nym_network_defaults::{REMAINING_BANDWIDTH_THRESHOLD, TOKENS_TO_BURN};
|
use nym_network_defaults::{REMAINING_BANDWIDTH_THRESHOLD, TOKENS_TO_BURN};
|
||||||
use nym_sphinx::forwarding::packet::MixPacket;
|
use nym_sphinx::forwarding::packet::MixPacket;
|
||||||
@@ -33,7 +33,7 @@ use validator_client::nyxd::CosmWasmClient;
|
|||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
#[cfg(not(feature = "mobile"))]
|
#[cfg(not(feature = "mobile"))]
|
||||||
use credential_storage::PersistentStorage;
|
use nym_credential_storage::PersistentStorage;
|
||||||
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
#[cfg(feature = "mobile")]
|
#[cfg(feature = "mobile")]
|
||||||
|
|||||||
@@ -3,13 +3,13 @@
|
|||||||
|
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
use crate::wasm_mockups::StorageError;
|
use crate::wasm_mockups::StorageError;
|
||||||
#[cfg(not(feature = "mobile"))]
|
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
|
||||||
use credential_storage::error::StorageError;
|
|
||||||
use gateway_requests::registration::handshake::error::HandshakeError;
|
use gateway_requests::registration::handshake::error::HandshakeError;
|
||||||
#[cfg(feature = "mobile")]
|
#[cfg(feature = "mobile")]
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
use mobile_storage::StorageError;
|
use mobile_storage::StorageError;
|
||||||
|
#[cfg(not(feature = "mobile"))]
|
||||||
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
|
use nym_credential_storage::error::StorageError;
|
||||||
use std::io;
|
use std::io;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
use tungstenite::Error as WsError;
|
use tungstenite::Error as WsError;
|
||||||
@@ -31,7 +31,7 @@ pub enum GatewayClientError {
|
|||||||
CredentialStorageError(#[from] StorageError),
|
CredentialStorageError(#[from] StorageError),
|
||||||
|
|
||||||
#[error("Coconut error - {0}")]
|
#[error("Coconut error - {0}")]
|
||||||
CoconutError(#[from] coconut_interface::CoconutError),
|
CoconutError(#[from] nym_coconut_interface::CoconutError),
|
||||||
|
|
||||||
// TODO: see if `JsValue` is a reasonable type for this
|
// TODO: see if `JsValue` is a reasonable type for this
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
@@ -48,7 +48,7 @@ pub enum GatewayClientError {
|
|||||||
NoBandwidthControllerAvailable,
|
NoBandwidthControllerAvailable,
|
||||||
|
|
||||||
#[error("Credential error - {0}")]
|
#[error("Credential error - {0}")]
|
||||||
CredentialError(#[from] credentials::error::Error),
|
CredentialError(#[from] nym_credentials::error::Error),
|
||||||
|
|
||||||
#[error("Connection was abruptly closed")]
|
#[error("Connection was abruptly closed")]
|
||||||
ConnectionAbruptlyClosed,
|
ConnectionAbruptlyClosed,
|
||||||
|
|||||||
@@ -11,13 +11,13 @@ rust-version = "1.56"
|
|||||||
base64 = "0.13"
|
base64 = "0.13"
|
||||||
colored = "2.0"
|
colored = "2.0"
|
||||||
|
|
||||||
coconut-dkg-common = { path = "../../cosmwasm-smart-contracts/coconut-dkg" }
|
nym-coconut-dkg-common = { path = "../../cosmwasm-smart-contracts/coconut-dkg" }
|
||||||
nym-contracts-common = { path = "../../cosmwasm-smart-contracts/contracts-common" }
|
nym-contracts-common = { path = "../../cosmwasm-smart-contracts/contracts-common" }
|
||||||
nym-mixnet-contract-common = { path= "../../cosmwasm-smart-contracts/mixnet-contract" }
|
nym-mixnet-contract-common = { path= "../../cosmwasm-smart-contracts/mixnet-contract" }
|
||||||
nym-vesting-contract-common = { path= "../../cosmwasm-smart-contracts/vesting-contract" }
|
nym-vesting-contract-common = { path= "../../cosmwasm-smart-contracts/vesting-contract" }
|
||||||
coconut-bandwidth-contract-common = { path= "../../cosmwasm-smart-contracts/coconut-bandwidth-contract" }
|
nym-coconut-bandwidth-contract-common = { path= "../../cosmwasm-smart-contracts/coconut-bandwidth-contract" }
|
||||||
multisig-contract-common = { path = "../../cosmwasm-smart-contracts/multisig-contract" }
|
nym-multisig-contract-common = { path = "../../cosmwasm-smart-contracts/multisig-contract" }
|
||||||
group-contract-common = { path = "../../cosmwasm-smart-contracts/group-contract" }
|
nym-group-contract-common = { path = "../../cosmwasm-smart-contracts/group-contract" }
|
||||||
nym-vesting-contract = { path = "../../../contracts/vesting" }
|
nym-vesting-contract = { path = "../../../contracts/vesting" }
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
serde_json = "1"
|
serde_json = "1"
|
||||||
@@ -28,9 +28,10 @@ url = { version = "2.2", features = ["serde"] }
|
|||||||
tokio = { version = "1.24.1", features = ["sync", "time"] }
|
tokio = { version = "1.24.1", features = ["sync", "time"] }
|
||||||
futures = "0.3"
|
futures = "0.3"
|
||||||
|
|
||||||
coconut-interface = { path = "../../coconut-interface" }
|
nym-coconut-interface = { path = "../../coconut-interface" }
|
||||||
nym-network-defaults = { path = "../../network-defaults" }
|
nym-network-defaults = { path = "../../network-defaults" }
|
||||||
nym-api-requests = { path = "../../../nym-api/nym-api-requests" }
|
nym-api-requests = { path = "../../../nym-api/nym-api-requests" }
|
||||||
|
nym-execute = { path = "../../execute" }
|
||||||
|
|
||||||
# required for nyxd-client
|
# required for nyxd-client
|
||||||
# at some point it might be possible to make it wasm-compatible
|
# at some point it might be possible to make it wasm-compatible
|
||||||
@@ -46,7 +47,7 @@ flate2 = { version = "1.0.20", optional = true }
|
|||||||
sha2 = { version = "0.9.5", optional = true }
|
sha2 = { version = "0.9.5", optional = true }
|
||||||
itertools = { version = "0.10", optional = true }
|
itertools = { version = "0.10", optional = true }
|
||||||
cosmwasm-std = { version = "1.0.0", optional = true }
|
cosmwasm-std = { version = "1.0.0", optional = true }
|
||||||
nym-execute = { path = "../../execute" }
|
zeroize = { version = "1.5.7", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
ts-rs = "6.1.2"
|
ts-rs = "6.1.2"
|
||||||
@@ -64,6 +65,7 @@ nyxd-client = [
|
|||||||
"sha2",
|
"sha2",
|
||||||
"itertools",
|
"itertools",
|
||||||
"cosmwasm-std",
|
"cosmwasm-std",
|
||||||
|
"zeroize"
|
||||||
]
|
]
|
||||||
generate-ts = []
|
generate-ts = []
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,6 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use crate::{nym_api, ValidatorClientError};
|
use crate::{nym_api, ValidatorClientError};
|
||||||
use coconut_dkg_common::types::NodeIndex;
|
|
||||||
use coconut_interface::VerificationKey;
|
|
||||||
use nym_api_requests::coconut::{
|
use nym_api_requests::coconut::{
|
||||||
BlindSignRequestBody, BlindedSignatureResponse, VerifyCredentialBody, VerifyCredentialResponse,
|
BlindSignRequestBody, BlindedSignatureResponse, VerifyCredentialBody, VerifyCredentialResponse,
|
||||||
};
|
};
|
||||||
@@ -11,6 +9,8 @@ use nym_api_requests::models::{
|
|||||||
GatewayCoreStatusResponse, MixnodeCoreStatusResponse, MixnodeStatusResponse,
|
GatewayCoreStatusResponse, MixnodeCoreStatusResponse, MixnodeStatusResponse,
|
||||||
RewardEstimationResponse, StakeSaturationResponse,
|
RewardEstimationResponse, StakeSaturationResponse,
|
||||||
};
|
};
|
||||||
|
use nym_coconut_dkg_common::types::NodeIndex;
|
||||||
|
use nym_coconut_interface::VerificationKey;
|
||||||
pub use nym_mixnet_contract_common::{mixnode::MixNodeDetails, GatewayBond, IdentityKeyRef, MixId};
|
pub use nym_mixnet_contract_common::{mixnode::MixNodeDetails, GatewayBond, IdentityKeyRef, MixId};
|
||||||
|
|
||||||
#[cfg(feature = "nyxd-client")]
|
#[cfg(feature = "nyxd-client")]
|
||||||
@@ -18,17 +18,17 @@ use crate::nyxd::traits::{DkgQueryClient, MixnetQueryClient, MultisigQueryClient
|
|||||||
#[cfg(feature = "nyxd-client")]
|
#[cfg(feature = "nyxd-client")]
|
||||||
use crate::nyxd::{self, CosmWasmClient, NyxdClient, QueryNyxdClient, SigningNyxdClient};
|
use crate::nyxd::{self, CosmWasmClient, NyxdClient, QueryNyxdClient, SigningNyxdClient};
|
||||||
#[cfg(feature = "nyxd-client")]
|
#[cfg(feature = "nyxd-client")]
|
||||||
use coconut_dkg_common::{
|
use cw3::ProposalResponse;
|
||||||
|
#[cfg(feature = "nyxd-client")]
|
||||||
|
use nym_api_requests::models::MixNodeBondAnnotated;
|
||||||
|
#[cfg(feature = "nyxd-client")]
|
||||||
|
use nym_coconut_dkg_common::{
|
||||||
dealer::ContractDealing,
|
dealer::ContractDealing,
|
||||||
types::{DealerDetails, EpochId},
|
types::{DealerDetails, EpochId},
|
||||||
verification_key::ContractVKShare,
|
verification_key::ContractVKShare,
|
||||||
};
|
};
|
||||||
#[cfg(feature = "nyxd-client")]
|
#[cfg(feature = "nyxd-client")]
|
||||||
use coconut_interface::Base58;
|
use nym_coconut_interface::Base58;
|
||||||
#[cfg(feature = "nyxd-client")]
|
|
||||||
use cw3::ProposalResponse;
|
|
||||||
#[cfg(feature = "nyxd-client")]
|
|
||||||
use nym_api_requests::models::MixNodeBondAnnotated;
|
|
||||||
#[cfg(feature = "nyxd-client")]
|
#[cfg(feature = "nyxd-client")]
|
||||||
use nym_mixnet_contract_common::{
|
use nym_mixnet_contract_common::{
|
||||||
families::{Family, FamilyHead},
|
families::{Family, FamilyHead},
|
||||||
@@ -130,10 +130,9 @@ impl Config {
|
|||||||
#[cfg(feature = "nyxd-client")]
|
#[cfg(feature = "nyxd-client")]
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Client<C: Clone> {
|
pub struct Client<C: Clone> {
|
||||||
// TODO: we really shouldn't be storing a mnemonic here, but removing it would be
|
// // TODO: we really shouldn't be storing a mnemonic here, but removing it would be
|
||||||
// non-trivial amount of work and it's out of scope of the current branch
|
// // non-trivial amount of work and it's out of scope of the current branch
|
||||||
mnemonic: Option<bip39::Mnemonic>,
|
// mnemonic: Option<bip39::Mnemonic>,
|
||||||
|
|
||||||
mixnode_page_limit: Option<u32>,
|
mixnode_page_limit: Option<u32>,
|
||||||
gateway_page_limit: Option<u32>,
|
gateway_page_limit: Option<u32>,
|
||||||
mixnode_delegations_page_limit: Option<u32>,
|
mixnode_delegations_page_limit: Option<u32>,
|
||||||
@@ -157,12 +156,11 @@ impl Client<SigningNyxdClient> {
|
|||||||
let nyxd_client = NyxdClient::connect_with_mnemonic(
|
let nyxd_client = NyxdClient::connect_with_mnemonic(
|
||||||
config.nyxd_config.clone(),
|
config.nyxd_config.clone(),
|
||||||
config.nyxd_url.as_str(),
|
config.nyxd_url.as_str(),
|
||||||
mnemonic.clone(),
|
mnemonic,
|
||||||
None,
|
None,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok(Client {
|
Ok(Client {
|
||||||
mnemonic: Some(mnemonic),
|
|
||||||
mixnode_page_limit: config.mixnode_page_limit,
|
mixnode_page_limit: config.mixnode_page_limit,
|
||||||
gateway_page_limit: config.gateway_page_limit,
|
gateway_page_limit: config.gateway_page_limit,
|
||||||
mixnode_delegations_page_limit: config.mixnode_delegations_page_limit,
|
mixnode_delegations_page_limit: config.mixnode_delegations_page_limit,
|
||||||
@@ -176,12 +174,7 @@ impl Client<SigningNyxdClient> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn change_nyxd(&mut self, new_endpoint: Url) -> Result<(), ValidatorClientError> {
|
pub fn change_nyxd(&mut self, new_endpoint: Url) -> Result<(), ValidatorClientError> {
|
||||||
self.nyxd = NyxdClient::connect_with_mnemonic(
|
self.nyxd.change_endpoint(new_endpoint.as_ref())?;
|
||||||
self.nyxd.current_config().clone(),
|
|
||||||
new_endpoint.as_ref(),
|
|
||||||
self.mnemonic.clone().unwrap(),
|
|
||||||
None,
|
|
||||||
)?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,7 +191,6 @@ impl Client<QueryNyxdClient> {
|
|||||||
NyxdClient::connect(config.nyxd_config.clone(), config.nyxd_url.as_str())?;
|
NyxdClient::connect(config.nyxd_config.clone(), config.nyxd_url.as_str())?;
|
||||||
|
|
||||||
Ok(Client {
|
Ok(Client {
|
||||||
mnemonic: None,
|
|
||||||
mixnode_page_limit: config.mixnode_page_limit,
|
mixnode_page_limit: config.mixnode_page_limit,
|
||||||
gateway_page_limit: config.gateway_page_limit,
|
gateway_page_limit: config.gateway_page_limit,
|
||||||
mixnode_delegations_page_limit: config.mixnode_delegations_page_limit,
|
mixnode_delegations_page_limit: config.mixnode_delegations_page_limit,
|
||||||
|
|||||||
@@ -6,8 +6,8 @@ use cosmrs::tendermint::abci;
|
|||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
pub use coconut_bandwidth_contract_common::event_attributes::*;
|
pub use nym_coconut_bandwidth_contract_common::event_attributes::*;
|
||||||
pub use coconut_dkg_common::event_attributes::*;
|
pub use nym_coconut_dkg_common::event_attributes::*;
|
||||||
|
|
||||||
// it seems that currently validators just emit stringified events (which are also returned as part of deliverTx response)
|
// it seems that currently validators just emit stringified events (which are also returned as part of deliverTx response)
|
||||||
// as theirs logs
|
// as theirs logs
|
||||||
|
|||||||
@@ -756,6 +756,19 @@ impl Client {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn change_endpoint<U>(&mut self, new_endpoint: U) -> Result<(), NyxdError>
|
||||||
|
where
|
||||||
|
U: TryInto<HttpClientUrl, Error = TendermintRpcError>,
|
||||||
|
{
|
||||||
|
let new_rpc_client = HttpClient::new(new_endpoint)?;
|
||||||
|
self.rpc_client = new_rpc_client;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn into_signer(self) -> DirectSecp256k1HdWallet {
|
||||||
|
self.signer
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_broadcast_polling_rate(&mut self, broadcast_polling_rate: Duration) {
|
pub fn set_broadcast_polling_rate(&mut self, broadcast_polling_rate: Duration) {
|
||||||
self.broadcast_polling_rate = broadcast_polling_rate
|
self.broadcast_polling_rate = broadcast_polling_rate
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ pub enum NyxdError {
|
|||||||
CosmwasmStdError(#[from] cosmwasm_std::StdError),
|
CosmwasmStdError(#[from] cosmwasm_std::StdError),
|
||||||
|
|
||||||
#[error("Coconut interface error: {0}")]
|
#[error("Coconut interface error: {0}")]
|
||||||
CoconutInterfaceError(#[from] coconut_interface::error::CoconutInterfaceError),
|
CoconutInterfaceError(#[from] nym_coconut_interface::error::CoconutInterfaceError),
|
||||||
|
|
||||||
#[error("Account had an unexpected bech32 prefix. Expected: {expected}, got: {got}")]
|
#[error("Account had an unexpected bech32 prefix. Expected: {expected}, got: {got}")]
|
||||||
UnexpectedBech32Prefix { got: String, expected: String },
|
UnexpectedBech32Prefix { got: String, expected: String },
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ pub use cosmrs::tendermint::Time as TendermintTime;
|
|||||||
pub use cosmrs::tx::{self, Gas};
|
pub use cosmrs::tx::{self, Gas};
|
||||||
pub use cosmrs::Coin as CosmosCoin;
|
pub use cosmrs::Coin as CosmosCoin;
|
||||||
pub use cosmrs::{bip32, AccountId, Decimal, Denom};
|
pub use cosmrs::{bip32, AccountId, Decimal, Denom};
|
||||||
|
use cosmwasm_std::Addr;
|
||||||
pub use cosmwasm_std::Coin as CosmWasmCoin;
|
pub use cosmwasm_std::Coin as CosmWasmCoin;
|
||||||
pub use fee::{gas_price::GasPrice, GasAdjustable, GasAdjustment};
|
pub use fee::{gas_price::GasPrice, GasAdjustable, GasAdjustment};
|
||||||
pub use signing_client::Client as SigningNyxdClient;
|
pub use signing_client::Client as SigningNyxdClient;
|
||||||
@@ -197,7 +198,7 @@ impl NyxdClient<SigningNyxdClient> {
|
|||||||
{
|
{
|
||||||
let prefix = &config.chain_details.bech32_account_prefix;
|
let prefix = &config.chain_details.bech32_account_prefix;
|
||||||
let denom = &config.chain_details.mix_denom.base;
|
let denom = &config.chain_details.mix_denom.base;
|
||||||
let wallet = DirectSecp256k1HdWallet::from_mnemonic(prefix, mnemonic)?;
|
let wallet = DirectSecp256k1HdWallet::from_mnemonic(prefix, mnemonic);
|
||||||
let client_address = wallet
|
let client_address = wallet
|
||||||
.try_derive_accounts()?
|
.try_derive_accounts()?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
@@ -212,6 +213,17 @@ impl NyxdClient<SigningNyxdClient> {
|
|||||||
simulated_gas_multiplier: DEFAULT_SIMULATED_GAS_MULTIPLIER,
|
simulated_gas_multiplier: DEFAULT_SIMULATED_GAS_MULTIPLIER,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn change_endpoint<U>(&mut self, new_endpoint: U) -> Result<(), NyxdError>
|
||||||
|
where
|
||||||
|
U: TryInto<HttpClientUrl, Error = TendermintRpcError>,
|
||||||
|
{
|
||||||
|
self.client.change_endpoint(new_endpoint)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn into_signer(self) -> DirectSecp256k1HdWallet {
|
||||||
|
self.client.into_signer()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C> NyxdClient<C>
|
impl<C> NyxdClient<C>
|
||||||
@@ -358,6 +370,15 @@ where
|
|||||||
&self.client_address.as_ref().unwrap()[0]
|
&self.client_address.as_ref().unwrap()[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn cw_address(&self) -> Addr
|
||||||
|
where
|
||||||
|
C: SigningCosmWasmClient,
|
||||||
|
{
|
||||||
|
// the call to unchecked is fine here as we're converting directly from `AccountId`
|
||||||
|
// which must have been a valid bech32 address
|
||||||
|
Addr::unchecked(self.address().as_ref())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn signer(&self) -> &DirectSecp256k1HdWallet
|
pub fn signer(&self) -> &DirectSecp256k1HdWallet
|
||||||
where
|
where
|
||||||
C: SigningCosmWasmClient,
|
C: SigningCosmWasmClient,
|
||||||
|
|||||||
+2
-2
@@ -4,8 +4,8 @@
|
|||||||
use crate::nyxd::error::NyxdError;
|
use crate::nyxd::error::NyxdError;
|
||||||
use crate::nyxd::{CosmWasmClient, NyxdClient};
|
use crate::nyxd::{CosmWasmClient, NyxdClient};
|
||||||
|
|
||||||
use coconut_bandwidth_contract_common::msg::QueryMsg;
|
use nym_coconut_bandwidth_contract_common::msg::QueryMsg;
|
||||||
use coconut_bandwidth_contract_common::spend_credential::SpendCredentialResponse;
|
use nym_coconut_bandwidth_contract_common::spend_credential::SpendCredentialResponse;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
|
||||||
|
|||||||
+2
-2
@@ -5,8 +5,8 @@ pub use crate::nyxd::cosmwasm_client::signing_client::SigningCosmWasmClient;
|
|||||||
use crate::nyxd::cosmwasm_client::types::ExecuteResult;
|
use crate::nyxd::cosmwasm_client::types::ExecuteResult;
|
||||||
use crate::nyxd::error::NyxdError;
|
use crate::nyxd::error::NyxdError;
|
||||||
use crate::nyxd::{Coin, Fee, NyxdClient};
|
use crate::nyxd::{Coin, Fee, NyxdClient};
|
||||||
use coconut_bandwidth_contract_common::spend_credential::SpendCredentialData;
|
use nym_coconut_bandwidth_contract_common::spend_credential::SpendCredentialData;
|
||||||
use coconut_bandwidth_contract_common::{deposit::DepositData, msg::ExecuteMsg};
|
use nym_coconut_bandwidth_contract_common::{deposit::DepositData, msg::ExecuteMsg};
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
|
||||||
|
|||||||
@@ -4,13 +4,13 @@
|
|||||||
use crate::nyxd::error::NyxdError;
|
use crate::nyxd::error::NyxdError;
|
||||||
use crate::nyxd::{CosmWasmClient, NyxdClient};
|
use crate::nyxd::{CosmWasmClient, NyxdClient};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use coconut_dkg_common::dealer::{
|
use cosmrs::AccountId;
|
||||||
|
use nym_coconut_dkg_common::dealer::{
|
||||||
DealerDetailsResponse, PagedDealerResponse, PagedDealingsResponse,
|
DealerDetailsResponse, PagedDealerResponse, PagedDealingsResponse,
|
||||||
};
|
};
|
||||||
use coconut_dkg_common::msg::QueryMsg as DkgQueryMsg;
|
use nym_coconut_dkg_common::msg::QueryMsg as DkgQueryMsg;
|
||||||
use coconut_dkg_common::types::{Epoch, EpochId, InitialReplacementData};
|
use nym_coconut_dkg_common::types::{Epoch, EpochId, InitialReplacementData};
|
||||||
use coconut_dkg_common::verification_key::PagedVKSharesResponse;
|
use nym_coconut_dkg_common::verification_key::PagedVKSharesResponse;
|
||||||
use cosmrs::AccountId;
|
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait DkgQueryClient {
|
pub trait DkgQueryClient {
|
||||||
|
|||||||
@@ -5,9 +5,9 @@ use crate::nyxd::cosmwasm_client::types::ExecuteResult;
|
|||||||
use crate::nyxd::error::NyxdError;
|
use crate::nyxd::error::NyxdError;
|
||||||
use crate::nyxd::{Fee, NyxdClient, SigningCosmWasmClient};
|
use crate::nyxd::{Fee, NyxdClient, SigningCosmWasmClient};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use coconut_dkg_common::msg::ExecuteMsg as DkgExecuteMsg;
|
use nym_coconut_dkg_common::msg::ExecuteMsg as DkgExecuteMsg;
|
||||||
use coconut_dkg_common::types::EncodedBTEPublicKeyWithProof;
|
use nym_coconut_dkg_common::types::EncodedBTEPublicKeyWithProof;
|
||||||
use coconut_dkg_common::verification_key::VerificationKeyShare;
|
use nym_coconut_dkg_common::verification_key::VerificationKeyShare;
|
||||||
use nym_contracts_common::dealings::ContractSafeBytes;
|
use nym_contracts_common::dealings::ContractSafeBytes;
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
use crate::nyxd::error::NyxdError;
|
use crate::nyxd::error::NyxdError;
|
||||||
use crate::nyxd::{CosmWasmClient, NyxdClient};
|
use crate::nyxd::{CosmWasmClient, NyxdClient};
|
||||||
|
|
||||||
use group_contract_common::msg::QueryMsg;
|
use nym_group_contract_common::msg::QueryMsg;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use cw4::MemberResponse;
|
use cw4::MemberResponse;
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use crate::nyxd::error::NyxdError;
|
|||||||
use crate::nyxd::NyxdClient;
|
use crate::nyxd::NyxdClient;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use cosmrs::AccountId;
|
use cosmrs::AccountId;
|
||||||
|
use nym_contracts_common::signing::Nonce;
|
||||||
use nym_mixnet_contract_common::delegation::{MixNodeDelegationResponse, OwnerProxySubKey};
|
use nym_mixnet_contract_common::delegation::{MixNodeDelegationResponse, OwnerProxySubKey};
|
||||||
use nym_mixnet_contract_common::families::Family;
|
use nym_mixnet_contract_common::families::Family;
|
||||||
use nym_mixnet_contract_common::mixnode::{
|
use nym_mixnet_contract_common::mixnode::{
|
||||||
@@ -18,12 +19,13 @@ use nym_mixnet_contract_common::rewarding::{
|
|||||||
};
|
};
|
||||||
use nym_mixnet_contract_common::{
|
use nym_mixnet_contract_common::{
|
||||||
delegation, ContractBuildInformation, ContractState, ContractStateParams,
|
delegation, ContractBuildInformation, ContractState, ContractStateParams,
|
||||||
CurrentIntervalResponse, EpochEventId, GatewayBondResponse, GatewayOwnershipResponse,
|
CurrentIntervalResponse, EpochEventId, EpochStatus, GatewayBondResponse,
|
||||||
IdentityKey, IntervalEventId, LayerDistribution, MixId, MixOwnershipResponse,
|
GatewayOwnershipResponse, IdentityKey, IntervalEventId, LayerDistribution, MixId,
|
||||||
MixnodeDetailsResponse, PagedAllDelegationsResponse, PagedDelegatorDelegationsResponse,
|
MixOwnershipResponse, MixnodeDetailsResponse, NumberOfPendingEventsResponse,
|
||||||
PagedFamiliesResponse, PagedGatewayResponse, PagedMembersResponse,
|
PagedAllDelegationsResponse, PagedDelegatorDelegationsResponse, PagedFamiliesResponse,
|
||||||
PagedMixNodeDelegationsResponse, PagedMixnodeBondsResponse, PagedRewardedSetResponse,
|
PagedGatewayResponse, PagedMembersResponse, PagedMixNodeDelegationsResponse,
|
||||||
PendingEpochEventsResponse, PendingIntervalEventsResponse, QueryMsg as MixnetQueryMsg,
|
PagedMixnodeBondsResponse, PagedRewardedSetResponse, PendingEpochEventsResponse,
|
||||||
|
PendingIntervalEventsResponse, QueryMsg as MixnetQueryMsg,
|
||||||
};
|
};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
@@ -60,6 +62,11 @@ pub trait MixnetQueryClient {
|
|||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn get_current_epoch_status(&self) -> Result<EpochStatus, NyxdError> {
|
||||||
|
self.query_mixnet_contract(MixnetQueryMsg::GetEpochStatus {})
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
async fn get_current_interval_details(&self) -> Result<CurrentIntervalResponse, NyxdError> {
|
async fn get_current_interval_details(&self) -> Result<CurrentIntervalResponse, NyxdError> {
|
||||||
self.query_mixnet_contract(MixnetQueryMsg::GetCurrentIntervalDetails {})
|
self.query_mixnet_contract(MixnetQueryMsg::GetCurrentIntervalDetails {})
|
||||||
.await
|
.await
|
||||||
@@ -377,6 +384,20 @@ pub trait MixnetQueryClient {
|
|||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn get_number_of_pending_events(
|
||||||
|
&self,
|
||||||
|
) -> Result<NumberOfPendingEventsResponse, NyxdError> {
|
||||||
|
self.query_mixnet_contract(MixnetQueryMsg::GetNumberOfPendingEvents {})
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_signing_nonce(&self, address: &AccountId) -> Result<Nonce, NyxdError> {
|
||||||
|
self.query_mixnet_contract(MixnetQueryMsg::GetSigningNonce {
|
||||||
|
address: address.to_string(),
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
async fn get_node_family_by_label(&self, label: &str) -> Result<Option<Family>, NyxdError> {
|
async fn get_node_family_by_label(&self, label: &str) -> Result<Option<Family>, NyxdError> {
|
||||||
self.query_mixnet_contract(MixnetQueryMsg::GetFamilyByLabel {
|
self.query_mixnet_contract(MixnetQueryMsg::GetFamilyByLabel {
|
||||||
label: label.to_string(),
|
label: label.to_string(),
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ use crate::nyxd::error::NyxdError;
|
|||||||
use crate::nyxd::{Fee, NyxdClient, SigningCosmWasmClient};
|
use crate::nyxd::{Fee, NyxdClient, SigningCosmWasmClient};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use cosmrs::AccountId;
|
use cosmrs::AccountId;
|
||||||
|
use nym_contracts_common::signing::MessageSignature;
|
||||||
use nym_mixnet_contract_common::mixnode::{MixNodeConfigUpdate, MixNodeCostParams};
|
use nym_mixnet_contract_common::mixnode::{MixNodeConfigUpdate, MixNodeCostParams};
|
||||||
use nym_mixnet_contract_common::reward_params::{IntervalRewardingParamsUpdate, Performance};
|
use nym_mixnet_contract_common::reward_params::{IntervalRewardingParamsUpdate, Performance};
|
||||||
use nym_mixnet_contract_common::{
|
use nym_mixnet_contract_common::{
|
||||||
@@ -106,6 +107,11 @@ pub trait MixnetSigningClient {
|
|||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn begin_epoch_transition(&self, fee: Option<Fee>) -> Result<ExecuteResult, NyxdError> {
|
||||||
|
self.execute_mixnet_contract(fee, MixnetExecuteMsg::BeginEpochTransition {}, vec![])
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
async fn advance_current_epoch(
|
async fn advance_current_epoch(
|
||||||
&self,
|
&self,
|
||||||
new_rewarded_set: Vec<LayerAssignment>,
|
new_rewarded_set: Vec<LayerAssignment>,
|
||||||
@@ -193,7 +199,8 @@ pub trait MixnetSigningClient {
|
|||||||
async fn join_family_on_behalf(
|
async fn join_family_on_behalf(
|
||||||
&self,
|
&self,
|
||||||
member_address: String,
|
member_address: String,
|
||||||
signature: String,
|
node_identity_signature: String,
|
||||||
|
family_signature: String,
|
||||||
family_head: String,
|
family_head: String,
|
||||||
fee: Option<Fee>,
|
fee: Option<Fee>,
|
||||||
) -> Result<ExecuteResult, NyxdError> {
|
) -> Result<ExecuteResult, NyxdError> {
|
||||||
@@ -201,7 +208,8 @@ pub trait MixnetSigningClient {
|
|||||||
fee,
|
fee,
|
||||||
MixnetExecuteMsg::JoinFamilyOnBehalf {
|
MixnetExecuteMsg::JoinFamilyOnBehalf {
|
||||||
member_address,
|
member_address,
|
||||||
signature,
|
node_identity_signature,
|
||||||
|
family_signature,
|
||||||
family_head,
|
family_head,
|
||||||
},
|
},
|
||||||
vec![],
|
vec![],
|
||||||
@@ -229,7 +237,7 @@ pub trait MixnetSigningClient {
|
|||||||
async fn leave_family_on_behalf(
|
async fn leave_family_on_behalf(
|
||||||
&self,
|
&self,
|
||||||
member_address: String,
|
member_address: String,
|
||||||
signature: String,
|
node_identity_signature: String,
|
||||||
family_head: String,
|
family_head: String,
|
||||||
fee: Option<Fee>,
|
fee: Option<Fee>,
|
||||||
) -> Result<ExecuteResult, NyxdError> {
|
) -> Result<ExecuteResult, NyxdError> {
|
||||||
@@ -237,7 +245,7 @@ pub trait MixnetSigningClient {
|
|||||||
fee,
|
fee,
|
||||||
MixnetExecuteMsg::LeaveFamilyOnBehalf {
|
MixnetExecuteMsg::LeaveFamilyOnBehalf {
|
||||||
member_address,
|
member_address,
|
||||||
signature,
|
node_identity_signature,
|
||||||
family_head,
|
family_head,
|
||||||
},
|
},
|
||||||
vec![],
|
vec![],
|
||||||
@@ -283,7 +291,7 @@ pub trait MixnetSigningClient {
|
|||||||
&self,
|
&self,
|
||||||
mix_node: MixNode,
|
mix_node: MixNode,
|
||||||
cost_params: MixNodeCostParams,
|
cost_params: MixNodeCostParams,
|
||||||
owner_signature: String,
|
owner_signature: MessageSignature,
|
||||||
pledge: Coin,
|
pledge: Coin,
|
||||||
fee: Option<Fee>,
|
fee: Option<Fee>,
|
||||||
) -> Result<ExecuteResult, NyxdError> {
|
) -> Result<ExecuteResult, NyxdError> {
|
||||||
@@ -304,7 +312,7 @@ pub trait MixnetSigningClient {
|
|||||||
owner: AccountId,
|
owner: AccountId,
|
||||||
mix_node: MixNode,
|
mix_node: MixNode,
|
||||||
cost_params: MixNodeCostParams,
|
cost_params: MixNodeCostParams,
|
||||||
owner_signature: String,
|
owner_signature: MessageSignature,
|
||||||
pledge: Coin,
|
pledge: Coin,
|
||||||
fee: Option<Fee>,
|
fee: Option<Fee>,
|
||||||
) -> Result<ExecuteResult, NyxdError> {
|
) -> Result<ExecuteResult, NyxdError> {
|
||||||
@@ -435,7 +443,7 @@ pub trait MixnetSigningClient {
|
|||||||
async fn bond_gateway(
|
async fn bond_gateway(
|
||||||
&self,
|
&self,
|
||||||
gateway: Gateway,
|
gateway: Gateway,
|
||||||
owner_signature: String,
|
owner_signature: MessageSignature,
|
||||||
pledge: Coin,
|
pledge: Coin,
|
||||||
fee: Option<Fee>,
|
fee: Option<Fee>,
|
||||||
) -> Result<ExecuteResult, NyxdError> {
|
) -> Result<ExecuteResult, NyxdError> {
|
||||||
@@ -454,7 +462,7 @@ pub trait MixnetSigningClient {
|
|||||||
&self,
|
&self,
|
||||||
owner: AccountId,
|
owner: AccountId,
|
||||||
gateway: Gateway,
|
gateway: Gateway,
|
||||||
owner_signature: String,
|
owner_signature: MessageSignature,
|
||||||
pledge: Coin,
|
pledge: Coin,
|
||||||
fee: Option<Fee>,
|
fee: Option<Fee>,
|
||||||
) -> Result<ExecuteResult, NyxdError> {
|
) -> Result<ExecuteResult, NyxdError> {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use crate::nyxd::error::NyxdError;
|
|||||||
use crate::nyxd::{CosmWasmClient, NyxdClient};
|
use crate::nyxd::{CosmWasmClient, NyxdClient};
|
||||||
|
|
||||||
use cw3::{ProposalListResponse, ProposalResponse};
|
use cw3::{ProposalListResponse, ProposalResponse};
|
||||||
use multisig_contract_common::msg::QueryMsg;
|
use nym_multisig_contract_common::msg::QueryMsg;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
|
||||||
|
|||||||
@@ -6,9 +6,9 @@ use crate::nyxd::cosmwasm_client::types::ExecuteResult;
|
|||||||
use crate::nyxd::error::NyxdError;
|
use crate::nyxd::error::NyxdError;
|
||||||
use crate::nyxd::{Fee, NyxdClient};
|
use crate::nyxd::{Fee, NyxdClient};
|
||||||
|
|
||||||
use coconut_bandwidth_contract_common::msg::ExecuteMsg as CoconutBandwidthExecuteMsg;
|
|
||||||
use cw3::Vote;
|
use cw3::Vote;
|
||||||
use multisig_contract_common::msg::ExecuteMsg;
|
use nym_coconut_bandwidth_contract_common::msg::ExecuteMsg as CoconutBandwidthExecuteMsg;
|
||||||
|
use nym_multisig_contract_common::msg::ExecuteMsg;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use cosmwasm_std::{to_binary, Coin, CosmosMsg, WasmMsg};
|
use cosmwasm_std::{to_binary, Coin, CosmosMsg, WasmMsg};
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ use crate::nyxd::cosmwasm_client::types::ExecuteResult;
|
|||||||
use crate::nyxd::error::NyxdError;
|
use crate::nyxd::error::NyxdError;
|
||||||
use crate::nyxd::{Coin, Fee, NyxdClient};
|
use crate::nyxd::{Coin, Fee, NyxdClient};
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
use nym_contracts_common::signing::MessageSignature;
|
||||||
use nym_mixnet_contract_common::mixnode::{MixNodeConfigUpdate, MixNodeCostParams};
|
use nym_mixnet_contract_common::mixnode::{MixNodeConfigUpdate, MixNodeCostParams};
|
||||||
use nym_mixnet_contract_common::{Gateway, MixId, MixNode};
|
use nym_mixnet_contract_common::{Gateway, MixId, MixNode};
|
||||||
use nym_vesting_contract_common::messages::{
|
use nym_vesting_contract_common::messages::{
|
||||||
@@ -43,7 +44,7 @@ pub trait VestingSigningClient {
|
|||||||
async fn vesting_bond_gateway(
|
async fn vesting_bond_gateway(
|
||||||
&self,
|
&self,
|
||||||
gateway: Gateway,
|
gateway: Gateway,
|
||||||
owner_signature: &str,
|
owner_signature: MessageSignature,
|
||||||
pledge: Coin,
|
pledge: Coin,
|
||||||
fee: Option<Fee>,
|
fee: Option<Fee>,
|
||||||
) -> Result<ExecuteResult, NyxdError>;
|
) -> Result<ExecuteResult, NyxdError>;
|
||||||
@@ -61,7 +62,7 @@ pub trait VestingSigningClient {
|
|||||||
&self,
|
&self,
|
||||||
mix_node: MixNode,
|
mix_node: MixNode,
|
||||||
cost_params: MixNodeCostParams,
|
cost_params: MixNodeCostParams,
|
||||||
owner_signature: &str,
|
owner_signature: MessageSignature,
|
||||||
pledge: Coin,
|
pledge: Coin,
|
||||||
fee: Option<Fee>,
|
fee: Option<Fee>,
|
||||||
) -> Result<ExecuteResult, NyxdError>;
|
) -> Result<ExecuteResult, NyxdError>;
|
||||||
@@ -208,14 +209,14 @@ impl<C: SigningCosmWasmClient + Sync + Send + Clone> VestingSigningClient for Ny
|
|||||||
async fn vesting_bond_gateway(
|
async fn vesting_bond_gateway(
|
||||||
&self,
|
&self,
|
||||||
gateway: Gateway,
|
gateway: Gateway,
|
||||||
owner_signature: &str,
|
owner_signature: MessageSignature,
|
||||||
pledge: Coin,
|
pledge: Coin,
|
||||||
fee: Option<Fee>,
|
fee: Option<Fee>,
|
||||||
) -> Result<ExecuteResult, NyxdError> {
|
) -> Result<ExecuteResult, NyxdError> {
|
||||||
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier)));
|
let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier)));
|
||||||
let req = VestingExecuteMsg::BondGateway {
|
let req = VestingExecuteMsg::BondGateway {
|
||||||
gateway,
|
gateway,
|
||||||
owner_signature: owner_signature.to_string(),
|
owner_signature,
|
||||||
amount: pledge.into(),
|
amount: pledge.into(),
|
||||||
};
|
};
|
||||||
self.client
|
self.client
|
||||||
@@ -272,7 +273,7 @@ impl<C: SigningCosmWasmClient + Sync + Send + Clone> VestingSigningClient for Ny
|
|||||||
&self,
|
&self,
|
||||||
mix_node: MixNode,
|
mix_node: MixNode,
|
||||||
cost_params: MixNodeCostParams,
|
cost_params: MixNodeCostParams,
|
||||||
owner_signature: &str,
|
owner_signature: MessageSignature,
|
||||||
pledge: Coin,
|
pledge: Coin,
|
||||||
fee: Option<Fee>,
|
fee: Option<Fee>,
|
||||||
) -> Result<ExecuteResult, NyxdError> {
|
) -> Result<ExecuteResult, NyxdError> {
|
||||||
@@ -281,7 +282,7 @@ impl<C: SigningCosmWasmClient + Sync + Send + Clone> VestingSigningClient for Ny
|
|||||||
VestingExecuteMsg::BondMixnode {
|
VestingExecuteMsg::BondMixnode {
|
||||||
mix_node,
|
mix_node,
|
||||||
cost_params,
|
cost_params,
|
||||||
owner_signature: owner_signature.to_string(),
|
owner_signature,
|
||||||
amount: pledge.into(),
|
amount: pledge.into(),
|
||||||
},
|
},
|
||||||
vec![],
|
vec![],
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ use cosmrs::crypto::PublicKey;
|
|||||||
use cosmrs::tx::SignDoc;
|
use cosmrs::tx::SignDoc;
|
||||||
use cosmrs::{tx, AccountId};
|
use cosmrs::{tx, AccountId};
|
||||||
use nym_config::defaults;
|
use nym_config::defaults;
|
||||||
|
use zeroize::Zeroize;
|
||||||
|
|
||||||
/// Derivation information required to derive a keypair and an address from a mnemonic.
|
/// Derivation information required to derive a keypair and an address from a mnemonic.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@@ -56,19 +57,40 @@ pub struct DirectSecp256k1HdWallet {
|
|||||||
accounts: Vec<Secp256k1Derivation>,
|
accounts: Vec<Secp256k1Derivation>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Zeroize for DirectSecp256k1HdWallet {
|
||||||
|
fn zeroize(&mut self) {
|
||||||
|
// in ideal world, Mnemonic would have had zeroize defined on it (there's an almost year old PR that introduces it)
|
||||||
|
// and the memory would have been filled with zeroes.
|
||||||
|
//
|
||||||
|
// we really don't want to keep our real mnemonic in memory, so let's do the semi-nasty thing
|
||||||
|
// of overwriting it with a fresh mnemonic that was never used before
|
||||||
|
//
|
||||||
|
// note: this function can only fail on an invalid word count, which clearly is not the case here
|
||||||
|
self.secret = bip39::Mnemonic::generate(self.secret.word_count()).unwrap();
|
||||||
|
self.seed.zeroize();
|
||||||
|
// there's nothing secret about derivation paths
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for DirectSecp256k1HdWallet {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
self.zeroize()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl DirectSecp256k1HdWallet {
|
impl DirectSecp256k1HdWallet {
|
||||||
pub fn builder(prefix: &str) -> DirectSecp256k1HdWalletBuilder {
|
pub fn builder(prefix: &str) -> DirectSecp256k1HdWalletBuilder {
|
||||||
DirectSecp256k1HdWalletBuilder::new(prefix)
|
DirectSecp256k1HdWalletBuilder::new(prefix)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Restores a wallet from the given BIP39 mnemonic using default options.
|
/// Restores a wallet from the given BIP39 mnemonic using default options.
|
||||||
pub fn from_mnemonic(prefix: &str, mnemonic: bip39::Mnemonic) -> Result<Self, NyxdError> {
|
pub fn from_mnemonic(prefix: &str, mnemonic: bip39::Mnemonic) -> Self {
|
||||||
DirectSecp256k1HdWalletBuilder::new(prefix).build(mnemonic)
|
DirectSecp256k1HdWalletBuilder::new(prefix).build(mnemonic)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate(prefix: &str, word_count: usize) -> Result<Self, NyxdError> {
|
pub fn generate(prefix: &str, word_count: usize) -> Result<Self, NyxdError> {
|
||||||
let mneomonic = bip39::Mnemonic::generate(word_count)?;
|
let mneomonic = bip39::Mnemonic::generate(word_count)?;
|
||||||
Self::from_mnemonic(prefix, mneomonic)
|
Ok(Self::from_mnemonic(prefix, mneomonic))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn derive_keypair(&self, hd_path: &DerivationPath) -> Result<Secp256k1Keypair, NyxdError> {
|
fn derive_keypair(&self, hd_path: &DerivationPath) -> Result<Secp256k1Keypair, NyxdError> {
|
||||||
@@ -145,11 +167,14 @@ impl DirectSecp256k1HdWallet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
|
#[derive(Zeroize)]
|
||||||
|
#[zeroize(drop)]
|
||||||
pub struct DirectSecp256k1HdWalletBuilder {
|
pub struct DirectSecp256k1HdWalletBuilder {
|
||||||
/// The password to use when deriving a BIP39 seed from a mnemonic.
|
/// The password to use when deriving a BIP39 seed from a mnemonic.
|
||||||
bip39_password: String,
|
bip39_password: String,
|
||||||
|
|
||||||
/// The BIP-32/SLIP-10 derivation paths
|
/// The BIP-32/SLIP-10 derivation paths
|
||||||
|
#[zeroize(skip)]
|
||||||
hd_paths: Vec<DerivationPath>,
|
hd_paths: Vec<DerivationPath>,
|
||||||
|
|
||||||
/// The bech32 address prefix (human readable part)
|
/// The bech32 address prefix (human readable part)
|
||||||
@@ -185,23 +210,23 @@ impl DirectSecp256k1HdWalletBuilder {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build(self, mnemonic: bip39::Mnemonic) -> Result<DirectSecp256k1HdWallet, NyxdError> {
|
pub fn build(self, mnemonic: bip39::Mnemonic) -> DirectSecp256k1HdWallet {
|
||||||
let seed = mnemonic.to_seed(&self.bip39_password);
|
let seed = mnemonic.to_seed(&self.bip39_password);
|
||||||
let prefix = self.prefix;
|
let prefix = self.prefix.clone();
|
||||||
let accounts = self
|
let accounts = self
|
||||||
.hd_paths
|
.hd_paths
|
||||||
.into_iter()
|
.iter()
|
||||||
.map(|hd_path| Secp256k1Derivation {
|
.map(|hd_path| Secp256k1Derivation {
|
||||||
hd_path,
|
hd_path: hd_path.clone(),
|
||||||
prefix: prefix.clone(),
|
prefix: prefix.clone(),
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
Ok(DirectSecp256k1HdWallet {
|
DirectSecp256k1HdWallet {
|
||||||
accounts,
|
accounts,
|
||||||
seed,
|
seed,
|
||||||
secret: mnemonic,
|
secret: mnemonic,
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -229,8 +254,7 @@ mod tests {
|
|||||||
"n17n9flp6jflljg6fp05dsy07wcprf2uuu8g40rf",
|
"n17n9flp6jflljg6fp05dsy07wcprf2uuu8g40rf",
|
||||||
];
|
];
|
||||||
for (idx, mnemonic) in mnemonics.iter().enumerate() {
|
for (idx, mnemonic) in mnemonics.iter().enumerate() {
|
||||||
let wallet =
|
let wallet = DirectSecp256k1HdWallet::from_mnemonic(&prefix, mnemonic.parse().unwrap());
|
||||||
DirectSecp256k1HdWallet::from_mnemonic(&prefix, mnemonic.parse().unwrap()).unwrap();
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
wallet.try_derive_accounts().unwrap()[0].address,
|
wallet.try_derive_accounts().unwrap()[0].address,
|
||||||
addrs[idx].parse().unwrap()
|
addrs[idx].parse().unwrap()
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "coconut-interface"
|
name = "nym-coconut-interface"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
description = "Crutch library until there is proper SerDe support for coconut structs"
|
description = "Crutch library until there is proper SerDe support for coconut structs"
|
||||||
|
|||||||
@@ -30,8 +30,9 @@ cosmwasm-std = { version = "1.0.0" }
|
|||||||
|
|
||||||
validator-client = { path = "../client-libs/validator-client", features = ["nyxd-client"] }
|
validator-client = { path = "../client-libs/validator-client", features = ["nyxd-client"] }
|
||||||
nym-network-defaults = { path = "../network-defaults" }
|
nym-network-defaults = { path = "../network-defaults" }
|
||||||
|
nym-contracts-common = { path = "../cosmwasm-smart-contracts/contracts-common" }
|
||||||
nym-mixnet-contract-common = { path = "../cosmwasm-smart-contracts/mixnet-contract" }
|
nym-mixnet-contract-common = { path = "../cosmwasm-smart-contracts/mixnet-contract" }
|
||||||
nym-vesting-contract-common = { path = "../cosmwasm-smart-contracts/vesting-contract" }
|
nym-vesting-contract-common = { path = "../cosmwasm-smart-contracts/vesting-contract" }
|
||||||
coconut-bandwidth-contract-common = { path = "../cosmwasm-smart-contracts/coconut-bandwidth-contract" }
|
nym-coconut-bandwidth-contract-common = { path = "../cosmwasm-smart-contracts/coconut-bandwidth-contract" }
|
||||||
coconut-dkg-common = { path = "../cosmwasm-smart-contracts/coconut-dkg" }
|
nym-coconut-dkg-common = { path = "../cosmwasm-smart-contracts/coconut-dkg" }
|
||||||
multisig-contract-common = { path = "../cosmwasm-smart-contracts/multisig-contract" }
|
nym-multisig-contract-common = { path = "../cosmwasm-smart-contracts/multisig-contract" }
|
||||||
|
|||||||
@@ -1,13 +1,20 @@
|
|||||||
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
|
// Copyright 2022 - Nym Technologies SA <contact@nymtech.net>
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
use cosmrs::AccountId;
|
||||||
|
use cosmwasm_std::{Addr, Coin as CosmWasmCoin, Decimal};
|
||||||
|
use log::error;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
|
|
||||||
use cosmwasm_std::{Coin as CosmWasmCoin, Decimal};
|
|
||||||
use log::error;
|
|
||||||
use validator_client::nyxd::Coin;
|
use validator_client::nyxd::Coin;
|
||||||
|
|
||||||
|
// TODO: perhaps it should be moved to some global common crate?
|
||||||
|
pub fn account_id_to_cw_addr(account_id: &AccountId) -> Addr {
|
||||||
|
// the call to unchecked is fine here as we're converting directly from `AccountId`
|
||||||
|
// which must have been a valid bech32 address
|
||||||
|
Addr::unchecked(account_id.as_ref())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn pretty_coin(coin: &Coin) -> String {
|
pub fn pretty_coin(coin: &Coin) -> String {
|
||||||
let amount = Decimal::from_ratio(coin.amount, 1_000_000u128);
|
let amount = Decimal::from_ratio(coin.amount, 1_000_000u128);
|
||||||
let denom = if coin.denom.starts_with('u') {
|
let denom = if coin.denom.starts_with('u') {
|
||||||
|
|||||||
@@ -15,8 +15,7 @@ pub fn create_account(args: Args, prefix: &str) {
|
|||||||
let word_count = args.word_count.unwrap_or(24);
|
let word_count = args.word_count.unwrap_or(24);
|
||||||
let mnemonic = bip39::Mnemonic::generate(word_count).expect("failed to generate mnemonic!");
|
let mnemonic = bip39::Mnemonic::generate(word_count).expect("failed to generate mnemonic!");
|
||||||
|
|
||||||
let wallet =
|
let wallet = DirectSecp256k1HdWallet::from_mnemonic(prefix, mnemonic);
|
||||||
DirectSecp256k1HdWallet::from_mnemonic(prefix, mnemonic).expect("failed to build wallet!");
|
|
||||||
|
|
||||||
// Output address and mnemonics into separate lines for easier parsing
|
// Output address and mnemonics into separate lines for easier parsing
|
||||||
println!("{}", wallet.mnemonic());
|
println!("{}", wallet.mnemonic());
|
||||||
|
|||||||
@@ -51,21 +51,19 @@ pub async fn get_pubkey(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_pubkey_from_mnemonic(address: AccountId, prefix: &str, mnemonic: bip39::Mnemonic) {
|
pub fn get_pubkey_from_mnemonic(address: AccountId, prefix: &str, mnemonic: bip39::Mnemonic) {
|
||||||
match DirectSecp256k1HdWallet::from_mnemonic(prefix, mnemonic) {
|
let wallet = DirectSecp256k1HdWallet::from_mnemonic(prefix, mnemonic);
|
||||||
Ok(wallet) => match wallet.try_derive_accounts() {
|
match wallet.try_derive_accounts() {
|
||||||
Ok(accounts) => match accounts.iter().find(|a| *a.address() == address) {
|
Ok(accounts) => match accounts.iter().find(|a| *a.address() == address) {
|
||||||
Some(account) => {
|
Some(account) => {
|
||||||
println!("{}", account.public_key().to_string());
|
println!("{}", account.public_key().to_string());
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
error!("Could not derive key that matches {}", address)
|
error!("Could not derive key that matches {}", address)
|
||||||
}
|
|
||||||
},
|
|
||||||
Err(e) => {
|
|
||||||
error!("Failed to derive accounts. {}", e);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Err(e) => show_error(e),
|
Err(e) => {
|
||||||
|
error!("Failed to derive accounts. {}", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use std::str::FromStr;
|
|||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use log::{debug, info};
|
use log::{debug, info};
|
||||||
|
|
||||||
use coconut_bandwidth_contract_common::msg::InstantiateMsg;
|
use nym_coconut_bandwidth_contract_common::msg::InstantiateMsg;
|
||||||
use validator_client::nyxd::AccountId;
|
use validator_client::nyxd::AccountId;
|
||||||
|
|
||||||
#[derive(Debug, Parser)]
|
#[derive(Debug, Parser)]
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ use clap::Parser;
|
|||||||
use log::{debug, info};
|
use log::{debug, info};
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use coconut_dkg_common::msg::InstantiateMsg;
|
use nym_coconut_dkg_common::msg::InstantiateMsg;
|
||||||
use coconut_dkg_common::types::TimeConfiguration;
|
use nym_coconut_dkg_common::types::TimeConfiguration;
|
||||||
use validator_client::nyxd::AccountId;
|
use validator_client::nyxd::AccountId;
|
||||||
|
|
||||||
#[derive(Debug, Parser)]
|
#[derive(Debug, Parser)]
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use clap::Parser;
|
|||||||
use cosmwasm_std::Decimal;
|
use cosmwasm_std::Decimal;
|
||||||
use cw_utils::{Duration, Threshold};
|
use cw_utils::{Duration, Threshold};
|
||||||
use log::{debug, info};
|
use log::{debug, info};
|
||||||
use multisig_contract_common::msg::InstantiateMsg;
|
use nym_multisig_contract_common::msg::InstantiateMsg;
|
||||||
use validator_client::nyxd::AccountId;
|
use validator_client::nyxd::AccountId;
|
||||||
|
|
||||||
#[derive(Debug, Parser)]
|
#[derive(Debug, Parser)]
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
use crate::context::SigningClient;
|
use crate::context::SigningClient;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use log::{info, warn};
|
use log::{info, warn};
|
||||||
|
use nym_contracts_common::signing::MessageSignature;
|
||||||
use nym_mixnet_contract_common::Coin;
|
use nym_mixnet_contract_common::Coin;
|
||||||
use nym_network_defaults::{DEFAULT_CLIENT_LISTENING_PORT, DEFAULT_MIX_LISTENING_PORT};
|
use nym_network_defaults::{DEFAULT_CLIENT_LISTENING_PORT, DEFAULT_MIX_LISTENING_PORT};
|
||||||
use validator_client::nyxd::traits::MixnetSigningClient;
|
use validator_client::nyxd::traits::MixnetSigningClient;
|
||||||
@@ -14,7 +15,7 @@ pub struct Args {
|
|||||||
pub host: String,
|
pub host: String,
|
||||||
|
|
||||||
#[clap(long)]
|
#[clap(long)]
|
||||||
pub signature: String,
|
pub signature: MessageSignature,
|
||||||
|
|
||||||
#[clap(long)]
|
#[clap(long)]
|
||||||
pub mix_port: Option<u16>,
|
pub mix_port: Option<u16>,
|
||||||
@@ -23,7 +24,7 @@ pub struct Args {
|
|||||||
pub clients_port: Option<u16>,
|
pub clients_port: Option<u16>,
|
||||||
|
|
||||||
#[clap(long)]
|
#[clap(long)]
|
||||||
pub location: Option<String>,
|
pub location: String,
|
||||||
|
|
||||||
#[clap(long)]
|
#[clap(long)]
|
||||||
pub sphinx_key: String,
|
pub sphinx_key: String,
|
||||||
@@ -59,9 +60,7 @@ pub async fn bond_gateway(args: Args, client: SigningClient) {
|
|||||||
host: args.host,
|
host: args.host,
|
||||||
mix_port: args.mix_port.unwrap_or(DEFAULT_MIX_LISTENING_PORT),
|
mix_port: args.mix_port.unwrap_or(DEFAULT_MIX_LISTENING_PORT),
|
||||||
clients_port: args.clients_port.unwrap_or(DEFAULT_CLIENT_LISTENING_PORT),
|
clients_port: args.clients_port.unwrap_or(DEFAULT_CLIENT_LISTENING_PORT),
|
||||||
location: args
|
location: args.location,
|
||||||
.location
|
|
||||||
.unwrap_or_else(|| "secret gateway location".to_owned()),
|
|
||||||
sphinx_key: args.sphinx_key,
|
sphinx_key: args.sphinx_key,
|
||||||
identity_key: args.identity_key,
|
identity_key: args.identity_key,
|
||||||
version: args.version,
|
version: args.version,
|
||||||
|
|||||||
+81
@@ -0,0 +1,81 @@
|
|||||||
|
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
use crate::context::SigningClient;
|
||||||
|
use crate::utils::account_id_to_cw_addr;
|
||||||
|
use clap::Parser;
|
||||||
|
use cosmwasm_std::Coin;
|
||||||
|
use nym_mixnet_contract_common::construct_gateway_bonding_sign_payload;
|
||||||
|
use nym_network_defaults::{DEFAULT_CLIENT_LISTENING_PORT, DEFAULT_MIX_LISTENING_PORT};
|
||||||
|
use validator_client::nyxd::traits::MixnetQueryClient;
|
||||||
|
|
||||||
|
#[derive(Debug, Parser)]
|
||||||
|
pub struct Args {
|
||||||
|
#[clap(long)]
|
||||||
|
pub host: String,
|
||||||
|
|
||||||
|
#[clap(long)]
|
||||||
|
pub mix_port: Option<u16>,
|
||||||
|
|
||||||
|
#[clap(long)]
|
||||||
|
pub clients_port: Option<u16>,
|
||||||
|
|
||||||
|
#[clap(long)]
|
||||||
|
pub location: String,
|
||||||
|
|
||||||
|
#[clap(long)]
|
||||||
|
pub sphinx_key: String,
|
||||||
|
|
||||||
|
#[clap(long)]
|
||||||
|
pub identity_key: String,
|
||||||
|
|
||||||
|
#[clap(long)]
|
||||||
|
pub version: String,
|
||||||
|
|
||||||
|
#[clap(
|
||||||
|
long,
|
||||||
|
help = "bonding amount in current DENOMINATION (so it would be 'unym', rather than 'nym')"
|
||||||
|
)]
|
||||||
|
pub amount: u128,
|
||||||
|
|
||||||
|
/// Indicates whether the gateway is going to get bonded via a vesting account
|
||||||
|
#[arg(long)]
|
||||||
|
pub with_vesting_account: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn create_payload(args: Args, client: SigningClient) {
|
||||||
|
let denom = client.current_chain_details().mix_denom.base.as_str();
|
||||||
|
|
||||||
|
let gateway = nym_mixnet_contract_common::Gateway {
|
||||||
|
host: args.host,
|
||||||
|
mix_port: args.mix_port.unwrap_or(DEFAULT_MIX_LISTENING_PORT),
|
||||||
|
clients_port: args.clients_port.unwrap_or(DEFAULT_CLIENT_LISTENING_PORT),
|
||||||
|
location: args.location,
|
||||||
|
sphinx_key: args.sphinx_key,
|
||||||
|
identity_key: args.identity_key,
|
||||||
|
version: args.version,
|
||||||
|
};
|
||||||
|
|
||||||
|
let coin = Coin::new(args.amount, denom);
|
||||||
|
|
||||||
|
let nonce = match client.get_signing_nonce(client.address()).await {
|
||||||
|
Ok(nonce) => nonce,
|
||||||
|
Err(err) => {
|
||||||
|
eprint!(
|
||||||
|
"failed to query for the signing nonce of {}: {err}",
|
||||||
|
client.address()
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let address = account_id_to_cw_addr(client.address());
|
||||||
|
let proxy = if args.with_vesting_account {
|
||||||
|
Some(account_id_to_cw_addr(client.vesting_contract_address()))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
let payload = construct_gateway_bonding_sign_payload(nonce, address, proxy, coin, gateway);
|
||||||
|
println!("{}", payload.to_base58_string().unwrap())
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
use clap::{Args, Subcommand};
|
use clap::{Args, Subcommand};
|
||||||
|
|
||||||
pub mod bond_gateway;
|
pub mod bond_gateway;
|
||||||
|
pub mod gateway_bonding_sign_payload;
|
||||||
pub mod unbond_gateway;
|
pub mod unbond_gateway;
|
||||||
pub mod vesting_bond_gateway;
|
pub mod vesting_bond_gateway;
|
||||||
pub mod vesting_unbond_gateway;
|
pub mod vesting_unbond_gateway;
|
||||||
@@ -25,4 +26,6 @@ pub enum MixnetOperatorsGatewayCommands {
|
|||||||
VestingBond(vesting_bond_gateway::Args),
|
VestingBond(vesting_bond_gateway::Args),
|
||||||
/// Unbound from a gateway (when originally using locked tokens)
|
/// Unbound from a gateway (when originally using locked tokens)
|
||||||
VestingUnbound(vesting_unbond_gateway::Args),
|
VestingUnbound(vesting_unbond_gateway::Args),
|
||||||
|
/// Create base58-encoded payload required for producing valid bonding signature.
|
||||||
|
CreateGatewayBondingSignPayload(gateway_bonding_sign_payload::Args),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
use crate::context::SigningClient;
|
use crate::context::SigningClient;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use log::{info, warn};
|
use log::{info, warn};
|
||||||
|
use nym_contracts_common::signing::MessageSignature;
|
||||||
use nym_mixnet_contract_common::{Coin, Gateway};
|
use nym_mixnet_contract_common::{Coin, Gateway};
|
||||||
use nym_network_defaults::{DEFAULT_CLIENT_LISTENING_PORT, DEFAULT_MIX_LISTENING_PORT};
|
use nym_network_defaults::{DEFAULT_CLIENT_LISTENING_PORT, DEFAULT_MIX_LISTENING_PORT};
|
||||||
use validator_client::nyxd::VestingSigningClient;
|
use validator_client::nyxd::VestingSigningClient;
|
||||||
@@ -14,7 +15,7 @@ pub struct Args {
|
|||||||
pub host: String,
|
pub host: String,
|
||||||
|
|
||||||
#[clap(long)]
|
#[clap(long)]
|
||||||
pub signature: String,
|
pub signature: MessageSignature,
|
||||||
|
|
||||||
#[clap(long)]
|
#[clap(long)]
|
||||||
pub mix_port: Option<u16>,
|
pub mix_port: Option<u16>,
|
||||||
@@ -23,7 +24,7 @@ pub struct Args {
|
|||||||
pub clients_port: Option<u16>,
|
pub clients_port: Option<u16>,
|
||||||
|
|
||||||
#[clap(long)]
|
#[clap(long)]
|
||||||
pub location: Option<String>,
|
pub location: String,
|
||||||
|
|
||||||
#[clap(long)]
|
#[clap(long)]
|
||||||
pub sphinx_key: String,
|
pub sphinx_key: String,
|
||||||
@@ -57,9 +58,7 @@ pub async fn vesting_bond_gateway(client: SigningClient, args: Args, denom: &str
|
|||||||
host: args.host,
|
host: args.host,
|
||||||
mix_port: args.mix_port.unwrap_or(DEFAULT_MIX_LISTENING_PORT),
|
mix_port: args.mix_port.unwrap_or(DEFAULT_MIX_LISTENING_PORT),
|
||||||
clients_port: args.clients_port.unwrap_or(DEFAULT_CLIENT_LISTENING_PORT),
|
clients_port: args.clients_port.unwrap_or(DEFAULT_CLIENT_LISTENING_PORT),
|
||||||
location: args
|
location: args.location,
|
||||||
.location
|
|
||||||
.unwrap_or_else(|| "secret gateway location".to_owned()),
|
|
||||||
sphinx_key: args.sphinx_key,
|
sphinx_key: args.sphinx_key,
|
||||||
identity_key: args.identity_key,
|
identity_key: args.identity_key,
|
||||||
version: args.version,
|
version: args.version,
|
||||||
@@ -68,7 +67,7 @@ pub async fn vesting_bond_gateway(client: SigningClient, args: Args, denom: &str
|
|||||||
let coin = Coin::new(args.amount, denom);
|
let coin = Coin::new(args.amount, denom);
|
||||||
|
|
||||||
let res = client
|
let res = client
|
||||||
.vesting_bond_gateway(gateway, &args.signature, coin.into(), None)
|
.vesting_bond_gateway(gateway, args.signature, coin.into(), None)
|
||||||
.await
|
.await
|
||||||
.expect("failed to bond gateway!");
|
.expect("failed to bond gateway!");
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ use clap::Parser;
|
|||||||
use cosmwasm_std::Uint128;
|
use cosmwasm_std::Uint128;
|
||||||
use log::{info, warn};
|
use log::{info, warn};
|
||||||
|
|
||||||
|
use nym_contracts_common::signing::MessageSignature;
|
||||||
use nym_mixnet_contract_common::{Coin, MixNodeCostParams, Percent};
|
use nym_mixnet_contract_common::{Coin, MixNodeCostParams, Percent};
|
||||||
use nym_network_defaults::{
|
use nym_network_defaults::{
|
||||||
DEFAULT_HTTP_API_LISTENING_PORT, DEFAULT_MIX_LISTENING_PORT, DEFAULT_VERLOC_LISTENING_PORT,
|
DEFAULT_HTTP_API_LISTENING_PORT, DEFAULT_MIX_LISTENING_PORT, DEFAULT_VERLOC_LISTENING_PORT,
|
||||||
@@ -20,7 +21,7 @@ pub struct Args {
|
|||||||
pub host: String,
|
pub host: String,
|
||||||
|
|
||||||
#[clap(long)]
|
#[clap(long)]
|
||||||
pub signature: String,
|
pub signature: MessageSignature,
|
||||||
|
|
||||||
#[clap(long)]
|
#[clap(long)]
|
||||||
pub mix_port: Option<u16>,
|
pub mix_port: Option<u16>,
|
||||||
|
|||||||
+108
@@ -0,0 +1,108 @@
|
|||||||
|
// Copyright 2023 - Nym Technologies SA <contact@nymtech.net>
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
use crate::context::SigningClient;
|
||||||
|
use crate::utils::account_id_to_cw_addr;
|
||||||
|
use clap::Parser;
|
||||||
|
use cosmwasm_std::{Coin, Uint128};
|
||||||
|
use nym_contracts_common::Percent;
|
||||||
|
use nym_mixnet_contract_common::{construct_mixnode_bonding_sign_payload, MixNodeCostParams};
|
||||||
|
use nym_network_defaults::{
|
||||||
|
DEFAULT_HTTP_API_LISTENING_PORT, DEFAULT_MIX_LISTENING_PORT, DEFAULT_VERLOC_LISTENING_PORT,
|
||||||
|
};
|
||||||
|
use validator_client::nyxd::traits::MixnetQueryClient;
|
||||||
|
use validator_client::nyxd::CosmWasmCoin;
|
||||||
|
|
||||||
|
#[derive(Debug, Parser)]
|
||||||
|
pub struct Args {
|
||||||
|
#[clap(long)]
|
||||||
|
pub host: String,
|
||||||
|
|
||||||
|
#[clap(long)]
|
||||||
|
pub mix_port: Option<u16>,
|
||||||
|
|
||||||
|
#[clap(long)]
|
||||||
|
pub verloc_port: Option<u16>,
|
||||||
|
|
||||||
|
#[clap(long)]
|
||||||
|
pub http_api_port: Option<u16>,
|
||||||
|
|
||||||
|
#[clap(long)]
|
||||||
|
pub sphinx_key: String,
|
||||||
|
|
||||||
|
#[clap(long)]
|
||||||
|
pub identity_key: String,
|
||||||
|
|
||||||
|
#[clap(long)]
|
||||||
|
pub version: String,
|
||||||
|
|
||||||
|
#[clap(long)]
|
||||||
|
pub profit_margin_percent: Option<u8>,
|
||||||
|
|
||||||
|
#[clap(
|
||||||
|
long,
|
||||||
|
help = "operating cost in current DENOMINATION (so it would be 'unym', rather than 'nym')"
|
||||||
|
)]
|
||||||
|
pub interval_operating_cost: Option<u128>,
|
||||||
|
|
||||||
|
#[clap(
|
||||||
|
long,
|
||||||
|
help = "bonding amount in current DENOMINATION (so it would be 'unym', rather than 'nym')"
|
||||||
|
)]
|
||||||
|
pub amount: u128,
|
||||||
|
|
||||||
|
/// Indicates whether the mixnode is going to get bonded via a vesting account
|
||||||
|
#[arg(long)]
|
||||||
|
pub with_vesting_account: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn create_payload(args: Args, client: SigningClient) {
|
||||||
|
let denom = client.current_chain_details().mix_denom.base.as_str();
|
||||||
|
|
||||||
|
let mixnode = nym_mixnet_contract_common::MixNode {
|
||||||
|
host: args.host,
|
||||||
|
mix_port: args.mix_port.unwrap_or(DEFAULT_MIX_LISTENING_PORT),
|
||||||
|
verloc_port: args.verloc_port.unwrap_or(DEFAULT_VERLOC_LISTENING_PORT),
|
||||||
|
http_api_port: args
|
||||||
|
.http_api_port
|
||||||
|
.unwrap_or(DEFAULT_HTTP_API_LISTENING_PORT),
|
||||||
|
sphinx_key: args.sphinx_key,
|
||||||
|
identity_key: args.identity_key,
|
||||||
|
version: args.version,
|
||||||
|
};
|
||||||
|
|
||||||
|
let coin = Coin::new(args.amount, denom);
|
||||||
|
|
||||||
|
let cost_params = MixNodeCostParams {
|
||||||
|
profit_margin_percent: Percent::from_percentage_value(
|
||||||
|
args.profit_margin_percent.unwrap_or(10) as u64,
|
||||||
|
)
|
||||||
|
.unwrap(),
|
||||||
|
interval_operating_cost: CosmWasmCoin {
|
||||||
|
denom: denom.into(),
|
||||||
|
amount: Uint128::new(args.interval_operating_cost.unwrap_or(40_000_000)),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
let nonce = match client.get_signing_nonce(client.address()).await {
|
||||||
|
Ok(nonce) => nonce,
|
||||||
|
Err(err) => {
|
||||||
|
eprint!(
|
||||||
|
"failed to query for the signing nonce of {}: {err}",
|
||||||
|
client.address()
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let address = account_id_to_cw_addr(client.address());
|
||||||
|
let proxy = if args.with_vesting_account {
|
||||||
|
Some(account_id_to_cw_addr(client.vesting_contract_address()))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
let payload =
|
||||||
|
construct_mixnode_bonding_sign_payload(nonce, address, proxy, coin, mixnode, cost_params);
|
||||||
|
println!("{}", payload.to_base58_string().unwrap())
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@ use clap::{Args, Subcommand};
|
|||||||
|
|
||||||
pub mod bond_mixnode;
|
pub mod bond_mixnode;
|
||||||
pub mod keys;
|
pub mod keys;
|
||||||
|
pub mod mixnode_bonding_sign_payload;
|
||||||
pub mod rewards;
|
pub mod rewards;
|
||||||
pub mod settings;
|
pub mod settings;
|
||||||
pub mod unbond_mixnode;
|
pub mod unbond_mixnode;
|
||||||
@@ -34,4 +35,6 @@ pub enum MixnetOperatorsMixnodeCommands {
|
|||||||
BondVesting(vesting_bond_mixnode::Args),
|
BondVesting(vesting_bond_mixnode::Args),
|
||||||
/// Unbound from a mixnode (when originally using locked tokens)
|
/// Unbound from a mixnode (when originally using locked tokens)
|
||||||
UnboundVesting(vesting_unbond_mixnode::Args),
|
UnboundVesting(vesting_unbond_mixnode::Args),
|
||||||
|
/// Create base58-encoded payload required for producing valid bonding signature.
|
||||||
|
CreateMixnodeBondingSignPayload(mixnode_bonding_sign_payload::Args),
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user