From 18837220f42fa9197fa500151c76e7eb6416f5f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= Date: Tue, 1 Mar 2022 12:20:27 +0100 Subject: [PATCH] Make wallet denom dynamic Making denom dynamic enables coin transfers on other nets than the default sandbox net, such as mainnet. --- Cargo.lock | 3 +- .../src/nymd/cosmwasm_client/mod.rs | 2 +- .../nymd/cosmwasm_client/signing_client.rs | 4 +- .../src/nymd/fee/gas_price.rs | 11 +- .../validator-client/src/nymd/mod.rs | 18 +- .../validator-client/src/nymd/wallet/mod.rs | 20 +- common/network-defaults/Cargo.toml | 1 + common/network-defaults/src/all.rs | 43 +++- contracts/Cargo.lock | 1 + nym-wallet/Cargo.lock | 1 + nym-wallet/src-tauri/src/coin.rs | 200 +++++++++++++----- nym-wallet/src-tauri/src/error.rs | 2 + .../src-tauri/src/operations/mixnet/bond.rs | 9 +- .../src/operations/mixnet/delegate.rs | 4 +- .../src-tauri/src/operations/mixnet/send.rs | 4 +- .../src-tauri/src/operations/vesting/bond.rs | 15 +- .../src/operations/vesting/delegate.rs | 5 +- 17 files changed, 238 insertions(+), 105 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4c13b838d6..aaba6879b6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3669,6 +3669,7 @@ dependencies = [ "cfg-if 1.0.0", "hex-literal", "serde", + "thiserror", "url", ] @@ -8248,4 +8249,4 @@ checksum = "615120c7a2431d16cf1cf979e7fc31ba7a5b5e5707b29c8a99e5dbf8a8392a33" dependencies = [ "cc", "libc", -] \ No newline at end of file +] diff --git a/common/client-libs/validator-client/src/nymd/cosmwasm_client/mod.rs b/common/client-libs/validator-client/src/nymd/cosmwasm_client/mod.rs index 4b2e55df42..fcc92bb893 100644 --- a/common/client-libs/validator-client/src/nymd/cosmwasm_client/mod.rs +++ b/common/client-libs/validator-client/src/nymd/cosmwasm_client/mod.rs @@ -24,7 +24,7 @@ where pub fn connect_with_signer( endpoint: U, signer: DirectSecp256k1HdWallet, - gas_price: Option, + gas_price: GasPrice, ) -> Result where U: TryInto, diff --git a/common/client-libs/validator-client/src/nymd/cosmwasm_client/signing_client.rs b/common/client-libs/validator-client/src/nymd/cosmwasm_client/signing_client.rs index 53067c6690..42d62971a9 100644 --- a/common/client-libs/validator-client/src/nymd/cosmwasm_client/signing_client.rs +++ b/common/client-libs/validator-client/src/nymd/cosmwasm_client/signing_client.rs @@ -644,7 +644,7 @@ impl Client { pub fn connect_with_signer( endpoint: U, signer: DirectSecp256k1HdWallet, - gas_price: Option, + gas_price: GasPrice, ) -> Result where U: TryInto, @@ -653,7 +653,7 @@ impl Client { Ok(Client { rpc_client, signer, - gas_price: gas_price.unwrap_or_default(), + gas_price, }) } } diff --git a/common/client-libs/validator-client/src/nymd/fee/gas_price.rs b/common/client-libs/validator-client/src/nymd/fee/gas_price.rs index 1924454ddf..72e2b23a2c 100644 --- a/common/client-libs/validator-client/src/nymd/fee/gas_price.rs +++ b/common/client-libs/validator-client/src/nymd/fee/gas_price.rs @@ -71,11 +71,9 @@ impl FromStr for GasPrice { } } -impl Default for GasPrice { - fn default() -> Self { - format!("{}{}", defaults::GAS_PRICE_AMOUNT, defaults::DENOM) - .parse() - .unwrap() +impl GasPrice { + pub fn new_with_default_price(denom: String) -> Result { + format!("{}{}", defaults::GAS_PRICE_AMOUNT, denom).parse() } } @@ -85,7 +83,8 @@ mod tests { #[test] fn default_gas_price_is_valid() { - let _ = GasPrice::default(); + let denom = "unym".parse().unwrap(); + let _ = GasPrice::new_with_default_price(denom); } #[test] diff --git a/common/client-libs/validator-client/src/nymd/mod.rs b/common/client-libs/validator-client/src/nymd/mod.rs index 9ae0fd863e..71b95fbdec 100644 --- a/common/client-libs/validator-client/src/nymd/mod.rs +++ b/common/client-libs/validator-client/src/nymd/mod.rs @@ -74,7 +74,7 @@ impl NymdClient { vesting_contract_address, erc20_bridge_contract_address, client_address: None, - custom_gas_limits: Default::default(), + custom_gas_limits: HashMap::default(), simulated_gas_multiplier: DEFAULT_SIMULATED_GAS_MULTIPLIER, }) } @@ -83,6 +83,7 @@ impl NymdClient { impl NymdClient { // maybe the wallet could be made into a generic, but for now, let's just have this one implementation pub fn connect_with_signer( + network: config::defaults::all::Network, endpoint: U, mixnet_contract_address: Option, vesting_contract_address: Option, @@ -93,11 +94,13 @@ impl NymdClient { where U: TryInto, { + let denom = network.denom(); let client_address = signer .try_derive_accounts()? .into_iter() .map(|account| account.address) .collect(); + let gas_price = gas_price.unwrap_or(GasPrice::new_with_default_price(denom)?); Ok(NymdClient { client: SigningNymdClient::connect_with_signer(endpoint, signer, gas_price)?, @@ -105,7 +108,7 @@ impl NymdClient { vesting_contract_address, erc20_bridge_contract_address, client_address: Some(client_address), - custom_gas_limits: Default::default(), + custom_gas_limits: HashMap::default(), simulated_gas_multiplier: DEFAULT_SIMULATED_GAS_MULTIPLIER, }) } @@ -123,12 +126,14 @@ impl NymdClient { U: TryInto, { let prefix = network.bech32_prefix(); + let denom = network.denom(); let wallet = DirectSecp256k1HdWallet::from_mnemonic(prefix, mnemonic)?; let client_address = wallet .try_derive_accounts()? .into_iter() .map(|account| account.address) .collect(); + let gas_price = gas_price.unwrap_or(GasPrice::new_with_default_price(denom)?); Ok(NymdClient { client: SigningNymdClient::connect_with_signer(endpoint, wallet, gas_price)?, @@ -136,7 +141,7 @@ impl NymdClient { vesting_contract_address, erc20_bridge_contract_address, client_address: Some(client_address), - custom_gas_limits: Default::default(), + custom_gas_limits: HashMap::default(), simulated_gas_multiplier: DEFAULT_SIMULATED_GAS_MULTIPLIER, }) } @@ -161,13 +166,6 @@ impl NymdClient { .ok_or(NymdError::NoContractAddressAvailable) } - // now the question is as follows: will denom always be in the format of `u{prefix}`? - pub fn denom(&self) -> Result { - Ok(format!("u{}", self.mixnet_contract_address()?.prefix()) - .parse() - .unwrap()) - } - pub fn address(&self) -> &AccountId where C: SigningCosmWasmClient, diff --git a/common/client-libs/validator-client/src/nymd/wallet/mod.rs b/common/client-libs/validator-client/src/nymd/wallet/mod.rs index 1cadbde59c..ed4e54e3c3 100644 --- a/common/client-libs/validator-client/src/nymd/wallet/mod.rs +++ b/common/client-libs/validator-client/src/nymd/wallet/mod.rs @@ -57,15 +57,13 @@ pub struct DirectSecp256k1HdWallet { } impl DirectSecp256k1HdWallet { - pub fn builder() -> DirectSecp256k1HdWalletBuilder { - DirectSecp256k1HdWalletBuilder::default() + pub fn builder(prefix: String) -> DirectSecp256k1HdWalletBuilder { + DirectSecp256k1HdWalletBuilder::new(prefix) } /// Restores a wallet from the given BIP39 mnemonic using default options. pub fn from_mnemonic(prefix: String, mnemonic: bip39::Mnemonic) -> Result { - DirectSecp256k1HdWalletBuilder::new() - .with_prefix(prefix) - .build(mnemonic) + DirectSecp256k1HdWalletBuilder::new(prefix).build(mnemonic) } pub fn generate(prefix: String, word_count: usize) -> Result { @@ -147,20 +145,14 @@ pub struct DirectSecp256k1HdWalletBuilder { prefix: String, } -impl Default for DirectSecp256k1HdWalletBuilder { - fn default() -> Self { +impl DirectSecp256k1HdWalletBuilder { + pub fn new(prefix: String) -> Self { DirectSecp256k1HdWalletBuilder { bip39_password: String::new(), hd_paths: vec![defaults::COSMOS_DERIVATION_PATH.parse().unwrap()], - prefix: defaults::BECH32_PREFIX.to_string(), + prefix, } } -} - -impl DirectSecp256k1HdWalletBuilder { - pub fn new() -> Self { - Default::default() - } pub fn with_bip39_password>(mut self, password: S) -> Self { self.bip39_password = password.into(); diff --git a/common/network-defaults/Cargo.toml b/common/network-defaults/Cargo.toml index ec1ee84178..c5127eefd4 100644 --- a/common/network-defaults/Cargo.toml +++ b/common/network-defaults/Cargo.toml @@ -10,4 +10,5 @@ edition = "2021" cfg-if = "1.0.0" hex-literal = "0.3.3" serde = {version = "1.0", features = ["derive"]} +thiserror = "1.0" url = "2.2" diff --git a/common/network-defaults/src/all.rs b/common/network-defaults/src/all.rs index f3e42442b2..624a1170c8 100644 --- a/common/network-defaults/src/all.rs +++ b/common/network-defaults/src/all.rs @@ -2,10 +2,18 @@ // SPDX-License-Identifier: Apache-2.0 use serde::{Deserialize, Serialize}; -use std::collections::HashMap; +use std::{collections::HashMap, fmt, str::FromStr}; use crate::{mainnet, qa, sandbox, ValidatorDetails}; +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum NetworkDefaultsError { + #[error("The provided network was invalid")] + MalformedNetworkProvided(String), +} + #[derive(Copy, Clone, Debug, Deserialize, Eq, Hash, PartialEq, Serialize)] pub enum Network { QA, @@ -21,6 +29,39 @@ impl Network { Self::MAINNET => String::from(mainnet::BECH32_PREFIX), } } + + pub fn denom(&self) -> String { + match self { + Self::QA => String::from(qa::DENOM), + Self::SANDBOX => String::from(sandbox::DENOM), + Self::MAINNET => String::from(mainnet::DENOM), + } + } +} + +impl FromStr for Network { + type Err = NetworkDefaultsError; + + fn from_str(s: &str) -> Result { + match s.to_lowercase().as_str() { + "qa" => Ok(Network::QA), + "sandbox" => Ok(Network::SANDBOX), + "mainnet" => Ok(Network::MAINNET), + _ => Err(NetworkDefaultsError::MalformedNetworkProvided( + s.to_string(), + )), + } + } +} + +impl fmt::Display for Network { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match *self { + Network::QA => f.write_str("QA"), + Network::SANDBOX => f.write_str("Sandbox"), + Network::MAINNET => f.write_str("Mainnet"), + } + } } #[derive(Clone, Debug, Deserialize, Serialize)] diff --git a/contracts/Cargo.lock b/contracts/Cargo.lock index 864a01cdab..de82a710a1 100644 --- a/contracts/Cargo.lock +++ b/contracts/Cargo.lock @@ -882,6 +882,7 @@ dependencies = [ "cfg-if", "hex-literal", "serde", + "thiserror", "url", ] diff --git a/nym-wallet/Cargo.lock b/nym-wallet/Cargo.lock index 2107c8e5b3..7d133aa1ed 100644 --- a/nym-wallet/Cargo.lock +++ b/nym-wallet/Cargo.lock @@ -2767,6 +2767,7 @@ dependencies = [ "cfg-if 1.0.0", "hex-literal", "serde", + "thiserror", "url", ] diff --git a/nym-wallet/src-tauri/src/coin.rs b/nym-wallet/src-tauri/src/coin.rs index 5c27fd737e..5c5a954cbe 100644 --- a/nym-wallet/src-tauri/src/coin.rs +++ b/nym-wallet/src-tauri/src/coin.rs @@ -2,14 +2,12 @@ use crate::error::BackendError; use crate::network::Network; -use ::config::defaults::DENOM; use cosmrs::Decimal; use cosmrs::Denom as CosmosDenom; use cosmwasm_std::Coin as CosmWasmCoin; use cosmwasm_std::Uint128; use serde::{Deserialize, Serialize}; use std::convert::TryFrom; -use std::fmt; use std::ops::{Add, Sub}; use std::str::FromStr; use strum::IntoEnumIterator; @@ -24,15 +22,6 @@ pub enum Denom { const MINOR_IN_MAJOR: f64 = 1_000_000.; -impl fmt::Display for Denom { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match *self { - Denom::Major => f.write_str(&DENOM[1..]), - Denom::Minor => f.write_str(DENOM), - } - } -} - impl FromStr for Denom { type Err = BackendError; @@ -65,19 +54,14 @@ pub struct Coin { denom: Denom, } -// TODO convert to TryFrom -impl From for Coin { - fn from(g: GasPrice) -> Coin { - Coin { - amount: g.amount.to_string(), - denom: Denom::from_str(&g.denom.to_string()).unwrap(), - } - } -} +impl TryFrom for Coin { + type Error = BackendError; -impl fmt::Display for Coin { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - f.write_str(&format!("{} {}", self.amount, self.denom)) + fn try_from(g: GasPrice) -> Result { + Ok(Coin { + amount: g.amount.to_string(), + denom: Denom::from_str(&g.denom.to_string())?, + }) } } @@ -126,6 +110,7 @@ impl Sub for Coin { } impl Coin { + #[allow(unused)] pub fn major(amount: T) -> Coin { Coin { amount: amount.to_string(), @@ -133,6 +118,7 @@ impl Coin { } } + #[allow(unused)] pub fn minor(amount: T) -> Coin { Coin { amount: amount.to_string(), @@ -171,34 +157,45 @@ impl Coin { self.amount.clone() } + #[allow(unused)] pub fn denom(&self) -> Denom { self.denom.clone() } -} -impl TryFrom for CosmWasmCoin { - type Error = BackendError; + // Helper function that returns the local denom in terms of the specified network denom. + fn denom_as_string(&self, network_denom: &CosmosDenom) -> Result { + // Currently there is the widespread assumption that network denomination is always in + // `Denom::Minor`, and starts with 'u'. + let network_denom = network_denom.to_string(); + if !network_denom.starts_with('u') { + return Err(BackendError::InvalidNetworkDenom(network_denom)); + } - fn try_from(coin: Coin) -> Result { - Ok(CosmWasmCoin::new( - Uint128::try_from(coin.amount.as_str()).unwrap().u128(), - coin.denom.to_string(), - )) + Ok(match &self.denom { + Denom::Minor => network_denom, + Denom::Major => network_denom[1..].to_string(), + }) } -} -impl TryFrom for CosmosCoin { - type Error = BackendError; - - fn try_from(coin: Coin) -> Result { - match Decimal::from_str(&coin.amount) { - Ok(d) => Ok(CosmosCoin { - amount: d, - denom: CosmosDenom::from_str(&coin.denom.to_string())?, + pub fn into_cosmos_coin(self, network_denom: &CosmosDenom) -> Result { + match Decimal::from_str(&self.amount) { + Ok(amount) => Ok(CosmosCoin { + amount, + denom: CosmosDenom::from_str(&self.denom_as_string(network_denom)?)?, }), Err(e) => Err(e.into()), } } + + pub fn into_cosmwasm_coin( + self, + network_denom: &CosmosDenom, + ) -> Result { + Ok(CosmWasmCoin { + denom: self.denom_as_string(network_denom)?, + amount: Uint128::try_from(self.amount.as_str())?, + }) + } } impl From for Coin { @@ -221,13 +218,14 @@ impl From for Coin { #[cfg(test)] mod test { - use crate::coin::{Coin, Denom}; + use super::*; + use crate::error::BackendError; use cosmrs::Coin as CosmosCoin; use cosmrs::Decimal; use cosmrs::Denom as CosmosDenom; use cosmwasm_std::Coin as CosmWasmCoin; use serde_json::json; - use std::convert::{TryFrom, TryInto}; + use std::convert::TryFrom; use std::str::FromStr; #[test] @@ -252,6 +250,19 @@ mod test { assert_eq!(major_coin, test_major_coin); } + #[test] + fn denom_from_str() { + assert_eq!(Denom::from_str("unym").unwrap(), Denom::Minor); + assert_eq!(Denom::from_str("nym").unwrap(), Denom::Major); + assert_eq!(Denom::from_str("minor").unwrap(), Denom::Minor); + assert_eq!(Denom::from_str("major").unwrap(), Denom::Major); + + assert!(matches!( + Denom::from_str("foo").unwrap_err(), + BackendError::InvalidDenom { .. }, + )); + } + #[test] fn denom_conversions() { let minor = Coin::minor("1"); @@ -263,6 +274,66 @@ mod test { assert_eq!(minor, Coin::minor("1")); } + #[test] + fn network_denom_is_assumed_to_be_in_minor_denom() { + let network_denom = CosmosDenom::from_str("nym").unwrap(); + assert!(matches!( + Coin::minor("42") + .denom_as_string(&network_denom) + .unwrap_err(), + BackendError::InvalidNetworkDenom { .. } + )); + } + + #[test] + fn local_denom_to_interpreted_using_network_denom() { + let network_denom = CosmosDenom::from_str("unym").unwrap(); + assert_eq!( + Coin::minor("42").denom_as_string(&network_denom).unwrap(), + "unym", + ); + assert_eq!( + Coin::major("42").denom_as_string(&network_denom).unwrap(), + "nym", + ); + } + + #[test] + fn coin_to_coin_minor() { + let network_denom = CosmosDenom::from_str("unym").unwrap(); + let coin = Coin::minor("42"); + + let cosmoswasm_coin = coin.clone().into_cosmwasm_coin(&network_denom).unwrap(); + assert_eq!(cosmoswasm_coin, CosmWasmCoin::new(42, "unym"),); + + let cosmos_coin = coin.into_cosmos_coin(&network_denom).unwrap(); + assert_eq!( + cosmos_coin, + CosmosCoin { + denom: CosmosDenom::from_str("unym").unwrap(), + amount: Decimal::from_str("42").unwrap(), + }, + ); + } + + #[test] + fn coin_to_coin_major() { + let network_denom = CosmosDenom::from_str("unym").unwrap(); + let coin = Coin::major("52"); + + let cosmoswasm_coin = coin.clone().into_cosmwasm_coin(&network_denom).unwrap(); + assert_eq!(cosmoswasm_coin, CosmWasmCoin::new(52, "nym"),); + + let cosmos_coin = coin.into_cosmos_coin(&network_denom).unwrap(); + assert_eq!( + cosmos_coin, + CosmosCoin { + denom: CosmosDenom::from_str("nym").unwrap(), + amount: Decimal::from_str("52").unwrap(), + }, + ); + } + fn amounts() -> Vec<&'static str> { vec![ "1", @@ -288,23 +359,24 @@ mod test { #[test] fn coin_to_cosmoswasm() { + let network_denom = CosmosDenom::from_str("unym").unwrap(); for amount in amounts() { - let coin: Coin = Coin::minor(amount).into(); - let cosmoswasm_coin: CosmWasmCoin = coin.try_into().unwrap(); + let coin = Coin::minor(amount); + let cosmoswasm_coin: CosmWasmCoin = coin.into_cosmwasm_coin(&network_denom).unwrap(); assert_eq!( cosmoswasm_coin, - CosmWasmCoin::new(amount.parse::().unwrap(), Denom::Minor.to_string()) + CosmWasmCoin::new(amount.parse::().unwrap(), "unym") ); assert_eq!( Coin::try_from(cosmoswasm_coin).unwrap(), Coin::minor(amount) ); - let coin: Coin = Coin::major(amount).into(); - let cosmoswasm_coin: CosmWasmCoin = coin.try_into().unwrap(); + let coin = Coin::major(amount); + let cosmoswasm_coin: CosmWasmCoin = coin.into_cosmwasm_coin(&network_denom).unwrap(); assert_eq!( cosmoswasm_coin, - CosmWasmCoin::new(amount.parse::().unwrap(), Denom::Major.to_string()) + CosmWasmCoin::new(amount.parse::().unwrap(), "nym") ); assert_eq!( Coin::try_from(cosmoswasm_coin).unwrap(), @@ -315,25 +387,26 @@ mod test { #[test] fn coin_to_cosmos() { + let network_denom = CosmosDenom::from_str("unym").unwrap(); for amount in amounts() { - let coin: Coin = Coin::minor(amount).into(); - let cosmos_coin: CosmosCoin = coin.try_into().unwrap(); + let coin = Coin::minor(amount); + let cosmos_coin: CosmosCoin = coin.into_cosmos_coin(&network_denom).unwrap(); assert_eq!( cosmos_coin, CosmosCoin { amount: Decimal::from_str(amount).unwrap(), - denom: CosmosDenom::from_str(&Denom::Minor.to_string()).unwrap() + denom: CosmosDenom::from_str("unym").unwrap() } ); assert_eq!(Coin::try_from(cosmos_coin).unwrap(), Coin::minor(amount)); - let coin: Coin = Coin::major(amount).into(); - let cosmos_coin: CosmosCoin = coin.try_into().unwrap(); + let coin = Coin::major(amount); + let cosmos_coin: CosmosCoin = coin.into_cosmos_coin(&network_denom).unwrap(); assert_eq!( cosmos_coin, CosmosCoin { amount: Decimal::from_str(amount).unwrap(), - denom: CosmosDenom::from_str(&Denom::Major.to_string()).unwrap() + denom: CosmosDenom::from_str("nym").unwrap() } ); assert_eq!(Coin::try_from(cosmos_coin).unwrap(), Coin::major(amount)); @@ -355,4 +428,23 @@ mod test { assert_eq!(Coin::minor("1") - Coin::major("1"), Coin::minor("-999999")); assert_eq!(Coin::major("1") - Coin::minor("1"), Coin::major("0.999999")); } + + #[test] + fn coin_from_gas_price() { + assert_eq!( + Coin::try_from(GasPrice::from_str("42unym").unwrap()).unwrap(), + Coin { + amount: "42".to_string(), + denom: Denom::Minor, + } + ); + + assert_eq!( + Coin::try_from(GasPrice::from_str("42nym").unwrap()).unwrap(), + Coin { + amount: "42".to_string(), + denom: Denom::Major, + } + ); + } } diff --git a/nym-wallet/src-tauri/src/error.rs b/nym-wallet/src-tauri/src/error.rs index 41d03532d2..3e5a9b2a58 100644 --- a/nym-wallet/src-tauri/src/error.rs +++ b/nym-wallet/src-tauri/src/error.rs @@ -61,6 +61,8 @@ pub enum BackendError { NoBalance(String), #[error("{0} is not a valid denomination string")] InvalidDenom(String), + #[error("{0} is not a valid network denomination string")] + InvalidNetworkDenom(String), #[error("The provided network is not supported (yet)")] NetworkNotSupported(config::defaults::all::Network), #[error("Could not access the local data storage directory")] diff --git a/nym-wallet/src-tauri/src/operations/mixnet/bond.rs b/nym-wallet/src-tauri/src/operations/mixnet/bond.rs index 3180bbf991..7118ee8a8f 100644 --- a/nym-wallet/src-tauri/src/operations/mixnet/bond.rs +++ b/nym-wallet/src-tauri/src/operations/mixnet/bond.rs @@ -4,7 +4,6 @@ use crate::nymd_client; use crate::state::State; use crate::{Gateway, MixNode}; use mixnet_contract_common::{GatewayBond, MixNodeBond}; -use std::convert::TryInto; use std::sync::Arc; use tokio::sync::RwLock; @@ -15,8 +14,10 @@ pub async fn bond_gateway( owner_signature: String, state: tauri::State<'_, Arc>>, ) -> Result<(), BackendError> { + let denom = state.read().await.current_network().denom(); + let pledge = pledge.into_cosmwasm_coin(&denom)?; nymd_client!(state) - .bond_gateway(gateway, owner_signature, pledge.try_into()?) + .bond_gateway(gateway, owner_signature, pledge) .await?; Ok(()) } @@ -44,8 +45,10 @@ pub async fn bond_mixnode( pledge: Coin, state: tauri::State<'_, Arc>>, ) -> Result<(), BackendError> { + let denom = state.read().await.current_network().denom(); + let pledge = pledge.into_cosmwasm_coin(&denom)?; nymd_client!(state) - .bond_mixnode(mixnode, owner_signature, pledge.try_into()?) + .bond_mixnode(mixnode, owner_signature, pledge) .await?; Ok(()) } diff --git a/nym-wallet/src-tauri/src/operations/mixnet/delegate.rs b/nym-wallet/src-tauri/src/operations/mixnet/delegate.rs index 5bcf21aa8e..d29917ab2e 100644 --- a/nym-wallet/src-tauri/src/operations/mixnet/delegate.rs +++ b/nym-wallet/src-tauri/src/operations/mixnet/delegate.rs @@ -5,7 +5,6 @@ use crate::state::State; use crate::utils::DelegationResult; use cosmwasm_std::Coin as CosmWasmCoin; use mixnet_contract_common::PagedDelegatorDelegationsResponse; -use std::convert::TryInto; use std::sync::Arc; use tokio::sync::RwLock; @@ -15,7 +14,8 @@ pub async fn delegate_to_mixnode( amount: Coin, state: tauri::State<'_, Arc>>, ) -> Result { - let delegation: CosmWasmCoin = amount.try_into()?; + let denom = state.read().await.current_network().denom(); + let delegation: CosmWasmCoin = amount.into_cosmwasm_coin(&denom)?; nymd_client!(state) .delegate_to_mixnode(identity, &delegation) .await?; diff --git a/nym-wallet/src-tauri/src/operations/mixnet/send.rs b/nym-wallet/src-tauri/src/operations/mixnet/send.rs index 1176d86227..911a3c87ed 100644 --- a/nym-wallet/src-tauri/src/operations/mixnet/send.rs +++ b/nym-wallet/src-tauri/src/operations/mixnet/send.rs @@ -3,7 +3,6 @@ use crate::error::BackendError; use crate::nymd_client; use crate::state::State; use serde::{Deserialize, Serialize}; -use std::convert::TryInto; use std::str::FromStr; use std::sync::Arc; use tendermint_rpc::endpoint::broadcast::tx_commit::Response; @@ -50,7 +49,8 @@ pub async fn send( state: tauri::State<'_, Arc>>, ) -> Result { let address = AccountId::from_str(address)?; - let cosmos_amount: CosmosCoin = amount.clone().try_into()?; + let network_denom = state.read().await.current_network().denom(); + let cosmos_amount: CosmosCoin = amount.clone().into_cosmos_coin(&network_denom)?; let result = nymd_client!(state) .send(&address, vec![cosmos_amount], memo) .await?; diff --git a/nym-wallet/src-tauri/src/operations/vesting/bond.rs b/nym-wallet/src-tauri/src/operations/vesting/bond.rs index 81cd99dfea..c90499bbbe 100644 --- a/nym-wallet/src-tauri/src/operations/vesting/bond.rs +++ b/nym-wallet/src-tauri/src/operations/vesting/bond.rs @@ -4,7 +4,6 @@ use crate::nymd_client; use crate::state::State; use crate::{Gateway, MixNode}; -use std::convert::TryInto; use std::sync::Arc; use tokio::sync::RwLock; use validator_client::nymd::VestingSigningClient; @@ -16,8 +15,10 @@ pub async fn vesting_bond_gateway( owner_signature: String, state: tauri::State<'_, Arc>>, ) -> Result<(), BackendError> { + let denom = state.read().await.current_network().denom(); + let pledge = pledge.into_cosmwasm_coin(&denom)?; nymd_client!(state) - .vesting_bond_gateway(gateway, &owner_signature, pledge.try_into()?) + .vesting_bond_gateway(gateway, &owner_signature, pledge) .await?; Ok(()) } @@ -45,8 +46,10 @@ pub async fn vesting_bond_mixnode( pledge: Coin, state: tauri::State<'_, Arc>>, ) -> Result<(), BackendError> { + let denom = state.read().await.current_network().denom(); + let pledge = pledge.into_cosmwasm_coin(&denom)?; nymd_client!(state) - .vesting_bond_mixnode(mixnode, &owner_signature, pledge.try_into()?) + .vesting_bond_mixnode(mixnode, &owner_signature, pledge) .await?; Ok(()) } @@ -56,8 +59,8 @@ pub async fn withdraw_vested_coins( amount: Coin, state: tauri::State<'_, Arc>>, ) -> Result<(), BackendError> { - nymd_client!(state) - .withdraw_vested_coins(amount.try_into()?) - .await?; + let denom = state.read().await.current_network().denom(); + let amount = amount.into_cosmwasm_coin(&denom)?; + nymd_client!(state).withdraw_vested_coins(amount).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 3e1ff81dd1..a7e1c79019 100644 --- a/nym-wallet/src-tauri/src/operations/vesting/delegate.rs +++ b/nym-wallet/src-tauri/src/operations/vesting/delegate.rs @@ -3,8 +3,6 @@ use crate::error::BackendError; use crate::nymd_client; use crate::state::State; use crate::utils::DelegationResult; -use cosmwasm_std::Coin as CosmWasmCoin; -use std::convert::TryInto; use std::sync::Arc; use tokio::sync::RwLock; use validator_client::nymd::VestingSigningClient; @@ -15,7 +13,8 @@ pub async fn vesting_delegate_to_mixnode( amount: Coin, state: tauri::State<'_, Arc>>, ) -> Result { - let delegation: CosmWasmCoin = amount.try_into()?; + let denom = state.read().await.current_network().denom(); + let delegation = amount.into_cosmwasm_coin(&denom)?; nymd_client!(state) .vesting_delegate_to_mixnode(identity, &delegation) .await?;