Skip to main content

defuse_core/payload/
nep413.rs

1use defuse_crypto::ed25519::{Ed25519, Ed25519PublicKey, Ed25519Signature};
2pub use defuse_nep413::{Nep413, Nep413Payload};
3use impl_tools::autoimpl;
4use serde::{
5    Deserialize, Serialize,
6    de::{self, DeserializeOwned},
7};
8use serde_with::serde_as;
9
10use crate::{
11    AccountId, Timestamp,
12    payload::{Payload, SignedPayload},
13};
14
15use super::{DefusePayload, ExtractDefusePayload};
16
17#[autoimpl(Deref using self.message)]
18#[autoimpl(DerefMut using self.message)]
19#[serde_as]
20#[cfg_attr(feature = "schemars-v0_8", derive(::schemars::JsonSchema))]
21#[derive(Debug, Clone, Serialize, Deserialize)]
22pub struct Nep413DefuseMessage<T> {
23    pub signer_id: AccountId,
24
25    pub deadline: Timestamp,
26
27    #[serde(flatten)]
28    pub message: T,
29}
30
31impl<T> ExtractDefusePayload<T> for Nep413Payload
32where
33    T: DeserializeOwned,
34{
35    type Error = serde_json::Error;
36
37    fn extract_defuse_payload(self) -> Result<DefusePayload<T>, Self::Error> {
38        let Nep413DefuseMessage {
39            signer_id,
40            deadline,
41            message,
42        } = serde_json::from_str(&self.message)?;
43
44        Ok(DefusePayload {
45            signer_id,
46            verifying_contract: self.recipient.parse().map_err(|_| {
47                de::Error::invalid_value(de::Unexpected::Str(&self.recipient), &"AccountId")
48            })?,
49            deadline,
50            nonce: self.nonce,
51            message,
52        })
53    }
54}
55
56#[autoimpl(Deref using self.payload)]
57#[serde_as]
58#[cfg_attr(feature = "schemars-v0_8", derive(::schemars::JsonSchema))]
59#[derive(Debug, Clone, Serialize, Deserialize)]
60pub struct SignedNep413Payload {
61    pub payload: Nep413Payload,
62
63    pub public_key: Ed25519PublicKey,
64    pub signature: Ed25519Signature,
65}
66
67impl Payload for SignedNep413Payload {
68    fn hash(&self) -> [u8; 32] {
69        Nep413::prehash(&self.payload)
70    }
71}
72
73impl SignedPayload for SignedNep413Payload {
74    type PublicKey = Ed25519PublicKey;
75
76    fn verify(&self) -> Option<Self::PublicKey> {
77        Nep413::verify::<Ed25519>(
78            &self.public_key.try_into().ok()?,
79            &self.payload,
80            &self.signature.into(),
81        )
82        .then_some(&self.public_key)
83        .copied()
84    }
85}
86
87impl<T> ExtractDefusePayload<T> for SignedNep413Payload
88where
89    T: DeserializeOwned,
90{
91    type Error = serde_json::Error;
92
93    #[inline]
94    fn extract_defuse_payload(self) -> Result<DefusePayload<T>, Self::Error> {
95        self.payload.extract_defuse_payload()
96    }
97}