use std::io::{self, Error, ErrorKind};
use crate::hash;
use primitive_types::H160;
pub fn h160_to_eth_address(h160_addr: &H160, chain_id: Option<u8>) -> String {
let prefixed_addr = match chain_id {
Some(chain_id) => format!("{chain_id}0x{h160_addr:x}"),
None => format!("{h160_addr:x}"),
};
let hex_h256 = hex::encode(hash::keccak256(prefixed_addr));
let hex_h256 = hex_h256.as_bytes();
let hex_addr = hex::encode(h160_addr.as_bytes());
let hex_addr = hex_addr.as_bytes();
hex_addr
.iter()
.zip(hex_h256)
.fold("0x".to_owned(), |mut s, (addr, hash)| {
s.push(if *hash >= 56 {
addr.to_ascii_uppercase() as char
} else {
addr.to_ascii_lowercase() as char
});
s
})
}
pub fn avax_address_to_short_bytes(chain_alias: &str, addr: &str) -> io::Result<(String, Vec<u8>)> {
let trimmed = if chain_alias.is_empty() {
addr.trim().to_string()
} else {
let pfx = if chain_alias.ends_with('-') {
chain_alias.to_string()
} else {
format!("{}-", chain_alias)
};
addr.trim_start_matches(&pfx).to_string()
};
let (hrp, data, _) = bech32::decode(&trimmed)
.map_err(|e| Error::new(ErrorKind::Other, format!("failed bech32::decode '{}'", e)))?;
let convert = bech32::convert_bits(&data, 5, 8, false).map_err(|e| {
Error::new(
ErrorKind::Other,
format!("failed bech32::convert_bits '{}'", e),
)
})?;
Ok((hrp, convert))
}
#[test]
fn test_avax_address_to_short_bytes() {
let _ = env_logger::builder()
.filter_level(log::LevelFilter::Info)
.is_test(true)
.try_init();
let pk = crate::key::secp256k1::private_key::Key::generate().unwrap();
let pubkey = pk.to_public_key();
let short_addr = pubkey.to_short_bytes().unwrap();
let x_avax_addr = pubkey.to_hrp_address(1, "X").unwrap();
let p_avax_addr = pubkey.to_hrp_address(1, "P").unwrap();
log::info!("AVAX X address: {}", x_avax_addr);
log::info!("AVAX P address: {}", p_avax_addr);
let (hrp, parsed_short_addr) = avax_address_to_short_bytes("X", &x_avax_addr).unwrap();
assert_eq!(hrp, "avax");
assert_eq!(parsed_short_addr, short_addr);
let (hrp, parsed_short_addr) = avax_address_to_short_bytes("P", &p_avax_addr).unwrap();
assert_eq!(hrp, "avax");
assert_eq!(parsed_short_addr, short_addr);
}