Skip to content

Commit 3616145

Browse files
committed
CreateWallet update+ListWallets+GetWalletInfo
1 parent a2a664f commit 3616145

File tree

3 files changed

+156
-8
lines changed

3 files changed

+156
-8
lines changed

client/src/client.rs

+20-2
Original file line numberDiff line numberDiff line change
@@ -272,9 +272,27 @@ pub trait RpcApi: Sized {
272272
&self,
273273
wallet: &str,
274274
disable_private_keys: Option<bool>,
275+
blank: Option<bool>,
276+
passphrase: Option<&str>,
277+
avoid_reuse: Option<bool>,
275278
) -> Result<json::LoadWalletResult> {
276-
let mut args = [wallet.into(), opt_into_json(disable_private_keys)?];
277-
self.call("createwallet", handle_defaults(&mut args, &[null()]))
279+
let mut args = [
280+
wallet.into(),
281+
opt_into_json(disable_private_keys)?,
282+
opt_into_json(blank)?,
283+
opt_into_json(passphrase)?,
284+
opt_into_json(avoid_reuse)?,
285+
];
286+
self.call("createwallet", handle_defaults(
287+
&mut args, &[false.into(), false.into(), into_json("")?, false.into()]))
288+
}
289+
290+
fn list_wallets(&self) -> Result<Vec<String>> {
291+
self.call("listwallets", &[])
292+
}
293+
294+
fn get_wallet_info(&self) -> Result<json::GetWalletInfoResult> {
295+
self.call("getwalletinfo", &[])
278296
}
279297

