From b451ce452b8fe8b1a0f7969810cbeb499b58a34b Mon Sep 17 00:00:00 2001 From: Calvin Lau Date: Fri, 31 Jan 2020 09:44:16 +0800 Subject: [PATCH] Problem: (Fix #972) Missing MultiSig public keys methods in JSONRPC and ClientCli Soltion: Add new and list methods to JSONRPC and ClientCLI --- .gitignore | 4 +- client-cli/src/command.rs | 12 ++++ client-cli/src/command/multisig_command.rs | 82 ++++++++++++++++++++++ client-rpc/src/rpc/multisig_rpc.rs | 21 ++++++ client-rpc/src/rpc/wallet_rpc.rs | 22 +----- 5 files changed, 118 insertions(+), 23 deletions(-) create mode 100644 client-cli/src/command/multisig_command.rs diff --git a/.gitignore b/.gitignore index c0ddd3b8c..d18865c3d 100644 --- a/.gitignore +++ b/.gitignore @@ -9,9 +9,9 @@ __pycache__ *.egg-info # Storage +/.storage* /.storage -/.storage.bak -/.cro-storage +/.cro-storage* # OS .DS_Store diff --git a/client-cli/src/command.rs b/client-cli/src/command.rs index ebade2b64..5d21bb110 100644 --- a/client-cli/src/command.rs +++ b/client-cli/src/command.rs @@ -1,4 +1,5 @@ mod address_command; +mod multisig_command; mod transaction_command; mod wallet_command; @@ -37,6 +38,7 @@ use client_network::network_ops::{DefaultNetworkOpsClient, NetworkOpsClient}; use log::warn; use self::address_command::AddressCommand; +use self::multisig_command::MultiSigCommand; use self::transaction_command::TransactionCommand; use self::wallet_command::WalletCommand; use crate::{ask_seckey, storage_path, tendermint_url}; @@ -167,6 +169,11 @@ pub enum Command { )] block_height_ensure: u64, }, + #[structopt(name = "multisig", about = "MultiSig operations")] + MultiSig { + #[structopt(subcommand)] + multisig_command: MultiSigCommand, + }, } /// normal @@ -312,6 +319,11 @@ impl Command { ); Self::resync(config, name.clone(), enckey, *force) } + Command::MultiSig { multisig_command } => { + let storage = SledStorage::new(storage_path())?; + let wallet_client = DefaultWalletClient::new_read_only(storage); + multisig_command.execute(wallet_client) + } } } diff --git a/client-cli/src/command/multisig_command.rs b/client-cli/src/command/multisig_command.rs new file mode 100644 index 000000000..790974f26 --- /dev/null +++ b/client-cli/src/command/multisig_command.rs @@ -0,0 +1,82 @@ +use quest::success; +use structopt::StructOpt; + +use client_common::{PublicKey, Result}; +use client_core::types::AddressType; +use client_core::WalletClient; + +use crate::ask_seckey; + +#[derive(Debug, StructOpt)] +pub enum MultiSigCommand { + #[structopt( + name = "new-address-public-key", + about = "Creates a new public key for MultiSig address" + )] + NewAddressPublicKey { + #[structopt( + name = "wallet name", + short = "n", + long = "name", + help = "Name of wallet" + )] + name: String, + }, + + #[structopt( + name = "list-address-public-keys", + about = "List public keys for MultiSig address" + )] + ListAddressPublicKeys { + #[structopt( + name = "wallet name", + short = "n", + long = "name", + help = "Name of wallet" + )] + name: String, + }, +} + +impl MultiSigCommand { + pub fn execute(&self, wallet_client: T) -> Result<()> { + match self { + MultiSigCommand::NewAddressPublicKey { name } => { + new_address_public_key(wallet_client, name) + } + MultiSigCommand::ListAddressPublicKeys { name } => { + list_address_public_keys(wallet_client, name) + } + } + } +} + +fn new_address_public_key(wallet_client: T, name: &str) -> Result<()> { + let enckey = ask_seckey(None)?; + + let public_key = wallet_client + .new_public_key(name, &enckey, Some(AddressType::Transfer)) + .map(|public_key| public_key.to_string())?; + + success(&format!("Public key: {}", public_key)); + + Ok(()) +} + +fn list_address_public_keys(wallet_client: T, name: &str) -> Result<()> { + let enckey = ask_seckey(None)?; + + let public_keys: Vec = wallet_client + .public_keys(name, &enckey) + .map(|keys| keys.into_iter().collect())?; + + if public_keys.is_empty() { + success("No public key found!"); + return Ok(()); + } + for public_key in public_keys { + success(&format!("Public key: {}", public_key.to_string())) + } + + Ok(()) +} diff --git a/client-rpc/src/rpc/multisig_rpc.rs b/client-rpc/src/rpc/multisig_rpc.rs index ecdf02840..84cddddec 100644 --- a/client-rpc/src/rpc/multisig_rpc.rs +++ b/client-rpc/src/rpc/multisig_rpc.rs @@ -5,12 +5,19 @@ use jsonrpc_derive::rpc; use chain_core::common::{H256, HASH_SIZE_256}; use chain_core::tx::data::Tx; use client_common::{Error, ErrorKind, PublicKey, Result as CommonResult, ResultExt, SecKey}; +use client_core::types::AddressType; use client_core::{MultiSigWalletClient, WalletClient}; use crate::server::{to_rpc_error, WalletRequest}; #[rpc] pub trait MultiSigRpc: Send + Sync { + #[rpc(name = "multiSig_newAddressPublicKey")] + fn new_address_public_key(&self, request: WalletRequest) -> Result; + + #[rpc(name = "multiSig_listAddressPublicKeys")] + fn list_address_public_keys(&self, request: WalletRequest) -> Result>; + #[rpc(name = "multiSig_createAddress")] fn create_address( &self, @@ -97,6 +104,20 @@ impl MultiSigRpc for MultiSigRpcImpl where T: WalletClient + MultiSigWalletClient + 'static, { + fn new_address_public_key(&self, request: WalletRequest) -> Result { + self.client + .new_public_key(&request.name, &request.enckey, Some(AddressType::Transfer)) + .map(|public_key| public_key.to_string()) + .map_err(to_rpc_error) + } + + fn list_address_public_keys(&self, request: WalletRequest) -> Result> { + self.client + .public_keys(&request.name, &request.enckey) + .map(|keys| keys.into_iter().collect()) + .map_err(to_rpc_error) + } + fn create_address( &self, request: WalletRequest, diff --git a/client-rpc/src/rpc/wallet_rpc.rs b/client-rpc/src/rpc/wallet_rpc.rs index 63d6c114f..42994102e 100644 --- a/client-rpc/src/rpc/wallet_rpc.rs +++ b/client-rpc/src/rpc/wallet_rpc.rs @@ -7,9 +7,9 @@ use secstr::SecUtf8; use chain_core::init::coin::Coin; use chain_core::tx::data::address::ExtendedAddr; use client_common::{PrivateKey, PublicKey, Result as CommonResult, SecKey}; +use client_core::types::TransactionChange; use client_core::types::WalletBalance; use client_core::types::WalletKind; -use client_core::types::{AddressType, TransactionChange}; use client_core::{Mnemonic, MultiSigWalletClient, UnspentTransactions, WalletClient}; use crate::server::{rpc_error_from_string, to_rpc_error, CreateWalletRequest, WalletRequest}; @@ -35,9 +35,6 @@ pub trait WalletRpc: Send + Sync { #[rpc(name = "wallet_delete")] fn delete(&self, request: CreateWalletRequest) -> Result<()>; - #[rpc(name = "wallet_newMultiSigAddressPublicKey")] - fn new_multi_sig_address_public_key(&self, request: WalletRequest) -> Result; - #[rpc(name = "wallet_createStakingAddress")] fn create_staking_address(&self, request: WalletRequest) -> Result; @@ -64,9 +61,6 @@ pub trait WalletRpc: Send + Sync { #[rpc(name = "wallet_list")] fn list(&self) -> Result>; - #[rpc(name = "wallet_listPublicKeys")] - fn list_public_keys(&self, request: WalletRequest) -> Result>; - #[rpc(name = "wallet_listStakingAddresses")] fn list_staking_addresses(&self, request: WalletRequest) -> Result>; @@ -194,13 +188,6 @@ where .map_err(to_rpc_error) } - fn new_multi_sig_address_public_key(&self, request: WalletRequest) -> Result { - self.client - .new_public_key(&request.name, &request.enckey, Some(AddressType::Transfer)) - .map(|public_key| public_key.to_string()) - .map_err(to_rpc_error) - } - fn create_staking_address(&self, request: WalletRequest) -> Result { self.client .new_staking_address(&request.name, &request.enckey) @@ -263,13 +250,6 @@ where self.client.wallets().map_err(to_rpc_error) } - fn list_public_keys(&self, request: WalletRequest) -> Result> { - self.client - .public_keys(&request.name, &request.enckey) - .map(|keys| keys.into_iter().collect()) - .map_err(to_rpc_error) - } - fn list_staking_addresses(&self, request: WalletRequest) -> Result> { self.client .staking_addresses(&request.name, &request.enckey)