koios-sdk 0.1.1

A Rust SDK for the Koios Cardano API
Documentation
use serde::{Deserialize, Serialize};

/// Block height for specifying time delta
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub struct AfterBlockHeight(pub u64);

/// Epoch Number to fetch details for
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EpochNo(pub String);

/// Cardano staking address (reward account) in bech32 format
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct StakeAddress(pub String);

/// Transaction Hash in hexadecimal format (hex)
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct TxHash(pub String);

/// Asset Policy ID in hexadecimal format (hex)
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AssetPolicy(pub String);

/// Asset Name in hexadecimal format (hex)
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AssetName(pub String);

/// NFT Policy ID in hexadecimal format (hex)
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AssetPolicyNft(pub String);

/// NFT Name in hexadecimal format (hex)
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AssetNameNft(pub String);

/// Voter ID (Drep, SPO, Committee Member) in Bech32 format (CIP-5 | CIP-129)
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VoterId(pub String);

/// DRep ID in bech32 format
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DrepId(pub String);

/// Committee member hot key ID in Bech32 format (CIP-5 | CIP-129)
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CcHotId(pub String);

/// Controls whether or not certain optional fields are populated
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub struct Extended(pub bool);

/// Include all historical transactions
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub struct History(pub bool);

/// Include information about nearing but not yet started epoch
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub struct IncludeNextEpoch(pub bool);

/// Pool ID in bech32 format
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PoolBech32(pub String);

/// Script hash in hexadecimal format (hex)
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ScriptHash(pub String);

/// Government proposal ID in CIP-129 Bech32 format
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ProposalId(pub String);

// Implementations for parameter validation and conversion

impl AfterBlockHeight {
    pub fn new(height: u64) -> Self {
        Self(height)
    }

    pub fn value(&self) -> u64 {
        self.0
    }
}

impl EpochNo {
    pub fn new<S: Into<String>>(epoch: S) -> Self {
        Self(epoch.into())
    }

    pub fn value(&self) -> &str {
        &self.0
    }
}

impl StakeAddress {
    pub fn new<S: Into<String>>(address: S) -> Self {
        Self(address.into())
    }

    pub fn value(&self) -> &str {
        &self.0
    }

    // Basic validation for bech32 stake address format
    pub fn validate(&self) -> bool {
        self.0.starts_with("stake1")
    }
}

impl TxHash {
    pub fn new<S: Into<String>>(hash: S) -> Self {
        Self(hash.into())
    }

    pub fn value(&self) -> &str {
        &self.0
    }

    // Basic validation for hex format
    pub fn validate(&self) -> bool {
        self.0.chars().all(|c| c.is_ascii_hexdigit())
    }
}

impl AssetPolicy {
    pub fn new<S: Into<String>>(policy: S) -> Self {
        Self(policy.into())
    }

    pub fn value(&self) -> &str {
        &self.0
    }

    // Basic validation for hex format
    pub fn validate(&self) -> bool {
        self.0.chars().all(|c| c.is_ascii_hexdigit())
    }
}

impl AssetName {
    pub fn new<S: Into<String>>(name: S) -> Self {
        Self(name.into())
    }

    pub fn value(&self) -> &str {
        &self.0
    }

    // Basic validation for hex format
    pub fn validate(&self) -> bool {
        self.0.chars().all(|c| c.is_ascii_hexdigit())
    }
}

impl AssetPolicyNft {
    pub fn new<S: Into<String>>(policy: S) -> Self {
        Self(policy.into())
    }

    pub fn value(&self) -> &str {
        &self.0
    }

    // Basic validation for hex format
    pub fn validate(&self) -> bool {
        self.0.chars().all(|c| c.is_ascii_hexdigit())
    }
}

impl AssetNameNft {
    pub fn new<S: Into<String>>(name: S) -> Self {
        Self(name.into())
    }

    pub fn value(&self) -> &str {
        &self.0
    }

    // Basic validation for hex format
    pub fn validate(&self) -> bool {
        self.0.chars().all(|c| c.is_ascii_hexdigit())
    }
}

impl VoterId {
    pub fn new<S: Into<String>>(voter_id: S) -> Self {
        Self(voter_id.into())
    }

    pub fn value(&self) -> &str {
        &self.0
    }

    // Basic validation for bech32 format
    pub fn validate(&self) -> bool {
        self.0.starts_with("drep1") || self.0.starts_with("pool1") || self.0.starts_with("cc_hot1")
    }
}

impl DrepId {
    pub fn new<S: Into<String>>(drep_id: S) -> Self {
        Self(drep_id.into())
    }

    pub fn value(&self) -> &str {
        &self.0
    }

    // Basic validation for bech32 format
    pub fn validate(&self) -> bool {
        self.0.starts_with("drep1")
    }
}

impl CcHotId {
    pub fn new<S: Into<String>>(cc_hot_id: S) -> Self {
        Self(cc_hot_id.into())
    }

    pub fn value(&self) -> &str {
        &self.0
    }

    // Basic validation for bech32 format
    pub fn validate(&self) -> bool {
        self.0.starts_with("cc_hot1")
    }
}

impl Extended {
    pub fn new(extended: bool) -> Self {
        Self(extended)
    }

    pub fn value(&self) -> bool {
        self.0
    }
}

impl History {
    pub fn new(history: bool) -> Self {
        Self(history)
    }

    pub fn value(&self) -> bool {
        self.0
    }
}

impl IncludeNextEpoch {
    pub fn new(include: bool) -> Self {
        Self(include)
    }

    pub fn value(&self) -> bool {
        self.0
    }
}

impl PoolBech32 {
    pub fn new<S: Into<String>>(pool_id: S) -> Self {
        Self(pool_id.into())
    }

    pub fn value(&self) -> &str {
        &self.0
    }

    // Basic validation for bech32 format
    pub fn validate(&self) -> bool {
        self.0.starts_with("pool1")
    }
}

impl ScriptHash {
    pub fn new<S: Into<String>>(hash: S) -> Self {
        Self(hash.into())
    }

    pub fn value(&self) -> &str {
        &self.0
    }

    // Basic validation for hex format
    pub fn validate(&self) -> bool {
        self.0.chars().all(|c| c.is_ascii_hexdigit())
    }
}

impl ProposalId {
    pub fn new<S: Into<String>>(proposal_id: S) -> Self {
        Self(proposal_id.into())
    }

    pub fn value(&self) -> &str {
        &self.0
    }

    // Basic validation for bech32 format
    pub fn validate(&self) -> bool {
        self.0.starts_with("gov_action1")
    }
}

// Unit tests for parameter validation
#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_stake_address_validation() {
        let valid =
            StakeAddress::new("stake1u8yxtugdv63wxafy9d00nuz6hjyyp4qnggvc9a3vxh8yl0ckml2uz");
        let invalid = StakeAddress::new("invalid_address");

        assert!(valid.validate());
        assert!(!invalid.validate());
    }
    #[test]
    fn test_tx_hash_validation() {
        let valid = TxHash::new("f144a8264acf4bdfe2e1241170969c930d64ab6b0996a4a45237b623f1dd670e");
        let invalid = TxHash::new("invalid_hash!");

        assert!(valid.validate());
        assert!(!invalid.validate());
    }

    // Add more tests for other parameter validations...
}