solana_presigner/
lib.rs

1pub use solana_signer::PresignerError;
2use {
3    solana_pubkey::Pubkey,
4    solana_signature::Signature,
5    solana_signer::{Signer, SignerError},
6};
7
8/// A `Signer` implementation that represents a `Signature` that has been
9/// constructed externally. Performs a signature verification against the
10/// expected message upon `sign()` requests to affirm its relationship to
11/// the `message` bytes
12#[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        // Signer
66        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        // PartialEq
76        assert_eq!(presigner, keypair);
77        assert_eq!(keypair, presigner);
78        let presigner2 = Presigner::new(&pubkey, &sig);
79        assert_eq!(presigner, presigner2);
80    }
81}