cw_authenticator/
types.rs

1use cosmwasm_schema::cw_serde;
2use cosmwasm_std::{Addr, Binary, Coin};
3
4use crate::cw_serde_struct_allow_unknown_fields;
5
6cw_serde_struct_allow_unknown_fields! {
7    // --- requests ---
8
9    pub struct OnAuthenticatorAddedRequest {
10        pub account: Addr,
11        pub authenticator_id: String,
12        pub authenticator_params: Option<Binary>,
13    }
14
15    pub struct OnAuthenticatorRemovedRequest {
16        pub account: Addr,
17        pub authenticator_id: String,
18        pub authenticator_params: Option<Binary>,
19    }
20
21    pub struct AuthenticationRequest {
22        pub authenticator_id: String,
23        pub account: Addr,
24        pub fee_payer: Addr,
25        pub fee_granter: Option<Addr>,
26        pub fee: Vec<Coin>,
27        pub msg: Any,
28        pub msg_index: u64,
29        pub signature: Binary,
30        pub sign_mode_tx_data: SignModeTxData,
31        pub tx_data: TxData,
32        pub signature_data: SignatureData,
33        pub simulate: bool,
34        pub authenticator_params: Option<Binary>,
35    }
36
37    pub struct TrackRequest {
38        pub authenticator_id: String,
39        pub account: Addr,
40        pub fee_payer: Addr,
41        pub fee_granter: Option<Addr>,
42        pub fee: Vec<Coin>,
43        pub msg: Any,
44        pub msg_index: u64,
45        pub authenticator_params: Option<Binary>,
46    }
47
48    pub struct ConfirmExecutionRequest {
49        pub authenticator_id: String,
50        pub account: Addr,
51        pub fee_payer: Addr,
52        pub fee_granter: Option<Addr>,
53        pub fee: Vec<Coin>,
54        pub msg: Any,
55        pub msg_index: u64,
56        pub authenticator_params: Option<Binary>,
57    }
58
59    // --- data ---
60
61    pub struct SignModeTxData {
62        pub sign_mode_direct: Binary,
63        pub sign_mode_textual: Option<String>, // Assuming it's a string or null
64    }
65
66    pub struct TxData {
67        pub chain_id: String,
68        pub account_number: u64,
69        pub sequence: u64,
70        pub timeout_height: u64,
71        pub msgs: Vec<Any>,
72        pub memo: String,
73    }
74
75    pub struct SignatureData {
76        pub signers: Vec<Addr>,
77        pub signatures: Vec<Binary>,
78    }
79
80    pub struct Any {
81        pub type_url: String,
82        pub value: cosmwasm_std::Binary,
83    }
84}
85
86/// `AuthenticatorSudoMsg` contains variants of messages that can be sent to the authenticator contract
87/// from smart account module through `CosmWasmAuthenticator`.
88///
89/// `AuthenticateRequest` is `Box`-ed due to large size difference between other variants
90#[cw_serde]
91pub enum AuthenticatorSudoMsg {
92    OnAuthenticatorAdded(OnAuthenticatorAddedRequest),
93    OnAuthenticatorRemoved(OnAuthenticatorRemovedRequest),
94    Authenticate(Box<AuthenticationRequest>),
95    Track(TrackRequest),
96    ConfirmExecution(ConfirmExecutionRequest),
97}
98
99#[cfg(test)]
100mod tests {
101    use cosmwasm_schema::schemars::JsonSchema;
102    use serde_json::{from_str, to_string, to_value, Value};
103
104    use super::*;
105
106    #[test]
107    fn test_any() {
108        let t = Any {
109            type_url: "type_url".to_string(),
110            value: Binary::from(vec![0x01, 0x02, 0x03]),
111        };
112
113        assert_eq!(t, with_unknown_field(t.clone()));
114        has_json_schema_impl::<Any>();
115    }
116
117    #[test]
118    fn test_on_authenticator_added_request() {
119        let t = OnAuthenticatorAddedRequest {
120            account: Addr::unchecked("account"),
121            authenticator_id: "authenticator_id".to_string(),
122            authenticator_params: Some(Binary::from(vec![0x01, 0x02, 0x03])),
123        };
124
125        assert_eq!(t, with_unknown_field(t.clone()));
126        has_json_schema_impl::<OnAuthenticatorAddedRequest>();
127    }
128
129    #[test]
130    fn test_on_authenticator_removed_request() {
131        let t = OnAuthenticatorRemovedRequest {
132            account: Addr::unchecked("account"),
133            authenticator_id: "authenticator_id".to_string(),
134            authenticator_params: Some(Binary::from(vec![0x01, 0x02, 0x03])),
135        };
136
137        assert_eq!(t, with_unknown_field(t.clone()));
138        has_json_schema_impl::<OnAuthenticatorRemovedRequest>();
139    }
140
141    #[test]
142    fn test_authentication_request() {
143        let t = AuthenticationRequest {
144            authenticator_id: "authenticator_id".to_string(),
145            account: Addr::unchecked("account"),
146            fee_payer: Addr::unchecked("fee_payer"),
147            fee_granter: None,
148            fee: vec![Coin::new(1000, "uosmo")],
149            msg: Any {
150                type_url: "type_url".to_string(),
151                value: Binary::from(vec![0x01, 0x02, 0x03]),
152            },
153            msg_index: 1,
154            signature: Binary::from(vec![0x01, 0x02, 0x03]),
155            sign_mode_tx_data: SignModeTxData {
156                sign_mode_direct: Binary::from(vec![0x01, 0x02, 0x03]),
157                sign_mode_textual: Some("sign_mode_textual".to_string()),
158            },
159            tx_data: TxData {
160                chain_id: "chain_id".to_string(),
161                account_number: 1,
162                sequence: 1,
163                timeout_height: 1,
164                msgs: vec![Any {
165                    type_url: "type_url".to_string(),
166                    value: Binary::from(vec![0x01, 0x02, 0x03]),
167                }],
168                memo: "memo".to_string(),
169            },
170            signature_data: SignatureData {
171                signers: vec![Addr::unchecked("account")],
172                signatures: vec![Binary::from(vec![0x01, 0x02, 0x03])],
173            },
174            simulate: true,
175            authenticator_params: Some(Binary::from(vec![0x01, 0x02, 0x03])),
176        };
177
178        assert_eq!(t, with_unknown_field(t.clone()));
179        has_json_schema_impl::<AuthenticationRequest>();
180    }
181
182    #[test]
183    fn test_sign_mode_tx_data() {
184        let t = SignModeTxData {
185            sign_mode_direct: Binary::from(vec![0x01, 0x02, 0x03]),
186            sign_mode_textual: Some("sign_mode_textual".to_string()),
187        };
188
189        assert_eq!(t, with_unknown_field(t.clone()));
190        has_json_schema_impl::<SignModeTxData>();
191    }
192
193    #[test]
194    fn test_tx_data() {
195        let t = TxData {
196            chain_id: "chain_id".to_string(),
197            account_number: 1,
198            sequence: 1,
199            timeout_height: 1,
200            msgs: vec![Any {
201                type_url: "type_url".to_string(),
202                value: Binary::from(vec![0x01, 0x02, 0x03]),
203            }],
204            memo: "memo".to_string(),
205        };
206
207        assert_eq!(t, with_unknown_field(t.clone()));
208        has_json_schema_impl::<TxData>();
209    }
210
211    #[test]
212    fn test_signature_data() {
213        let t = SignatureData {
214            signers: vec![Addr::unchecked("account")],
215            signatures: vec![Binary::from(vec![0x01, 0x02, 0x03])],
216        };
217
218        assert_eq!(t, with_unknown_field(t.clone()));
219        has_json_schema_impl::<SignatureData>();
220    }
221
222    #[test]
223    fn test_track_request() {
224        let t = TrackRequest {
225            authenticator_id: "authenticator_id".to_string(),
226            account: Addr::unchecked("account"),
227            fee_payer: Addr::unchecked("fee_payer"),
228            fee_granter: None,
229            fee: vec![Coin::new(1000, "uosmo")],
230            msg: Any {
231                type_url: "type_url".to_string(),
232                value: Binary::from(vec![0x01, 0x02, 0x03]),
233            },
234            msg_index: 1,
235            authenticator_params: Some(Binary::from(vec![0x01, 0x02, 0x03])),
236        };
237
238        assert_eq!(t, with_unknown_field(t.clone()));
239        has_json_schema_impl::<TrackRequest>();
240    }
241
242    #[test]
243    fn test_confirm_execution_request() {
244        let t = ConfirmExecutionRequest {
245            authenticator_id: "authenticator_id".to_string(),
246            account: Addr::unchecked("account"),
247            fee_payer: Addr::unchecked("fee_payer"),
248            fee_granter: None,
249            fee: vec![Coin::new(1000, "uosmo")],
250            msg: Any {
251                type_url: "type_url".to_string(),
252                value: Binary::from(vec![0x01, 0x02, 0x03]),
253            },
254            msg_index: 1,
255            authenticator_params: Some(Binary::from(vec![0x01, 0x02, 0x03])),
256        };
257
258        assert_eq!(t, with_unknown_field(t.clone()));
259        has_json_schema_impl::<ConfirmExecutionRequest>();
260    }
261
262    #[test]
263    fn test_sudo_msg() {
264        has_json_schema_impl::<AuthenticatorSudoMsg>();
265    }
266
267    fn with_unknown_field<
268        T: cosmwasm_schema::serde::Serialize + cosmwasm_schema::serde::de::DeserializeOwned,
269    >(
270        t: T,
271    ) -> T {
272        let json = to_value(t).unwrap();
273
274        let json = match json {
275            Value::Object(mut map) => {
276                map.entry("unknown")
277                    .or_insert(Value::String("unknown".to_string()));
278
279                Value::Object(map)
280            }
281            _ => panic!("expected object"),
282        };
283
284        let json_string = to_string(&json).unwrap();
285
286        from_str::<T>(json_string.as_str()).unwrap()
287    }
288
289    fn has_json_schema_impl<T: JsonSchema>() {}
290}