280298
fn backup_wallet(&self, destination: Option<&str>) -> Result<()> {

integration_test/src/main.rs

+105-6
Original file line numberDiff line numberDiff line change
@@ -75,15 +75,23 @@ fn sbtc<F: Into<f64>>(btc: F) -> SignedAmount {
7575
SignedAmount::from_btc(btc.into()).unwrap()
7676
}
7777

78-
fn main() {
79-
let rpc_url = std::env::var("RPC_URL").expect("RPC_URL must be set");
80-
let auth = if let Ok(cookie) = std::env::var("RPC_COOKIE") {
81-
Auth::CookieFile(cookie.into())
78+
fn get_rpc_url() -> String {
79+
return std::env::var("RPC_URL").expect("RPC_URL must be set");
80+
}
81+
82+
fn get_auth() -> bitcoincore_rpc::Auth {
83+
if let Ok(cookie) = std::env::var("RPC_COOKIE") {
84+
return Auth::CookieFile(cookie.into());
8285
} else if let Ok(user) = std::env::var("RPC_USER") {
83-
Auth::UserPass(user, std::env::var("RPC_PASS").unwrap_or_default())
86+
return Auth::UserPass(user, std::env::var("RPC_PASS").unwrap_or_default());
8487
} else {
8588
panic!("Either RPC_COOKIE or RPC_USER + RPC_PASS must be set.");
8689
};
90+
}
91+
92+
fn main() {
93+
let rpc_url = get_rpc_url();
94+
let auth = get_auth();
8795

8896
let cl = Client::new(rpc_url, auth).unwrap();
8997

@@ -137,6 +145,7 @@ fn main() {
137145
test_ping(&cl);
138146
test_get_peer_info(&cl);
139147
test_rescan_blockchain(&cl);
148+
test_create_wallet(&cl);
140149
//TODO import_multi(
141150
//TODO verify_message(
142151
//TODO wait_for_new_block(&self, timeout: u64) -> Result<json::BlockRef> {
@@ -148,7 +157,6 @@ fn main() {
148157
//TODO add_multisig_address(
149158
//TODO load_wallet(&self, wallet: &str) -> Result<json::LoadWalletResult> {
150159
//TODO unload_wallet(&self, wallet: Option<&str>) -> Result<()> {
151-
//TODO create_wallet(
152160
//TODO backup_wallet(&self, destination: Option<&str>) -> Result<()> {
153161
test_stop(cl);
154162
}
@@ -778,6 +786,97 @@ fn test_rescan_blockchain(cl: &Client) {
778786
assert_eq!(stop, Some(count - 1));
779787
}
780788

789+
struct WalletParams<'a> {
790+
name: &'a str,
791+
disable_private_keys: Option<bool>,
792+
blank: Option<bool>,
793+
passphrase: Option<&'a str>,
794+
avoid_reuse: Option<bool>,
795+
}
796+
797+
fn build_wallet_params<'a>(
798+
name: &'a str,
799+
disable_private_keys: Option<bool>,
800+
blank: Option<bool>,
801+
passphrase: Option<&'a str>,
802+
avoid_reuse: Option<bool>,
803+
) -> WalletParams<'a> {
804+
WalletParams {
805+
name,
806+
disable_private_keys,
807+
blank,
808+
passphrase,
809+
avoid_reuse,
810+
}
811+
}
812+
813+
fn test_create_single_wallet(cl: &Client, wallet_param: WalletParams) {
814+
let result = cl
815+
.create_wallet(
816+
wallet_param.name,
817+
wallet_param.disable_private_keys,
818+
wallet_param.blank,
819+
wallet_param.passphrase,
820+
wallet_param.avoid_reuse,
821+
)
822+
.unwrap();
823+
824+
assert_eq!(result.name, wallet_param.name);
825+
let expected_warning = match (wallet_param.passphrase, wallet_param.avoid_reuse) {
826+
(None, Some(true)) => Some("Empty string given as passphrase, wallet will not be encrypted.".to_string()),
827+
_ => Some("".to_string()),
828+
};
829+
assert_eq!(result.warning, expected_warning);
830+
831+
let wallet_client_url = format!("{}{}{}", get_rpc_url(), "/wallet/", wallet_param.name);
832+
let wallet_client = Client::new(wallet_client_url, get_auth()).unwrap();
833+
let wallet_info = wallet_client.get_wallet_info().unwrap();
834+
835+
assert_eq!(wallet_info.wallet_name, wallet_param.name);
836+
837+
fn option_to_bool(option: Option<bool>) -> bool {
838+
match option {
839+
None | Some(false) => false,
840+
Some(true) => true,
841+
}
842+
}
843+
844+
let has_private_keys = !option_to_bool(wallet_param.disable_private_keys);
845+
assert_eq!(wallet_info.private_keys_enabled, has_private_keys);
846+
let has_hd_seed = has_private_keys && !option_to_bool(wallet_param.blank);
847+
assert_eq!(wallet_info.hd_seed_id.is_some(), has_hd_seed);
848+
let has_avoid_reuse = option_to_bool(wallet_param.avoid_reuse);
849+
assert_eq!(option_to_bool(wallet_info.avoid_reuse), has_avoid_reuse);
850+
}
851+
852+
fn test_create_wallet(cl: &Client) {
853+
let wallet_names = vec!["alice", "bob", "carol", "denise", "emily"];
854+
let mut wallet_params = vec![
855+
build_wallet_params(wallet_names[0], None, None, None, None),
856+
build_wallet_params(wallet_names[1], Some(true), None, None, None),
857+
build_wallet_params(wallet_names[2], None, Some(true), None, None),
858+
];
859+
860+
if version() >= 190000 {
861+
wallet_params.push(build_wallet_params(wallet_names[3], None, None, Some("pass"), None));
862+
wallet_params.push(build_wallet_params(wallet_names[4], None, None, None, Some(true)));
863+
}
864+
865+
for param in wallet_params {
866+
test_create_single_wallet(&cl, param);
867+
}
868+
869+
let mut wallet_list = cl.list_wallets().unwrap();
870+
871+
wallet_list.sort();
872+
873+
// Default wallet
874+
assert_eq!(wallet_list.remove(0), "");
875+
876+
// Created wallets
877+
assert!(wallet_list.iter().zip(wallet_names).all(|(a, b)| a == b));
878+
}
879+
781880
fn test_stop(cl: Client) {
782881
println!("Stopping: '{}'", cl.stop().unwrap());
783882
}

json/src/lib.rs

+31
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,37 @@ pub struct LoadWalletResult {
123123
pub warning: Option<String>,
124124
}
125125

126+
#[derive(Clone, PartialEq, Eq, Debug, Deserialize, Serialize)]
127+
pub struct GetWalletInfoResult {
128+
#[serde(rename = "walletname")]
129+
pub wallet_name: String,
130+
#[serde(rename = "walletversion")]
131+
pub wallet_version: u32,
132+
#[serde(with = "bitcoin::util::amount::serde::as_btc")]
133+
pub balance: Amount,
134+
#[serde(with = "bitcoin::util::amount::serde::as_btc")]
135+
pub unconfirmed_balance: Amount,
136+
#[serde(with = "bitcoin::util::amount::serde::as_btc")]
137+
pub immature_balance: Amount,
138+
#[serde(rename = "txcount")]
139+
pub tx_count: usize,
140+
#[serde(rename = "keypoololdest")]
141+
pub keypool_oldest: usize,
142+
#[serde(rename = "keypoolsize")]
143+
pub keypool_size: usize,
144+
#[serde(rename = "keypoolsize_hd_internal")]
145+
pub keypool_size_hd_internal: usize,
146+
pub unlocked_until: Option<usize>,
147+
#[serde(rename = "paytxfee", with = "bitcoin::util::amount::serde::as_btc")]
148+
pub pay_tx_fee: Amount,
149+
#[serde(rename = "hdseedid")]
150+
pub hd_seed_id: Option<String>,
151+
#[serde(rename = "hdmasterkeyid")]
152+
pub hd_master_key_id: Option<String>,
153+
pub private_keys_enabled: bool,
154+
pub avoid_reuse: Option<bool>,
155+
}
156+
126157
#[derive(Clone, PartialEq, Debug, Deserialize, Serialize)]
127158
#[serde(rename_all = "camelCase")]
128159
pub struct GetBlockResult {

0 commit comments

Comments
 (0)