diff --git a/moksha-cli/src/bin/moksha-cli.rs b/moksha-cli/src/bin/moksha-cli.rs index 8e242cd4..86f8291c 100644 --- a/moksha-cli/src/bin/moksha-cli.rs +++ b/moksha-cli/src/bin/moksha-cli.rs @@ -10,6 +10,7 @@ use moksha_wallet::client::CashuClient; use moksha_wallet::http::CrossPlatformHttpClient; +use moksha_wallet::localstore::WalletKeysetFilter; use mokshacli::cli::{self, choose_mint, get_mints_with_balance}; use num_format::{Locale, ToFormattedString}; use qrcode::render::unicode; @@ -151,9 +152,8 @@ async fn main() -> anyhow::Result<()> { let wallet_keysets = wallet.get_wallet_keysets().await?; let wallet_keyset = wallet_keysets - .iter() - .find(|k| k.mint_url == token_mint_url) - .expect("Keyset not found"); + .get_active(&token_mint_url, &CurrencyUnit::Sat) + .expect("no active keyset found"); wallet.receive_tokens(wallet_keyset, &token).await?; cli::show_total_balance(&wallet).await?; @@ -170,9 +170,8 @@ async fn main() -> anyhow::Result<()> { let wallet_keysets = wallet.get_wallet_keysets().await?; let wallet_keyset = wallet_keysets - .iter() - .find(|k| k.mint_url == mint_url) - .expect("Keyset not found"); + .get_active(&mint_url, &CurrencyUnit::Sat) + .expect("no active keyset found"); term.write_line(&format!("Using tokens from mint: {mint_url}"))?; let result = wallet.send_tokens(wallet_keyset, amount).await?; @@ -201,15 +200,15 @@ async fn main() -> anyhow::Result<()> { cli::show_total_balance(&wallet).await?; } Command::Pay { invoice } => { - let mint_url = choose_mint(&wallet, &CurrencyUnit::Sat).await?.0; + let currency_unit = CurrencyUnit::Sat; + let mint_url = choose_mint(&wallet, ¤cy_unit).await?.0; let wallet_keysets = wallet.get_wallet_keysets().await?; let wallet_keyset = wallet_keysets - .iter() - .find(|k| k.mint_url == mint_url) - .expect("Keyset not found"); + .get_active(&mint_url, ¤cy_unit) + .expect("no active keyset found"); let quote = wallet - .get_melt_quote_bolt11(&mint_url, invoice.clone(), CurrencyUnit::Sat) + .get_melt_quote_bolt11(&mint_url, invoice.clone(), currency_unit) .await?; let pay_confirmed = Confirm::new() @@ -254,8 +253,7 @@ async fn main() -> anyhow::Result<()> { let wallet_keysets = wallet.get_wallet_keysets().await?; let wallet_keyset = wallet_keysets - .iter() - .find(|k| k.mint_url == mint_url) + .get_active(&mint_url, &CurrencyUnit::Sat) .expect("Keyset not found"); let info = wallet.get_mint_info(&mint_url).await?; @@ -398,8 +396,7 @@ async fn main() -> anyhow::Result<()> { let wallet_keysets = wallet.get_wallet_keysets().await?; let wallet_keyset = wallet_keysets - .iter() - .find(|k| k.mint_url == mint_url) + .get_active(&mint_url, &CurrencyUnit::Sat) .expect("Keyset not found"); let progress_bar = cli::progress_bar()?; diff --git a/moksha-cli/src/cli.rs b/moksha-cli/src/cli.rs index 9705c909..b1023dfb 100644 --- a/moksha-cli/src/cli.rs +++ b/moksha-cli/src/cli.rs @@ -68,7 +68,7 @@ pub async fn get_mints_with_balance( } Ok(keysets .into_iter() - .filter(|k| &k.currency_unit == currency_unit) + .filter(|k| &k.currency_unit == currency_unit && k.active) .map(|k| { ( k.mint_url, diff --git a/moksha-wallet/src/http/reqwest.rs b/moksha-wallet/src/http/reqwest.rs index 4dd79be4..caefb27c 100644 --- a/moksha-wallet/src/http/reqwest.rs +++ b/moksha-wallet/src/http/reqwest.rs @@ -1,10 +1,10 @@ use super::CrossPlatformHttpClient; use crate::error::MokshaWalletError; -use moksha_core::primitives::CashuErrorResponse; use reqwest::{ header::{HeaderValue, CONTENT_TYPE}, Response, StatusCode, }; +use serde_json::Value; use url::Url; impl CrossPlatformHttpClient { @@ -23,32 +23,38 @@ impl CrossPlatformHttpClient { match serde_json::from_str::(&response_text) { Ok(data) => Ok(data), Err(_) => { - let data = serde_json::from_str::(&response_text) + // FIXME cleanup code + let data: Value = serde_json::from_str(&response_text) .map_err(|_| MokshaWalletError::UnexpectedResponse(response_text)) - .unwrap(); + .expect("invalid value"); + let detail = data["detail"].as_str().expect("detail not found"); + // let data = serde_json::from_str::(&response_text) + // .map_err(|_| MokshaWalletError::UnexpectedResponse(response_text)) + // .unwrap(); // FIXME: use the error code to return a proper error - match data.detail.as_str() { + match detail { "Lightning invoice not paid yet." => { - Err(MokshaWalletError::InvoiceNotPaidYet(data.code, data.detail)) + Err(MokshaWalletError::InvoiceNotPaidYet(0, detail.to_owned())) } - _ => Err(MokshaWalletError::MintError(data.detail)), + _ => Err(MokshaWalletError::MintError(detail.to_owned())), } } } } _ => { - let txt = response.text().await?; - let data = serde_json::from_str::(&txt) - .map_err(|_| MokshaWalletError::UnexpectedResponse(txt)) - .unwrap(); + let response_text = response.text().await?; + let data: Value = serde_json::from_str(&response_text) + .map_err(|_| MokshaWalletError::UnexpectedResponse(response_text)) + .expect("invalid value"); + let detail = data["detail"].as_str().expect("detail not found"); // FIXME: use the error code to return a proper error - match data.detail.as_str() { + match detail { "Lightning invoice not paid yet." => { - Err(MokshaWalletError::InvoiceNotPaidYet(data.code, data.detail)) + Err(MokshaWalletError::InvoiceNotPaidYet(0, detail.to_owned())) } - _ => Err(MokshaWalletError::MintError(data.detail)), + _ => Err(MokshaWalletError::MintError(detail.to_owned())), } } } diff --git a/moksha-wallet/src/localstore/mod.rs b/moksha-wallet/src/localstore/mod.rs index c4120c9c..73d27531 100644 --- a/moksha-wallet/src/localstore/mod.rs +++ b/moksha-wallet/src/localstore/mod.rs @@ -26,6 +26,17 @@ pub struct WalletKeyset { pub active: bool, } +impl WalletKeysetFilter for Vec { + fn get_active(&self, mint_url: &Url, currency_unit: &CurrencyUnit) -> Option<&WalletKeyset> { + self.iter() + .find(|k| k.mint_url == *mint_url && k.currency_unit == *currency_unit && k.active) + } +} + +pub trait WalletKeysetFilter { + fn get_active(&self, mint_url: &Url, currency_unit: &CurrencyUnit) -> Option<&WalletKeyset>; +} + impl WalletKeyset { pub fn new( keyset_id: &KeysetId, diff --git a/moksha-wallet/src/wallet.rs b/moksha-wallet/src/wallet.rs index 94c0009a..08a38e2a 100644 --- a/moksha-wallet/src/wallet.rs +++ b/moksha-wallet/src/wallet.rs @@ -210,27 +210,35 @@ where return Err(MokshaWalletError::UnsupportedApiVersion); } - // FIXME cleanup code let mint_keysets = self.client.get_keysets(mint_url).await?; let mut tx = self.localstore.begin_tx().await?; let mut result = vec![]; for keyset in mint_keysets.keysets.iter() { - let public_keys = self + let keysets = self .client .get_keys_by_id(mint_url, keyset.id.clone()) - .await? - .keysets - .into_iter() - .find(|k| k.id == keyset.id) - .expect("no valid keyset found") - .keys - .clone(); + .await; + + let public_keys = match keysets { + Ok(k) => k + .keysets + .into_iter() + .find(|k| k.id == keyset.id && k.unit == keyset.unit) + .expect("no valid keyset found") + .keys + .clone(), + Err(_) => { + //println!("Ignoring keyset without public_keys {:?}", keyset.id); + continue; + } + }; // ignore legacy keysets let keyset_id = match KeysetId::new(&keyset.id) { Ok(id) => id, Err(_) => { + //println!("Ignoring legacy keyset {:?}", keyset.id); continue; } }; @@ -243,6 +251,7 @@ where public_keys, keyset.active, ); + result.push(wallet_keyset.clone()); self.localstore .upsert_keyset(&mut tx, &wallet_keyset) @@ -496,7 +505,7 @@ where let keyset = all_keysets .iter() .find(|k| k.keyset_id == *keyset_id) - .expect("keyset not found"); + .expect("keyset not found create-secrets"); let start_index = (keyset.last_index + 1) as u32; let secret_range = self.secret.derive_range(keyset_id, start_index, amount)?;