#![no_std]
#[macro_use]
pub extern crate alloc;
#[cfg(feature = "std")]
extern crate std;
pub mod error;
pub mod sign;
pub mod utils;
pub mod verify;
pub use error::*;
#[allow(unused_imports)]
pub use sign::*;
pub use utils::*;
pub use verify::*;
use crate::Error;
use alloc::{
string::{String, ToString},
vec::Vec,
};
use bitcoin::{
Address, Amount, OutPoint, Psbt,
base64::{Engine, engine::general_purpose},
};
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum SignatureFormat {
Legacy,
Simple,
Full,
FullProofOfFunds,
}
pub trait BIP322 {
fn sign_message(
&mut self,
message: &str,
signature_type: SignatureFormat,
address: &Address,
utxos: Option<Vec<OutPoint>>,
) -> Result<MessageProof, Error>;
fn verify_message(
&self,
proof: &MessageProof,
message: &str,
address: &Address,
) -> Result<MessageVerificationResult, Error>;
}
pub struct MessageVerificationResult {
pub valid: bool,
pub proven_amount: Option<Amount>,
}
#[derive(Debug)]
pub enum MessageProof {
Signed(String),
Psbt(Psbt),
}
impl MessageProof {
pub fn to_base64(&self) -> String {
match self {
MessageProof::Signed(s) => s.clone(),
MessageProof::Psbt(psbt) => general_purpose::STANDARD.encode(psbt.serialize()),
}
}
pub fn from_base64(s: &str) -> Result<Self, Error> {
if let Ok(bytes) = general_purpose::STANDARD.decode(s) {
if let Ok(psbt) = Psbt::deserialize(&bytes) {
return Ok(MessageProof::Psbt(psbt));
}
}
Ok(MessageProof::Signed(s.to_string()))
}
}