// file: kb_rpc/src/validation.rs // version: 2 //! Shared validation helpers for Solana RPC addresses, hashes and signatures. /// Validates one base58 Solana transaction signature. pub fn validate_transaction_signature_text(value: &str, field_name: &str) -> kb_core::Result<()> { return crate::validation::validate_base58_length(value, field_name, 64); } /// Validates one base58 Solana public key or account address. pub fn validate_solana_pubkey_text(value: &str, field_name: &str) -> kb_core::Result<()> { return crate::validation::validate_base58_length(value, field_name, 32); } /// Validates one base58 Solana blockhash or genesis hash. pub fn validate_solana_hash_text(value: &str, field_name: &str) -> kb_core::Result<()> { return crate::validation::validate_base58_length(value, field_name, 32); } fn validate_base58_length( value: &str, field_name: &str, expected_length: usize, ) -> kb_core::Result<()> { if value.trim().is_empty() { return std::result::Result::Err(kb_core::Error::config(format!( "{field_name} must not be empty" ))); } let decode_result = bs58::decode(value).into_vec(); let decoded = match decode_result { std::result::Result::Ok(bytes) => bytes, std::result::Result::Err(error) => { return std::result::Result::Err(kb_core::Error::config(format!( "{field_name} is not valid base58: {error}" ))); }, }; if decoded.len() != expected_length { return std::result::Result::Err(kb_core::Error::config(format!( "{field_name} must decode to {expected_length} bytes" ))); } return std::result::Result::Ok(()); } #[cfg(test)] mod tests { #[test] fn signature_validation_accepts_sixty_four_bytes() { let signature = bs58::encode([7_u8; 64]).into_string(); let result = crate::validate_transaction_signature_text(&signature, "signature"); assert!(result.is_ok()); } #[test] fn pubkey_validation_accepts_thirty_two_bytes() { let pubkey = bs58::encode([9_u8; 32]).into_string(); let result = crate::validate_solana_pubkey_text(&pubkey, "pubkey"); assert!(result.is_ok()); } #[test] fn hash_validation_accepts_thirty_two_bytes() { let hash = bs58::encode([10_u8; 32]).into_string(); let result = crate::validate_solana_hash_text(&hash, "hash"); assert!(result.is_ok()); } #[test] fn signature_validation_rejects_public_key_length() { let pubkey = bs58::encode([11_u8; 32]).into_string(); let result = crate::validate_transaction_signature_text(&pubkey, "signature"); assert!(result.is_err()); } }