acta-maker-sdk 0.8.2

Rust SDK for the Acta options RFQ venue on Solana: maker and vault-operator WebSocket clients, order signing, chain builders
Documentation
use thiserror::Error;

/// Decodes a nullable field while requiring its JSON key to be present.
pub fn deserialize_required_option<'de, D, T>(deserializer: D) -> Result<Option<T>, D::Error>
where
    D: serde::Deserializer<'de>,
    T: serde::Deserialize<'de>,
{
    <Option<T> as serde::Deserialize>::deserialize(deserializer)
}

#[derive(Debug, Error)]
pub enum WireError {
    #[error("invalid hex: {0}")]
    InvalidHex(String),
    #[error("invalid base58: {0}")]
    InvalidBase58(String),
    #[error("invalid length: expected {expected}, got {actual}")]
    InvalidLength { expected: usize, actual: usize },
}

pub(crate) fn strip_0x(s: &str) -> &str {
    match s.strip_prefix("0x") {
        Some(rest) => rest,
        None => s,
    }
}

pub fn decode_hex_32(hex_str: &str) -> Result<[u8; 32], WireError> {
    let trimmed = strip_0x(hex_str);
    let bytes = hex::decode(trimmed).map_err(|err| WireError::InvalidHex(err.to_string()))?;
    if bytes.len() != 32 {
        return Err(WireError::InvalidLength {
            expected: 32,
            actual: bytes.len(),
        });
    }
    let mut out = [0u8; 32];
    out.copy_from_slice(&bytes);
    Ok(out)
}

pub fn decode_base58_32(value: &str) -> Result<[u8; 32], WireError> {
    decode_base58_fixed::<32>(value)
}

pub fn decode_base58_64(value: &str) -> Result<[u8; 64], WireError> {
    decode_base58_fixed::<64>(value)
}

pub fn encode_base58(bytes: &[u8]) -> String {
    bs58::encode(bytes).into_string()
}

pub fn encode_hex(bytes: &[u8]) -> String {
    hex::encode(bytes)
}

fn decode_base58_fixed<const N: usize>(value: &str) -> Result<[u8; N], WireError> {
    let bytes = bs58::decode(value)
        .into_vec()
        .map_err(|err| WireError::InvalidBase58(err.to_string()))?;
    if bytes.len() != N {
        return Err(WireError::InvalidLength {
            expected: N,
            actual: bytes.len(),
        });
    }
    let mut out = [0u8; N];
    out.copy_from_slice(&bytes);
    Ok(out)
}