cashu/util/
mod.rs

1//! Cashu utils
2
3pub mod hex;
4
5use bitcoin::secp256k1::{rand, All, Secp256k1};
6use once_cell::sync::Lazy;
7use web_time::{SystemTime, UNIX_EPOCH};
8
9/// Secp256k1 global context
10pub static SECP256K1: Lazy<Secp256k1<All>> = Lazy::new(|| {
11    let mut ctx = Secp256k1::new();
12    let mut rng = rand::thread_rng();
13    ctx.randomize(&mut rng);
14    ctx
15});
16
17/// Seconds since unix epoch
18pub fn unix_time() -> u64 {
19    SystemTime::now()
20        .duration_since(UNIX_EPOCH)
21        .unwrap_or_default()
22        .as_secs()
23}
24
25#[derive(Debug, thiserror::Error)]
26/// Error type for serialization
27pub enum CborError {
28    /// CBOR serialization error
29    #[error("CBOR serialization error")]
30    Cbor(#[from] ciborium::ser::Error<std::io::Error>),
31
32    /// CBOR diagnostic notation error
33    #[error("CBOR diagnostic notation error: {0}")]
34    CborDiag(#[from] cbor_diag::Error),
35}
36
37/// Serializes a struct to the CBOR diagnostic notation.
38///
39/// See <https://www.rfc-editor.org/rfc/rfc8949.html#name-diagnostic-notation>
40pub fn serialize_to_cbor_diag<T: serde::Serialize>(data: &T) -> Result<String, CborError> {
41    let mut cbor_buffer = Vec::<u8>::new();
42    ciborium::ser::into_writer(data, &mut cbor_buffer)?;
43
44    let diag = cbor_diag::parse_bytes(&cbor_buffer)?;
45    Ok(diag.to_diag_pretty())
46}