Bootstrap nymd client with config

This commit is contained in:
Drazen Urch
2021-08-24 12:54:49 +02:00
parent 3da08ee33c
commit ce75769703
9 changed files with 236 additions and 23 deletions
Generated
+9 -2
View File
@@ -8,10 +8,16 @@ version = 3
name = "Nym-Wallet"
version = "0.1.0"
dependencies = [
"config",
"dirs 3.0.2",
"mixnet-contract",
"serde",
"serde_json",
"tauri",
"tauri-build",
"tokio",
"url",
"validator-client",
]
[[package]]
@@ -3292,6 +3298,7 @@ checksum = "c44922cb3dbb1c70b5e5f443d63b64363a898564d739ba5198e3a9138442868d"
name = "network-defaults"
version = "0.1.0"
dependencies = [
"serde",
"url",
]
@@ -6410,9 +6417,9 @@ dependencies = [
[[package]]
name = "tokio"
version = "1.9.0"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b7b349f11a7047e6d1276853e612d152f5e8a352c61917887cc2169e2366b4c"
checksum = "01cf844b23c6131f624accf65ce0e4e9956a8bb329400ea5bcc26ae3a5c20b0b"
dependencies = [
"autocfg 1.0.1",
"bytes",
+1
View File
@@ -7,4 +7,5 @@ edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
serde = {version = "1.0", features = ["derive"]}
url = "2.2"
+24 -16
View File
@@ -1,19 +1,24 @@
// Copyright 2020 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use serde::{Deserialize, Serialize};
use url::Url;
pub struct ValidatorDetails<'a> {
#[derive(Debug, Serialize, Deserialize)]
pub struct ValidatorDetails {
// it is assumed those values are always valid since they're being provided in our defaults file
pub nymd_url: &'a str,
pub nymd_url: String,
// Right now api_url is optional as we are not running the api reliably on all validators
// however, later on it should be a mandatory field
pub api_url: Option<&'a str>,
pub api_url: Option<String>,
}
impl<'a> ValidatorDetails<'a> {
pub const fn new(nymd_url: &'a str, api_url: Option<&'a str>) -> Self {
ValidatorDetails { nymd_url, api_url }
impl ValidatorDetails {
pub fn new(nymd_url: &str, api_url: Option<&str>) -> Self {
let api_url = api_url.map(|api_url_str| api_url_str.to_string());
ValidatorDetails {
nymd_url: nymd_url.to_string(),
api_url,
}
}
pub fn nymd_url(&self) -> Url {
@@ -24,27 +29,30 @@ impl<'a> ValidatorDetails<'a> {
pub fn api_url(&self) -> Option<Url> {
self.api_url
.as_ref()
.map(|url| url.parse().expect("the provided api url is invalid!"))
}
}
pub const DEFAULT_VALIDATORS: &[ValidatorDetails] = &[
ValidatorDetails::new(
"https://testnet-milhon-validator1.nymtech.net",
Some("https://testnet-milhon-validator1.nymtech.net/api"),
),
ValidatorDetails::new("https://testnet-milhon-validator2.nymtech.net", None),
];
pub fn default_validators() -> Vec<ValidatorDetails> {
vec![
ValidatorDetails::new(
"https://testnet-milhon-validator1.nymtech.net",
Some("https://testnet-milhon-validator1.nymtech.net/api"),
),
ValidatorDetails::new("https://testnet-milhon-validator2.nymtech.net", None),
]
}
pub fn default_nymd_endpoints() -> Vec<Url> {
DEFAULT_VALIDATORS
default_validators()
.iter()
.map(|validator| validator.nymd_url())
.collect()
}
pub fn default_api_endpoints() -> Vec<Url> {
DEFAULT_VALIDATORS
default_validators()
.iter()
.filter_map(|validator| validator.api_url())
.collect()
+11 -2
View File
@@ -18,7 +18,16 @@ tauri-build = { version = "1.0.0-beta.4" }
serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }
tauri = { version = "1.0.0-beta.6", features = ["api-all"] }
tokio = { version = "1.10", features = ["sync"] }
dirs = "3.0"
url = "2.2"
validator-client = { path = "../../common/client-libs/validator-client", features = [
"nymd-client",
] }
mixnet-contract = { path = "../../common/mixnet-contract" }
config = { path = "../../common/config" }
[features]
default = [ "custom-protocol" ]
custom-protocol = [ "tauri/custom-protocol" ]
default = ["custom-protocol"]
custom-protocol = ["tauri/custom-protocol"]
+90
View File
@@ -0,0 +1,90 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use config::defaults::{
default_api_endpoints, default_validators, ValidatorDetails, DEFAULT_MIXNET_CONTRACT_ADDRESS,
};
use config::NymConfig;
use serde::{Deserialize, Serialize};
use std::path::PathBuf;
use url::Url;
mod template;
use template::config_template;
#[derive(Debug, Default, Deserialize, Serialize)]
#[serde(deny_unknown_fields)]
pub struct Config {
base: Base,
}
#[derive(Debug, Deserialize, Serialize)]
#[serde(deny_unknown_fields)]
pub struct Base {
validators: Vec<ValidatorDetails>,
/// Address of the validator contract managing the network
mixnet_contract_address: String,
/// Mnemonic (currently of the network monitor) used for rewarding
mnemonic: String,
// Avoid breaking derives for now
keypair_bs58: String,
}
impl Default for Base {
fn default() -> Self {
Base {
validators: default_validators(),
mixnet_contract_address: DEFAULT_MIXNET_CONTRACT_ADDRESS.to_string(),
mnemonic: String::default(),
keypair_bs58: String::default(),
}
}
}
impl NymConfig for Config {
fn template() -> &'static str {
config_template()
}
fn default_root_directory() -> PathBuf {
dirs::home_dir()
.expect("Failed to evaluate $HOME value")
.join(".nym")
.join("wallet")
}
fn root_directory(&self) -> PathBuf {
Self::default_root_directory()
}
fn config_directory(&self) -> PathBuf {
self.root_directory().join("config")
}
fn data_directory(&self) -> PathBuf {
self.root_directory().join("data")
}
}
impl Config {
pub fn get_nymd_validator_url(&self) -> Url {
// TODO make this a random choice
if let Some(validator_details) = self.base.validators.first() {
validator_details.nymd_url()
} else {
panic!("No validators found in config")
}
}
pub fn get_mixnet_contract_address(&self) -> String {
self.base.mixnet_contract_address.clone()
}
pub fn get_mnemonic(&self) -> String {
self.base.mnemonic.clone()
}
}
@@ -0,0 +1,17 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
pub(crate) fn config_template() -> &'static str {
r#"
# This is a TOML config file.
# For more information, see https://github.com/toml-lang/toml
##### main base tauri-wallet config options #####
[base]
# Validator server to which the API will be getting information about the network.
validator_url = '{{ base.validator_url }}'
"#
}
+3
View File
@@ -3,6 +3,9 @@
windows_subsystem = "windows"
)]
mod nymd_client;
mod config;
fn main() {
tauri::Builder::default()
.run(tauri::generate_context!())
+80
View File
@@ -0,0 +1,80 @@
// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
// SPDX-License-Identifier: Apache-2.0
use crate::config::Config;
use config::defaults::DEFAULT_VALIDATOR_API_PORT;
use mixnet_contract::{GatewayBond, MixNodeBond};
use std::sync::Arc;
use tokio::sync::RwLock;
use validator_client::nymd::{CosmWasmClient, QueryNymdClient, SigningNymdClient};
use validator_client::ValidatorClientError;
#[derive(Clone)]
pub(crate) struct Client<C>(Arc<RwLock<validator_client::Client<C>>>);
impl Client<QueryNymdClient> {
pub(crate) fn new_query(config: &Config) -> Self {
// the api address is irrelevant here as **WE ARE THE API**
let api_url = format!("http://localhost:{}", DEFAULT_VALIDATOR_API_PORT)
.parse()
.unwrap();
let nymd_url = config.get_nymd_validator_url();
let mixnet_contract = config
.get_mixnet_contract_address()
.parse()
.expect("the mixnet contract address is invalid!");
let client_config = validator_client::Config::new(nymd_url, api_url, Some(mixnet_contract));
let inner =
validator_client::Client::new_query(client_config).expect("Failed to connect to nymd!");
Client(Arc::new(RwLock::new(inner)))
}
}
impl Client<SigningNymdClient> {
pub(crate) fn new_signing(config: &Config) -> Self {
// the api address is irrelevant here as **WE ARE THE API**
let api_url = format!("http://localhost:{}", DEFAULT_VALIDATOR_API_PORT)
.parse()
.unwrap();
let nymd_url = config.get_nymd_validator_url();
let mixnet_contract = config
.get_mixnet_contract_address()
.parse()
.expect("the mixnet contract address is invalid!");
let mnemonic = config
.get_mnemonic()
.parse()
.expect("the mnemonic is invalid!");
let client_config = validator_client::Config::new(nymd_url, api_url, Some(mixnet_contract));
let inner = validator_client::Client::new_signing(client_config, mnemonic)
.expect("Failed to connect to nymd!");
Client(Arc::new(RwLock::new(inner)))
}
}
impl<C> Client<C> {
pub(crate) async fn get_mixnodes(&self) -> Result<Vec<MixNodeBond>, ValidatorClientError>
where
C: CosmWasmClient + Sync,
{
self.0.read().await.get_all_nymd_mixnodes().await
}
pub(crate) async fn get_gateways(&self) -> Result<Vec<GatewayBond>, ValidatorClientError>
where
C: CosmWasmClient + Sync,
{
self.0.read().await.get_all_nymd_gateways().await
}
#[allow(dead_code)]
pub(crate) async fn some_rewarding_stuff_here(&self) {
todo!()
}
}
+1 -3
View File
@@ -48,9 +48,7 @@
"updater": {
"active": false
},
"allowlist": {
"all": true
},
"allowlist": {},
"windows": [
{
"title": "nym-wallet",