mint.rs 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  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::types::WalletKey;
  8. use cdk::wallet::{MultiMintWallet, WalletSubscription};
  9. use cdk::Amount;
  10. use clap::Args;
  11. use serde::{Deserialize, Serialize};
  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 = match multi_mint_wallet
  36. .get_wallet(&WalletKey::new(mint_url.clone(), unit.clone()))
  37. .await
  38. {
  39. Some(wallet) => wallet.clone(),
  40. None => {
  41. tracing::debug!("Wallet does not exist creating..");
  42. multi_mint_wallet
  43. .create_and_add_wallet(&mint_url.to_string(), unit, None)
  44. .await?
  45. }
  46. };
  47. let quote_id = match &sub_command_args.quote_id {
  48. None => {
  49. let amount = sub_command_args
  50. .amount
  51. .ok_or(anyhow!("Amount must be defined"))?;
  52. let quote = wallet.mint_quote(Amount::from(amount), description).await?;
  53. println!("Quote: {:#?}", quote);
  54. println!("Please pay: {}", quote.request);
  55. let mut subscription = wallet
  56. .subscribe(WalletSubscription::Bolt11MintQuoteState(vec![quote
  57. .id
  58. .clone()]))
  59. .await;
  60. while let Some(msg) = subscription.recv().await {
  61. if let NotificationPayload::MintQuoteBolt11Response(response) = msg {
  62. if response.state == MintQuoteState::Paid {
  63. break;
  64. }
  65. }
  66. }
  67. quote.id
  68. }
  69. Some(quote_id) => quote_id.to_string(),
  70. };
  71. let proofs = wallet.mint(&quote_id, SplitTarget::default(), None).await?;
  72. let receive_amount = proofs.total_amount()?;
  73. println!("Received {receive_amount} from mint {mint_url}");
  74. Ok(())
  75. }