eosio_client_api/
api_types.rs

1use crate::errors::Result;
2use chrono::{DateTime, Duration, Utc};
3use libabieos_sys::{eosio_datetime_format, ABIEOS};
4use serde::{Deserialize, Serialize};
5
6
7#[derive(Debug, Serialize, Deserialize)]
8pub struct ResourceLimit {
9    pub max: isize,
10    pub available: isize,
11    pub used: isize,
12}
13
14#[derive(Debug, Serialize, Deserialize)]
15pub struct Key {
16    pub key: String,
17    pub weight: isize,
18}
19
20#[derive(Debug, Serialize, Deserialize)]
21pub struct Permission {
22    pub permission: String,
23    pub actor: String,
24}
25
26#[derive(Debug, Serialize, Deserialize)]
27pub struct Account {
28    pub weight: isize,
29    pub permission: Permission,
30}
31
32#[derive(Debug, Serialize, Deserialize)]
33pub struct RequiredAuth {
34    pub waits: Vec<String>,
35    pub threshold: isize,
36    pub accounts: Vec<Account>,
37    pub keys: Vec<Key>,
38}
39
40#[derive(Debug, Serialize, Deserialize)]
41pub struct Permissions {
42    pub parent: String,
43    pub perm_name: String,
44    pub required_auth: RequiredAuth,
45}
46
47#[derive(Debug, Serialize, Deserialize)]
48pub struct VoterInfo {
49    pub producers: Vec<String>,
50    pub is_proxy: isize,
51    pub owner: String,
52    // staked: usize, Wax holds this as a string, EOS is a usize
53    pub proxy: String,
54    pub flags1: isize,
55}
56
57#[derive(Debug, Serialize, Deserialize)]
58pub struct GetAccount {
59    pub account_name: String,
60    pub head_block_num: usize,
61    pub privileged: bool,
62    #[serde(with = "eosio_datetime_format")]
63    pub last_code_update: DateTime<Utc>,
64    #[serde(with = "eosio_datetime_format")]
65    pub head_block_time: DateTime<Utc>,
66    #[serde(with = "eosio_datetime_format")]
67    pub created: DateTime<Utc>,
68    pub core_liquid_balance: Option<String>,
69    pub ram_quota: isize,
70    pub net_weight: isize,
71    pub cpu_weight: isize,
72    pub ram_usage: usize,
73    pub cpu_limit: ResourceLimit,
74    pub net_limit: ResourceLimit,
75    pub voter_info: Option<VoterInfo>,
76    pub refund_request: Option<String>,
77    pub permissions: Vec<Permissions>,
78}
79
80#[derive(Debug, Serialize, Deserialize)]
81pub struct AbiTypes {
82    pub new_type_name: String,
83    #[serde(rename = "type")]
84    pub abi_type: String,
85}
86
87#[derive(Debug, Serialize, Deserialize)]
88pub struct AbiField {
89    pub name: String,
90    #[serde(rename = "type")]
91    pub abi_type: String,
92}
93
94#[derive(Debug, Serialize, Deserialize)]
95pub struct AbiStruct {
96    pub name: String,
97    pub base: String,
98    pub fields: Vec<AbiField>,
99}
100
101#[derive(Debug, Serialize, Deserialize)]
102pub struct AbiAction {
103    pub name: String,
104    #[serde(rename = "type")]
105    pub abi_type: String,
106    pub ricardian_contract: String,
107}
108
109#[derive(Debug, Serialize, Deserialize)]
110pub struct AbiTable {
111    pub name: String,
112    #[serde(rename = "type")]
113    pub abi_type: String,
114    pub index_type: String,
115    pub key_names: Vec<String>,
116    pub key_types: Vec<String>,
117}
118
119#[derive(Debug, Serialize, Deserialize)]
120pub struct AbiRicardianClauses {
121    pub id: String,
122    pub body: String,
123}
124
125#[derive(Debug, Serialize, Deserialize)]
126pub struct AbiErrorMessages {
127    pub error_code: String,
128    pub error_msg: String,
129}
130
131#[derive(Debug, Serialize, Deserialize)]
132pub struct AbiExtensions {
133    pub tag: String,
134    pub value: String,
135}
136
137#[derive(Debug, Serialize, Deserialize)]
138pub struct AbiVariants {
139    pub name: String,
140    pub types: Vec<String>,
141}
142
143#[derive(Debug, Serialize, Deserialize)]
144pub struct Abi {
145    pub version: String,
146    pub types: Vec<AbiTypes>,
147    pub structs: Vec<AbiStruct>,
148    pub actions: Vec<AbiAction>,
149    pub tables: Vec<AbiTable>,
150    pub ricardian_clauses: Vec<AbiRicardianClauses>,
151    pub error_messages: Vec<AbiErrorMessages>,
152    pub abi_extensions: Vec<AbiExtensions>,
153    pub variants: Vec<AbiVariants>,
154}
155
156#[derive(Debug, Serialize, Deserialize)]
157pub struct GetAbi {
158    pub account_name: String,
159    pub abi: Option<Abi>,
160}
161
162#[derive(Debug, Serialize, Deserialize)]
163pub struct RequiredKeys {
164    pub required_keys: Vec<String>,
165}
166
167#[derive(Debug, Serialize, Deserialize)]
168pub struct GetInfo {
169    server_version: String,
170    pub chain_id: String,
171    pub head_block_num: usize,
172    pub last_irreversible_block_num: usize,
173    pub last_irreversible_block_id: String,
174    pub head_block_id: String,
175    #[serde(with = "eosio_datetime_format")]
176    pub head_block_time: DateTime<Utc>,
177    pub head_block_producer: String,
178    pub virtual_block_cpu_limit: usize,
179    pub virtual_block_net_limit: usize,
180    pub block_cpu_limit: usize,
181    pub block_net_limit: usize,
182    pub server_version_string: String,
183    pub fork_db_head_block_num: usize,
184    pub fork_db_head_block_id: String,
185    pub server_full_version_string: Option<String>,
186}
187
188impl GetInfo {
189    pub fn set_exp_time(&self, duration: Duration) -> DateTime<Utc> {
190        self.head_block_time + duration
191    }
192}
193
194#[derive(Debug, Serialize, Deserialize)]
195pub struct AuthorizationIn {
196    pub actor: String,
197    pub permission: String,
198}
199
200#[derive(Debug, Serialize, Deserialize)]
201pub struct GetCodeHash {
202    pub account_name: String,
203    pub code_hash: String,
204}
205
206#[derive(Debug, Serialize, Deserialize)]
207pub struct ActionIn {
208    pub account: String,
209    pub name: String,
210    pub authorization: Vec<AuthorizationIn>,
211    pub data: String,
212}
213
214#[derive(Debug, Serialize, Deserialize)]
215pub struct TransactionInSigned {
216    #[serde(with = "eosio_datetime_format")]
217    pub expiration: DateTime<Utc>,
218    pub ref_block_num: u16,
219    pub ref_block_prefix: u32,
220    pub max_net_usage_words: u32,
221    pub max_cpu_usage_ms: u8,
222    pub delay_sec: u32,
223    pub context_free_actions: Vec<String>,
224    pub actions: Vec<ActionIn>,
225    pub transaction_extensions: Vec<String>,
226    pub signatures: Vec<String>, // KleosD 2.1 returns signatures here
227}
228
229/***
230 Be aware. The ordering of this struct is important.
231 EOSIO (abieos) expects the fields in the same order as shown in transaction.abi.json, and does not
232 handle extra fields either.
233
234 ref_block_num & ref_block_prefix are derived from the last_irreversible_block_id. retrieved from
235 the get_info call.
236
237--> thank you to @arhag for the detailed explanation.
238
239if I use the last_irreversible_block_id from getinfo — (I added the '-' for clarity)
240“0000daabcc9912b6-2359def6033b0463-d3a605c0ba7d6c77-9452ed321649db15”
241The block ID modifies the hash of the block header such that its first 4 bytes represents the block
242height as a big endian number. This is so that when it is printed out as a hex string, one could
243just grab the first 8 hex characters to quickly determine what the block height is.
244
245So the block height of that block you reference there is actually 0x0000daab (or 55979 in decimal).
246
247The ref_block_num field of a transaction is the height of the reference block (modulo 2^16).
248So in this case it would again be 55979.
249
250The ref_block_prefix field of a transaction is some 32-bits of the reference block ID
251(other than the first 4 bytes which represents the height and therefore serves no meaningful
252validation purposes) as a simple check to ensure you are referencing the actual block you meant
253to reference and not some other block on another fork that has the same block height.
254
255Those are taken from the 2nd 64-bit word of the block ID which is then cast to
256uint32_t so it is the least significant 32-bits of the 2nd 64-bit word.
257
258So the 2nd 64-bit word would be taken from the sequence of bytes
259(represented in hex): 0x23, 0x59, 0xde, 0xf6, 0x03, 0x3b, 0x04, 0x63.
260When pulled as a uint64_t number on a little endian machine, that is the number 0x63043b03f6de5923.
261And the least significant 32-bits of that number is 0xf6de5923 which is what ref_block_prefix
262should be.
263
264The ref_block_num would be 0x0000daab mod 2^16 which is 0xdaab.
265
266expiration has a max of now + 3600 seconds.
267delay_sec should be 0 for normal things. (it's used in deferred txn's which aren't really used).
268 */
269#[derive(Debug, Serialize, Deserialize)]
270pub struct TransactionIn {
271    #[serde(with = "eosio_datetime_format")]
272    pub expiration: DateTime<Utc>,
273    pub ref_block_num: u16,
274    pub ref_block_prefix: u32,
275    pub max_net_usage_words: u32,
276    pub max_cpu_usage_ms: u8,
277    pub delay_sec: u32,
278    pub context_free_actions: Vec<String>,
279    pub actions: Vec<ActionIn>,
280    pub transaction_extensions: Vec<String>,
281}
282
283impl TransactionIn {
284    pub fn dummy() -> TransactionIn {
285        TransactionIn {
286            transaction_extensions: vec![],
287            ref_block_num: 0,
288            max_net_usage_words: 0,
289            expiration: Utc::now() + Duration::days(1),
290            delay_sec: 0,
291            max_cpu_usage_ms: 0,
292            actions: vec![],
293            ref_block_prefix: 0,
294            context_free_actions: vec![],
295        }
296    }
297    pub fn simple(
298        actions: Vec<ActionIn>,
299        ref_block_id: &str,
300        expiration: DateTime<Utc>,
301    ) -> Result<TransactionIn> {
302        let hash = TransactionIn::block_to_hash(ref_block_id)?;
303
304        let ref_block_num: u16 = (((hash[0] >> 32) & 0xffff_ffff) as u16).to_le();
305        let ref_block_prefix: u32 = ((hash[1] >> 32 & 0xffff_ffff) as u32).to_be();
306
307        Ok(TransactionIn {
308            transaction_extensions: vec![],
309            ref_block_num,
310            max_net_usage_words: 0,
311            expiration,
312            delay_sec: 0,
313            max_cpu_usage_ms: 0,
314            actions,
315            ref_block_prefix,
316            context_free_actions: vec![],
317        })
318    }
319
320    pub fn hex_to_u64(hex: &str) -> u64 {
321        let mut val: u64 = 0;
322        for char in hex.bytes() {
323            let digit = if char >= b'a' {
324                char + 10 - b'a'
325            } else {
326                char - b'0'
327            };
328            val = (val << 4) + digit as u64;
329        }
330        val
331    }
332    pub fn block_to_hash(ref_block_id: &str) -> Result<Vec<u64>> {
333        if ref_block_id.len() != 64 {
334            Err("Invalid ref_block id. expecting len of 64".into())
335        } else {
336            let v: Vec<u64> = vec![
337                TransactionIn::hex_to_u64(&ref_block_id[0..16]),
338                TransactionIn::hex_to_u64(&ref_block_id[16..32]),
339                TransactionIn::hex_to_u64(&ref_block_id[33..48]),
340                TransactionIn::hex_to_u64(&ref_block_id[49..64]),
341            ];
342            Ok(v)
343        }
344    }
345}
346
347#[derive(Debug, Deserialize, Serialize)]
348pub struct ErrorDetails {
349    pub message: String,
350    pub file: String,
351    pub line_number: usize,
352    pub method: String,
353}
354
355#[derive(Debug, Deserialize, Serialize)]
356pub struct ErrorInt {
357    pub code: usize,
358    pub name: String,
359    pub what: String,
360    pub details: Vec<ErrorDetails>,
361}
362
363#[derive(Debug, Deserialize, Serialize)]
364pub struct ErrorReply {
365    pub code: usize,
366    pub message: String,
367    pub error: ErrorInt,
368}#[derive(Debug, Deserialize, Serialize)]
369
370pub struct ErrorReply2 {
371    pub code: usize,
372    pub message: String,
373    pub error: ErrorInt,
374}
375
376#[derive(Debug, Serialize, Deserialize)]
377pub struct PackedTransactionIn {
378    pub signatures: Vec<String>,
379    pub compression: String,
380    pub packed_context_free_data: String,
381    pub packed_trx: String,
382}
383
384#[derive(Debug, Serialize, Deserialize)]
385pub struct GetRawABI {
386    pub account_name: String,
387    pub code_hash: String,
388    pub abi_hash: String,
389    pub abi: String,
390}
391
392impl GetRawABI {
393    /*
394    EOSIO doesn't seem to pad base64 correctly
395    see https://github.com/EOSIO/eos/issues/8161
396     */
397    fn fix_padding(str: &str) -> String {
398        let mut bare: String = str.replacen('=', "", 4);
399        let len = bare.len();
400        let to_len = len + (4 - (len % 4));
401        for _i in len..to_len {
402            bare.push('=');
403        }
404        bare
405    }
406
407    pub fn decode_abi(&self) -> Result<Vec<u8>> {
408        let fixed = GetRawABI::fix_padding(&self.abi);
409        Ok(base64::decode(fixed)?)
410    }
411}
412
413#[derive(Debug, Serialize, Deserialize)]
414pub struct ActionSetcodeData {
415    pub(crate) account: String,
416    pub(crate) vmtype: u8,
417    pub(crate) vmversion: u8,
418    pub(crate) code: String,
419}
420
421impl ActionSetcodeData {
422    pub fn to_hex(&self, abieos: &ABIEOS) -> Result<String> {
423        // abieos NEEDS the json to be in a specific order serde_json doesn't do that
424        let json = format!(
425            "{{ \"account\":\"{}\", \"vmtype\":{},\"vmversion\":{},\"code\":\"{}\" }}",
426            self.account, self.vmtype, self.vmversion, self.code
427        );
428
429        let hex = abieos.json_to_hex("eosio", "setcode", &json)?;
430        Ok(String::from(hex))
431    }
432}
433
434#[derive(Debug, Serialize, Deserialize)]
435pub struct ActionSetData {
436    pub(crate) account: String,
437    pub(crate) abi: String,
438}
439
440impl ActionSetData {
441    pub fn to_hex(&self, abieos: &ABIEOS) -> Result<String> {
442        let json = format!(
443            "{{ \"account\":\"{}\", \"abi\":\"{}\"}}",
444            self.account, self.abi
445        );
446
447        let hex = abieos.json_to_hex("eosio", "setabi", &json);
448        Ok(String::from(hex?))
449    }
450}
451
452#[derive(Debug, Deserialize)]
453pub struct TransactionResponse {
454    pub processed: TransactionProcessedResponse,
455    pub transaction_id: String,
456}
457
458#[derive(Debug, Deserialize)]
459pub struct TransactionReceipt {
460    pub cpu_usage_us: usize,
461    pub net_usage_words: usize,
462    pub status: String,
463}
464
465#[derive(Debug, Serialize, Deserialize)]
466pub struct AccountRamDelta {
467    pub account: String,
468    pub delta: isize,
469}
470
471#[derive(Debug, Deserialize)]
472pub struct ActionReceipt {
473    pub receiver: String,
474    pub abi_sequence: usize,
475    pub recv_sequence: usize,
476    // auth_sequence: Vec< String|usize>
477    pub code_sequence: usize,
478    pub global_sequence: usize,
479    pub act_digest: String,
480}
481
482#[derive(Debug, Deserialize)]
483#[serde(untagged)]
484pub enum ActionACTData {
485    ActionACTDataSetCode {
486        code: Option<String>,
487        vmtype: usize,
488        account: String,
489        vmversion: usize,
490    },
491    String,
492    /*
493    ActionACTDataSetABI {
494        account: String,
495        abi: String,
496    }*/
497}
498
499#[derive(Debug, Deserialize)]
500pub struct ActionACT {
501    pub authorization: Vec<Permission>,
502    pub name: String,
503
504    //  #[serde(with = "eosio_action_trace")]
505    // data: HashMap<String,Value>,
506    pub account: String,
507    pub hex_data: String,
508}
509
510#[derive(Debug, Deserialize)]
511pub struct ActionTrace {
512    pub account_ram_deltas: Vec<AccountRamDelta>,
513    pub console: Option<String>,
514    pub action_ordinal: isize,
515    // inline_traces:[],
516    pub receipt: ActionReceipt,
517    pub act: ActionACT,
518    pub context_free: bool,
519    pub producer_block_id: Option<String>,
520    pub except: Option<String>,
521    pub trx_id: String,
522    pub block_num: usize,
523    pub error_code: Option<String>,
524    #[serde(with = "eosio_datetime_format")]
525    pub block_time: DateTime<Utc>,
526    pub closest_unnotified_ancestor_action_ordinal: usize,
527    pub elapsed: usize,
528    pub receiver: String,
529    //account_disk_deltas : [],
530    pub return_value: Option<String>,
531}
532
533#[derive(Debug, Deserialize)]
534pub struct TransactionProcessedResponse {
535    pub scheduled: bool,
536    pub error_code: Option<String>,
537    pub action_traces: Vec<ActionTrace>,
538    pub block_num: usize,
539    pub producer_block_id: Option<String>,
540    pub except: Option<String>,
541    pub receipt: TransactionReceipt,
542    pub id: String,
543    pub elapsed: usize,
544    pub net_usage: usize,
545    #[serde(with = "eosio_datetime_format")]
546    pub block_time: DateTime<Utc>,
547    pub account_ram_delta: Option<String>,
548}
549
550#[derive(Debug, Serialize, Deserialize)]
551pub struct BlockTransactionAction {
552    pub account: String,
553    pub name: String,
554    pub authorization: Vec<AuthorizationIn>,
555    pub data: String,
556}
557
558#[derive(Debug, Serialize, Deserialize)]
559pub struct BlockTransaction {
560    #[serde(with = "eosio_datetime_format")]
561    pub expiration: DateTime<Utc>,
562    pub ref_block_num: u16,
563    pub ref_block_prefix: u32,
564    pub max_net_usage_words: u32,
565    pub max_cpu_usage_ms: u8,
566    pub delay_sec: u32,
567    pub context_free_actions: Vec<String>,
568    pub actions: Vec<BlockTransactionAction>,
569}
570
571#[derive(Debug, Deserialize)]
572pub struct BlockTransactionTrx {
573    pub id: String,
574    signatures: Vec<String>,
575    compression: String,
576    packed_context_free_data: String,
577    // context_free_data: Vec<?>
578    packed_trx: String,
579    pub transaction: BlockTransaction,
580}
581
582#[derive(Debug, Deserialize)]
583pub struct BlockTransactions {
584    pub status: String,
585    pub cpu_usage_us: usize,
586    pub net_usage_words: usize,
587    pub trx: BlockTransactionTrx,
588}
589
590#[derive(Debug, Deserialize)]
591pub struct GetBlock {
592    #[serde(with = "eosio_datetime_format")]
593    pub timestamp: DateTime<Utc>,
594    pub producer: String,
595    pub confirmed: usize,
596    pub previous: String,
597    pub transaction_mroot: String,
598    pub action_mroot: String,
599    pub schedule_version: usize,
600    pub new_producers: Option<String>,
601    pub producer_signature: String,
602    pub transactions: Vec<BlockTransactions>,
603    pub id: String,
604    pub block_num: usize,
605    pub ref_block_prefix: usize,
606}
607
608#[derive(Debug, Deserialize)]
609pub struct TableRow {
610    pub code: String,
611    pub scope: String,
612    pub table: String,
613    pub payer: String,
614    pub count: usize,
615}
616
617#[derive(Debug, Deserialize)]
618pub struct GetTableByScope {
619    pub rows: Vec<TableRow>,
620    pub more: String,
621}
622
623#[derive(Debug, Serialize, Deserialize)]
624pub struct GetTableByScopeIn {
625    pub code: String,
626    pub table: String,
627    pub lower_bound: String,
628    pub upper_bound: String,
629    pub limit: usize,
630    pub reverse: bool,
631}
632
633#[derive(Debug, Serialize, Deserialize)]
634pub struct GetTableRowsIn {
635    pub json: bool,
636    /// set this to false if you are using GetTableRow
637    pub code: String,
638    pub scope: String,
639    pub table: String,
640    pub table_key: String,
641    pub lower_bound: String,
642    pub upper_bound: String,
643    pub limit: usize,
644    pub key_type: String,
645    pub index_position: String,
646    pub encode_type: String,
647    pub reverse: bool,
648    pub show_payer: bool,
649}
650#[derive(Debug, Deserialize)]
651pub struct GetTableRow {
652    pub data: String,
653    /// set to json:false in request, returns abieos-packed version
654    pub payer: Option<String>,
655}
656#[derive(Debug, Deserialize)]
657pub struct GetTableRows {
658    pub rows: Vec<GetTableRow>,
659    pub more: bool,
660    pub next_key: String,
661}