create_request.rs 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. use anyhow::Result;
  2. use cdk::nuts::nut18::TransportType;
  3. use cdk::nuts::{CurrencyUnit, PaymentRequest, PaymentRequestPayload, Token, Transport};
  4. use cdk::wallet::MultiMintWallet;
  5. use clap::Args;
  6. use nostr_sdk::nips::nip19::Nip19Profile;
  7. use nostr_sdk::prelude::*;
  8. use nostr_sdk::{Client as NostrClient, Filter, Keys, ToBech32};
  9. #[derive(Args)]
  10. pub struct CreateRequestSubCommand {
  11. #[arg(short, long)]
  12. amount: Option<u64>,
  13. /// Currency unit e.g. sat
  14. #[arg(default_value = "sat")]
  15. unit: String,
  16. /// Quote description
  17. description: Option<String>,
  18. }
  19. pub async fn create_request(
  20. multi_mint_wallet: &MultiMintWallet,
  21. sub_command_args: &CreateRequestSubCommand,
  22. ) -> Result<()> {
  23. let keys = Keys::generate();
  24. let relays = vec!["wss://relay.nos.social", "wss://relay.damus.io"];
  25. let nprofile = Nip19Profile::new(keys.public_key, relays.clone())?;
  26. let nostr_transport = Transport {
  27. _type: TransportType::Nostr,
  28. target: nprofile.to_bech32()?,
  29. tags: Some(vec![vec!["n".to_string(), "17".to_string()]]),
  30. };
  31. let mints: Vec<cdk::mint_url::MintUrl> = multi_mint_wallet
  32. .get_balances(&CurrencyUnit::Sat)
  33. .await?
  34. .keys()
  35. .cloned()
  36. .collect();
  37. let req = PaymentRequest {
  38. payment_id: None,
  39. amount: sub_command_args.amount.map(|a| a.into()),
  40. unit: None,
  41. single_use: Some(true),
  42. mints: Some(mints),
  43. description: sub_command_args.description.clone(),
  44. transports: vec![nostr_transport],
  45. };
  46. println!("{}", req);
  47. let client = NostrClient::new(keys);
  48. let filter = Filter::new().pubkey(nprofile.public_key);
  49. for relay in relays {
  50. client.add_read_relay(relay).await?;
  51. }
  52. client.connect().await;
  53. client.subscribe(vec![filter], None).await?;
  54. // Handle subscription notifications with `handle_notifications` method
  55. client
  56. .handle_notifications(|notification| async {
  57. let mut exit = false;
  58. if let RelayPoolNotification::Event {
  59. subscription_id: _,
  60. event,
  61. ..
  62. } = notification
  63. {
  64. let unwrapped = client.unwrap_gift_wrap(&event).await?;
  65. let rumor = unwrapped.rumor;
  66. let payload: PaymentRequestPayload = serde_json::from_str(&rumor.content)?;
  67. let token = Token::new(payload.mint, payload.proofs, payload.memo, payload.unit);
  68. let amount = multi_mint_wallet
  69. .receive(&token.to_string(), &[], &[])
  70. .await?;
  71. println!("Received {}", amount);
  72. exit = true;
  73. }
  74. Ok(exit) // Set to true to exit from the loop
  75. })
  76. .await?;
  77. Ok(())
  78. }