From f0e13e3cafb2bb1e77c27f6c7dff445449d71d0b Mon Sep 17 00:00:00 2001 From: Aditya Kulkarni Date: Fri, 10 Jul 2020 10:08:52 -0700 Subject: [PATCH] Allow raw memos to be fetched. Fixes #30 --- lib/src/commands.rs | 21 ++++++++++++++++++--- lib/src/lightclient.rs | 31 ++++++++++++++++++++++++------- lib/src/lightwallet.rs | 36 +++++++++++++++++------------------- 3 files changed, 59 insertions(+), 29 deletions(-) diff --git a/lib/src/commands.rs b/lib/src/commands.rs index 9a248d3..c63dc16 100644 --- a/lib/src/commands.rs +++ b/lib/src/commands.rs @@ -633,8 +633,9 @@ impl Command for TransactionsCommand { let mut h = vec![]; h.push("List all incoming and outgoing transactions from this wallet"); h.push("Usage:"); - h.push("list"); + h.push("list [allmemos]"); h.push(""); + h.push("If you include the 'allmemos' argument, all memos are returned in their raw hex format"); h.join("\n") } @@ -643,8 +644,22 @@ impl Command for TransactionsCommand { "List all transactions in the wallet".to_string() } - fn exec(&self, _args: &[&str], lightclient: &LightClient) -> String { - format!("{}", lightclient.do_list_transactions().pretty(2)) + fn exec(&self, args: &[&str], lightclient: &LightClient) -> String { + if args.len() > 1 { + return format!("Didn't understand arguments\n{}", self.help()); + } + + let include_memo_hex = if args.len() == 1 { + if args[0] == "allmemos" || args[0] == "true" || args[0] == "yes" { + true + } else { + return format!("Couldn't understand first argument '{}'\n{}", args[0], self.help()); + } + } else { + false + }; + + format!("{}", lightclient.do_list_transactions(include_memo_hex).pretty(2)) } } diff --git a/lib/src/lightclient.rs b/lib/src/lightclient.rs index 35819c7..c1a157b 100644 --- a/lib/src/lightclient.rs +++ b/lib/src/lightclient.rs @@ -862,7 +862,7 @@ impl LightClient { } } - pub fn do_list_transactions(&self) -> JsonValue { + pub fn do_list_transactions(&self, include_memo_hex: bool) -> JsonValue { let wallet = self.wallet.read().unwrap(); // Create a list of TransactionItems from wallet txns @@ -882,11 +882,18 @@ impl LightClient { // Collect outgoing metadata let outgoing_json = v.outgoing_metadata.iter() - .map(|om| - object!{ + .map(|om| { + let mut o = object!{ "address" => om.address.clone(), "value" => om.value, - "memo" => LightWallet::memo_str(&Some(om.memo.clone())), + "memo" => LightWallet::memo_str(&Some(om.memo.clone())) + }; + + if include_memo_hex { + o.insert("memohex", hex::encode(om.memo.as_bytes())).unwrap(); + } + + return o; }) .collect::>(); @@ -905,15 +912,25 @@ impl LightClient { txns.extend(v.notes.iter() .filter( |nd| !nd.is_change ) .enumerate() - .map ( |(i, nd)| - object! { + .map ( |(i, nd)| { + let mut o = object! { "block_height" => v.block, "datetime" => v.datetime, "position" => i, "txid" => format!("{}", v.txid), "amount" => nd.note.value as i64, "address" => LightWallet::note_address(self.config.hrp_sapling_address(), nd), - "memo" => LightWallet::memo_str(&nd.memo), + "memo" => LightWallet::memo_str(&nd.memo) + }; + + if include_memo_hex { + o.insert("memohex", match &nd.memo { + Some(m) => hex::encode(m.as_bytes()), + _ => "".to_string(), + }).unwrap(); + } + + return o; }) ); diff --git a/lib/src/lightwallet.rs b/lib/src/lightwallet.rs index 69a1c78..5e6a7d5 100644 --- a/lib/src/lightwallet.rs +++ b/lib/src/lightwallet.rs @@ -1089,27 +1089,25 @@ impl LightWallet { Some(ret) => ret, None => continue, }; + + info!("A sapling note was sent to wallet in {}", tx.txid()); + + // Do it in a short scope because of the write lock. + let mut txs = self.txs.write().unwrap(); - if memo.to_utf8().is_some() { - info!("A sapling note was sent to wallet in {} that had a memo", tx.txid()); - - // Do it in a short scope because of the write lock. - let mut txs = self.txs.write().unwrap(); - - // Update memo if we have this Tx. - match txs.get_mut(&tx.txid()) - .and_then(|t| { - t.notes.iter_mut().find(|nd| nd.note == note) - }) { - None => { - info!("No txid matched for incoming sapling funds while updating memo"); - () - }, - Some(nd) => { - nd.memo = Some(memo) - } + // Update memo if we have this Tx. + match txs.get_mut(&tx.txid()) + .and_then(|t| { + t.notes.iter_mut().find(|nd| nd.note == note) + }) { + None => { + info!("No txid matched for incoming sapling funds while updating memo"); + () + }, + Some(nd) => { + nd.memo = Some(memo) } - } + } } // Also scan the output to see if it can be decoded with our OutgoingViewKey