token-proofs.rs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. //! Example: Decoding a token and getting proofs using MultiMintWallet
  2. //!
  3. //! This example demonstrates how to:
  4. //! 1. Create a MultiMintWallet
  5. //! 2. Decode a cashu token
  6. //! 3. Use `get_token_data` to extract mint URL and proofs in one call
  7. //! 4. Alternatively, get keysets manually and extract proofs
  8. use std::str::FromStr;
  9. use std::sync::Arc;
  10. use cdk::nuts::nut00::ProofsMethods;
  11. use cdk::nuts::{CurrencyUnit, Token};
  12. use cdk::wallet::MultiMintWallet;
  13. use cdk_sqlite::wallet::memory;
  14. use rand::random;
  15. #[tokio::main]
  16. async fn main() -> Result<(), Box<dyn std::error::Error>> {
  17. // Generate a random seed for the wallet
  18. let seed = random::<[u8; 64]>();
  19. // Initialize the memory store
  20. let localstore = Arc::new(memory::empty().await?);
  21. // Create a new multi-mint wallet for satoshis
  22. let wallet = MultiMintWallet::new(localstore, seed, CurrencyUnit::Sat).await?;
  23. // Example: A cashu token string (in practice, this would come from user input)
  24. let token = Token::from_str("cashuBo2FteB1odHRwczovL2Zha2UudGhlc2ltcGxla2lkLmRldmF1Y3NhdGF0gaJhaUgAlNWndMQKMmFwg6RhYRkIAGFzeEAwYjk0ZjU5ZjU0OTBkNTkzMzI4ZTIwNDllZTNlZmFjYjM5NzljZjU5NzA5ZTM3N2U5YzBmMDQyNDBmZTUyZTVhYWNYIQNGQCYyf1j996pS-LuP_7VsUE-uzRpAm-K4rZiDEFFc1GFko2FlWCBbuMkhvz39ytCzm7xPaY5vdTbqxlxTzXOsks_8S3sf1GFzWCBg22l0CXH5-QLcfJtUJZ2lfylNfC6_o9FTfKClLzthaGFyWCCP2nJ6Qzd8mwLa_85cu8TrwRIprElVgrhqJeoHJwXmSKRhYRkCAGFzeEBhNmMyODliMjMwMTdlMDhjYTFhOTc4ZjAwNGRiNjI4ZDk1NWI5ZTlmNjMwMjY0MjNjZDc4OGExNDBhOWJiYjgxYWNYIQPMXkT68L8Y0a6royMbkoUTbvxOUgsyDwvRZRNTvwUsWWFko2FlWCCj9BFXexBOrlUyUiY_1qEIEHvd1YphWA2l3YhdFwVRh2FzWCBTNgyGeXvGSFtvYKj3MnJCXA8qjI9fzZHFsIw-F_OAGmFyWCDRHiDbVysUuQZucifYx5zMvOKyVIz7zvcJcfd01FoI3KRhYQhhc3hAMWJjOWQ1MjE5ZTZhYzNjZmZhNTM0NTRkY2JjMzE1YzZjZjY5MmM5MDEzYTUzYTA1YzIzN2YwZTBiOTViZTkwMWFjWCEDXd5sxFgxYgUHctpLENYStcr50UtJ4QRojy0g7mkdvWRhZKNhZVggZzSifCUG692E2sW4L6DT_FuKwLZdUFoMnds3tQyMlAdhc1ggtIo0BS2-6arws5fJx_w0phOiCZZcHIFknlrDXSh3C0NhclggM2dDF0kQyuRoOqrOOMHFrmNnvtGiXWxuvqtD7HidR8I")?;
  25. // Get the mint URL from the token
  26. let mint_url = token.mint_url()?;
  27. println!("Token mint URL: {}", mint_url);
  28. // Get token value
  29. let value = token.value()?;
  30. println!("Token value: {} sats", value);
  31. // Get token memo if present
  32. if let Some(memo) = token.memo() {
  33. println!("Token memo: {}", memo);
  34. }
  35. // Add the mint to our wallet so we can fetch keysets
  36. wallet.add_mint(mint_url.clone()).await?;
  37. // =========================================================================
  38. // Method 1: Use get_token_data() for a simple one-call approach
  39. // =========================================================================
  40. println!("\n--- Using get_token_data() ---");
  41. let token_data = wallet.get_token_data(&token).await?;
  42. println!("Mint URL: {}", token_data.mint_url);
  43. println!("Number of proofs: {}", token_data.proofs.len());
  44. for (i, proof) in token_data.proofs.iter().enumerate() {
  45. println!(
  46. " Proof {}: {} sats, keyset: {}",
  47. i + 1,
  48. proof.amount,
  49. proof.keyset_id
  50. );
  51. }
  52. // =========================================================================
  53. // Method 2: Manual approach - get keysets first, then extract proofs
  54. // =========================================================================
  55. println!("\n--- Using manual keyset lookup ---");
  56. // Get the keysets for this mint
  57. let keysets = wallet.get_mint_keysets(&mint_url).await?;
  58. println!("Found {} keysets for mint", keysets.len());
  59. for keyset in &keysets {
  60. println!(
  61. " - Keyset ID: {}, Unit: {:?}, Active: {}",
  62. keyset.id, keyset.unit, keyset.active
  63. );
  64. }
  65. // Extract proofs from the token using the keysets
  66. let proofs = token.proofs(&keysets)?;
  67. println!("\nToken contains {} proofs:", proofs.len());
  68. // Calculate total amount from proofs
  69. let total = proofs.total_amount()?;
  70. println!("Total amount from proofs: {} sats", total);
  71. // Verify total matches token value
  72. assert_eq!(total, value, "Proof total should match token value");
  73. println!("\nSuccessfully decoded token and extracted proofs!");
  74. Ok(())
  75. }