utils.rs 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. //! Utils
  2. use bitcoin::hashes::sha256::Hash as Sha256;
  3. use bitcoin::hashes::Hash;
  4. use rand::prelude::*;
  5. use regex::Regex;
  6. use crate::Amount;
  7. /// Split amount into cashu denominations (powers of 2)
  8. pub fn split_amount(amount: Amount) -> Vec<Amount> {
  9. let mut chunks = Vec::new();
  10. let value = amount.to_sat();
  11. for i in 0..64 {
  12. let mask = 1 << i;
  13. if (value & mask) != 0 {
  14. chunks.push(Amount::from_sat(2u64.pow(i as u32)));
  15. }
  16. }
  17. chunks
  18. }
  19. pub fn extract_url_from_error(error: &str) -> Option<String> {
  20. let regex = Regex::new(r"https?://[^\s]+").unwrap();
  21. if let Some(capture) = regex.captures(error) {
  22. return Some(capture[0].to_owned());
  23. }
  24. None
  25. }
  26. pub fn random_hash() -> Vec<u8> {
  27. let mut rng = rand::thread_rng();
  28. let mut random_bytes = [0u8; Sha256::LEN];
  29. rng.fill_bytes(&mut random_bytes);
  30. let hash = Sha256::hash(&random_bytes);
  31. hash.to_byte_array().to_vec()
  32. }
  33. #[cfg(test)]
  34. mod tests {
  35. use super::*;
  36. #[test]
  37. fn test_split_amount() {
  38. assert_eq!(split_amount(Amount::from_sat(1)), vec![Amount::from_sat(1)]);
  39. assert_eq!(split_amount(Amount::from_sat(2)), vec![Amount::from_sat(2)]);
  40. assert_eq!(
  41. split_amount(Amount::from_sat(3)),
  42. vec![Amount::from_sat(1), Amount::from_sat(2)]
  43. );
  44. let amounts: Vec<Amount> = vec![1, 2, 8].iter().map(|a| Amount::from_sat(*a)).collect();
  45. assert_eq!(split_amount(Amount::from_sat(11)), amounts);
  46. let amounts: Vec<Amount> = vec![1, 2, 4, 8, 16, 32, 64, 128]
  47. .iter()
  48. .map(|a| Amount::from_sat(*a))
  49. .collect();
  50. assert_eq!(split_amount(Amount::from_sat(255)), amounts);
  51. }
  52. }