mint.rs 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. use std::str::FromStr;
  2. use anyhow::{anyhow, Result};
  3. use cdk::amount::SplitTarget;
  4. use cdk::mint_url::MintUrl;
  5. use cdk::nuts::nut00::ProofsMethods;
  6. use cdk::nuts::{CurrencyUnit, MintQuoteState, NotificationPayload};
  7. use cdk::wallet::{MultiMintWallet, WalletSubscription};
  8. use cdk::Amount;
  9. use clap::Args;
  10. use serde::{Deserialize, Serialize};
  11. use crate::utils::get_or_create_wallet;
  12. #[derive(Args, Serialize, Deserialize)]
  13. pub struct MintSubCommand {
  14. /// Mint url
  15. mint_url: MintUrl,
  16. /// Amount
  17. amount: Option<u64>,
  18. /// Currency unit e.g. sat
  19. #[arg(default_value = "sat")]
  20. unit: String,
  21. /// Quote description
  22. #[serde(skip_serializing_if = "Option::is_none")]
  23. description: Option<String>,
  24. /// Quote Id
  25. #[arg(short, long)]
  26. quote_id: Option<String>,
  27. }
  28. pub async fn mint(
  29. multi_mint_wallet: &MultiMintWallet,
  30. sub_command_args: &MintSubCommand,
  31. ) -> Result<()> {
  32. let mint_url = sub_command_args.mint_url.clone();
  33. let unit = CurrencyUnit::from_str(&sub_command_args.unit)?;
  34. let description: Option<String> = sub_command_args.description.clone();
  35. let wallet = get_or_create_wallet(multi_mint_wallet, &mint_url, unit).await?;
  36. let quote_id = match &sub_command_args.quote_id {
  37. None => {
  38. let amount = sub_command_args
  39. .amount
  40. .ok_or(anyhow!("Amount must be defined"))?;
  41. let quote = wallet.mint_quote(Amount::from(amount), description).await?;
  42. println!("Quote: {quote:#?}");
  43. println!("Please pay: {}", quote.request);
  44. let mut subscription = wallet
  45. .subscribe(WalletSubscription::Bolt11MintQuoteState(vec![quote
  46. .id
  47. .clone()]))
  48. .await;
  49. while let Some(msg) = subscription.recv().await {
  50. if let NotificationPayload::MintQuoteBolt11Response(response) = msg {
  51. if response.state == MintQuoteState::Paid {
  52. break;
  53. }
  54. }
  55. }
  56. quote.id
  57. }
  58. Some(quote_id) => quote_id.to_string(),
  59. };
  60. let proofs = wallet.mint(&quote_id, SplitTarget::default(), None).await?;
  61. let receive_amount = proofs.total_amount()?;
  62. println!("Received {receive_amount} from mint {mint_url}");
  63. Ok(())
  64. }