ex3_ic_agent/agent/
signed.rs

1//! Types representing signed messages.
2
3use crate::{export::Principal, RequestId};
4
5use serde::{Deserialize, Serialize};
6
7/// A signed query request message. Produced by [`QueryBuilder::sign`](super::QueryBuilder::sign).
8#[derive(Debug, Clone, Deserialize, Serialize)]
9pub struct SignedQuery {
10    /// The Unix timestamp that the request will expire at.
11    pub ingress_expiry: u64,
12    /// The principal ID of the caller.
13    pub sender: Principal,
14    /// The principal ID of the canister being called.
15    pub canister_id: Principal,
16    /// The name of the canister method being called.
17    pub method_name: String,
18    /// The argument blob to be passed to the method.
19    #[serde(with = "serde_bytes")]
20    pub arg: Vec<u8>,
21    /// The [effective canister ID](https://smartcontracts.org/docs/interface-spec/index.html#http-effective-canister-id) of the destination.
22    pub effective_canister_id: Principal,
23    /// The CBOR-encoded [authentication envelope](https://smartcontracts.org/docs/interface-spec/index.html#authentication) for the request.
24    #[serde(with = "serde_bytes")]
25    pub signed_query: Vec<u8>,
26}
27
28/// A signed update request message. Produced by [`UpdateBuilder::sign`](super::UpdateBuilder::sign).
29#[derive(Debug, Clone, Deserialize, Serialize)]
30pub struct SignedUpdate {
31    /// A nonce to uniquely identify this update call.
32    #[serde(default)]
33    #[serde(skip_serializing_if = "Option::is_none")]
34    #[serde(with = "serde_bytes")]
35    pub nonce: Option<Vec<u8>>,
36    /// The Unix timestamp that the request will expire at.
37    pub ingress_expiry: u64,
38    /// The principal ID of the caller.
39    pub sender: Principal,
40    /// The principal ID of the canister being called.
41    pub canister_id: Principal,
42    /// The name of the canister method being called.
43    pub method_name: String,
44    /// The argument blob to be passed to the method.
45    #[serde(with = "serde_bytes")]
46    pub arg: Vec<u8>,
47    /// The [effective canister ID](https://smartcontracts.org/docs/interface-spec/index.html#http-effective-canister-id) of the destination.
48    pub effective_canister_id: Principal,
49    #[serde(with = "serde_bytes")]
50    /// The CBOR-encoded [authentication envelope](https://smartcontracts.org/docs/interface-spec/index.html#authentication) for the request.
51    pub signed_update: Vec<u8>,
52    /// The request ID.
53    pub request_id: RequestId,
54}
55
56/// A signed request-status request message. Produced by [`Agent::sign_request_status`](super::Agent::sign_request_status).
57#[derive(Debug, Clone, Deserialize, Serialize)]
58pub struct SignedRequestStatus {
59    /// The Unix timestamp that the request will expire at.
60    pub ingress_expiry: u64,
61    /// The principal ID of the caller.
62    pub sender: Principal,
63    /// The [effective canister ID](https://smartcontracts.org/docs/interface-spec/index.html#http-effective-canister-id) of the destination.
64    pub effective_canister_id: Principal,
65    /// The request ID.
66    pub request_id: RequestId,
67    /// The CBOR-encoded [authentication envelope](https://smartcontracts.org/docs/interface-spec/index.html#authentication) for the request.
68    #[serde(with = "serde_bytes")]
69    pub signed_request_status: Vec<u8>,
70}
71
72#[cfg(test)]
73mod tests {
74    // Note this useful idiom: importing names from outer (for mod tests) scope.
75    use super::*;
76
77    #[test]
78    fn test_query_serde() {
79        let query = SignedQuery {
80            ingress_expiry: 1,
81            sender: Principal::management_canister(),
82            canister_id: Principal::management_canister(),
83            method_name: "greet".to_string(),
84            arg: vec![0, 1],
85            effective_canister_id: Principal::management_canister(),
86            signed_query: vec![0, 1, 2, 3],
87        };
88        let serialized = serde_json::to_string(&query).unwrap();
89        let deserialized = serde_json::from_str::<SignedQuery>(&serialized);
90        assert!(deserialized.is_ok());
91    }
92
93    #[test]
94    fn test_update_serde() {
95        let update = SignedUpdate {
96            nonce: None,
97            ingress_expiry: 1,
98            sender: Principal::management_canister(),
99            canister_id: Principal::management_canister(),
100            method_name: "greet".to_string(),
101            arg: vec![0, 1],
102            effective_canister_id: Principal::management_canister(),
103            signed_update: vec![0, 1, 2, 3],
104            request_id: RequestId::new(&[0; 32]),
105        };
106        let serialized = serde_json::to_string(&update).unwrap();
107        let deserialized = serde_json::from_str::<SignedUpdate>(&serialized);
108        assert!(deserialized.is_ok());
109    }
110
111    #[test]
112    fn test_request_status_serde() {
113        let request_status = SignedRequestStatus {
114            ingress_expiry: 1,
115            sender: Principal::management_canister(),
116            effective_canister_id: Principal::management_canister(),
117            request_id: RequestId::new(&[0; 32]),
118            signed_request_status: vec![0, 1, 2, 3],
119        };
120        let serialized = serde_json::to_string(&request_status).unwrap();
121        let deserialized = serde_json::from_str::<SignedRequestStatus>(&serialized);
122        assert!(deserialized.is_ok());
123    }
124}