diff --git a/src/client/mod.rs b/src/client/mod.rs index 51f5297..7d97d7d 100644 --- a/src/client/mod.rs +++ b/src/client/mod.rs @@ -4,7 +4,7 @@ use reqwest::blocking::Client; use log::info; use rust_decimal::Decimal; -use std::net::TcpListener; +use std::{collections::HashSet, net::TcpListener}; pub mod queries; pub use queries::*; @@ -15,10 +15,22 @@ pub use error::*; pub mod batch; pub use batch::Batch; -use self::query_me::WalletCurrency; +pub use self::query_me::WalletCurrency; + +use crate::types::*; pub mod server; +impl From<&WalletCurrency> for Wallet { + fn from(currency: &WalletCurrency) -> Self { + match currency { + WalletCurrency::USD => Wallet::Usd, + WalletCurrency::BTC => Wallet::Btc, + _ => panic!("Unsupported currency"), + } + } +} + pub struct GaloyClient { graphql_client: Client, api: String, @@ -97,6 +109,46 @@ impl GaloyClient { Ok(me) } + pub fn fetch_balance( + &self, + wallet_type: Option, + wallet_ids: Vec, + ) -> anyhow::Result> { + let me = self.me()?; + let default_wallet_id = me.default_account.default_wallet_id; + let wallets = &me.default_account.wallets; + + let wallet_ids_set: HashSet<_> = wallet_ids.into_iter().collect(); + + let balances: Vec<_> = wallets + .iter() + .filter(|wallet_info| { + wallet_ids_set.contains(&wallet_info.id) + || wallet_type.as_ref().map_or(wallet_ids_set.is_empty(), |w| { + *w == Wallet::from(&wallet_info.wallet_currency) + }) + }) + .map(|wallet_info| WalletBalance { + currency: format!("{:?}", Wallet::from(&wallet_info.wallet_currency)), + balance: wallet_info.balance, + id: if wallet_info.wallet_currency == WalletCurrency::USD + || wallet_info.wallet_currency == WalletCurrency::BTC + { + None + } else { + Some(wallet_info.id.clone()) + }, + default: wallet_info.id == default_wallet_id, + }) + .collect(); + + if balances.is_empty() { + Err(anyhow::anyhow!("No matching wallet found")) + } else { + Ok(balances) + } + } + pub fn request_phone_code(&self, phone: String, nocaptcha: bool) -> std::io::Result<()> { match nocaptcha { false => { diff --git a/src/client/queries.rs b/src/client/queries.rs index 0400205..a3463be 100644 --- a/src/client/queries.rs +++ b/src/client/queries.rs @@ -41,7 +41,7 @@ pub use self::query_globals::QueryGlobalsGlobals; query_path = "src/client/graphql/queries/me.graphql", response_derives = "Debug, Serialize, PartialEq" )] -pub(super) struct QueryMe; +pub struct QueryMe; pub use self::query_me::QueryMeMe; // mutations diff --git a/src/lib.rs b/src/lib.rs index 610f485..1b404bf 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,3 +4,5 @@ mod client; pub use client::*; + +pub mod types; diff --git a/src/main.rs b/src/main.rs index 1e1b49d..f0ab6ca 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,6 +15,8 @@ use std::fs::{self}; mod constants; mod token; +use galoy_cli::types::*; + #[derive(Parser)] #[clap(author, version, about, long_about = None)] struct Cli { @@ -65,6 +67,15 @@ enum Commands { }, /// Execute Me query Me, + /// Fetch the balance of a wallet + Balance { + #[clap(long)] + btc: bool, + #[clap(long)] + usd: bool, + #[clap(long, use_value_delimiter = true)] + wallet_ids: Vec, + }, /// Execute a Payment Pay { #[clap(short, long)] @@ -82,12 +93,6 @@ enum Commands { Batch { filename: String, price: Decimal }, } -#[derive(Debug, Clone, clap::ValueEnum, PartialEq, Eq)] -enum Wallet { - Btc, - Usd, -} - fn main() -> anyhow::Result<()> { log::set_max_level(LevelFilter::Warn); @@ -128,6 +133,24 @@ fn main() -> anyhow::Result<()> { serde_json::to_string_pretty(&result).expect("Can't serialize json") ); } + Commands::Balance { + btc, + usd, + wallet_ids, + } => { + let wallet_type = match (btc, usd) { + (true, true) | (false, false) => None, + (true, false) => Some(Wallet::Btc), + (false, true) => Some(Wallet::Usd), + }; + + let balances = galoy_cli + .fetch_balance(wallet_type, wallet_ids) + .context("can't fetch balance")?; + let balances_json = + serde_json::to_string_pretty(&balances).context("Can't serialize json")?; + println!("{}", balances_json); + } Commands::Pay { username, wallet, diff --git a/src/types.rs b/src/types.rs new file mode 100644 index 0000000..065d01d --- /dev/null +++ b/src/types.rs @@ -0,0 +1,16 @@ +use rust_decimal::Decimal; +use serde::Serialize; + +#[derive(Debug, Clone, clap::ValueEnum, PartialEq, Eq)] +pub enum Wallet { + Btc, + Usd, +} + +#[derive(Debug, Serialize)] +pub struct WalletBalance { + pub currency: String, + pub balance: Decimal, + pub id: Option, + pub default: bool, +}