use crate::EncodingError;
use crate::multicodec::MultiEncoded;
pub const BASE58BTC_PREFIX: char = 'z';
pub fn decode_base58btc(s: &str) -> Result<Vec<u8>, EncodingError> {
let Some(encoded) = s.strip_prefix(BASE58BTC_PREFIX) else {
let prefix = s.chars().next().unwrap_or('\0');
return Err(EncodingError::InvalidMultibasePrefix(prefix));
};
bs58::decode(encoded)
.into_vec()
.map_err(|e| EncodingError::InvalidBase58(e.to_string()))
}
pub fn encode_base58btc(bytes: &[u8]) -> String {
format!("{}{}", BASE58BTC_PREFIX, bs58::encode(bytes).into_string())
}
pub fn validate_base58btc(s: &str) -> Result<(), EncodingError> {
decode_base58btc(s)?;
Ok(())
}
pub fn decode_multikey(key: &str) -> Result<Vec<u8>, EncodingError> {
let bytes = decode_base58btc(key)?;
let multi_encoded = MultiEncoded::new(&bytes)?;
Ok(multi_encoded.data().to_vec())
}
pub fn decode_multikey_with_codec(key: &str) -> Result<(u64, Vec<u8>), EncodingError> {
let bytes = decode_base58btc(key)?;
let multi_encoded = MultiEncoded::new(&bytes)?;
Ok((multi_encoded.codec(), multi_encoded.data().to_vec()))
}
pub fn encode_multikey(codec: u64, key_bytes: &[u8]) -> String {
let encoded = crate::multicodec::MultiEncodedBuf::encode_bytes(codec, key_bytes);
encode_base58btc(encoded.as_bytes())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_decode_base58btc() {
let result = decode_base58btc("zCn8eVZg").unwrap();
assert_eq!(result, b"hello");
}
#[test]
fn test_encode_base58btc() {
let encoded = encode_base58btc(b"hello");
assert_eq!(encoded, "zCn8eVZg");
}
#[test]
fn test_roundtrip() {
let original = b"test data for encoding";
let encoded = encode_base58btc(original);
let decoded = decode_base58btc(&encoded).unwrap();
assert_eq!(decoded, original);
}
#[test]
fn test_invalid_prefix() {
let result = decode_base58btc("fABCDEF"); assert!(matches!(
result.unwrap_err(),
EncodingError::InvalidMultibasePrefix('f')
));
}
#[test]
fn test_invalid_base58() {
let result = decode_base58btc("z0OIl");
assert!(matches!(
result.unwrap_err(),
EncodingError::InvalidBase58(_)
));
}
#[test]
fn test_did_key_identifier() {
let id = "z6MkhaXgBZDvotDkL5257faiztiGiC2QtKLGpbnnEGta2doK";
let result = decode_base58btc(id);
assert!(result.is_ok());
let bytes = result.unwrap();
assert_eq!(bytes[0], 0xed);
}
}