use crate::{RippleAddress, RippleFormat};
use anychain_core::{hex, libsecp256k1, Address, AddressError, PublicKey, PublicKeyError};
use core::{fmt, str::FromStr};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct RipplePublicKey {
public_key: libsecp256k1::PublicKey,
compressed: bool,
}
impl PublicKey for RipplePublicKey {
type SecretKey = libsecp256k1::SecretKey;
type Address = RippleAddress;
type Format = RippleFormat;
fn from_secret_key(secret_key: &Self::SecretKey) -> Self {
Self {
public_key: libsecp256k1::PublicKey::from_secret_key(secret_key),
compressed: true,
}
}
fn to_address(&self, format: &Self::Format) -> Result<Self::Address, AddressError> {
Self::Address::from_public_key(self, format)
}
}
impl RipplePublicKey {
pub fn from_secp256k1_public_key(
public_key: libsecp256k1::PublicKey,
compressed: bool,
) -> Self {
Self {
public_key,
compressed,
}
}
pub fn to_secp256k1_public_key(&self) -> libsecp256k1::PublicKey {
self.public_key
}
pub fn serialize(&self) -> Vec<u8> {
match self.compressed {
true => self.public_key.serialize_compressed().to_vec(),
false => self.public_key.serialize().to_vec(),
}
}
pub fn is_compressed(&self) -> bool {
self.compressed
}
}
impl FromStr for RipplePublicKey {
type Err = PublicKeyError;
fn from_str(public_key: &str) -> Result<Self, Self::Err> {
Ok(Self {
public_key: libsecp256k1::PublicKey::parse_slice(&hex::decode(public_key)?, None)?,
compressed: public_key.len() == 66,
})
}
}
impl fmt::Display for RipplePublicKey {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if self.compressed {
for s in &self.public_key.serialize_compressed()[..] {
write!(f, "{:02x}", s)?;
}
} else {
for s in &self.public_key.serialize()[..] {
write!(f, "{:02x}", s)?;
}
}
Ok(())
}
}