defuse_core/payload/
nep413.rs1use 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}