Skip to main content

defuse_core/payload/
erc191.rs

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