diff --git a/zcash_client_sqlite/src/query.rs b/zcash_client_sqlite/src/query.rs index 7806b8da9..656e6924f 100644 --- a/zcash_client_sqlite/src/query.rs +++ b/zcash_client_sqlite/src/query.rs @@ -2,7 +2,7 @@ use rusqlite::Connection; use std::path::Path; -use zcash_primitives::transaction::components::Amount; +use zcash_primitives::{note_encryption::Memo, transaction::components::Amount}; use crate::{ error::{Error, ErrorKind}, @@ -91,6 +91,74 @@ pub fn get_verified_balance>(db_data: P, account: u32) -> Result< } } +/// Returns the memo for a received note, if it is known and a valid UTF-8 string. +/// +/// The note is identified by its row index in the `received_notes` table within the data +/// database. +/// +/// # Examples +/// +/// ``` +/// use zcash_client_sqlite::query::get_received_memo_as_utf8; +/// +/// let memo = get_received_memo_as_utf8("/path/to/data.db", 27); +pub fn get_received_memo_as_utf8>( + db_data: P, + id_note: i64, +) -> Result, Error> { + let data = Connection::open(db_data)?; + + let memo: Vec<_> = data.query_row( + "SELECT memo FROM received_notes + WHERE id_note = ?", + &[id_note], + |row| row.get(0), + )?; + + match Memo::from_bytes(&memo) { + Some(memo) => match memo.to_utf8() { + Some(Ok(res)) => Ok(Some(res)), + Some(Err(e)) => Err(Error(ErrorKind::InvalidMemo(e))), + None => Ok(None), + }, + None => Ok(None), + } +} + +/// Returns the memo for a sent note, if it is known and a valid UTF-8 string. +/// +/// The note is identified by its row index in the `sent_notes` table within the data +/// database. +/// +/// # Examples +/// +/// ``` +/// use zcash_client_sqlite::query::get_sent_memo_as_utf8; +/// +/// let memo = get_sent_memo_as_utf8("/path/to/data.db", 12); +pub fn get_sent_memo_as_utf8>( + db_data: P, + id_note: i64, +) -> Result, Error> { + let data = Connection::open(db_data)?; + + let memo: Vec<_> = data.query_row( + "SELECT memo FROM sent_notes + WHERE id_note = ?", + &[id_note], + |row| row.get(0), + )?; + + match Memo::from_bytes(&memo) { + Some(memo) => match memo.to_utf8() { + Some(Ok(res)) => Ok(Some(res)), + Some(Err(e)) => Err(Error(ErrorKind::InvalidMemo(e))), + None => Ok(None), + }, + None => Ok(None), + } +} + #[cfg(test)] mod tests { use tempfile::NamedTempFile;