Skip to main content

acta_maker_sdk/
wire.rs

1use thiserror::Error;
2
3/// Decodes a nullable field while requiring its JSON key to be present.
4pub fn deserialize_required_option<'de, D, T>(deserializer: D) -> Result<Option<T>, D::Error>
5where
6    D: serde::Deserializer<'de>,
7    T: serde::Deserialize<'de>,
8{
9    <Option<T> as serde::Deserialize>::deserialize(deserializer)
10}
11
12#[derive(Debug, Error)]
13pub enum WireError {
14    #[error("invalid hex: {0}")]
15    InvalidHex(String),
16    #[error("invalid base58: {0}")]
17    InvalidBase58(String),
18    #[error("invalid length: expected {expected}, got {actual}")]
19    InvalidLength { expected: usize, actual: usize },
20}
21
22pub(crate) fn strip_0x(s: &str) -> &str {
23    match s.strip_prefix("0x") {
24        Some(rest) => rest,
25        None => s,
26    }
27}
28
29pub fn decode_hex_32(hex_str: &str) -> Result<[u8; 32], WireError> {
30    let trimmed = strip_0x(hex_str);
31    let bytes = hex::decode(trimmed).map_err(|err| WireError::InvalidHex(err.to_string()))?;
32    if bytes.len() != 32 {
33        return Err(WireError::InvalidLength {
34            expected: 32,
35            actual: bytes.len(),
36        });
37    }
38    let mut out = [0u8; 32];
39    out.copy_from_slice(&bytes);
40    Ok(out)
41}
42
43pub fn decode_base58_32(value: &str) -> Result<[u8; 32], WireError> {
44    decode_base58_fixed::<32>(value)
45}
46
47pub fn decode_base58_64(value: &str) -> Result<[u8; 64], WireError> {
48    decode_base58_fixed::<64>(value)
49}
50
51pub fn encode_base58(bytes: &[u8]) -> String {
52    bs58::encode(bytes).into_string()
53}
54
55pub fn encode_hex(bytes: &[u8]) -> String {
56    hex::encode(bytes)
57}
58
59fn decode_base58_fixed<const N: usize>(value: &str) -> Result<[u8; N], WireError> {
60    let bytes = bs58::decode(value)
61        .into_vec()
62        .map_err(|err| WireError::InvalidBase58(err.to_string()))?;
63    if bytes.len() != N {
64        return Err(WireError::InvalidLength {
65            expected: N,
66            actual: bytes.len(),
67        });
68    }
69    let mut out = [0u8; N];
70    out.copy_from_slice(&bytes);
71    Ok(out)
72}