1use crate::{export::Principal, AgentError};
2use ic_certification::Label;
3use serde::{Deserialize, Serialize};
4use serde_repr::{Deserialize_repr, Serialize_repr};
5
6#[derive(Debug, Clone, Deserialize, Serialize)]
7#[serde(rename_all = "snake_case")]
8pub struct Envelope<T: Serialize> {
9 pub content: T,
10 #[serde(default)]
11 #[serde(skip_serializing_if = "Option::is_none")]
12 #[serde(with = "serde_bytes")]
13 pub sender_pubkey: Option<Vec<u8>>,
14 #[serde(default)]
15 #[serde(skip_serializing_if = "Option::is_none")]
16 #[serde(with = "serde_bytes")]
17 pub sender_sig: Option<Vec<u8>>,
18}
19
20#[derive(Debug, Clone, Deserialize, Serialize)]
21#[serde(tag = "request_type")]
22pub enum AsyncContent {
23 #[serde(rename = "call")]
24 CallRequest {
25 #[serde(default)]
26 #[serde(skip_serializing_if = "Option::is_none")]
27 #[serde(with = "serde_bytes")]
28 nonce: Option<Vec<u8>>,
29 ingress_expiry: u64,
30 sender: Principal,
31 canister_id: Principal,
32 method_name: String,
33 #[serde(with = "serde_bytes")]
34 arg: Vec<u8>,
35 },
36}
37
38#[derive(Debug, Clone, Deserialize, Serialize)]
40#[serde(tag = "request_type")]
41pub enum CallRequestContent {
42 #[serde(rename = "call")]
43 CallRequest {
44 #[serde(default)]
45 #[serde(skip_serializing_if = "Option::is_none")]
46 #[serde(with = "serde_bytes")]
47 nonce: Option<Vec<u8>>,
48 ingress_expiry: u64,
49 sender: Principal,
50 canister_id: Principal,
51 method_name: String,
52 #[serde(with = "serde_bytes")]
53 arg: Vec<u8>,
54 },
55}
56
57#[derive(Debug, Clone, Deserialize, Serialize)]
59#[serde(tag = "request_type")]
60pub enum ReadStateContent {
61 #[serde(rename = "read_state")]
62 ReadStateRequest {
63 ingress_expiry: u64,
64 sender: Principal,
65 paths: Vec<Vec<Label>>,
66 },
67}
68
69#[derive(Debug, Clone, Deserialize, Serialize)]
71#[serde(tag = "request_type")]
72pub enum QueryContent {
73 #[serde(rename = "query")]
74 QueryRequest {
75 ingress_expiry: u64,
76 sender: Principal,
77 canister_id: Principal,
78 method_name: String,
79 #[serde(with = "serde_bytes")]
80 arg: Vec<u8>,
81 },
82}
83
84#[derive(Debug, Clone, Deserialize, Serialize)]
85#[serde(tag = "request_type")]
86pub enum SyncContent {
87 #[serde(rename = "read_state")]
88 ReadStateRequest {
89 ingress_expiry: u64,
90 sender: Principal,
91 paths: Vec<Vec<Label>>,
92 },
93 #[serde(rename = "query")]
94 QueryRequest {
95 ingress_expiry: u64,
96 sender: Principal,
97 canister_id: Principal,
98 method_name: String,
99 #[serde(with = "serde_bytes")]
100 arg: Vec<u8>,
101 },
102}
103
104#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
105pub struct ReadStateResponse {
106 #[serde(with = "serde_bytes")]
107 pub certificate: Vec<u8>,
108}
109
110#[derive(Debug, Clone, Deserialize, Serialize)]
111#[serde(tag = "status")]
112pub enum Status {
113 #[serde(rename = "unknown")]
114 Unknown {},
115 #[serde(rename = "received")]
116 Received {},
117 #[serde(rename = "processing")]
118 Processing {},
119 #[serde(rename = "replied")]
120 Replied { reply: RequestStatusResponseReplied },
121 #[serde(rename = "rejected")]
122 Rejected {
123 reject_code: u64,
124 reject_message: String,
125 },
126 #[serde(rename = "done")]
127 Done {},
128}
129
130#[derive(Debug, Clone, Deserialize, Serialize)]
131#[serde(untagged)]
132pub enum RequestStatusResponseReplied {
133 CallReply(CallReply),
134}
135
136#[derive(Debug, Clone, Deserialize, Serialize)]
137pub struct CallReply {
138 #[serde(with = "serde_bytes")]
139 pub arg: Vec<u8>,
140}
141
142#[derive(Debug, Clone, Deserialize, Serialize)]
143#[serde(tag = "status")]
144pub enum QueryResponse {
145 #[serde(rename = "replied")]
146 Replied { reply: CallReply },
147 #[serde(rename = "rejected")]
148 Rejected(RejectResponse),
149}
150
151#[derive(Debug, Clone, Serialize, Deserialize, Ord, PartialOrd, Eq, PartialEq)]
153pub struct RejectResponse {
154 pub reject_code: RejectCode,
156 pub reject_message: String,
158 #[serde(default)]
160 pub error_code: Option<String>,
161}
162
163#[derive(
165 Clone, Copy, Debug, PartialEq, Eq, Hash, Serialize_repr, Deserialize_repr, Ord, PartialOrd,
166)]
167#[repr(u8)]
168pub enum RejectCode {
169 SysFatal = 1,
171 SysTransient = 2,
173 DestinationInvalid = 3,
175 CanisterReject = 4,
177 CanisterError = 5,
179}
180
181impl TryFrom<u64> for RejectCode {
182 type Error = AgentError;
183
184 fn try_from(value: u64) -> Result<Self, AgentError> {
185 match value {
186 1 => Ok(RejectCode::SysFatal),
187 2 => Ok(RejectCode::SysTransient),
188 3 => Ok(RejectCode::DestinationInvalid),
189 4 => Ok(RejectCode::CanisterReject),
190 5 => Ok(RejectCode::CanisterError),
191 _ => Err(AgentError::MessageError(format!(
192 "Received an invalid reject code {}",
193 value
194 ))),
195 }
196 }
197}