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