newton-core 0.4.16

newton protocol core sdk
use alloy::{
    dyn_abi::SolType,
    primitives::{Bytes, ChainId},
    sol,
};
use bincode::error;
use serde_json::Value;

/// Chain module
pub mod chain;

/// Confidential-namespace key builders (see `docs/PRIVATE_DATA_STORAGE.md` § 5.2).
#[cfg(feature = "state-tree")]
pub mod confidential_key;
/// Identity-namespace key builders (see `docs/PRIVATE_DATA_STORAGE.md` § 5.1).
#[cfg(feature = "state-tree")]
pub mod identity_key;
/// Secrets-namespace key builders (see `docs/PRIVATE_DATA_STORAGE.md` § 5.3).
#[cfg(feature = "state-tree")]
pub mod secrets_key;

sol! {
    /// Evaluation result
    type EvaluationResult is bool;
}

/// Hex encode bool
pub fn hex_encode_bool(b: bool) -> Bytes {
    EvaluationResult::from(b).abi_encode().into()
}

/// Hex decode bool
pub fn hex_decode_bool(b: Bytes) -> bool {
    EvaluationResult::abi_decode(&b).unwrap()
}

/// Write serialized data to buffer
/// # Arguments
/// * `buffer` - The buffer to encode to
/// * `data` - The data to encode
pub fn write_serialized(buffer: &mut Vec<u8>, data: &[u8]) -> Result<(), error::EncodeError> {
    let mut input: Vec<u8> = Vec::new();
    bincode::encode_into_slice(data, &mut input, bincode::config::standard())?;
    buffer.extend_from_slice(&input);
    Ok(())
}

/// Recursively converts byte arrays (arrays of u8 values) in JSON to hex-encoded strings
/// for better readability in logs.
pub fn json_recursive_hex(value: Value) -> Value {
    match value {
        Value::Array(arr) => {
            // Check if this is a byte array (all elements are u8 numbers)
            let is_byte_array = arr
                .iter()
                .all(|v| if let Some(n) = v.as_u64() { n <= 255 } else { false });

            if is_byte_array && !arr.is_empty() {
                // Convert to hex string
                let bytes: Vec<u8> = arr.iter().map(|v| v.as_u64().unwrap() as u8).collect();
                Value::String(format!("0x{}", hex::encode(bytes)))
            } else {
                // Recursively process nested arrays
                Value::Array(arr.into_iter().map(json_recursive_hex).collect())
            }
        }
        Value::Object(map) => Value::Object(map.into_iter().map(|(k, v)| (k, json_recursive_hex(v))).collect()),
        other => other,
    }
}

/// bytes serialization module
pub mod bytes_serde {
    use alloy::primitives::Bytes;
    use serde::{Deserialize, Deserializer, Serializer};
    use std::str::FromStr;

    /// Deserialize bytes from hex string
    pub fn deserialize<'de, D>(deserializer: D) -> Result<Bytes, D::Error>
    where
        D: Deserializer<'de>,
    {
        let s = String::deserialize(deserializer)?;
        // If the string has odd length, pad with leading zero
        let padded = if s.len() % 2 != 0 { format!("0{}", s) } else { s };

        Bytes::from_str(&padded).map_err(serde::de::Error::custom)
    }

    /// Serialize bytes to hex string
    pub fn serialize<S>(bytes: &Bytes, serializer: S) -> Result<S::Ok, S::Error>
    where
        S: Serializer,
    {
        serializer.serialize_str(&crate::hex!(bytes))
    }
}