utils.rs 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. //! Utils
  2. use base64::{engine::general_purpose, Engine as _};
  3. use bitcoin::Amount;
  4. use rand::prelude::*;
  5. /// Split amount into cashu denominations (powers of 2)
  6. pub fn split_amount(amount: Amount) -> Vec<Amount> {
  7. let mut chunks = Vec::new();
  8. let value = amount.to_sat();
  9. for i in 0..64 {
  10. let mask = 1 << i;
  11. if (value & mask) != 0 {
  12. chunks.push(Amount::from_sat(2u64.pow(i as u32)));
  13. }
  14. }
  15. chunks
  16. }
  17. /// Generate Secret Message
  18. pub fn generate_secret() -> String {
  19. let mut rng = rand::thread_rng();
  20. let mut secret = [0u8; 32];
  21. rng.fill_bytes(&mut secret);
  22. general_purpose::STANDARD.encode(secret)
  23. }
  24. #[cfg(test)]
  25. mod tests {
  26. use super::*;
  27. #[test]
  28. fn test_split_amount() {
  29. assert_eq!(split_amount(Amount::from_sat(1)), vec![Amount::from_sat(1)]);
  30. assert_eq!(split_amount(Amount::from_sat(2)), vec![Amount::from_sat(2)]);
  31. assert_eq!(
  32. split_amount(Amount::from_sat(3)),
  33. vec![Amount::from_sat(1), Amount::from_sat(2)]
  34. );
  35. let amounts: Vec<Amount> = vec![1, 2, 8].iter().map(|a| Amount::from_sat(*a)).collect();
  36. assert_eq!(split_amount(Amount::from_sat(11)), amounts);
  37. let amounts: Vec<Amount> = vec![1, 2, 4, 8, 16, 32, 64, 128]
  38. .iter()
  39. .map(|a| Amount::from_sat(*a))
  40. .collect();
  41. assert_eq!(split_amount(Amount::from_sat(255)), amounts);
  42. }
  43. }