Skip to main content

defuse_core/payload/
nep413.rs

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