solana_sdk/signer/
presigner.rs

1#![cfg(feature = "full")]
2
3use {
4    crate::{
5        pubkey::Pubkey,
6        signature::Signature,
7        signer::{Signer, SignerError},
8    },
9    thiserror::Error,
10};
11
12/// A `Signer` implementation that represents a `Signature` that has been
13/// constructed externally. Performs a signature verification against the
14/// expected message upon `sign()` requests to affirm its relationship to
15/// the `message` bytes
16#[derive(Clone, Debug, Default)]
17pub struct Presigner {
18    pubkey: Pubkey,
19    signature: Signature,
20}
21
22impl Presigner {
23    pub fn new(pubkey: &Pubkey, signature: &Signature) -> Self {
24        Self {
25            pubkey: *pubkey,
26            signature: *signature,
27        }
28    }
29}
30
31#[derive(Debug, Error, PartialEq, Eq)]
32pub enum PresignerError {
33    #[error("pre-generated signature cannot verify data")]
34    VerificationFailure,
35}
36
37impl Signer for Presigner {
38    fn try_pubkey(&self) -> Result<Pubkey, SignerError> {
39        Ok(self.pubkey)
40    }
41
42    fn try_sign_message(&self, message: &[u8]) -> Result<Signature, SignerError> {
43        if self.signature.verify(self.pubkey.as_ref(), message) {
44            Ok(self.signature)
45        } else {
46            Err(PresignerError::VerificationFailure.into())
47        }
48    }
49
50    fn is_interactive(&self) -> bool {
51        false
52    }
53}
54
55impl<T> PartialEq<T> for Presigner
56where
57    T: Signer,
58{
59    fn eq(&self, other: &T) -> bool {
60        self.pubkey() == other.pubkey()
61    }
62}
63
64#[cfg(test)]
65mod tests {
66    use {super::*, crate::signer::keypair::keypair_from_seed};
67
68    #[test]
69    fn test_presigner() {
70        let keypair = keypair_from_seed(&[0u8; 32]).unwrap();
71        let pubkey = keypair.pubkey();
72        let data = [1u8];
73        let sig = keypair.sign_message(&data);
74
75        // Signer
76        let presigner = Presigner::new(&pubkey, &sig);
77        assert_eq!(presigner.try_pubkey().unwrap(), pubkey);
78        assert_eq!(presigner.pubkey(), pubkey);
79        assert_eq!(presigner.try_sign_message(&data).unwrap(), sig);
80        assert_eq!(presigner.sign_message(&data), sig);
81        let bad_data = [2u8];
82        assert!(presigner.try_sign_message(&bad_data).is_err());
83        assert_eq!(presigner.sign_message(&bad_data), Signature::default());
84
85        // PartialEq
86        assert_eq!(presigner, keypair);
87        assert_eq!(keypair, presigner);
88        let presigner2 = Presigner::new(&pubkey, &sig);
89        assert_eq!(presigner, presigner2);
90    }
91}