use subsoil::core::{crypto::ByteArray, ecdsa::Public};
pub trait ECDSAExt {
fn to_eth_address(&self) -> Result<[u8; 20], ()>;
}
impl ECDSAExt for Public {
fn to_eth_address(&self) -> Result<[u8; 20], ()> {
use k256::{elliptic_curve::sec1::ToEncodedPoint, PublicKey};
PublicKey::from_sec1_bytes(self.as_slice()).map_err(drop).and_then(|pub_key| {
let uncompressed = pub_key.to_encoded_point(false);
<[u8; 20]>::try_from(
subsoil::io::hashing::keccak_256(&uncompressed.as_bytes()[1..])[12..].as_ref(),
)
.map_err(drop)
})
}
}
#[cfg(test)]
mod tests {
use super::*;
use subsoil::core::{ecdsa, Pair};
#[test]
fn to_eth_address_works() {
let pair = ecdsa::Pair::from_string("//Alice//password", None).unwrap();
let eth_address = pair.public().to_eth_address().unwrap();
assert_eq!(
array_bytes::bytes2hex("0x", ð_address),
"0xdc1cce4263956850a3c8eb349dc6fc3f7792cb27"
);
}
}