1extern crate quick_protobuf;
2
3use base64::engine::general_purpose;
4use base64::Engine;
5use quick_protobuf::Writer;
6use serde::Serialize;
7use std::borrow::Cow;
8use std::str;
9
10pub const KIND_STRING: &str = "String";
11pub const KIND_ARRAY: &str = "Array";
12pub const KIND_MESSAGE: &str = "Message";
13pub const KIND_BYTES: &str = "Bytes";
14pub const KIND_INT: &str = "Int";
15
16#[derive(Serialize, Clone, Debug, Eq, PartialEq)]
17#[serde(rename_all = "camelCase")]
18pub struct StringObject {
19 pub string: String,
20}
21
22#[derive(Serialize, Clone, Debug, Eq, PartialEq)]
23#[serde(rename_all = "camelCase")]
24pub struct ArrayDetail {
25 pub kind: String,
26 pub elems: Vec<Objects>,
27}
28
29#[derive(Serialize, Clone, Debug, Eq, PartialEq)]
30#[serde(rename_all = "camelCase")]
31pub struct ArrayObject {
32 pub array: ArrayDetail,
33}
34
35#[derive(Serialize, Clone, Debug, Eq, PartialEq)]
36#[serde(rename_all = "camelCase")]
37pub struct MessageObject {
38 pub message: Vec<MesssageDetails>,
39}
40
41#[derive(Serialize, Clone, Debug, Eq, PartialEq)]
42#[serde(rename_all = "camelCase")]
43pub struct BytesObject {
44 pub bytes: String,
45}
46
47#[derive(Serialize, Clone, Debug, Eq, PartialEq)]
48#[serde(rename_all = "camelCase")]
49pub struct IntObject {
50 pub int: String,
51}
52
53#[derive(Serialize, Clone, Debug, Eq, PartialEq)]
54#[serde(untagged)]
55pub enum Objects {
56 String(StringObject),
57 Array(ArrayObject),
58 Message(MessageObject),
59 Bytes(BytesObject),
60 Int(IntObject),
61}
62
63#[derive(Serialize, Clone, Debug, Eq, PartialEq)]
64#[serde(rename_all = "camelCase")]
65pub struct MesssageDetails {
66 pub kind: String,
67 pub name: String,
68 pub field_id: u32,
69 pub value: Box<Objects>,
70}
71
72#[derive(Serialize, Clone, Debug, Eq, PartialEq)]
73pub struct Message {
74 pub url: String,
75 pub message: Vec<MesssageDetails>,
76}
77
78impl Message {
79 fn encode_proto_string(data: &str) -> String {
80 let mut out = Vec::new();
81 let mut writer = Writer::new(&mut out);
82 writer
83 .write_message(&crate::proto::authz::Authz {
84 msg: Cow::Borrowed(data),
85 })
86 .expect("encode_proto_string error");
87
88 let out2 = &out.as_slice()[1..];
89
90 general_purpose::STANDARD.encode(out2)
91 }
92
93 pub fn build_authz_message(
94 granter: String,
95 grantee: String,
96 authorization: String,
97 _expiration: String,
98 ) -> Message {
99 Message {
100 url: "/cosmos.authz.v1beta1.MsgGrant".to_string(),
101 message: vec![
102 MesssageDetails {
103 kind: KIND_STRING.to_string(),
104 name: "granter".to_string(),
105 field_id: 1,
106 value: Box::new(Objects::String(StringObject { string: granter })),
107 },
108 MesssageDetails {
109 kind: KIND_STRING.to_string(),
110 name: "grantee".to_string(),
111 field_id: 2,
112 value: Box::new(Objects::String(StringObject { string: grantee })),
113 },
114 MesssageDetails {
115 kind: KIND_MESSAGE.to_string(),
116 name: "grant".to_string(),
117 field_id: 3,
118 value: Box::new(Objects::Message(MessageObject {
119 message: vec![
120 MesssageDetails {
121 kind: KIND_MESSAGE.to_string(),
122 name: "authorization".to_string(),
123 field_id: 1,
124 value: Box::new(Objects::Message(MessageObject {
125 message: vec![
126 MesssageDetails {
127 kind: "String".to_string(),
128 name: "type_url".to_string(),
129 field_id: 1,
130 value: Box::new(Objects::String(StringObject {
131 string:
132 "/cosmos.authz.v1beta1.GenericAuthorization"
133 .to_string(),
134 })),
135 },
136 MesssageDetails {
137 kind: KIND_BYTES.to_string(),
138 name: "value".to_string(),
139 field_id: 2,
140 value: Box::new(Objects::Bytes(BytesObject {
141 bytes: Self::encode_proto_string(
142 authorization.as_str(),
143 ),
144 })),
145 },
146 ],
147 })),
148 },
149 MesssageDetails {
150 kind: KIND_MESSAGE.to_string(),
151 name: "timestamp".to_string(),
152 field_id: 2,
153 value: Box::new(Objects::Message(MessageObject {
154 message: vec![
155 MesssageDetails {
156 kind: KIND_INT.to_string(),
157 name: "seconds".to_string(),
158 field_id: 1,
159 value: Box::new(Objects::Int(IntObject {
160 int: "1732193243".to_string(),
161 })),
162 },
163 MesssageDetails {
164 kind: KIND_INT.to_string(),
165 name: "nanos".to_string(),
166 field_id: 2,
167 value: Box::new(Objects::Int(IntObject {
168 int: "0".to_string(),
169 })),
170 },
171 ],
172 })),
173 },
174 ],
175 })),
176 },
177 ],
178 }
179 }
180
181 pub fn build_revoke_message(granter: String, grantee: String, msg_type_url: String) -> Message {
182 Message {
183 url: "/cosmos.authz.v1beta1.MsgRevoke".to_string(),
184 message: vec![
185 MesssageDetails {
186 kind: KIND_STRING.to_string(),
187 name: "granter".to_string(),
188 field_id: 1,
189 value: Box::new(Objects::String(StringObject { string: granter })),
190 },
191 MesssageDetails {
192 kind: KIND_STRING.to_string(),
193 name: "grantee".to_string(),
194 field_id: 2,
195 value: Box::new(Objects::String(StringObject { string: grantee })),
196 },
197 MesssageDetails {
198 kind: KIND_STRING.to_string(),
199 name: "msg_type_url".to_string(),
200 field_id: 3,
201 value: Box::new(Objects::String(StringObject {
202 string: msg_type_url,
203 })),
204 },
205 ],
206 }
207 }
208
209 pub fn build_contract_migrate(
210 sender: String,
211 contract: String,
212 code_id: u64,
213 msg: String,
214 ) -> Message {
215 Message {
216 url: "/cosmwasm.wasm.v1.MsgMigrateContract".to_string(),
217 message: vec![
218 MesssageDetails {
219 kind: KIND_STRING.to_string(),
220 name: "sender".to_string(),
221 field_id: 1,
222 value: Box::new(Objects::String(StringObject { string: sender })),
223 },
224 MesssageDetails {
225 kind: KIND_STRING.to_string(),
226 name: "contract".to_string(),
227 field_id: 2,
228 value: Box::new(Objects::String(StringObject { string: contract })),
229 },
230 MesssageDetails {
231 kind: KIND_INT.to_string(),
232 name: "code_id".to_string(),
233 field_id: 3,
234 value: Box::new(Objects::Int(IntObject {
235 int: code_id.to_string(),
236 })),
237 },
238 MesssageDetails {
239 kind: KIND_BYTES.to_string(),
240 name: "msg".to_string(),
241 field_id: 4,
242 value: Box::new(Objects::Bytes(BytesObject { bytes: msg })),
243 },
244 ],
245 }
246 }
247
248 pub fn build_contract_instantiate(
249 sender: String,
250 admin: String,
251 label: String,
252 code_id: u64,
253 msg: String,
254 ) -> Message {
255 Message {
256 url: "/cosmwasm.wasm.v1.MsgInstantiateContract".to_string(),
257 message: vec![
258 MesssageDetails {
259 kind: KIND_STRING.to_string(),
260 name: "sender".to_string(),
261 field_id: 1,
262 value: Box::new(Objects::String(StringObject { string: sender })),
263 },
264 MesssageDetails {
265 kind: KIND_STRING.to_string(),
266 name: "admin".to_string(),
267 field_id: 2,
268 value: Box::new(Objects::String(StringObject { string: admin })),
269 },
270 MesssageDetails {
271 kind: KIND_INT.to_string(),
272 name: "code_id".to_string(),
273 field_id: 3,
274 value: Box::new(Objects::Int(IntObject {
275 int: code_id.to_string(),
276 })),
277 },
278 MesssageDetails {
279 kind: KIND_STRING.to_string(),
280 name: "label".to_string(),
281 field_id: 4,
282 value: Box::new(Objects::String(StringObject { string: label })),
283 },
284 MesssageDetails {
285 kind: KIND_BYTES.to_string(),
286 name: "msg".to_string(),
287 field_id: 5,
288 value: Box::new(Objects::Bytes(BytesObject { bytes: msg })),
289 },
290 ],
291 }
292 }
293}