1#![cfg(feature = "full")]
2
3use {
4 crate::{
5 pubkey::Pubkey,
6 signature::{PresignerError, Signature},
7 transaction::TransactionError,
8 },
9 itertools::Itertools,
10 thiserror::Error,
11};
12
13pub mod keypair;
14pub mod null_signer;
15pub mod presigner;
16pub mod signers;
17
18#[derive(Debug, Error, PartialEq, Eq)]
19pub enum SignerError {
20 #[error("keypair-pubkey mismatch")]
21 KeypairPubkeyMismatch,
22
23 #[error("not enough signers")]
24 NotEnoughSigners,
25
26 #[error("transaction error")]
27 TransactionError(#[from] TransactionError),
28
29 #[error("custom error: {0}")]
30 Custom(String),
31
32 #[error("presigner error")]
34 PresignerError(#[from] PresignerError),
35
36 #[error("connection error: {0}")]
38 Connection(String),
39
40 #[error("invalid input: {0}")]
41 InvalidInput(String),
42
43 #[error("no device found")]
44 NoDeviceFound,
45
46 #[error("{0}")]
47 Protocol(String),
48
49 #[error("{0}")]
50 UserCancel(String),
51
52 #[error("too many signers")]
53 TooManySigners,
54}
55
56pub trait Signer {
60 fn pubkey(&self) -> Pubkey {
63 self.try_pubkey().unwrap_or_default()
64 }
65 fn try_pubkey(&self) -> Result<Pubkey, SignerError>;
67 fn sign_message(&self, message: &[u8]) -> Signature {
70 self.try_sign_message(message).unwrap_or_default()
71 }
72 fn try_sign_message(&self, message: &[u8]) -> Result<Signature, SignerError>;
74 fn is_interactive(&self) -> bool;
76}
77
78impl<T> From<T> for Box<dyn Signer>
79where
80 T: Signer + 'static,
81{
82 fn from(signer: T) -> Self {
83 Box::new(signer)
84 }
85}
86
87impl PartialEq for dyn Signer {
88 fn eq(&self, other: &dyn Signer) -> bool {
89 self.pubkey() == other.pubkey()
90 }
91}
92
93impl std::fmt::Debug for dyn Signer {
94 fn fmt(&self, fmt: &mut std::fmt::Formatter) -> std::fmt::Result {
95 write!(fmt, "Signer: {:?}", self.pubkey())
96 }
97}
98
99pub fn unique_signers(signers: Vec<&dyn Signer>) -> Vec<&dyn Signer> {
101 signers.into_iter().unique_by(|s| s.pubkey()).collect()
102}
103
104#[cfg(test)]
105mod tests {
106 use {super::*, crate::signer::keypair::Keypair};
107
108 fn pubkeys(signers: &[&dyn Signer]) -> Vec<Pubkey> {
109 signers.iter().map(|x| x.pubkey()).collect()
110 }
111
112 #[test]
113 fn test_unique_signers() {
114 let alice = Keypair::new();
115 let bob = Keypair::new();
116 assert_eq!(
117 pubkeys(&unique_signers(vec![&alice, &bob, &alice])),
118 pubkeys(&[&alice, &bob])
119 );
120 }
121}