thesimplekid 1 сар өмнө
parent
commit
de5f9111e1

+ 52 - 9
crates/cdk-cli/src/sub_commands/melt.rs

@@ -10,7 +10,10 @@ use clap::Args;
 use tokio::task::JoinSet;
 
 use crate::sub_commands::balance::mint_balances;
-use crate::utils::{get_number_input, get_user_input, get_wallet_by_index, validate_mint_number};
+use crate::utils::{
+    get_number_input, get_user_input, get_wallet_by_index, get_wallet_by_mint_url,
+    validate_mint_number,
+};
 
 #[derive(Args)]
 pub struct MeltSubCommand {
@@ -18,8 +21,11 @@ pub struct MeltSubCommand {
     #[arg(default_value = "sat")]
     unit: String,
     /// Mpp
-    #[arg(short, long)]
+    #[arg(short, long, conflicts_with = "mint_url")]
     mpp: bool,
+    /// Mint URL to use for melting
+    #[arg(long, conflicts_with = "mpp")]
+    mint_url: Option<String>,
 }
 
 pub async fn pay(
@@ -32,6 +38,31 @@ pub async fn pay(
     let mut mints = vec![];
     let mut mint_amounts = vec![];
     if sub_command_args.mpp {
+        // MPP functionality expects multiple mints, so mint_url flag doesn't fully apply here,
+        // but we can offer to use the specified mint as the first one if provided
+        if let Some(mint_url) = &sub_command_args.mint_url {
+            println!("Using mint URL {mint_url} as the first mint for MPP payment.");
+
+            // Check if the mint exists
+            if let Ok(_wallet) =
+                get_wallet_by_mint_url(multi_mint_wallet, mint_url, unit.clone()).await
+            {
+                // Find the index of this mint in the mints_amounts list
+                if let Some(mint_index) = mints_amounts
+                    .iter()
+                    .position(|(url, _)| url.to_string() == *mint_url)
+                {
+                    mints.push(mint_index);
+                    let melt_amount: u64 =
+                        get_number_input("Enter amount to mint from this mint in sats.")?;
+                    mint_amounts.push(melt_amount);
+                } else {
+                    println!("Warning: Mint URL exists but no balance found. Continuing with manual selection.");
+                }
+            } else {
+                println!("Warning: Could not find wallet for the specified mint URL. Continuing with manual selection.");
+            }
+        }
         loop {
             let mint_number: String =
                 get_user_input("Enter mint number to melt from and -1 when done.")?;
@@ -122,16 +153,28 @@ pub async fn pay(
             bail!("Could not complete all melts");
         }
     } else {
-        let mint_number: usize = get_number_input("Enter mint number to melt from")?;
-
-        let wallet =
+        // Get wallet either by mint URL or by index
+        let wallet = if let Some(mint_url) = &sub_command_args.mint_url {
+            // Use the provided mint URL
+            get_wallet_by_mint_url(multi_mint_wallet, mint_url, unit.clone()).await?
+        } else {
+            // Fallback to the index-based selection
+            let mint_number: usize = get_number_input("Enter mint number to melt from")?;
             get_wallet_by_index(multi_mint_wallet, &mints_amounts, mint_number, unit.clone())
-                .await?;
+                .await?
+        };
 
-        let bolt11 = Bolt11Invoice::from_str(&get_user_input("Enter bolt11 invoice request")?)?;
+        // Find the mint amount for the selected wallet to check available funds
+        let mint_url = &wallet.mint_url;
+        let mint_amount = mints_amounts
+            .iter()
+            .find(|(url, _)| url == mint_url)
+            .map(|(_, amount)| *amount)
+            .ok_or_else(|| anyhow::anyhow!("Could not find balance for mint: {}", mint_url))?;
 
-        let available_funds =
-            <cdk::Amount as Into<u64>>::into(mints_amounts[mint_number].1) * MSAT_IN_SAT;
+        let available_funds = <cdk::Amount as Into<u64>>::into(mint_amount) * MSAT_IN_SAT;
+
+        let bolt11 = Bolt11Invoice::from_str(&get_user_input("Enter bolt11 invoice request")?)?;
 
         // Determine payment amount and options
         let options = if bolt11.amount_milli_satoshis().is_none() {

+ 25 - 6
crates/cdk-cli/src/sub_commands/send.rs

@@ -1,6 +1,6 @@
 use std::str::FromStr;
 
-use anyhow::Result;
+use anyhow::{anyhow, Result};
 use cdk::nuts::{Conditions, CurrencyUnit, PublicKey, SpendingConditions};
 use cdk::wallet::types::SendKind;
 use cdk::wallet::{MultiMintWallet, SendMemo, SendOptions};
@@ -8,7 +8,9 @@ use cdk::Amount;
 use clap::Args;
 
 use crate::sub_commands::balance::mint_balances;
-use crate::utils::{check_sufficient_funds, get_number_input, get_wallet_by_index};
+use crate::utils::{
+    check_sufficient_funds, get_number_input, get_wallet_by_index, get_wallet_by_mint_url,
+};
 
 #[derive(Args)]
 pub struct SendSubCommand {
@@ -45,6 +47,9 @@ pub struct SendSubCommand {
     /// Amount willing to overpay to avoid a swap
     #[arg(short, long)]
     tolerance: Option<u64>,
+    /// Mint URL to use for sending
+    #[arg(long)]
+    mint_url: Option<String>,
     /// Currency unit e.g. sat
     #[arg(default_value = "sat")]
     unit: String,
@@ -57,13 +62,27 @@ pub async fn send(
     let unit = CurrencyUnit::from_str(&sub_command_args.unit)?;
     let mints_amounts = mint_balances(multi_mint_wallet, &unit).await?;
 
-    let mint_number: usize = get_number_input("Enter mint number to create token")?;
-
-    let wallet = get_wallet_by_index(multi_mint_wallet, &mints_amounts, mint_number, unit).await?;
+    // Get wallet either by mint URL or by index
+    let wallet = if let Some(mint_url) = &sub_command_args.mint_url {
+        // Use the provided mint URL
+        get_wallet_by_mint_url(multi_mint_wallet, mint_url, unit).await?
+    } else {
+        // Fallback to the index-based selection
+        let mint_number: usize = get_number_input("Enter mint number to create token")?;
+        get_wallet_by_index(multi_mint_wallet, &mints_amounts, mint_number, unit).await?
+    };
 
     let token_amount = Amount::from(get_number_input::<u64>("Enter value of token in sats")?);
 
-    check_sufficient_funds(mints_amounts[mint_number].1, token_amount)?;
+    // Find the mint amount for the selected wallet to check if we have sufficient funds
+    let mint_url = &wallet.mint_url;
+    let mint_amount = mints_amounts
+        .iter()
+        .find(|(url, _)| url == mint_url)
+        .map(|(_, amount)| *amount)
+        .ok_or_else(|| anyhow!("Could not find balance for mint: {}", mint_url))?;
+
+    check_sufficient_funds(mint_amount, token_amount)?;
 
     let conditions = match (&sub_command_args.preimage, &sub_command_args.hash) {
         (Some(_), Some(_)) => {

+ 17 - 0
crates/cdk-cli/src/utils.rs

@@ -44,6 +44,23 @@ pub fn check_sufficient_funds(available: Amount, required: Amount) -> Result<()>
     Ok(())
 }
 
+/// Helper function to get a wallet from the multi-mint wallet by mint URL
+pub async fn get_wallet_by_mint_url(
+    multi_mint_wallet: &MultiMintWallet,
+    mint_url_str: &str,
+    unit: CurrencyUnit,
+) -> Result<cdk::wallet::Wallet> {
+    let mint_url = MintUrl::from_str(mint_url_str)?;
+
+    let wallet_key = WalletKey::new(mint_url.clone(), unit);
+    let wallet = multi_mint_wallet
+        .get_wallet(&wallet_key)
+        .await
+        .ok_or_else(|| anyhow::anyhow!("Wallet not found for mint URL: {}", mint_url_str))?;
+
+    Ok(wallet.clone())
+}
+
 /// Helper function to get a wallet from the multi-mint wallet
 pub async fn get_wallet_by_index(
     multi_mint_wallet: &MultiMintWallet,