saa_common/types/
signed.rs

1use saa_schema::saa_type;
2use crate::PayloadExtension;
3
4
5/// Payload message used for telling which credential to use
6/// or how to modify it
7#[saa_type]
8pub struct AuthPayload {
9    /// Which credential to use if multiple are available
10    pub credential_id   :   Option<crate::CredentialId>,
11    /// Human readable prefix to use to derive an address
12    pub hrp             :   Option<String>,
13    /// Additional arguments to pass depending on a credential in question
14    pub extension       :   Option<PayloadExtension>,
15}
16
17
18
19/// A wrapper for signed data used for constructing credentials and verifying them
20/// `data` is base64 encoded JSON string that contains the data to be verified.  
21/// When `replay` feature tag is enabled, must be a JSON object corresponding to `MsgDataToSign` struct.
22#[saa_type]
23pub struct SignedDataMsg {
24    /// Base64 encoded JSON string of replay envelope, serialized actions messages, both of them or none of them
25    pub data        :   crate::Binary,
26    /// Signature to verify the data
27    pub signature   :   crate::Binary,
28    /// Optional payload to use customize the verification flow if possible
29    pub payload     :   Option<AuthPayload>,
30}
31
32
33
34#[saa_type(no_deny)]
35pub struct MsgDataToVerify {
36    pub chain_id: String,
37    pub contract_address: String,
38    pub nonce: crate::Uint64,
39}
40
41
42
43#[cfg(feature = "optimise")]
44mod optimised {
45    use crate::String;
46
47    #[derive(serde::Serialize)]
48    pub struct MsgDataToSign {
49        pub chain_id: String,
50        pub contract_address: String,
51        #[serde(skip_serializing_if = "Vec::is_empty")]
52        pub messages: Vec<String>,
53        pub nonce: crate::Uint64,
54    }
55
56    impl MsgDataToSign {
57        pub fn new(cid: String, addr: String, msgs: Vec<String>, nonce: u64) -> Self {
58            Self {
59                chain_id: cid,
60                messages: msgs,
61                contract_address: addr,
62                nonce: nonce.into(),
63            }
64        }
65    }
66}
67
68#[cfg(not(feature = "optimise"))]
69mod default {
70    use super::MsgDataToVerify;
71
72    #[saa_schema::saa_type]
73    pub struct MsgDataToSign<M: serde::Serialize = String> {
74        pub chain_id: String,
75        pub contract_address: String,
76        #[cfg_attr(feature = "wasm", serde(skip_serializing_if = "Vec::is_empty"))]
77        pub messages: Vec<M>,
78        pub nonce: crate::Uint64,
79    }
80
81    impl<M: serde::Serialize> MsgDataToSign<M> {
82        pub fn new(cid: String, addr: String, msgs: Vec<M>, nonce: u64) -> Self {
83            Self {
84                chain_id: cid,
85                messages: msgs,
86                contract_address: addr,
87                nonce: nonce.into(),
88            }
89        }
90    }
91
92    impl<M : serde::Serialize> Into<MsgDataToVerify> for &MsgDataToSign<M> {
93        fn into(self) -> MsgDataToVerify {
94            MsgDataToVerify {
95                chain_id: self.chain_id.clone(),
96                contract_address: self.contract_address.clone(),
97                nonce: self.nonce.clone(),
98            }
99        }
100    }
101
102    #[cfg(feature = "wasm")]
103    mod wasm_impl {
104        use crate::wasm::{Env, ensure};
105        impl super::MsgDataToVerify {
106            pub fn validate(&self, env: &Env, expected: u64 ) -> Result<(), crate::ReplayError> {
107                ensure!(self.chain_id == env.block.chain_id, crate::ReplayError::ChainIdMismatch);
108                ensure!(self.contract_address == env.contract.address.to_string(), crate::ReplayError::AddressMismatch);
109                let signed = self.nonce.u64();
110                ensure!(signed == expected, crate::ReplayError::InvalidNonce(expected));
111                Ok(())
112            }
113        }
114        impl crate::wasm::CustomMsg for super::super::SignedDataMsg {}
115    }
116}
117
118#[cfg(not(feature = "optimise"))]
119pub use default::MsgDataToSign;
120#[cfg(feature = "optimise")]
121pub use optimised::MsgDataToSign;