From efc970d1e084c84445bd20c58bacd41c15cbb650 Mon Sep 17 00:00:00 2001 From: yse <70684173+hydra-yse@users.noreply.github.com> Date: Tue, 9 Apr 2024 21:30:02 +0200 Subject: [PATCH] feat: add json responses to cli (#81) --- cli/Cargo.lock | 3 ++ cli/Cargo.toml | 2 ++ cli/src/commands.rs | 75 ++++++++++++++++++--------------------------- cli/src/main.rs | 19 +++++++----- lib/Cargo.lock | 1 + lib/Cargo.toml | 1 + lib/src/model.rs | 12 +++++--- 7 files changed, 55 insertions(+), 58 deletions(-) diff --git a/cli/Cargo.lock b/cli/Cargo.lock index 1f91396..bd912e9 100644 --- a/cli/Cargo.lock +++ b/cli/Cargo.lock @@ -315,6 +315,7 @@ dependencies = [ "lwk_wollet", "rusqlite", "rusqlite_migration", + "serde", "thiserror", ] @@ -330,6 +331,8 @@ dependencies = [ "log", "qr2term", "rustyline", + "serde", + "serde_json", ] [[package]] diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 2b4ce0e..19d4443 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -14,6 +14,8 @@ env_logger = "0.11" log = "0.4.20" qr2term = "0.3.1" rustyline = { version = "13.0.0", features = ["derive"] } +serde = { version = "1.0.197", features = ["derive"] } +serde_json = "1.0.115" [patch.crates-io] secp256k1-zkp = {git = "https://github.com/BlockstreamResearch/rust-secp256k1-zkp.git", rev = "60e631c24588a0c9e271badd61959294848c665d"} diff --git a/cli/src/commands.rs b/cli/src/commands.rs index b6d98f8..b91777c 100644 --- a/cli/src/commands.rs +++ b/cli/src/commands.rs @@ -8,7 +8,9 @@ use rustyline::history::DefaultHistory; use rustyline::Editor; use rustyline::{hint::HistoryHinter, Completer, Helper, Hinter, Validator}; -use breez_sdk_liquid::{ReceivePaymentRequest, SendPaymentResponse, Wallet}; +use breez_sdk_liquid::{ReceivePaymentRequest, Wallet}; +use serde::Serialize; +use serde_json::to_string_pretty; #[derive(Parser, Debug, Clone, PartialEq)] pub(crate) enum Command { @@ -42,12 +44,27 @@ impl Highlighter for CliHelper { } } +#[derive(Serialize)] +pub(crate) struct CommandResult { + pub success: bool, + pub message: T, +} + +macro_rules! command_result { + ($expr:expr) => {{ + to_string_pretty(&CommandResult { + success: true, + message: $expr, + })? + }}; +} + pub(crate) fn handle_command( _rl: &mut Editor, wallet: &Arc, command: Command, ) -> Result { - match command { + Ok(match command { Command::ReceivePayment { onchain_amount_sat, invoice_amount_sat, @@ -56,57 +73,23 @@ pub(crate) fn handle_command( invoice_amount_sat, onchain_amount_sat, })?; - dbg!(&response); qr2term::print_qr(response.invoice.clone())?; - - Ok(format!( - "Please pay the following invoice: {}", - response.invoice - )) + command_result!(response) } Command::SendPayment { bolt11 } => { let prepare_response = wallet.prepare_payment(&bolt11)?; - let SendPaymentResponse { txid } = wallet.send_payment(&prepare_response)?; - - Ok(format!( - r#" - Successfully paid the invoice! - You can view the onchain transaction at https://blockstream.info/liquidtestnet/tx/{}"#, - txid - )) + let response = wallet.send_payment(&prepare_response)?; + command_result!(response) } Command::GetInfo => { - let info = wallet.get_info(true)?; - - Ok(format!( - "Current Balance: {} sat\nPublic Key: {}\nLiquid Address: {}", - info.balance_sat, info.pubkey, info.active_address - )) + command_result!(wallet.get_info(true)?) } Command::ListPayments => { - let payments_str = wallet - .list_payments(true, true)? - .iter() - .map(|tx| { - format!( - "Id: {} | Type: {:?} | Amount: {} sat | Timestamp: {}", - tx.id.clone().unwrap_or("None".to_string()), - tx.payment_type, - tx.amount_sat, - match tx.timestamp { - Some(t) => t.to_string(), - None => "None".to_string(), - }, - ) - }) - .collect::>() - .join("\n"); - - Ok(payments_str) + command_result!(wallet.list_payments(true, true)?) } - Command::EmptyCache => Ok(match wallet.empty_wallet_cache() { - Ok(_) => "Cache emptied successfully".to_string(), - Err(e) => format!("Could not empty cache. Err: {e}"), - }), - } + Command::EmptyCache => { + wallet.empty_wallet_cache()?; + command_result!("Cache emptied successfully") + } + }) } diff --git a/cli/src/main.rs b/cli/src/main.rs index 3ee4467..f8bfc8b 100644 --- a/cli/src/main.rs +++ b/cli/src/main.rs @@ -6,7 +6,7 @@ use std::{fs, path::PathBuf}; use anyhow::{anyhow, Result}; use breez_sdk_liquid::{Network, Wallet}; use clap::Parser; -use commands::{handle_command, CliHelper, Command}; +use commands::{handle_command, CliHelper, Command, CommandResult}; use log::{error, info}; use persist::CliPersistence; use rustyline::{error::ReadlineError, hint::HistoryHinter, Editor}; @@ -17,11 +17,16 @@ pub(crate) struct Args { pub(crate) data_dir: Option, } -fn show_results(res: Result) { - match res { - Ok(inner) => println!("{inner}"), - Err(err) => eprintln!("Error: {err}"), - } +fn show_results(result: Result) -> Result<()> { + let result_str = match result { + Ok(r) => r, + Err(err) => serde_json::to_string_pretty(&CommandResult { + success: false, + message: err.to_string(), + })?, + }; + + Ok(println!("{result_str}")) } fn main() -> Result<()> { @@ -64,7 +69,7 @@ fn main() -> Result<()> { continue; } let res = handle_command(rl, &wallet, cli_res.unwrap()); - show_results(res); + show_results(res)?; } Err(ReadlineError::Interrupted) => { info!("CTRL-C"); diff --git a/lib/Cargo.lock b/lib/Cargo.lock index fc282b2..e447a19 100644 --- a/lib/Cargo.lock +++ b/lib/Cargo.lock @@ -267,6 +267,7 @@ dependencies = [ "lwk_wollet", "rusqlite", "rusqlite_migration", + "serde", "tempdir", "thiserror", "uuid", diff --git a/lib/Cargo.toml b/lib/Cargo.toml index 82d2d8c..3ed74c8 100644 --- a/lib/Cargo.toml +++ b/lib/Cargo.toml @@ -17,6 +17,7 @@ lwk_signer = "0.3.0" lwk_wollet = "0.3.0" rusqlite = "0.29" rusqlite_migration = "1.0" +serde = { version = "1.0.197", features = ["derive"] } thiserror = "1.0.57" [dev-dependencies] diff --git a/lib/src/model.rs b/lib/src/model.rs index 23400d6..b3975a1 100644 --- a/lib/src/model.rs +++ b/lib/src/model.rs @@ -2,6 +2,7 @@ use boltz_client::error::Error; use boltz_client::network::Chain; use lwk_signer::SwSigner; use lwk_wollet::{ElectrumUrl, ElementsNetwork, WolletDescriptor}; +use serde::Serialize; #[derive(Debug, Copy, Clone, PartialEq)] pub enum Network { @@ -62,7 +63,7 @@ pub struct ReceivePaymentRequest { pub onchain_amount_sat: Option, } -#[derive(Debug)] +#[derive(Debug, Serialize)] pub struct ReceivePaymentResponse { pub id: String, pub invoice: String, @@ -75,7 +76,7 @@ pub struct PreparePaymentResponse { pub funding_address: String, } -#[derive(Debug)] +#[derive(Debug, Serialize)] pub struct SendPaymentResponse { pub txid: String, } @@ -112,7 +113,7 @@ impl From for PaymentError { } } -#[derive(Debug)] +#[derive(Debug, Serialize)] pub struct WalletInfo { pub balance_sat: u64, pub pubkey: String, @@ -136,7 +137,7 @@ pub(crate) enum OngoingSwap { }, } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Serialize)] pub enum PaymentType { Sent, Received, @@ -144,11 +145,12 @@ pub enum PaymentType { PendingSend, } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, Serialize)] pub struct Payment { pub id: Option, pub timestamp: Option, pub amount_sat: u64, + #[serde(rename(serialize = "type"))] pub payment_type: PaymentType, }