diff --git a/rust-lightclient/Cargo.toml b/rust-lightclient/Cargo.toml index 37189b0..90402ed 100644 --- a/rust-lightclient/Cargo.toml +++ b/rust-lightclient/Cargo.toml @@ -22,6 +22,7 @@ protobuf = "2" rustyline = "5.0.2" byteorder = "1" rand = "0.5.6" +json = "0.12.0" [dependencies.bellman] path = "../../librustzcash/bellman" diff --git a/rust-lightclient/src/commands.rs b/rust-lightclient/src/commands.rs index e2e9fc8..5ad7820 100644 --- a/rust-lightclient/src/commands.rs +++ b/rust-lightclient/src/commands.rs @@ -72,7 +72,8 @@ impl Command for AddressCommand { } fn exec(&self, _args: &[String], lightclient: &mut LightClient) { - lightclient.do_address(); + let res = lightclient.do_address(); + println!("{}", res.pretty(2)); } } diff --git a/rust-lightclient/src/lightclient.rs b/rust-lightclient/src/lightclient.rs index 1774e70..1a24097 100644 --- a/rust-lightclient/src/lightclient.rs +++ b/rust-lightclient/src/lightclient.rs @@ -11,8 +11,13 @@ use std::sync::atomic::{AtomicU64, AtomicUsize, Ordering}; use std::error::Error; +use json::{object, JsonValue}; + use zcash_primitives::transaction::{TxId, Transaction}; use zcash_primitives::note_encryption::Memo; +use zcash_client_backend::{ + constants::testnet::HRP_SAPLING_PAYMENT_ADDRESS, encoding::encode_payment_address, +}; use futures::Future; use hyper::client::connect::{Destination, HttpConnector}; @@ -67,9 +72,21 @@ impl LightClient { self.wallet.last_scanned_height() as u64 } - pub fn do_address(&self) { - println!("Address: {}", self.wallet.address(0)); // TODO: This is showing only the default address - println!("Balance: {}", self.wallet.balance()); + pub fn do_address(&self) -> json::JsonValue{ + let addresses = self.wallet.address.iter().map( |ad| { + let address = encode_payment_address(HRP_SAPLING_PAYMENT_ADDRESS, &ad); + object!{ + "address" => address.clone(), + "balance" => self.wallet.balance(Some(address.clone())), + "verified_balance" => self.wallet.verified_balance(Some(address)), + } + }).collect::>(); + + object!{ + "balance" => self.wallet.balance(None), + "verified_balance" => self.wallet.verified_balance(None), + "addresses" => addresses + } } pub fn do_read(&mut self) { @@ -223,7 +240,7 @@ impl LightClient { }; print!("Syncing {}/{}, Balance = {} \r", - last_scanned_height, last_block, self.wallet.balance()); + last_scanned_height, last_block, self.wallet.balance(None)); self.fetch_blocks(last_scanned_height, end_height, simple_callback); diff --git a/rust-lightclient/src/lightwallet.rs b/rust-lightclient/src/lightwallet.rs index 0dd2cb6..5fe1e9f 100644 --- a/rust-lightclient/src/lightwallet.rs +++ b/rust-lightclient/src/lightwallet.rs @@ -356,7 +356,7 @@ pub struct LightWallet { // a private key extsks: Vec, extfvks: Vec, - address: Vec>, + pub address: Vec>, blocks: Arc>>, pub txs: Arc>>, @@ -539,7 +539,7 @@ impl LightWallet { encode_payment_address(HRP_SAPLING_PAYMENT_ADDRESS, &self.address[account]) } - pub fn balance(&self) -> u64 { + pub fn balance(&self, addr: Option) -> u64 { self.txs .read() .unwrap() @@ -547,13 +547,23 @@ impl LightWallet { .map(|tx| { tx.notes .iter() + .filter(|nd| { // TODO, this whole section is shared with verified_balance. Refactor it. + match addr.clone() { + Some(a) => a == encode_payment_address( + HRP_SAPLING_PAYMENT_ADDRESS, + &nd.extfvk.fvk.vk + .into_payment_address(nd.diversifier, &JUBJUB).unwrap() + ), + None => true + } + }) .map(|nd| if nd.spent.is_none() { nd.note.value } else { 0 }) .sum::() }) .sum::() } - pub fn verified_balance(&self) -> u64 { + pub fn verified_balance(&self, addr: Option) -> u64 { let anchor_height = match self.get_target_height_and_anchor_offset() { Some((height, anchor_offset)) => height - anchor_offset as u32, None => return 0, @@ -567,6 +577,16 @@ impl LightWallet { if tx.block as u32 <= anchor_height { tx.notes .iter() + .filter(|nd| { // TODO, this whole section is shared with verified_balance. Refactor it. + match addr.clone() { + Some(a) => a == encode_payment_address( + HRP_SAPLING_PAYMENT_ADDRESS, + &nd.extfvk.fvk.vk + .into_payment_address(nd.diversifier, &JUBJUB).unwrap() + ), + None => true + } + }) .map(|nd| if nd.spent.is_none() { nd.note.value } else { 0 }) .sum::() } else {