#![cfg_attr(not(feature = "std"), no_std)]
extern crate alloc;
use alloc::vec::Vec;
mod error;
mod macros;
pub use error::SignError;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SignOutput {
pub signature: Vec<u8>,
pub recovery_id: Option<u8>,
pub public_key: Option<Vec<u8>>,
}
impl SignOutput {
#[must_use]
pub const fn secp256k1(signature: Vec<u8>, recovery_id: u8) -> Self {
Self {
signature,
recovery_id: Some(recovery_id),
public_key: None,
}
}
#[must_use]
pub const fn ed25519(signature: Vec<u8>) -> Self {
Self {
signature,
recovery_id: None,
public_key: None,
}
}
#[must_use]
pub const fn ed25519_with_pubkey(signature: Vec<u8>, public_key: Vec<u8>) -> Self {
Self {
signature,
recovery_id: None,
public_key: Some(public_key),
}
}
}
pub trait Sign: Send + Sync {
type Error: core::fmt::Debug + core::fmt::Display + From<SignError> + Send + Sync;
fn sign_hash(&self, hash: &[u8]) -> Result<SignOutput, Self::Error>;
fn sign_message(&self, message: &[u8]) -> Result<SignOutput, Self::Error>;
fn sign_transaction(&self, tx_bytes: &[u8]) -> Result<SignOutput, Self::Error>;
fn extract_signable_bytes<'a>(&self, tx_bytes: &'a [u8]) -> Result<&'a [u8], Self::Error> {
Ok(tx_bytes)
}
fn encode_signed_transaction(
&self,
_tx_bytes: &[u8],
_signature: &SignOutput,
) -> Result<Vec<u8>, Self::Error> {
Err(
SignError::InvalidTransaction("encode_signed_transaction not implemented".into())
.into(),
)
}
}
pub trait SignExt: Sign {
fn sign_hash_bytes(&self, hash: &[u8]) -> Result<Vec<u8>, Self::Error> {
self.sign_hash(hash).map(|out| out.signature)
}
fn sign_transaction_bytes(&self, tx_bytes: &[u8]) -> Result<Vec<u8>, Self::Error> {
self.sign_transaction(tx_bytes).map(|out| out.signature)
}
}
impl<T: Sign> SignExt for T {}