1use serde::de::{Deserialize, Deserializer};
2use serde_json;
3use std::collections::HashMap;
4
5#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)]
6#[serde(rename_all = "camelCase")]
7pub struct RequestError {
8 pub status_code: i16,
9 #[serde(skip_serializing_if = "Option::is_none")]
10 pub message: Option<String>,
11 #[serde(skip_serializing_if = "Option::is_none")]
12 pub error: Option<String>,
13 #[serde(skip_serializing_if = "Option::is_none")]
14 pub description: Option<String>,
15}
16
17#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)]
18#[serde(rename_all = "camelCase")]
19pub struct Response<T> {
20 #[serde(skip_serializing_if = "Option::is_none")]
21 pub meta: Option<Meta>,
22 pub data: T,
23}
24
25#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)]
26#[serde(rename_all = "camelCase")]
27pub struct Meta {
28 pub count: u32,
29 pub page_count: u32,
30 pub total_count: u32,
31 pub next: Option<String>,
32 pub previous: Option<String>,
33 #[serde(rename = "self")]
34 pub self_url: String,
35 pub first: String,
36 pub last: Option<String>,
37}
38
39#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)]
40#[serde(rename_all = "camelCase")]
41pub struct Block {
42 pub id: String,
43 pub version: u8,
44 pub height: u64,
45 pub previous: String,
46 pub forged: Forged,
47 pub payload: Payload,
48 pub generator: Generator,
49 pub signature: String,
50 pub transactions: u32,
51 pub timestamp: Timestamp,
52}
53
54#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)]
55pub struct Forged {
56 pub reward: u64,
57 pub fee: u64,
58 pub total: u64,
59 pub amount: u64,
60}
61
62#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)]
63pub struct Payload {
64 pub hash: String,
65 pub length: u32,
66}
67
68#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)]
69#[serde(rename_all = "camelCase")]
70pub struct Generator {
71 pub username: String,
72 pub address: String,
73 pub public_key: String,
74}
75
76#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)]
77pub struct Timestamp {
78 pub epoch: u32,
79 pub unix: u32,
80 pub human: String,
81}
82
83#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)]
84#[serde(rename_all = "camelCase")]
85pub struct Delegate {
86 pub username: String,
87 pub address: String,
88 pub public_key: String,
89 pub votes: u64,
90 pub rank: u32,
91 pub blocks: Blocks,
92 pub production: Production,
93 pub forged: DelegateForged,
94}
95
96#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)]
97pub struct Blocks {
98 pub produced: u64,
99 pub missed: u64,
100 #[serde(skip_serializing_if = "Option::is_none")]
101 pub last: Option<Last>,
102}
103
104#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)]
105pub struct Production {
106 pub approval: f64,
107 pub productivity: f64,
108}
109
110#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)]
111pub struct Last {
112 pub id: String,
113 pub timestamp: Timestamp,
114}
115
116pub type Balances = HashMap<String, u64>;
117
118#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)]
119pub struct DelegateForged {
120 pub rewards: u64,
121 pub fees: u64,
122 pub total: u64,
123}
124
125#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)]
126#[serde(rename_all = "camelCase")]
127pub struct NodeConfiguration {
128 #[serde(rename = "nethash")]
129 pub nethash: String,
130 pub token: String,
131 pub symbol: String,
132 pub explorer: String,
133 pub version: u32,
134 pub ports: HashMap<String, u16>,
135 pub constants: NodeConstants,
136 pub fee_statistics: Vec<FeeStatistics>,
137}
138
139#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)]
140#[serde(rename_all = "camelCase")]
141pub struct NodeStatus {
142 pub synced: bool,
143 pub now: u64,
144 pub blocks_count: i64,
145}
146
147#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)]
148pub struct NodeSyncing {
149 pub syncing: bool,
150 pub blocks: i64,
151 pub height: u64,
152 pub id: String,
153}
154
155#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)]
156#[serde(rename_all = "camelCase")]
157pub struct NodeConstants {
158 pub height: u64,
159 pub reward: u64,
160 pub active_delegates: u32,
161 pub blocktime: u32,
162 pub block: NodeBlock,
163 pub epoch: String,
164 pub fees: Fees,
165}
166
167#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)]
168#[serde(rename_all = "camelCase")]
169pub struct NodeBlock {
170 pub version: u32,
171 pub max_transactions: u64,
172 pub max_payload: u64,
173}
174
175#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)]
176#[serde(rename_all = "camelCase")]
177pub struct Fees {
178 pub dynamic: bool,
179 #[serde(skip_serializing_if = "Option::is_none")]
180 pub dynamic_fees: Option<DynamicFees>,
181 pub static_fees: FeeSchema,
182}
183
184#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)]
185#[serde(rename_all = "camelCase")]
186pub struct DynamicFees {
187 pub min_fee_pool: u64,
188 pub min_fee_broadcast: u64,
189 pub addon_bytes: FeeSchema,
190}
191
192#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)]
193#[serde(rename_all = "camelCase")]
194pub struct FeeSchema {
195 pub transfer: u64,
196 pub second_signature: u64,
197 pub delegate_registration: u64,
198 pub vote: u64,
199 pub multi_signature: u64,
200 pub ipfs: u64,
201 pub timelock_transfer: u64,
202 pub multi_payment: u64,
203 pub delegate_resignation: u64,
204}
205
206#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)]
207pub struct FeeStatistics {
208 #[serde(rename = "type")]
209 pub transaction_type: TransactionType,
210 pub fees: FeeStats,
211}
212
213#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)]
214#[serde(rename_all = "camelCase")]
215pub struct FeeStats {
216 pub min_fee: u64,
217 pub max_fee: u64,
218 pub avg_fee: u64,
219}
220
221#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)]
222pub struct Peer {
223 pub ip: String,
224 pub port: u16,
225 pub version: String,
226 pub height: u64,
227 pub status: u16,
228 pub os: String,
229 pub latency: u32,
230 pub hashid: String,
231}
232
233#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)]
234#[serde(default)]
235#[serde(rename_all = "camelCase")]
236pub struct Transaction {
237 pub id: String,
238 pub block_id: String,
239 #[serde(skip_serializing_if = "Option::is_none")]
240 pub version: Option<u16>,
241 #[serde(rename = "type")]
242 pub transaction_type: TransactionType,
243 pub amount: u64,
244 pub fee: u64,
245 pub sender: String,
246 #[serde(skip_serializing_if = "Option::is_none")]
247 pub recipient: Option<String>,
248 pub signature: String,
249 #[serde(skip_serializing_if = "Option::is_none")]
250 pub sign_signature: Option<String>,
251 #[serde(skip_serializing_if = "Option::is_none")]
252 pub vendor_field: Option<String>,
253 #[serde(skip_serializing_if = "Asset::is_none")]
254 pub asset: Asset,
255 pub confirmations: u64,
256 pub timestamp: Timestamp,
257}
258
259#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)]
260#[serde(rename_all = "camelCase")]
261pub struct TransactionFees {
262 pub transfer: u64,
263 pub second_signature: u64,
264 pub delegate_registration: u64,
265 pub vote: u64,
266 pub multi_signature: u64,
267 pub ipfs: u64,
268 pub timelock_transfer: u64,
269 pub multi_payment: u64,
270 pub delegate_resignation: u64,
271}
272
273#[derive(Clone, Debug, Default, PartialEq, Deserialize, Serialize)]
274#[serde(rename_all = "PascalCase")]
275pub struct TransactionTypes {
276 pub transfer: u16,
277 pub second_signature: u16,
278 pub delegate_registration: u16,
279 pub vote: u16,
280 pub multi_signature: u16,
281 pub ipfs: u16,
282 pub timelock_transfer: u16,
283 pub multi_payment: u16,
284 pub delegate_resignation: u16,
285}
286
287#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
288#[serde(rename_all = "camelCase")]
289pub struct Wallet {
290 pub address: String,
291 pub public_key: Option<String>,
292 pub username: Option<String>,
293 pub second_public_key: Option<String>,
294 #[serde(deserialize_with = "deserialize_u64_as_number_or_string")]
295 pub balance: u64,
296 pub is_delegate: bool,
297}
298
299fn deserialize_u64_as_number_or_string<'de, D>(de: D) -> Result<u64, D::Error>
300where
301 D: Deserializer<'de>,
302{
303 let deser_result: serde_json::Value = try!(Deserialize::deserialize(de));
304
305 match deser_result {
306 serde_json::Value::Number(ref obj) if obj.is_u64() => Ok(obj.as_u64().unwrap()),
307 serde_json::Value::String(ref obj) if !obj.is_empty() => {
308 Ok(obj.as_str().parse::<u64>().unwrap())
309 }
310 _ => Ok(0),
311 }
312}
313
314#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
315#[serde(rename_all = "lowercase")]
316pub enum Asset {
317 #[serde(skip)]
318 None,
319 Signature {
320 #[serde(rename = "publicKey")]
321 public_key: String,
322 },
323 Delegate {
324 username: String,
325 },
326 Votes(Vec<String>),
327 #[serde(rename = "multisignature")]
328 MultiSignatureRegistration {
329 min: u8,
330 keysgroup: Vec<String>,
331 lifetime: u8,
332 },
333}
334
335impl Asset {
336 pub fn is_none(&self) -> bool {
337 match *self {
338 Asset::None => true,
339 _ => false,
340 }
341 }
342}
343
344impl Default for Asset {
345 fn default() -> Self {
346 Asset::None
347 }
348}
349
350enum_number!(TransactionType {
351 Transfer = 0,
352 SecondSignatureRegistration = 1,
353 DelegateRegistration = 2,
354 Vote = 3,
355 MultiSignatureRegistration = 4,
356 Ipfs = 5,
357 TimelockTransfer = 6,
358 MultiPayment = 7,
359 DelegateResignation = 8,
360});
361
362use std::mem::transmute;
363impl From<u8> for TransactionType {
364 fn from(t: u8) -> TransactionType {
365 assert!(
366 TransactionType::Transfer as u8 <= t && t <= TransactionType::DelegateResignation as u8
367 );
368 unsafe { transmute(t) }
369 }
370}
371
372impl Default for TransactionType {
373 fn default() -> Self {
374 TransactionType::Transfer
375 }
376}