diff --git a/nym-wallet/src-tauri/Cargo.toml b/nym-wallet/src-tauri/Cargo.toml index 8b2da3c711..7d122b7f27 100644 --- a/nym-wallet/src-tauri/Cargo.toml +++ b/nym-wallet/src-tauri/Cargo.toml @@ -24,7 +24,7 @@ dirs = "4.0" bip39 = "1.0" thiserror = "1.0" tendermint-rpc = "0.23.0" -url = "2.0" +url = "2.2" rand = "0.6.5" eyre = "0.6.5" diff --git a/nym-wallet/src-tauri/src/coin.rs b/nym-wallet/src-tauri/src/coin.rs index ecfe2faa4f..5df1d9532b 100644 --- a/nym-wallet/src-tauri/src/coin.rs +++ b/nym-wallet/src-tauri/src/coin.rs @@ -46,6 +46,14 @@ impl FromStr for Denom { } } +impl TryFrom for Denom { + type Error = BackendError; + + fn try_from(value: CosmosDenom) -> Result { + Denom::from_str(&value.to_string()) + } +} + #[cfg_attr(test, derive(ts_rs::TS))] #[derive(Serialize, Deserialize, Clone, PartialEq, Debug)] pub struct Coin { diff --git a/nym-wallet/src-tauri/src/config/mod.rs b/nym-wallet/src-tauri/src/config/mod.rs index 90fbf670fa..a5107fe393 100644 --- a/nym-wallet/src-tauri/src/config/mod.rs +++ b/nym-wallet/src-tauri/src/config/mod.rs @@ -5,15 +5,12 @@ use config::defaults::{default_validators, ValidatorDetails, DEFAULT_MIXNET_CONT use config::NymConfig; use serde::{Deserialize, Serialize}; use std::path::PathBuf; -use std::str::FromStr; -use tendermint_rpc::Url; +use url::Url; mod template; use template::config_template; -use crate::error::BackendError; - #[derive(Debug, Default, Deserialize, Serialize, Clone)] #[serde(deny_unknown_fields)] pub struct Config { @@ -68,23 +65,33 @@ impl NymConfig for Config { } impl Config { - pub fn get_nymd_validator_url(&self) -> Result { + pub fn get_nymd_validator_url(&self) -> Url { // TODO make this a random choice if let Some(validator_details) = self.base.validators.first() { - match tendermint_rpc::Url::from_str(&validator_details.nymd_url().to_string()) { - Ok(url) => Ok(url), - Err(e) => Err(e.into()), - } + 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_validator_api_url(&self) -> Url { + // TODO make this a random choice + if let Some(validator_details) = self.base.validators.first() { + validator_details.api_url().expect("no api url provided") + } else { + panic!("No validators found in config") + } } - // pub fn get_mnemonic(&self) -> String { - // self.base.mnemonic.clone() - // } + pub fn get_mixnet_contract_address(&self) -> cosmrs::AccountId { + self + .base + .mixnet_contract_address + .parse() + .expect("stored mixnet contract address is not a valid account address") + } + + pub fn get_vesting_contract_address(&self) -> Option { + None + } } diff --git a/nym-wallet/src-tauri/src/main.rs b/nym-wallet/src-tauri/src/main.rs index a52b9a4a91..c0c89b1a21 100644 --- a/nym-wallet/src-tauri/src/main.rs +++ b/nym-wallet/src-tauri/src/main.rs @@ -43,7 +43,7 @@ fn main() { mixnet::delegate::get_reverse_mix_delegations_paged, mixnet::delegate::undelegate_from_mixnode, mixnet::send::send, - utils::get_approximate_fee, + utils::outdated_get_approximate_fee, utils::major_to_minor, utils::minor_to_major, utils::owns_gateway, diff --git a/nym-wallet/src-tauri/src/operations/mixnet/account.rs b/nym-wallet/src-tauri/src/operations/mixnet/account.rs index 5824b355a7..320f84e4d4 100644 --- a/nym-wallet/src-tauri/src/operations/mixnet/account.rs +++ b/nym-wallet/src-tauri/src/operations/mixnet/account.rs @@ -1,14 +1,16 @@ -use crate::client; use crate::coin::{Coin, Denom}; use crate::config::Config; use crate::error::BackendError; +use crate::nymd_client; use crate::state::State; use bip39::{Language, Mnemonic}; use serde::{Deserialize, Serialize}; +use std::convert::TryInto; use std::str::FromStr; use std::sync::Arc; use tokio::sync::RwLock; -use validator_client::nymd::{AccountId, NymdClient, SigningNymdClient}; +use validator_client::nymd::SigningNymdClient; +use validator_client::Client; #[cfg_attr(test, derive(ts_rs::TS))] #[derive(Serialize, Deserialize)] @@ -37,14 +39,14 @@ pub async fn connect_with_mnemonic( _connect_with_mnemonic(mnemonic, &r_state.config()) }; - let contract_address = client.mixnet_contract_address()?.to_string(); - let client_address = client.address().to_string(); - let denom = client.denom()?; + let contract_address = client.nymd.mixnet_contract_address()?.to_string(); + let client_address = client.nymd.address().to_string(); + let denom = client.nymd.denom()?; let account = Account { contract_address, client_address, - denom: Denom::from_str(&denom.to_string())?, + denom: denom.try_into()?, mnemonic: None, }; @@ -58,8 +60,8 @@ pub async fn connect_with_mnemonic( pub async fn get_balance( state: tauri::State<'_, Arc>>, ) -> Result { - match client!(state) - .get_mixnet_balance(client!(state).address()) + match nymd_client!(state) + .get_mixnet_balance(nymd_client!(state).address()) .await { Ok(Some(coin)) => { @@ -73,7 +75,7 @@ pub async fn get_balance( }) } Ok(None) => Err(BackendError::NoBalance( - client!(state).address().to_string(), + nymd_client!(state).address().to_string(), )), Err(e) => Err(BackendError::from(e)), } @@ -94,13 +96,15 @@ fn random_mnemonic() -> Mnemonic { Mnemonic::generate_in_with(&mut rng, Language::English, 24).unwrap() } -fn _connect_with_mnemonic(mnemonic: Mnemonic, config: &Config) -> NymdClient { - match NymdClient::connect_with_mnemonic( - config.get_nymd_validator_url().unwrap(), - Some(AccountId::from_str(&config.get_mixnet_contract_address()).unwrap()), - None, +fn _connect_with_mnemonic(mnemonic: Mnemonic, config: &Config) -> Client { + match validator_client::Client::new_signing( + validator_client::Config::new( + config.get_nymd_validator_url(), + config.get_validator_api_url(), + Some(config.get_mixnet_contract_address()), + config.get_vesting_contract_address(), + ), mnemonic, - None, ) { Ok(client) => client, Err(e) => panic!("{}", e), diff --git a/nym-wallet/src-tauri/src/operations/mixnet/admin.rs b/nym-wallet/src-tauri/src/operations/mixnet/admin.rs index 961a57b4e7..4413ea1efc 100644 --- a/nym-wallet/src-tauri/src/operations/mixnet/admin.rs +++ b/nym-wallet/src-tauri/src/operations/mixnet/admin.rs @@ -1,5 +1,5 @@ -use crate::client; use crate::error::BackendError; +use crate::nymd_client; use crate::state::State; use cosmwasm_std::Uint128; use mixnet_contract::ContractStateParams; @@ -48,7 +48,7 @@ impl TryFrom for ContractStateParams { pub async fn get_contract_settings( state: tauri::State<'_, Arc>>, ) -> Result { - Ok(client!(state).get_contract_settings().await?.into()) + Ok(nymd_client!(state).get_contract_settings().await?.into()) } #[tauri::command] @@ -57,7 +57,7 @@ pub async fn update_contract_settings( state: tauri::State<'_, Arc>>, ) -> Result { let mixnet_contract_settings_params: ContractStateParams = params.try_into()?; - client!(state) + nymd_client!(state) .update_contract_settings(mixnet_contract_settings_params.clone()) .await?; Ok(mixnet_contract_settings_params.into()) diff --git a/nym-wallet/src-tauri/src/operations/mixnet/bond.rs b/nym-wallet/src-tauri/src/operations/mixnet/bond.rs index fce6c4219a..c7da0fa4d5 100644 --- a/nym-wallet/src-tauri/src/operations/mixnet/bond.rs +++ b/nym-wallet/src-tauri/src/operations/mixnet/bond.rs @@ -1,6 +1,6 @@ -use crate::client; use crate::coin::Coin; use crate::error::BackendError; +use crate::nymd_client; use crate::state::State; use crate::{Gateway, MixNode}; use mixnet_contract::{GatewayBond, MixNodeBond}; @@ -15,7 +15,7 @@ pub async fn bond_gateway( owner_signature: String, state: tauri::State<'_, Arc>>, ) -> Result<(), BackendError> { - client!(state) + nymd_client!(state) .bond_gateway(gateway, owner_signature, pledge.try_into()?) .await?; Ok(()) @@ -25,7 +25,7 @@ pub async fn bond_gateway( pub async fn unbond_gateway( state: tauri::State<'_, Arc>>, ) -> Result<(), BackendError> { - client!(state).unbond_gateway().await?; + nymd_client!(state).unbond_gateway().await?; Ok(()) } @@ -33,7 +33,7 @@ pub async fn unbond_gateway( pub async fn unbond_mixnode( state: tauri::State<'_, Arc>>, ) -> Result<(), BackendError> { - client!(state).unbond_mixnode().await?; + nymd_client!(state).unbond_mixnode().await?; Ok(()) } @@ -44,7 +44,7 @@ pub async fn bond_mixnode( pledge: Coin, state: tauri::State<'_, Arc>>, ) -> Result<(), BackendError> { - client!(state) + nymd_client!(state) .bond_mixnode(mixnode, owner_signature, pledge.try_into()?) .await?; Ok(()) @@ -55,7 +55,7 @@ pub async fn update_mixnode( profit_margin_percent: u8, state: tauri::State<'_, Arc>>, ) -> Result<(), BackendError> { - client!(state) + nymd_client!(state) .update_mixnode_config(profit_margin_percent) .await?; Ok(()) @@ -67,7 +67,7 @@ pub async fn mixnode_bond_details( ) -> Result, BackendError> { let guard = state.read().await; let client = guard.client()?; - let bond = client.owns_mixnode(client.address()).await?; + let bond = client.nymd.owns_mixnode(client.nymd.address()).await?; Ok(bond) } @@ -77,6 +77,6 @@ pub async fn gateway_bond_details( ) -> Result, BackendError> { let guard = state.read().await; let client = guard.client()?; - let bond = client.owns_gateway(client.address()).await?; + let bond = client.nymd.owns_gateway(client.nymd.address()).await?; Ok(bond) } diff --git a/nym-wallet/src-tauri/src/operations/mixnet/delegate.rs b/nym-wallet/src-tauri/src/operations/mixnet/delegate.rs index 1fb96308e4..842ed3fb59 100644 --- a/nym-wallet/src-tauri/src/operations/mixnet/delegate.rs +++ b/nym-wallet/src-tauri/src/operations/mixnet/delegate.rs @@ -1,6 +1,6 @@ -use crate::client; use crate::coin::Coin; use crate::error::BackendError; +use crate::nymd_client; use crate::state::State; use crate::utils::DelegationResult; use cosmwasm_std::Coin as CosmWasmCoin; @@ -16,11 +16,11 @@ pub async fn delegate_to_mixnode( state: tauri::State<'_, Arc>>, ) -> Result { let delegation: CosmWasmCoin = amount.try_into()?; - client!(state) + nymd_client!(state) .delegate_to_mixnode(identity, &delegation) .await?; Ok(DelegationResult::new( - &client!(state).address().to_string(), + &nymd_client!(state).address().to_string(), identity, Some(delegation.into()), )) @@ -31,9 +31,11 @@ pub async fn undelegate_from_mixnode( identity: &str, state: tauri::State<'_, Arc>>, ) -> Result { - client!(state).remove_mixnode_delegation(identity).await?; + nymd_client!(state) + .remove_mixnode_delegation(identity) + .await?; Ok(DelegationResult::new( - &client!(state).address().to_string(), + &nymd_client!(state).address().to_string(), identity, None, )) @@ -44,8 +46,8 @@ pub async fn get_reverse_mix_delegations_paged( state: tauri::State<'_, Arc>>, ) -> Result { Ok( - client!(state) - .get_delegator_delegations_paged(client!(state).address().to_string(), None, None) + nymd_client!(state) + .get_delegator_delegations_paged(nymd_client!(state).address().to_string(), None, None) .await?, ) } diff --git a/nym-wallet/src-tauri/src/operations/mixnet/send.rs b/nym-wallet/src-tauri/src/operations/mixnet/send.rs index 417aa42177..1176d86227 100644 --- a/nym-wallet/src-tauri/src/operations/mixnet/send.rs +++ b/nym-wallet/src-tauri/src/operations/mixnet/send.rs @@ -1,6 +1,6 @@ -use crate::client; use crate::coin::Coin; use crate::error::BackendError; +use crate::nymd_client; use crate::state::State; use serde::{Deserialize, Serialize}; use std::convert::TryInto; @@ -51,13 +51,13 @@ pub async fn send( ) -> Result { let address = AccountId::from_str(address)?; let cosmos_amount: CosmosCoin = amount.clone().try_into()?; - let result = client!(state) + let result = nymd_client!(state) .send(&address, vec![cosmos_amount], memo) .await?; Ok(TauriTxResult::new( result, TransactionDetails { - from_address: client!(state).address().to_string(), + from_address: nymd_client!(state).address().to_string(), to_address: address.to_string(), amount, }, diff --git a/nym-wallet/src-tauri/src/operations/vesting/bond.rs b/nym-wallet/src-tauri/src/operations/vesting/bond.rs index 58a559b414..8962d9c58c 100644 --- a/nym-wallet/src-tauri/src/operations/vesting/bond.rs +++ b/nym-wallet/src-tauri/src/operations/vesting/bond.rs @@ -1,6 +1,6 @@ -use crate::client; use crate::coin::Coin; use crate::error::BackendError; +use crate::nymd_client; use crate::state::State; use crate::{Gateway, MixNode}; use std::convert::TryInto; @@ -15,7 +15,7 @@ pub async fn vesting_bond_gateway( owner_signature: String, state: tauri::State<'_, Arc>>, ) -> Result<(), BackendError> { - client!(state) + nymd_client!(state) .vesting_bond_gateway(gateway, &owner_signature, pledge.try_into()?) .await?; Ok(()) @@ -25,7 +25,7 @@ pub async fn vesting_bond_gateway( pub async fn vesting_unbond_gateway( state: tauri::State<'_, Arc>>, ) -> Result<(), BackendError> { - client!(state).vesting_unbond_gateway().await?; + nymd_client!(state).vesting_unbond_gateway().await?; Ok(()) } @@ -33,7 +33,7 @@ pub async fn vesting_unbond_gateway( pub async fn vesting_unbond_mixnode( state: tauri::State<'_, Arc>>, ) -> Result<(), BackendError> { - client!(state).vesting_unbond_mixnode().await?; + nymd_client!(state).vesting_unbond_mixnode().await?; Ok(()) } @@ -44,7 +44,7 @@ pub async fn vesting_bond_mixnode( pledge: Coin, state: tauri::State<'_, Arc>>, ) -> Result<(), BackendError> { - client!(state) + nymd_client!(state) .vesting_bond_mixnode(mixnode, &owner_signature, pledge.try_into()?) .await?; Ok(()) diff --git a/nym-wallet/src-tauri/src/operations/vesting/delegate.rs b/nym-wallet/src-tauri/src/operations/vesting/delegate.rs index ed7bb14135..c807ce2297 100644 --- a/nym-wallet/src-tauri/src/operations/vesting/delegate.rs +++ b/nym-wallet/src-tauri/src/operations/vesting/delegate.rs @@ -1,6 +1,6 @@ -use crate::client; use crate::coin::Coin; use crate::error::BackendError; +use crate::nymd_client; use crate::state::State; use crate::utils::DelegationResult; use cosmwasm_std::Coin as CosmWasmCoin; @@ -16,11 +16,11 @@ pub async fn vesting_delegate_to_mixnode( state: tauri::State<'_, Arc>>, ) -> Result { let delegation: CosmWasmCoin = amount.try_into()?; - client!(state) + nymd_client!(state) .vesting_delegate_to_mixnode(identity, &delegation) .await?; Ok(DelegationResult::new( - &client!(state).address().to_string(), + &nymd_client!(state).address().to_string(), identity, Some(delegation.into()), )) @@ -31,11 +31,11 @@ pub async fn vesting_undelegate_from_mixnode( identity: &str, state: tauri::State<'_, Arc>>, ) -> Result { - client!(state) + nymd_client!(state) .vesting_undelegate_from_mixnode(identity) .await?; Ok(DelegationResult::new( - &client!(state).address().to_string(), + &nymd_client!(state).address().to_string(), identity, None, )) diff --git a/nym-wallet/src-tauri/src/operations/vesting/queries.rs b/nym-wallet/src-tauri/src/operations/vesting/queries.rs index 3512ce8a9d..be6e68d663 100644 --- a/nym-wallet/src-tauri/src/operations/vesting/queries.rs +++ b/nym-wallet/src-tauri/src/operations/vesting/queries.rs @@ -1,6 +1,6 @@ -use crate::client; use crate::coin::Coin; use crate::error::BackendError; +use crate::nymd_client; use crate::state::State; use cosmwasm_std::Timestamp; use std::sync::Arc; @@ -14,7 +14,7 @@ pub async fn locked_coins( state: tauri::State<'_, Arc>>, ) -> Result { Ok( - client!(state) + nymd_client!(state) .locked_coins(address, block_time.map(Timestamp::from_seconds)) .await? .into(), @@ -28,7 +28,7 @@ pub async fn spendable_coins( state: tauri::State<'_, Arc>>, ) -> Result { Ok( - client!(state) + nymd_client!(state) .spendable_coins( vesting_account_address, block_time.map(Timestamp::from_seconds), @@ -45,7 +45,7 @@ pub async fn vested_coins( state: tauri::State<'_, Arc>>, ) -> Result { Ok( - client!(state) + nymd_client!(state) .vested_coins( vesting_account_address, block_time.map(Timestamp::from_seconds), @@ -62,7 +62,7 @@ pub async fn vesting_coins( state: tauri::State<'_, Arc>>, ) -> Result { Ok( - client!(state) + nymd_client!(state) .vesting_coins( vesting_account_address, block_time.map(Timestamp::from_seconds), @@ -78,7 +78,7 @@ pub async fn vesting_start_time( state: tauri::State<'_, Arc>>, ) -> Result { Ok( - client!(state) + nymd_client!(state) .vesting_start_time(vesting_account_address) .await? .seconds(), @@ -91,7 +91,7 @@ pub async fn vesting_end_time( state: tauri::State<'_, Arc>>, ) -> Result { Ok( - client!(state) + nymd_client!(state) .vesting_end_time(vesting_account_address) .await? .seconds(), @@ -104,7 +104,7 @@ pub async fn original_vesting( state: tauri::State<'_, Arc>>, ) -> Result { Ok( - client!(state) + nymd_client!(state) .original_vesting(vesting_account_address) .await? .into(), @@ -118,7 +118,7 @@ pub async fn delegated_free( state: tauri::State<'_, Arc>>, ) -> Result { Ok( - client!(state) + nymd_client!(state) .delegated_free( vesting_account_address, block_time.map(Timestamp::from_seconds), @@ -135,7 +135,7 @@ pub async fn delegated_vesting( state: tauri::State<'_, Arc>>, ) -> Result { Ok( - client!(state) + nymd_client!(state) .delegated_vesting( vesting_account_address, block_time.map(Timestamp::from_seconds), diff --git a/nym-wallet/src-tauri/src/state.rs b/nym-wallet/src-tauri/src/state.rs index 8603d0c592..2b423cf744 100644 --- a/nym-wallet/src-tauri/src/state.rs +++ b/nym-wallet/src-tauri/src/state.rs @@ -1,15 +1,16 @@ use crate::config::Config; use crate::error::BackendError; -use validator_client::nymd::{NymdClient, SigningNymdClient}; +use validator_client::nymd::SigningNymdClient; +use validator_client::Client; #[derive(Default)] pub struct State { config: Config, - signing_client: Option>, + signing_client: Option>, } impl State { - pub fn client(&self) -> Result<&NymdClient, BackendError> { + pub fn client(&self) -> Result<&Client, BackendError> { self .signing_client .as_ref() @@ -20,7 +21,7 @@ impl State { self.config.clone() } - pub fn set_client(&mut self, signing_client: NymdClient) { + pub fn set_client(&mut self, signing_client: Client) { self.signing_client = Some(signing_client) } } @@ -31,3 +32,17 @@ macro_rules! client { $state.read().await.client()? }; } + +#[macro_export] +macro_rules! nymd_client { + ($state:ident) => { + $state.read().await.client()?.nymd + }; +} + +#[macro_export] +macro_rules! api_client { + ($state:ident) => { + $state.read().await.client()?.validator_api + }; +} diff --git a/nym-wallet/src-tauri/src/utils.rs b/nym-wallet/src-tauri/src/utils.rs index 83b35ae9be..7cb64f91f0 100644 --- a/nym-wallet/src-tauri/src/utils.rs +++ b/nym-wallet/src-tauri/src/utils.rs @@ -1,6 +1,6 @@ -use crate::client; use crate::coin::{Coin, Denom}; use crate::error::BackendError; +use crate::nymd_client; use crate::state::State; use crate::Operation; use serde::{Deserialize, Serialize}; @@ -24,8 +24,8 @@ pub async fn owns_mixnode( state: tauri::State<'_, Arc>>, ) -> Result { Ok( - client!(state) - .owns_mixnode(client!(state).address()) + nymd_client!(state) + .owns_mixnode(nymd_client!(state).address()) .await? .is_some(), ) @@ -36,8 +36,8 @@ pub async fn owns_gateway( state: tauri::State<'_, Arc>>, ) -> Result { Ok( - client!(state) - .owns_gateway(client!(state).address()) + nymd_client!(state) + .owns_gateway(nymd_client!(state).address()) .await? .is_some(), ) @@ -46,11 +46,11 @@ pub async fn owns_gateway( // NOTE: this uses OUTDATED defaults that might have no resemblance with the reality // as for the actual transaction, the gas cost is being simulated beforehand #[tauri::command] -pub async fn get_approximate_fee( +pub async fn outdated_get_approximate_fee( operation: Operation, state: tauri::State<'_, Arc>>, ) -> Result { - let approximate_fee = operation.default_fee(client!(state).gas_price()); + let approximate_fee = operation.default_fee(nymd_client!(state).gas_price()); let mut coin = Coin::new("0", &Denom::Major); for f in approximate_fee.amount { coin = coin + f.into();