use alloy_signer::SignerSync;
use alloy_signer_local::PrivateKeySigner;
use crate::error::{Result, XmtpError};
use crate::types::{AccountIdentifier, IdentifierKind, Signer};
#[derive(Debug, Clone)]
pub struct AlloySigner {
inner: PrivateKeySigner,
}
impl AlloySigner {
pub fn from_hex(key: &str) -> Result<Self> {
let inner: PrivateKeySigner = key
.parse()
.map_err(|e: alloy_signer_local::LocalSignerError| XmtpError::Signing(e.to_string()))?;
Ok(Self { inner })
}
pub fn from_bytes(key: &[u8; 32]) -> Result<Self> {
let inner =
PrivateKeySigner::from_slice(key).map_err(|e| XmtpError::Signing(e.to_string()))?;
Ok(Self { inner })
}
#[must_use]
pub fn random() -> Self {
Self {
inner: PrivateKeySigner::random(),
}
}
#[must_use]
pub fn address(&self) -> String {
self.inner.address().to_checksum(None)
}
#[must_use]
pub fn into_inner(self) -> PrivateKeySigner {
self.inner
}
}
impl From<PrivateKeySigner> for AlloySigner {
fn from(inner: PrivateKeySigner) -> Self {
Self { inner }
}
}
impl Signer for AlloySigner {
fn identifier(&self) -> AccountIdentifier {
AccountIdentifier {
address: self.inner.address().to_string().to_lowercase(),
kind: IdentifierKind::Ethereum,
}
}
fn sign(&self, text: &str) -> Result<Vec<u8>> {
let sig = self
.inner
.sign_message_sync(text.as_bytes())
.map_err(|e| XmtpError::Signing(e.to_string()))?;
Ok(sig.as_bytes().to_vec())
}
}