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 serde::{Deserialize, Serialize, de::DeserializeOwned};
7use serde_with::serde_as;
8
9#[serde_as]
10#[cfg_attr(feature = "schemars-v0_8", derive(::schemars::JsonSchema))]
11#[derive(Debug, Clone, Serialize, Deserialize)]
12pub struct SignedErc191Payload {
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 SignedErc191Payload {
21    #[inline]
22    fn hash(&self) -> [u8; 32] {
23        Erc191::prehash(&self.payload)
24    }
25}
26
27impl SignedPayload for SignedErc191Payload {
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        Erc191::recover(&self.payload, &signature, recovery_id).map(Into::into)
35    }
36}
37
38impl<T> ExtractDefusePayload<T> for SignedErc191Payload
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}