use std::time::{SystemTime, UNIX_EPOCH};
pub fn current_timestamp() -> u64 {
SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs()
}
pub fn bytes_to_hex(bytes: &[u8]) -> String {
bytes.iter().map(|b| format!("{:02x}", b)).collect()
}
use std::fmt;
#[derive(Debug)]
pub struct HexError(String);
impl fmt::Display for HexError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Invalid hex string: {}", self.0)
}
}
impl std::error::Error for HexError {}
pub fn hex_to_bytes(hex: &str) -> Result<Vec<u8>, HexError> {
if hex.len() % 2 != 0 {
return Err(HexError("Invalid hex length".to_string()));
}
let mut bytes = Vec::with_capacity(hex.len() / 2);
let mut chars = hex.chars();
while let (Some(h), Some(l)) = (chars.next(), chars.next()) {
let byte =
u8::from_str_radix(&format!("{}{}", h, l), 16).map_err(|e| HexError(e.to_string()))?;
bytes.push(byte);
}
Ok(bytes)
}
pub fn validate_bech32(address: &str) -> bool {
address.starts_with("addr1")
|| address.starts_with("stake1")
|| address.starts_with("pool1")
|| address.starts_with("drep1")
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_hex_conversion() {
let bytes = vec![0xde, 0xad, 0xbe, 0xef];
let hex = bytes_to_hex(&bytes);
assert_eq!(hex, "deadbeef");
assert_eq!(hex_to_bytes(&hex).unwrap(), bytes);
}
#[test]
fn test_validate_bech32() {
assert!(validate_bech32("addr1qxqs59lphg8g6qndelq8xwqn60ag3aeyfcp33c2kdp46a09re5df3pzwwmyq946axfcejy5n4x0y99wqpgtp2gd0k09qsgy6pz"));
assert!(validate_bech32(
"stake1ux3g2c9dx2nhhehyrezyxpkstartcqmu9hk63qgfkccw5rqttygt7"
));
assert!(!validate_bech32("invalid_address"));
}
}