78 lines
2.7 KiB
Rust
78 lines
2.7 KiB
Rust
// 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());
|
|
}
|
|
}
|