Add connect_with_mnemonic and get_balance tauri functions
This commit is contained in:
Generated
+18
-16
@@ -4,22 +4,6 @@
|
|||||||
# SPDX-License-Identifier: Apache-2.0
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
version = 3
|
version = 3
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "Nym-Wallet"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"config",
|
|
||||||
"dirs",
|
|
||||||
"mixnet-contract",
|
|
||||||
"serde",
|
|
||||||
"serde_json",
|
|
||||||
"tauri",
|
|
||||||
"tauri-build",
|
|
||||||
"tokio",
|
|
||||||
"url",
|
|
||||||
"validator-client",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "addr2line"
|
name = "addr2line"
|
||||||
version = "0.16.0"
|
version = "0.16.0"
|
||||||
@@ -3520,6 +3504,24 @@ dependencies = [
|
|||||||
"version-checker",
|
"version-checker",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nym_wallet"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"bip39",
|
||||||
|
"config",
|
||||||
|
"dirs",
|
||||||
|
"mixnet-contract",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"tauri",
|
||||||
|
"tauri-build",
|
||||||
|
"tendermint-rpc",
|
||||||
|
"thiserror",
|
||||||
|
"tokio",
|
||||||
|
"validator-client",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nymsphinx"
|
name = "nymsphinx"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|||||||
@@ -442,6 +442,7 @@ pub trait SigningCosmWasmClient: CosmWasmClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct Client {
|
pub struct Client {
|
||||||
rpc_client: HttpClient,
|
rpc_client: HttpClient,
|
||||||
signer: DirectSecp256k1HdWallet,
|
signer: DirectSecp256k1HdWallet,
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ pub(crate) mod fee_helpers;
|
|||||||
pub mod gas_price;
|
pub mod gas_price;
|
||||||
pub mod wallet;
|
pub mod wallet;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct NymdClient<C> {
|
pub struct NymdClient<C> {
|
||||||
client: C,
|
client: C,
|
||||||
contract_address: Option<AccountId>,
|
contract_address: Option<AccountId>,
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ use cosmos_sdk::tx::SignDoc;
|
|||||||
use cosmos_sdk::{tx, AccountId};
|
use cosmos_sdk::{tx, AccountId};
|
||||||
|
|
||||||
/// 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)]
|
||||||
struct Secp256k1Derivation {
|
struct Secp256k1Derivation {
|
||||||
hd_path: DerivationPath,
|
hd_path: DerivationPath,
|
||||||
prefix: String,
|
prefix: String,
|
||||||
@@ -25,6 +26,7 @@ pub struct AccountData {
|
|||||||
|
|
||||||
type Secp256k1Keypair = (SigningKey, PublicKey);
|
type Secp256k1Keypair = (SigningKey, PublicKey);
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
pub struct DirectSecp256k1HdWallet {
|
pub struct DirectSecp256k1HdWallet {
|
||||||
/// Base secret
|
/// Base secret
|
||||||
secret: bip39::Mnemonic,
|
secret: bip39::Mnemonic,
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "Nym-Wallet"
|
name = "nym_wallet"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
description = "A Tauri App"
|
description = "A Tauri App"
|
||||||
authors = ["you"]
|
authors = ["you"]
|
||||||
license = ""
|
license = ""
|
||||||
repository = ""
|
repository = ""
|
||||||
default-run = "Nym-Wallet"
|
default-run = "nym_wallet"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
build = "src/build.rs"
|
build = "src/build.rs"
|
||||||
|
|
||||||
@@ -20,7 +20,10 @@ serde = { version = "1.0", features = ["derive"] }
|
|||||||
tauri = { version = "1.0.0-beta.6", features = [] }
|
tauri = { version = "1.0.0-beta.6", features = [] }
|
||||||
tokio = { version = "1.10", features = ["sync"] }
|
tokio = { version = "1.10", features = ["sync"] }
|
||||||
dirs = "3.0"
|
dirs = "3.0"
|
||||||
url = "2.2"
|
# url = "2.2"
|
||||||
|
bip39 = "1.0"
|
||||||
|
thiserror = "1.0"
|
||||||
|
tendermint-rpc = "0.21.0"
|
||||||
|
|
||||||
validator-client = { path = "../../common/client-libs/validator-client", features = [
|
validator-client = { path = "../../common/client-libs/validator-client", features = [
|
||||||
"nymd-client",
|
"nymd-client",
|
||||||
|
|||||||
@@ -7,12 +7,15 @@ use config::defaults::{
|
|||||||
use config::NymConfig;
|
use config::NymConfig;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use url::Url;
|
use std::str::FromStr;
|
||||||
|
use tendermint_rpc::Url;
|
||||||
|
|
||||||
mod template;
|
mod template;
|
||||||
|
|
||||||
use template::config_template;
|
use template::config_template;
|
||||||
|
|
||||||
|
use crate::error::BackendError;
|
||||||
|
|
||||||
#[derive(Debug, Default, Deserialize, Serialize)]
|
#[derive(Debug, Default, Deserialize, Serialize)]
|
||||||
#[serde(deny_unknown_fields)]
|
#[serde(deny_unknown_fields)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
@@ -71,20 +74,23 @@ impl NymConfig for Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
impl Config {
|
||||||
pub fn get_nymd_validator_url(&self) -> Url {
|
pub fn get_nymd_validator_url(&self) -> Result<Url, BackendError> {
|
||||||
// TODO make this a random choice
|
// TODO make this a random choice
|
||||||
if let Some(validator_details) = self.base.validators.first() {
|
if let Some(validator_details) = self.base.validators.first() {
|
||||||
validator_details.nymd_url()
|
match tendermint_rpc::Url::from_str(&validator_details.nymd_url().to_string()) {
|
||||||
|
Ok(url) => Ok(url),
|
||||||
|
Err(e) => Err(e.into()),
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
panic!("No validators found in config")
|
panic!("No validators found in config")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_mixnet_contract_address(&self) -> String {
|
// pub fn get_mixnet_contract_address(&self) -> String {
|
||||||
self.base.mixnet_contract_address.clone()
|
// self.base.mixnet_contract_address.clone()
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub fn get_mnemonic(&self) -> String {
|
// pub fn get_mnemonic(&self) -> String {
|
||||||
self.base.mnemonic.clone()
|
// self.base.mnemonic.clone()
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
use thiserror::Error;
|
||||||
|
use validator_client::nymd::error::NymdError;
|
||||||
|
|
||||||
|
#[derive(Error, Debug)]
|
||||||
|
pub enum BackendError {
|
||||||
|
#[error("Error parsing bip39 mnemonic")]
|
||||||
|
Bip39Error {
|
||||||
|
#[from]
|
||||||
|
source: bip39::Error
|
||||||
|
},
|
||||||
|
#[error("Error parsing into tendermint Url")]
|
||||||
|
TendermintError {
|
||||||
|
#[from]
|
||||||
|
source: tendermint_rpc::Error
|
||||||
|
},
|
||||||
|
#[error("Error getting balances")]
|
||||||
|
NymdError {
|
||||||
|
#[from]
|
||||||
|
source: NymdError
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,11 +3,97 @@
|
|||||||
windows_subsystem = "windows"
|
windows_subsystem = "windows"
|
||||||
)]
|
)]
|
||||||
|
|
||||||
mod nymd_client;
|
use bip39::Mnemonic;
|
||||||
|
use error::BackendError;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::str::FromStr;
|
||||||
|
use validator_client::nymd::{NymdClient, SigningNymdClient};
|
||||||
|
|
||||||
mod config;
|
mod config;
|
||||||
|
mod error;
|
||||||
|
// mod nymd_client;
|
||||||
|
|
||||||
|
use std::sync::Arc;
|
||||||
|
use tokio::sync::RwLock;
|
||||||
|
|
||||||
|
use crate::config::Config;
|
||||||
|
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
struct State {
|
||||||
|
config: Config,
|
||||||
|
signing_client: Option<NymdClient<SigningNymdClient>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
async fn connect_with_mnemonic(
|
||||||
|
mnemonic: String,
|
||||||
|
state: tauri::State<'_, Arc<RwLock<State>>>,
|
||||||
|
) -> Result<bool, String> {
|
||||||
|
let mnemonic = match Mnemonic::from_str(&mnemonic) {
|
||||||
|
Ok(mnemonic) => mnemonic,
|
||||||
|
Err(e) => return Err(BackendError::from(e).to_string()),
|
||||||
|
};
|
||||||
|
let r_state = state.read().await;
|
||||||
|
let client = _connect_with_mnemonic(mnemonic, &r_state.config);
|
||||||
|
let mut w_state = state.write().await;
|
||||||
|
w_state.signing_client = Some(client);
|
||||||
|
Ok(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
async fn get_balance(
|
||||||
|
state: tauri::State<'_, Arc<RwLock<State>>>,
|
||||||
|
) -> Result<HashMap<&str, String>, String> {
|
||||||
|
let r_state = state.read().await;
|
||||||
|
if let Some(client) = &r_state.signing_client {
|
||||||
|
match client.get_balance(client.address()).await {
|
||||||
|
Ok(Some(coin)) => {
|
||||||
|
let mut balance = HashMap::new();
|
||||||
|
balance.insert("amount", coin.amount.to_string());
|
||||||
|
balance.insert("denom", coin.denom.to_string());
|
||||||
|
Ok(balance)
|
||||||
|
},
|
||||||
|
Ok(None) => Err(format!("No balance available for address {}", client.address())),
|
||||||
|
Err(e) => Err(BackendError::from(e).to_string()),
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Err(String::from("Client has not been initialized yet"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _connect_with_mnemonic(mnemonic: Mnemonic, config: &Config) -> NymdClient<SigningNymdClient> {
|
||||||
|
match NymdClient::connect_with_mnemonic(config.get_nymd_validator_url().unwrap(), None, mnemonic)
|
||||||
|
{
|
||||||
|
Ok(client) => client,
|
||||||
|
Err(e) => panic!("{}", e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
tauri::Builder::default()
|
tauri::Builder::default()
|
||||||
|
.manage(Arc::new(RwLock::new(State::default())))
|
||||||
|
.invoke_handler(tauri::generate_handler![connect_with_mnemonic, get_balance])
|
||||||
.run(tauri::generate_context!())
|
.run(tauri::generate_context!())
|
||||||
.expect("error while running tauri application");
|
.expect("error while running tauri application");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
mod test {
|
||||||
|
#![allow(unused_imports)]
|
||||||
|
use crate::Config;
|
||||||
|
use crate::_connect_with_mnemonic;
|
||||||
|
use bip39::Mnemonic;
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_connect_with_mnemonic() {
|
||||||
|
let config = Config::default();
|
||||||
|
assert_eq!(
|
||||||
|
"https://testnet-milhon-validator1.nymtech.net/",
|
||||||
|
config.get_nymd_validator_url().unwrap().to_string()
|
||||||
|
);
|
||||||
|
let mnemonic = Mnemonic::from_str("riot worth swear negative toward hood absent crater release net detect weasel profit wash market key smart member prize cancel awkward famous sauce sport").unwrap();
|
||||||
|
let client = _connect_with_mnemonic(mnemonic, &config);
|
||||||
|
assert!(client.contract_address().is_ok());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use config::defaults::DEFAULT_VALIDATOR_API_PORT;
|
|||||||
use mixnet_contract::{GatewayBond, MixNodeBond};
|
use mixnet_contract::{GatewayBond, MixNodeBond};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tokio::sync::RwLock;
|
use tokio::sync::RwLock;
|
||||||
use validator_client::nymd::{CosmWasmClient, QueryNymdClient, SigningNymdClient};
|
use validator_client::nymd::{CosmWasmClient, QueryNymdClient, SigningNymdClient, NymdClient};
|
||||||
use validator_client::ValidatorClientError;
|
use validator_client::ValidatorClientError;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
|||||||
Reference in New Issue
Block a user