ubl_sirp/
lib.rs

1#![forbid(unsafe_code)]
2#![deny(missing_docs)]
3#![allow(clippy::multiple_crate_versions)]
4//! SIRP network capsule + receipt handling (HTTP/server optional).
5//!
6//! Also provides minimal wire protocol via the `wire` module.
7
8/// Capsule encode/decode.
9pub mod capsule;
10/// Idempotency store (sqlite).
11#[cfg(feature = "sqlite")]
12pub mod idempotency;
13/// Receipt encode/verify.
14pub mod receipt;
15/// Minimal server/router.
16#[cfg(feature = "server")]
17pub mod server;
18/// HTTP transport helpers.
19#[cfg(feature = "http")]
20pub mod transport_http;
21/// SIRP Wire Protocol (TLV-based minimal frames).
22pub mod wire;
23
24pub use capsule::{build_capsule, parse_capsule, CapsuleBytes};
25pub use receipt::{sign_receipt, verify_receipt, Receipt};
26pub use wire::{
27    decode_frame, encode_frame, CanonIntent, SirpError, SirpFrame, DOMAIN_FRAME_SIGN, FLAG_SIGNED,
28    SIRP_MAGIC, SIRP_VERSION,
29};
30
31/// Convenience: build a `CanonIntent` from any JSON value.
32///
33/// Internally uses `json_atomic::canonize` for deterministic bytes
34/// and `ubl_crypto::blake3_cid` for the CID.
35///
36/// # Errors
37///
38/// Returns error if canonicalization fails.
39pub fn canon_intent_from_value(v: &serde_json::Value) -> Result<CanonIntent, SirpError> {
40    let bytes = json_atomic::canonize(v).map_err(|e| SirpError::Canon(format!("{e:?}")))?;
41    let cid = ubl_crypto::blake3_cid(&bytes);
42    Ok(CanonIntent { cid, bytes })
43}