melt.rs 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. use std::io;
  2. use std::io::Write;
  3. use std::str::FromStr;
  4. use anyhow::{bail, Result};
  5. use cdk::amount::MSAT_IN_SAT;
  6. use cdk::nuts::{CurrencyUnit, MeltOptions};
  7. use cdk::wallet::multi_mint_wallet::MultiMintWallet;
  8. use cdk::wallet::types::WalletKey;
  9. use cdk::Bolt11Invoice;
  10. use clap::Args;
  11. use crate::sub_commands::balance::mint_balances;
  12. #[derive(Args)]
  13. pub struct MeltSubCommand {
  14. /// Currency unit e.g. sat
  15. #[arg(default_value = "sat")]
  16. unit: String,
  17. /// Mpp
  18. #[arg(short, long)]
  19. mpp: bool,
  20. }
  21. pub async fn pay(
  22. multi_mint_wallet: &MultiMintWallet,
  23. sub_command_args: &MeltSubCommand,
  24. ) -> Result<()> {
  25. let unit = CurrencyUnit::from_str(&sub_command_args.unit)?;
  26. let mints_amounts = mint_balances(multi_mint_wallet, &unit).await?;
  27. println!("Enter mint number to melt from");
  28. let mut user_input = String::new();
  29. let stdin = io::stdin();
  30. io::stdout().flush().unwrap();
  31. stdin.read_line(&mut user_input)?;
  32. let mint_number: usize = user_input.trim().parse()?;
  33. if mint_number.gt(&(mints_amounts.len() - 1)) {
  34. bail!("Invalid mint number");
  35. }
  36. let wallet = mints_amounts[mint_number].0.clone();
  37. let wallet = multi_mint_wallet
  38. .get_wallet(&WalletKey::new(wallet, unit))
  39. .await
  40. .expect("Known wallet");
  41. println!("Enter bolt11 invoice request");
  42. let mut user_input = String::new();
  43. let stdin = io::stdin();
  44. io::stdout().flush().unwrap();
  45. stdin.read_line(&mut user_input)?;
  46. let bolt11 = Bolt11Invoice::from_str(user_input.trim())?;
  47. let mut options: Option<MeltOptions> = None;
  48. if sub_command_args.mpp {
  49. println!("Enter the amount you would like to pay in sats, for a mpp payment.");
  50. let mut user_input = String::new();
  51. let stdin = io::stdin();
  52. io::stdout().flush().unwrap();
  53. stdin.read_line(&mut user_input)?;
  54. let user_amount = user_input.trim_end().parse::<u64>()?;
  55. if user_amount
  56. .gt(&(<cdk::Amount as Into<u64>>::into(mints_amounts[mint_number].1) * MSAT_IN_SAT))
  57. {
  58. bail!("Not enough funds");
  59. }
  60. options = Some(MeltOptions::new_mpp(user_amount * MSAT_IN_SAT));
  61. } else if bolt11
  62. .amount_milli_satoshis()
  63. .unwrap()
  64. .gt(&(<cdk::Amount as Into<u64>>::into(mints_amounts[mint_number].1) * MSAT_IN_SAT))
  65. {
  66. bail!("Not enough funds");
  67. }
  68. let quote = wallet.melt_quote(bolt11.to_string(), options).await?;
  69. println!("{:?}", quote);
  70. let melt = wallet.melt(&quote.id).await?;
  71. println!("Paid invoice: {}", melt.state);
  72. if let Some(preimage) = melt.preimage {
  73. println!("Payment preimage: {}", preimage);
  74. }
  75. Ok(())
  76. }