Skip to content

Commit

Permalink
fix: use tokens from selected wallet/keyset
Browse files Browse the repository at this point in the history
  • Loading branch information
ngutech21 committed Apr 3, 2024
1 parent 199b561 commit 7bbe788
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 15 deletions.
54 changes: 41 additions & 13 deletions moksha-cli/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use clap::{Parser, Subcommand};
use dialoguer::{theme::ColorfulTheme, Confirm, Select};
use moksha_core::keyset::KeysetIdType;
use moksha_core::primitives::{
CurrencyUnit, PaymentMethod, PostMeltBtcOnchainResponse, PostMintQuoteBolt11Response,
PostMintQuoteBtcOnchainResponse,
Expand All @@ -11,7 +12,6 @@ use moksha_wallet::http::CrossPlatformHttpClient;
use moksha_wallet::localstore::sqlite::SqliteLocalStore;
use moksha_wallet::wallet::Wallet;
use num_format::{Locale, ToFormattedString};
use std::collections::HashSet;
use std::io::Write;
use std::process::exit;
use std::str::FromStr;
Expand Down Expand Up @@ -156,7 +156,14 @@ async fn main() -> anyhow::Result<()> {
);
}
Command::Send { amount } => {
let mint_url = choose_mint_url(&wallet).await?;
let mint_url = choose_mint(&wallet, KeysetIdType::Sat).await?;

if mint_url.1 < amount {
println!("Error: Not enough tokens in selected mint");
return Ok(());
}

let mint_url = mint_url.0;

let wallet_keysets = wallet.get_wallet_keysets().await?;
let wallet_keyset = wallet_keysets
Expand All @@ -179,7 +186,7 @@ async fn main() -> anyhow::Result<()> {
println!("Balance: {balance} (sat)");
}
Command::Pay { invoice } => {
let mint_url = choose_mint_url(&wallet).await?;
let mint_url = choose_mint(&wallet, KeysetIdType::Sat).await?.0;
let wallet_keysets = wallet.get_wallet_keysets().await?;
let wallet_keyset = wallet_keysets
.iter()
Expand Down Expand Up @@ -225,7 +232,14 @@ async fn main() -> anyhow::Result<()> {
}
Command::PayOnchain { address, amount } => {
// FIXME remove redundant code
let mint_url = choose_mint_url(&wallet).await?;
let mint_url = choose_mint(&wallet, KeysetIdType::Sat).await?;

if mint_url.1 < amount {
println!("Error: Not enough tokens in selected mint");
return Ok(());
}
let mint_url = mint_url.0;

let wallet_keysets = wallet.get_wallet_keysets().await?;
let wallet_keyset = wallet_keysets
.iter()
Expand Down Expand Up @@ -288,7 +302,7 @@ async fn main() -> anyhow::Result<()> {
}
}
Command::Mint { amount } => {
let mint_url = choose_mint_url(&wallet).await?;
let mint_url = choose_mint(&wallet, KeysetIdType::Sat).await?.0;

let info = wallet.get_mint_info(&mint_url).await?;

Expand Down Expand Up @@ -399,29 +413,43 @@ async fn main() -> anyhow::Result<()> {
Ok(())
}

pub async fn choose_mint_url(
pub async fn choose_mint(
wallet: &Wallet<SqliteLocalStore, CrossPlatformHttpClient>,
) -> Result<Url, MokshaWalletError> {
keysetid_type: KeysetIdType,
) -> Result<(Url, u64), MokshaWalletError> {
let all_proofs = wallet.get_proofs().await?;

let keysets = wallet.get_wallet_keysets().await?;
if keysets.is_empty() {
println!("No keysets found.");
exit(1)
}
let mints: HashSet<Url> = keysets.into_iter().map(|k| k.mint_url).collect();
let mints: Vec<Url> = mints.into_iter().collect();
let mints: Vec<(Url, u64)> = keysets
.into_iter()
.filter(|k| k.keyset_id.keyset_type() == keysetid_type)
.map(|k| {
(
k.mint_url,
all_proofs.proofs_by_keyset(&k.keyset_id).total_amount(),
)
})
.collect();

if mints.len() == 1 {
println!("No mints found.");
exit(1)
}

let mints_display = mints
.iter()
.map(|(url, balance)| format!("{url} - {balance} (sat)"))
.collect::<Vec<String>>();

let selection = Select::with_theme(&ColorfulTheme::default())
.with_prompt("Choose a mint:")
.default(0)
.items(&mints[..])
.items(&mints_display[..])
.interact()
.unwrap();
let url = mints[selection].clone();

Ok(url)
Ok(mints[selection].clone())
}
4 changes: 4 additions & 0 deletions moksha-core/src/keyset.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,10 @@ impl KeysetId {
let num = u64::from_be_bytes(bytes_array);
Ok((num % (2u64.pow(31) - 1)) as u32)
}

pub fn keyset_type(&self) -> KeysetIdType {
self.0.clone()
}
}

impl ToString for KeysetId {
Expand Down
11 changes: 10 additions & 1 deletion moksha-core/src/proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use serde::{Deserialize, Serialize};
use serde_with::skip_serializing_none;
use utoipa::ToSchema;

use crate::error::MokshaCoreError;
use crate::{error::MokshaCoreError, keyset::KeysetId};

#[skip_serializing_none]
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, ToSchema)]
Expand Down Expand Up @@ -77,6 +77,15 @@ impl Proofs {
self.0.is_empty()
}

pub fn proofs_by_keyset(&self, keyset_id: &KeysetId) -> Self {
self.0
.iter()
.filter(|proof| proof.keyset_id == keyset_id.to_string())
.cloned()
.collect::<Vec<Proof>>()
.into()
}

pub fn proofs_for_amount(&self, amount: u64) -> Result<Self, MokshaCoreError> {
let mut all_proofs = self.0.clone();
if amount > self.total_amount() {
Expand Down
14 changes: 13 additions & 1 deletion moksha-wallet/src/wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,8 +270,13 @@ where
}

let mut tx = self.localstore.begin_tx().await?;
let all_proofs = self.localstore.get_proofs(&mut tx).await?;
let all_proofs = self
.localstore
.get_proofs(&mut tx)
.await?
.proofs_by_keyset(&wallet_keyset.keyset_id);
tx.commit().await?;

let selected_proofs = all_proofs.proofs_for_amount(amount)?;
let selected_tokens = (wallet_keyset.mint_url.to_owned(), selected_proofs.clone()).into();

Expand Down Expand Up @@ -780,6 +785,13 @@ where
.collect::<Vec<Proof>>()
.into())
}

pub async fn get_proofs(&self) -> Result<Proofs, MokshaWalletError> {
let mut tx = self.localstore.begin_tx().await?;
let proofs = self.localstore.get_proofs(&mut tx).await?;
tx.commit().await?;
Ok(proofs)
}
}

// FIXME implement for Vec<BlindedMessage, Secretkey>
Expand Down

0 comments on commit 7bbe788

Please sign in to comment.