1pub use solana_signer::PresignerError;
2use {
3 solana_pubkey::Pubkey,
4 solana_signature::Signature,
5 solana_signer::{Signer, SignerError},
6};
7
8#[derive(Clone, Debug, Default)]
13pub struct Presigner {
14 pubkey: Pubkey,
15 signature: Signature,
16}
17
18impl Presigner {
19 pub fn new(pubkey: &Pubkey, signature: &Signature) -> Self {
20 Self {
21 pubkey: *pubkey,
22 signature: *signature,
23 }
24 }
25}
26
27impl Signer for Presigner {
28 fn try_pubkey(&self) -> Result<Pubkey, SignerError> {
29 Ok(self.pubkey)
30 }
31
32 fn try_sign_message(&self, message: &[u8]) -> Result<Signature, SignerError> {
33 if self.signature.verify(self.pubkey.as_ref(), message) {
34 Ok(self.signature)
35 } else {
36 Err(PresignerError::VerificationFailure.into())
37 }
38 }
39
40 fn is_interactive(&self) -> bool {
41 false
42 }
43}
44
45impl<T> PartialEq<T> for Presigner
46where
47 T: Signer,
48{
49 fn eq(&self, other: &T) -> bool {
50 self.pubkey() == other.pubkey()
51 }
52}
53
54#[cfg(test)]
55mod tests {
56 use {super::*, solana_keypair::keypair_from_seed};
57
58 #[test]
59 fn test_presigner() {
60 let keypair = keypair_from_seed(&[0u8; 32]).unwrap();
61 let pubkey = keypair.pubkey();
62 let data = [1u8];
63 let sig = keypair.sign_message(&data);
64
65 let presigner = Presigner::new(&pubkey, &sig);
67 assert_eq!(presigner.try_pubkey().unwrap(), pubkey);
68 assert_eq!(presigner.pubkey(), pubkey);
69 assert_eq!(presigner.try_sign_message(&data).unwrap(), sig);
70 assert_eq!(presigner.sign_message(&data), sig);
71 let bad_data = [2u8];
72 assert!(presigner.try_sign_message(&bad_data).is_err());
73 assert_eq!(presigner.sign_message(&bad_data), Signature::default());
74
75 assert_eq!(presigner, keypair);
77 assert_eq!(keypair, presigner);
78 let presigner2 = Presigner::new(&pubkey, &sig);
79 assert_eq!(presigner, presigner2);
80 }
81}