Skip to main content

defuse_core/payload/
tip191.rs

1use defuse_crypto::secp256k1::{Secp256k1RecoverableSignature, Secp256k1UncompressedPublicKey};
2use defuse_tip191::Tip191;
3use near_sdk::{CryptoHash, serde_json};
4use serde::{Deserialize, Serialize, de::DeserializeOwned};
5
6use crate::payload::{Payload, SignedPayload};
7
8use super::{DefusePayload, ExtractDefusePayload};
9
10#[cfg_attr(feature = "abi", derive(::schemars::JsonSchema))]
11#[derive(Debug, Clone, Serialize, Deserialize)]
12pub struct SignedTip191Payload {
13    pub payload: String,
14
15    /// There is no public key member because the public key can be recovered
16    /// via `ecrecover()` knowing the data and the signature
17    pub signature: Secp256k1RecoverableSignature,
18}
19
20impl Payload for SignedTip191Payload {
21    #[inline]
22    fn hash(&self) -> CryptoHash {
23        Tip191::prehash(&self.payload)
24    }
25}
26
27impl SignedPayload for SignedTip191Payload {
28    type PublicKey = Secp256k1UncompressedPublicKey;
29
30    #[inline]
31    fn verify(&self) -> Option<Self::PublicKey> {
32        let (signature, recovery_id) = self.signature.try_into().ok()?;
33
34        Tip191::recover(&self.payload, &signature, recovery_id).map(Into::into)
35    }
36}
37
38impl<T> ExtractDefusePayload<T> for SignedTip191Payload
39where
40    T: DeserializeOwned,
41{
42    type Error = serde_json::Error;
43
44    #[inline]
45    fn extract_defuse_payload(self) -> Result<DefusePayload<T>, Self::Error> {
46        serde_json::from_str(&self.payload)
47    }
48}