use crate::error::{Result, SignerError};
pub use libp2p_identity::PeerId;
pub trait ToPeerId {
fn to_peer_id(&self) -> Result<PeerId>;
}
#[cfg(feature = "secp256k1")]
impl ToPeerId for crate::schemes::secp256k1::PublicKey {
fn to_peer_id(&self) -> Result<PeerId> {
peer_id_from_secp256k1(self)
}
}
#[cfg(feature = "secp256k1")]
pub fn peer_id_from_secp256k1(public: &crate::schemes::secp256k1::PublicKey) -> Result<PeerId> {
let key = libp2p_identity::secp256k1::PublicKey::try_from_bytes(&public.to_bytes())
.map_err(|e| SignerError::InvalidKey(format!("Invalid secp256k1 for PeerId: {e}")))?;
Ok(PeerId::from_public_key(&libp2p_identity::PublicKey::from(
key,
)))
}
#[cfg(feature = "ed25519")]
impl ToPeerId for crate::schemes::ed25519::PublicKey {
fn to_peer_id(&self) -> Result<PeerId> {
peer_id_from_ed25519(self)
}
}
#[cfg(feature = "ed25519")]
pub fn peer_id_from_ed25519(public: &crate::schemes::ed25519::PublicKey) -> Result<PeerId> {
let key = libp2p_identity::ed25519::PublicKey::try_from_bytes(&public.to_bytes())
.map_err(|e| SignerError::InvalidKey(format!("Invalid ed25519 for PeerId: {e}")))?;
Ok(PeerId::from_public_key(&libp2p_identity::PublicKey::from(
key,
)))
}
#[cfg(test)]
mod tests {
use super::*;
#[cfg(feature = "secp256k1")]
#[test]
fn test_secp256k1_to_peer_id() {
use crate::schemes::secp256k1::PrivateKey;
let private = PrivateKey::random();
let public = private.public_key();
let peer_id_trait = public.to_peer_id().unwrap();
let peer_id_fn = peer_id_from_secp256k1(&public).unwrap();
assert_eq!(peer_id_trait, peer_id_fn);
assert!(!peer_id_trait.to_string().is_empty());
}
#[cfg(feature = "ed25519")]
#[test]
fn test_ed25519_to_peer_id() {
use crate::schemes::ed25519::PrivateKey;
let private = PrivateKey::random();
let public = private.public_key();
let peer_id_trait = public.to_peer_id().unwrap();
let peer_id_fn = peer_id_from_ed25519(&public).unwrap();
assert_eq!(peer_id_trait, peer_id_fn);
assert!(!peer_id_trait.to_string().is_empty());
}
#[cfg(all(feature = "secp256k1", feature = "ed25519"))]
#[test]
fn test_different_schemes_produce_different_peer_ids() {
use crate::schemes::{
ed25519::PrivateKey as Ed25519Private, secp256k1::PrivateKey as Secp256k1Private,
};
let secp_private = Secp256k1Private::random();
let secp_public = secp_private.public_key();
let secp_peer_id = secp_public.to_peer_id().unwrap();
let ed_private = Ed25519Private::random();
let ed_public = ed_private.public_key();
let ed_peer_id = ed_public.to_peer_id().unwrap();
assert_ne!(secp_peer_id, ed_peer_id);
}
#[cfg(feature = "secp256k1")]
#[test]
fn test_deterministic_peer_id() {
use crate::schemes::secp256k1::PrivateKey;
let private = PrivateKey::random();
let public = private.public_key();
let peer_id_1 = public.to_peer_id().unwrap();
let peer_id_2 = public.to_peer_id().unwrap();
assert_eq!(peer_id_1, peer_id_2);
}
}