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