├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── LICENSE ├── README.md ├── analysis_options.yaml ├── example ├── eosdart_example.dart ├── eosdart_get_table.dart ├── get_required_keys.dart ├── new_account.dart └── push_transaction.dart ├── lib ├── eosdart.dart └── src │ ├── client.dart │ ├── eosdart_base.dart │ ├── jsons.dart │ ├── models │ ├── abi.dart │ ├── abi.g.dart │ ├── account.dart │ ├── account.g.dart │ ├── action.dart │ ├── action.g.dart │ ├── action_block.dart │ ├── action_block.g.dart │ ├── block.dart │ ├── block.g.dart │ ├── block_header_state.dart │ ├── block_header_state.g.dart │ ├── conversion_helper.dart │ ├── node_info.dart │ ├── node_info.g.dart │ ├── primary_wrapper.dart │ ├── primary_wrapper.g.dart │ ├── transaction.dart │ └── transaction.g.dart │ ├── numeric.dart │ └── serialize.dart ├── pubspec.yaml └── test ├── eosdart_test.dart └── models ├── abi_test.dart ├── abi_test_data.json ├── account_test.dart ├── account_test_data.json ├── action_test.dart ├── action_test_data.json ├── block_header_state_test.dart ├── block_header_state_test_data.json ├── block_test.dart ├── block_test_data.json ├── node_info_test.dart ├── node_info_test_data.json ├── transaction_test.dart ├── transaction_test_data1.json ├── transaction_test_data2.json └── transaction_test_data3.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Files and directories created by pub 2 | .dart_tool/ 3 | .packages 4 | # Remove the following pattern if you wish to check in your lock file 5 | pubspec.lock 6 | 7 | # Conventional directory for build outputs 8 | build/ 9 | 10 | # Directory created by dartdoc 11 | doc/api/ 12 | 13 | # Android Studio/idea 14 | .idea/ 15 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: dart 2 | dart_task: 3 | - dart format: sdk 4 | - test 5 | - dart analyze 6 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 0.4.9 2 | 3 | - Key serialization 4 | 5 | ## 0.4.8 6 | 7 | - Migrates to null safety 8 | 9 | ## 0.4.7 10 | 11 | - Handle any amount 12 | 13 | ## 0.4.6 14 | 15 | - More exports 16 | 17 | ## 0.4.5 18 | 19 | - Support adding timeout on http request 20 | 21 | ## 0.4.4 22 | 23 | - Support abi float32 and float64 24 | - Update dependencies 25 | 26 | ## 0.4.3 27 | 28 | - Add model for committed transaction 29 | - Reuse eos client instance with different private keys 30 | 31 | ## 0.4.2 32 | 33 | - Upgrade eosdart_ecc version to 0.4.0 34 | 35 | ## 0.4.1 36 | 37 | support: 38 | 39 | - /v1/chain/get_table_rows 40 | 41 | ## 0.4.0 42 | 43 | - Initial version to support push transaction 44 | 45 | ## 0.3.3 46 | 47 | - Update README.md 48 | 49 | ## 0.3.2 50 | 51 | - Correct the async operation 52 | - Better error handling 53 | 54 | ## 0.3.1 55 | 56 | Fix: Class name conflict with flutter - https://github.com/primes-network/eosdart/issues/12 57 | 58 | ## 0.3.0 59 | 60 | Supports the following APIs: 61 | 62 | - /v1/chain/get_info 63 | - /v1/chain/get_block 64 | - /v1/chain/get_block_header_state 65 | - /v1/chain/get_account 66 | - /v1/chain/get_abi 67 | - /v1/chain/get_raw_abi 68 | - /v1/chain/get_raw_code_and_abi 69 | - /v1/chain/get_currency_balance 70 | - /v1/history/get_actions 71 | - /v1/history/get_transaction 72 | - /v1/history/get_key_accounts 73 | 74 | ## 0.0.1 75 | 76 | - Initial version, created by Stagehand 77 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Primes Network 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # eosdart 2 | 3 | [![Build Status](https://travis-ci.com/primes-network/eosdart.svg?branch=master)](https://travis-ci.com/primes-network/eosdart) 4 | 5 | A library for EOS Node API 6 | 7 | It talks to the EOS nodes by the given endpoint and API method. 8 | 9 | ## Sample 10 | 11 | Sample Flutter application uses eosdart to fetch EOS account info: 12 | 13 | https://github.com/primes-network/sample_flutter_eosdart 14 | 15 | 16 | ## Usage 17 | 18 | A simple usage example: 19 | 20 | ```dart 21 | import 'package:eosdart/eosdart.dart'; 22 | 23 | main() { 24 | EOSClient client = EOSClient('https://eos.greymass.com', 'v1'); 25 | 26 | // Get EOS Node Info 27 | client.getInfo().then((NodeInfo nodeInfo) { 28 | print(nodeInfo); 29 | }); 30 | 31 | // Get EOS Abi 32 | client.getAbi('eosio.token').then((AbiResp abi) { 33 | print(abi); 34 | }); 35 | 36 | // Get EOS Raw Abi 37 | client.getRawAbi('eosio.token').then((AbiResp abi) { 38 | print(abi); 39 | }); 40 | 41 | // Get EOS Raw code and Abi 42 | client.getRawCodeAndAbi('eosio.token').then((AbiResp abi) { 43 | print(abi); 44 | }); 45 | 46 | // Get EOS Block Info 47 | client.getBlock('298674').then((Block block) { 48 | print(block); 49 | }); 50 | 51 | // Get Account Info 52 | client.getAccount('eosio.token').then((Account account) { 53 | print(account); 54 | }); 55 | 56 | // Get Account Actions 57 | client.getActions('eosio.token', pos: -1, offset: -1).then((Actions actions) { 58 | print(actions); 59 | }); 60 | 61 | // Get Transaction 62 | client 63 | .getTransaction( 64 | '83875faeb054ba20b20f392418e3a0002c4bb1c36cc4e3fde15cbd0963da8a15') 65 | .then((TransactionBlock transaction) { 66 | print(transaction); 67 | }); 68 | 69 | // Get Accounts from public key 70 | client 71 | .getKeyAccounts('EOS8RWQpzzMi5uFXXXAChi4dHnyxMYKKdAQ3Y3pHQTrvhzGk95LbT') 72 | .then((AccountNames accountNames) { 73 | print(accountNames); 74 | }); 75 | 76 | // Get currency balance 77 | client 78 | .getCurrencyBalance('parslseed123', 'newdexpocket') 79 | .then((List balance) { 80 | print(balance); 81 | }); 82 | } 83 | ``` 84 | 85 | ## Push Transaction 86 | 87 | ```dart 88 | import 'package:eosdart/eosdart.dart'; 89 | 90 | main() { 91 | EOSClient client = EOSClient('http://127.0.0.1:8888', 'v1', 92 | privateKeys: ["5J9b3xMkbvcT6gYv2EpQ8FD4ZBjgypuNKwE1jxkd7Wd1DYzhk88"]); 93 | 94 | List auth = [ 95 | Authorization() 96 | ..actor = 'bob' 97 | ..permission = 'active' 98 | ]; 99 | 100 | Map data = { 101 | 'from': 'bob', 102 | 'to': 'alice', 103 | 'quantity': '0.0001 SYS', 104 | 'memo': '', 105 | }; 106 | 107 | List actions = [ 108 | Action() 109 | ..account = 'eosio.token' 110 | ..name = 'transfer' 111 | ..authorization = auth 112 | ..data = data 113 | ]; 114 | 115 | Transaction transaction = Transaction()..actions = actions; 116 | 117 | // will print something like: 118 | // {transaction_id: c28bf8c168741adb96f3aef8723e953140cc60ecd20cec0d22e5a2dc5cdd5571, processed: {id: c28bf8c168741adb96f3aef8723e953140cc60ecd20cec0d22e5a2dc5cdd5571, block_num: 576745, block_time: 2019-05-03T06:07:54.500, producer_block_id: null, receipt: {status: executed, cpu_usage_us: 216, net_usage_words: 16}, elapsed: 216, net_usage: 128, scheduled: false, action_traces: [{receipt: {receiver: eosio.token, act_digest: 117d5840be4ff21fad764d5d497182916f76e772b279e65e964bccfa7c888331, global_sequence: 576794, recv_sequence: 17, auth_sequence: [[bob, 37]], code_sequence: 1, abi_sequence: 1}, act: {account: eosio.token, name: transfer, authorization: [{actor: bob, permission: active}], data: {from: bob, to: alice, quantity: 0.0001 SYS, memo: }, hex_data: 0000000000000e3d0000000000855c340100000000000000045359530000000000}, context_free: false, elapsed: 73, console: , trx_id: c28bf8c168741adb96f3aef8723e953140cc60ecd20cec0d22e5a2dc5cdd5571, block_num: 576745, block_time: 2019-05-03T06:07:54.500, producer_block_id: null, account_ram_deltas: [], except: null, inline_traces: [{receipt: {receiver: bob, act_digest: 117d5840be4ff21fad764d5d497182916f76e772b279e65e964bccfa7c888331, global_sequence: 576795, recv_sequence: 14, auth_sequence: [[bob, 38]], code_sequence: 1, abi_sequence: 1}, act: {account: eosio.token, name: transfer, authorization: [{actor: bob, permission: active}], data: {from: bob, to: alice, quantity: 0.0001 SYS, memo: }, hex_data: 0000000000000e3d0000000000855c340100000000000000045359530000000000}, context_free: false, elapsed: 2, console: , trx_id: c28bf8c168741adb96f3aef8723e953140cc60ecd20cec0d22e5a2dc5cdd5571, block_num: 576745, block_time: 2019-05-03T06:07:54.500, producer_block_id: null, account_ram_deltas: [], except: null, inline_traces: []}, {receipt: {receiver: alice, act_digest: 117d5840be4ff21fad764d5d497182916f76e772b279e65e964bccfa7c888331, global_sequence: 576796, recv_sequence: 15, auth_sequence: [[bob, 39]], code_sequence: 1, abi_sequence: 1}, act: {account: eosio.token, name: transfer, authorization: [{actor: bob, permission: active}], data: {from: bob, to: alice, quantity: 0.0001 SYS, memo: }, hex_data: 0000000000000e3d0000000000855c340100000000000000045359530000000000}, context_free: false, elapsed: 2, console: , trx_id: c28bf8c168741adb96f3aef8723e953140cc60ecd20cec0d22e5a2dc5cdd5571, block_num: 576745, block_time: 2019-05-03T06:07:54.500, producer_block_id: null, account_ram_deltas: [], except: null, inline_traces: []}]}], except: null}} 119 | client.pushTransaction(transaction, broadcast: true).then((trx) { 120 | print(trx); 121 | }); 122 | } 123 | 124 | ``` 125 | 126 | ## Installing 127 | 128 | https://pub.dartlang.org/packages/eosdart#-installing-tab- 129 | 130 | 131 | ## Features and bugs 132 | 133 | Please file feature requests and bugs at the [issue tracker][tracker]. 134 | 135 | [tracker]: https://github.com/primes-network/eosdart/issues 136 | -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | analyzer: 2 | # exclude: 3 | # - path/to/excluded/files/** 4 | 5 | # Lint rules and documentation, see http://dart-lang.github.io/linter/lints 6 | linter: 7 | rules: 8 | - cancel_subscriptions 9 | - hash_and_equals 10 | - iterable_contains_unrelated_type 11 | - list_remove_unrelated_type 12 | - test_types_in_equals 13 | - unrelated_type_equality_checks 14 | - valid_regexps 15 | -------------------------------------------------------------------------------- /example/eosdart_example.dart: -------------------------------------------------------------------------------- 1 | import 'package:eosdart/eosdart.dart'; 2 | 3 | main() { 4 | EOSClient client = EOSClient('https://eos.greymass.com', 'v1'); 5 | // EOSClient client = EOSClient('http://127.0.0.1:8888', 'v1', httpTimeout: 15); 6 | 7 | // Get EOS Node Info 8 | client.getInfo().then((NodeInfo nodeInfo) { 9 | print(nodeInfo); 10 | }); 11 | 12 | // Get EOS Abi 13 | client.getAbi('eosio.token').then((AbiResp abi) { 14 | print(abi); 15 | }); 16 | 17 | // Get EOS Raw Abi 18 | client.getRawAbi('eosio.token').then((AbiResp abi) { 19 | print(abi); 20 | }); 21 | 22 | // Get EOS Raw code and Abi 23 | client.getRawCodeAndAbi('eosio.token').then((AbiResp abi) { 24 | print(abi); 25 | }); 26 | 27 | // Get EOS Block Info 28 | client.getBlock('298674').then((Block block) { 29 | print(block); 30 | }); 31 | 32 | // Get Account Info 33 | client.getAccount('eosio.token').then((Account account) { 34 | print(account); 35 | }); 36 | 37 | // Get Account Actions 38 | client.getActions('eosio.token', pos: -1, offset: -1).then((Actions actions) { 39 | print(actions); 40 | }); 41 | 42 | // Get Transaction 43 | client 44 | .getTransaction( 45 | '83875faeb054ba20b20f392418e3a0002c4bb1c36cc4e3fde15cbd0963da8a15') 46 | .then((TransactionBlock transaction) { 47 | print(transaction); 48 | }); 49 | 50 | // Get Accounts from public key 51 | client 52 | .getKeyAccounts('EOS8RWQpzzMi5uFXXXAChi4dHnyxMYKKdAQ3Y3pHQTrvhzGk95LbT') 53 | .then((AccountNames accountNames) { 54 | print(accountNames); 55 | }); 56 | 57 | // Get currency balance 58 | client 59 | .getCurrencyBalance('parslseed123', 'newdexpocket') 60 | .then((List balance) { 61 | print(balance); 62 | }); 63 | 64 | // Get Tables 65 | client.getTableRows('eosio', 'eosio', 'abihash').then((rows) => print(rows)); 66 | client.getTableRow('eosio', 'eosio', 'abihash').then((row) => print(row)); 67 | } 68 | -------------------------------------------------------------------------------- /example/eosdart_get_table.dart: -------------------------------------------------------------------------------- 1 | import 'package:eosdart/eosdart.dart'; 2 | 3 | main() async { 4 | EOSClient client = EOSClient('https://eos.greymass.com', 'v1'); 5 | 6 | // Get Tables 7 | client.getTableRows('eosio', 'eosio', 'abihash').then((rows) => print(rows)); 8 | client.getTableRow('eosio', 'eosio', 'abihash').then((row) => print(row)); 9 | } 10 | -------------------------------------------------------------------------------- /example/get_required_keys.dart: -------------------------------------------------------------------------------- 1 | import 'package:eosdart/eosdart.dart'; 2 | 3 | main() { 4 | EOSClient client = EOSClient('http://127.0.0.1:8888', 'v1'); 5 | 6 | List auth = [ 7 | Authorization() 8 | ..actor = 'bob' 9 | ..permission = 'active' 10 | ]; 11 | 12 | Map data = { 13 | 'from': 'bob', 14 | 'to': 'alice', 15 | 'quantity': '0.0001 SYS', 16 | 'memo': '', 17 | }; 18 | 19 | List auth2 = [ 20 | Authorization() 21 | ..actor = 'alice' 22 | ..permission = 'active' 23 | ]; 24 | 25 | Map data2 = { 26 | 'from': 'alice', 27 | 'to': 'bob', 28 | 'quantity': '0.0002 SYS', 29 | 'memo': '', 30 | }; 31 | 32 | List actions = [ 33 | Action() 34 | ..account = 'eosio.token' 35 | ..name = 'transfer' 36 | ..authorization = auth 37 | ..data = data, 38 | Action() 39 | ..account = 'eosio.token' 40 | ..name = 'transfer' 41 | ..authorization = auth2 42 | ..data = data2 43 | ]; 44 | 45 | Transaction transaction = Transaction()..actions = actions; 46 | 47 | List availableKeys = [ 48 | "EOS8Qi58kbERkTJC7A4gabxYU4SbrAxStJHacoke4sf6AvJyEDZXj", 49 | "EOS5hF6jM5otV3jYdLVWqQ2Lidpb7LtN8dsXsFHFocggzvfGHGfR1" 50 | ]; 51 | client.getRequiredKeys(transaction, availableKeys).then((RequiredKeys rkeys) { 52 | print(rkeys); 53 | }); 54 | } 55 | -------------------------------------------------------------------------------- /example/new_account.dart: -------------------------------------------------------------------------------- 1 | import 'package:eosdart/eosdart.dart'; 2 | 3 | main() { 4 | EOSClient client = EOSClient('https://jungle3.cryptolions.io', 'v1', 5 | privateKeys: ["5J9b3xMkbvcT6gYv2EpQ8FD4ZBjgypuNKwE1jxkd7Wd1DYzhk88"]); 6 | 7 | //privateKeys can also be set after client was constructed, as following 8 | //client.privateKeys = ["5J9b3xMkbvcT6gYv2EpQ8FD4ZBjgypuNKwE1jxkd7Wd1DYzhk88"]; 9 | 10 | List auth = [ 11 | Authorization() 12 | ..actor = 'xuelongqy2cn' 13 | ..permission = 'active' 14 | ]; 15 | 16 | Map data = { 17 | 'creator': 'xuelongqy2cn', 18 | 'name': 'xuelongqy3cn', 19 | 'owner': { 20 | 'threshold': 1, 21 | 'keys': [ 22 | { 23 | 'key': "EOS65xaKR6zw4cjy9kuwuCbi7vTTbWNYSHdVgNf7492VAjCPi6gT6", 24 | 'weight': 1, 25 | } 26 | ], 27 | 'accounts': [], 28 | 'waits': [] 29 | }, 30 | 'active': { 31 | 'threshold': 1, 32 | 'keys': [ 33 | { 34 | 'key': "EOS65xaKR6zw4cjy9kuwuCbi7vTTbWNYSHdVgNf7492VAjCPi6gT6", 35 | 'weight': 1, 36 | } 37 | ], 38 | 'accounts': [], 39 | 'waits': [] 40 | }, 41 | }; 42 | 43 | List actions = [ 44 | Action() 45 | ..account = 'eosio' 46 | ..name = 'newaccount' 47 | ..authorization = auth 48 | ..data = data, 49 | Action() 50 | ..account = 'eosio' 51 | ..name = 'buyram' 52 | ..authorization = auth 53 | ..data = { 54 | 'payer': "xuelongqy2cn", 55 | 'receiver': "xuelongqy3cn", 56 | 'quant': "2.0000 EOS", 57 | }, 58 | Action() 59 | ..account = 'eosio' 60 | ..name = 'delegatebw' 61 | ..authorization = auth 62 | ..data = { 63 | 'from': "xuelongqy2cn", 64 | 'receiver': "xuelongqy3cn", 65 | 'stake_net_quantity': "1.0000 EOS", 66 | 'stake_cpu_quantity': "1.0000 EOS", 67 | 'transfer': false, 68 | } 69 | ]; 70 | 71 | Transaction transaction = Transaction()..actions = actions; 72 | 73 | // print result 74 | client.pushTransaction(transaction, broadcast: true).then((trx) { 75 | print(trx); 76 | }); 77 | } 78 | -------------------------------------------------------------------------------- /example/push_transaction.dart: -------------------------------------------------------------------------------- 1 | import 'package:eosdart/eosdart.dart'; 2 | 3 | main() { 4 | EOSClient client = EOSClient('http://127.0.0.1:8888', 'v1', 5 | privateKeys: ["5J9b3xMkbvcT6gYv2EpQ8FD4ZBjgypuNKwE1jxkd7Wd1DYzhk88"]); 6 | 7 | //privateKeys can also be set after client was constructed, as following 8 | //client.privateKeys = ["5J9b3xMkbvcT6gYv2EpQ8FD4ZBjgypuNKwE1jxkd7Wd1DYzhk88"]; 9 | 10 | List auth = [ 11 | Authorization() 12 | ..actor = 'bob' 13 | ..permission = 'active' 14 | ]; 15 | 16 | Map data = { 17 | 'from': 'bob', 18 | 'to': 'alice', 19 | 'quantity': '0.0001 SYS', 20 | 'memo': '', 21 | }; 22 | 23 | List actions = [ 24 | Action() 25 | ..account = 'eosio.token' 26 | ..name = 'transfer' 27 | ..authorization = auth 28 | ..data = data 29 | ]; 30 | 31 | Transaction transaction = Transaction()..actions = actions; 32 | 33 | // will print something like: 34 | // {transaction_id: c28bf8c168741adb96f3aef8723e953140cc60ecd20cec0d22e5a2dc5cdd5571, processed: {id: c28bf8c168741adb96f3aef8723e953140cc60ecd20cec0d22e5a2dc5cdd5571, block_num: 576745, block_time: 2019-05-03T06:07:54.500, producer_block_id: null, receipt: {status: executed, cpu_usage_us: 216, net_usage_words: 16}, elapsed: 216, net_usage: 128, scheduled: false, action_traces: [{receipt: {receiver: eosio.token, act_digest: 117d5840be4ff21fad764d5d497182916f76e772b279e65e964bccfa7c888331, global_sequence: 576794, recv_sequence: 17, auth_sequence: [[bob, 37]], code_sequence: 1, abi_sequence: 1}, act: {account: eosio.token, name: transfer, authorization: [{actor: bob, permission: active}], data: {from: bob, to: alice, quantity: 0.0001 SYS, memo: }, hex_data: 0000000000000e3d0000000000855c340100000000000000045359530000000000}, context_free: false, elapsed: 73, console: , trx_id: c28bf8c168741adb96f3aef8723e953140cc60ecd20cec0d22e5a2dc5cdd5571, block_num: 576745, block_time: 2019-05-03T06:07:54.500, producer_block_id: null, account_ram_deltas: [], except: null, inline_traces: [{receipt: {receiver: bob, act_digest: 117d5840be4ff21fad764d5d497182916f76e772b279e65e964bccfa7c888331, global_sequence: 576795, recv_sequence: 14, auth_sequence: [[bob, 38]], code_sequence: 1, abi_sequence: 1}, act: {account: eosio.token, name: transfer, authorization: [{actor: bob, permission: active}], data: {from: bob, to: alice, quantity: 0.0001 SYS, memo: }, hex_data: 0000000000000e3d0000000000855c340100000000000000045359530000000000}, context_free: false, elapsed: 2, console: , trx_id: c28bf8c168741adb96f3aef8723e953140cc60ecd20cec0d22e5a2dc5cdd5571, block_num: 576745, block_time: 2019-05-03T06:07:54.500, producer_block_id: null, account_ram_deltas: [], except: null, inline_traces: []}, {receipt: {receiver: alice, act_digest: 117d5840be4ff21fad764d5d497182916f76e772b279e65e964bccfa7c888331, global_sequence: 576796, recv_sequence: 15, auth_sequence: [[bob, 39]], code_sequence: 1, abi_sequence: 1}, act: {account: eosio.token, name: transfer, authorization: [{actor: bob, permission: active}], data: {from: bob, to: alice, quantity: 0.0001 SYS, memo: }, hex_data: 0000000000000e3d0000000000855c340100000000000000045359530000000000}, context_free: false, elapsed: 2, console: , trx_id: c28bf8c168741adb96f3aef8723e953140cc60ecd20cec0d22e5a2dc5cdd5571, block_num: 576745, block_time: 2019-05-03T06:07:54.500, producer_block_id: null, account_ram_deltas: [], except: null, inline_traces: []}]}], except: null}} 35 | client.pushTransaction(transaction, broadcast: true).then((trx) { 36 | print(trx); 37 | }); 38 | } 39 | -------------------------------------------------------------------------------- /lib/eosdart.dart: -------------------------------------------------------------------------------- 1 | /// Support for EOS API lib in Dart 2 | /// 3 | /// More dartdocs go here. 4 | library eosdart; 5 | 6 | export 'src/client.dart'; 7 | export 'src/models/account.dart'; 8 | export 'src/models/node_info.dart'; 9 | export 'src/models/block.dart'; 10 | export 'src/models/action.dart'; 11 | export 'src/models/action_block.dart'; 12 | export 'src/models/transaction.dart'; 13 | export 'src/models/primary_wrapper.dart'; 14 | export 'src/models/block_header_state.dart'; 15 | export 'src/models/abi.dart'; 16 | 17 | export 'src/numeric.dart'; 18 | export 'src/serialize.dart'; 19 | export 'src/eosdart_base.dart'; 20 | -------------------------------------------------------------------------------- /lib/src/client.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'dart:convert'; 3 | import 'dart:typed_data'; 4 | 5 | import 'package:eosdart_ecc/eosdart_ecc.dart' as ecc; 6 | import 'package:http/http.dart' as http; 7 | 8 | import './models/abi.dart'; 9 | import './models/account.dart'; 10 | import './models/action.dart'; 11 | import './models/action_block.dart'; 12 | import './models/block.dart'; 13 | import './models/block_header_state.dart'; 14 | import './models/node_info.dart'; 15 | import './models/primary_wrapper.dart'; 16 | import './models/transaction.dart'; 17 | import 'eosdart_base.dart'; 18 | import 'jsons.dart'; 19 | import 'serialize.dart' as ser; 20 | 21 | /// EOSClient calls APIs against given EOS nodes 22 | class EOSClient { 23 | final String _nodeURL; 24 | final String _version; 25 | late int expirationInSec; 26 | late int httpTimeout; 27 | Map keys = Map(); 28 | 29 | /// Converts abi files between binary and structured form (`abi.abi.json`) */ 30 | late Map abiTypes; 31 | late Map transactionTypes; 32 | 33 | /// Construct the EOS client from eos node URL 34 | EOSClient( 35 | this._nodeURL, 36 | this._version, { 37 | this.expirationInSec = 180, 38 | List privateKeys = const [], 39 | this.httpTimeout = 10, 40 | }) { 41 | _mapKeys(privateKeys); 42 | 43 | abiTypes = ser.getTypesFromAbi( 44 | ser.createInitialTypes(), Abi.fromJson(json.decode(abiJson))); 45 | transactionTypes = ser.getTypesFromAbi( 46 | ser.createInitialTypes(), Abi.fromJson(json.decode(transactionJson))); 47 | } 48 | 49 | /// Sets private keys. Required to sign transactions. 50 | void _mapKeys(List privateKeys) { 51 | for (String privateKey in privateKeys) { 52 | ecc.EOSPrivateKey pKey = ecc.EOSPrivateKey.fromString(privateKey); 53 | String publicKey = pKey.toEOSPublicKey().toString(); 54 | keys[publicKey] = pKey; 55 | } 56 | } 57 | 58 | set privateKeys(List privateKeys) => _mapKeys(privateKeys); 59 | 60 | Future _post(String path, Object body) async { 61 | Completer completer = Completer(); 62 | http 63 | .post(Uri.parse('${this._nodeURL}/${this._version}${path}'), 64 | body: json.encode(body)) 65 | .timeout(Duration(seconds: this.httpTimeout)) 66 | .then((http.Response response) { 67 | if (response.statusCode >= 300) { 68 | completer.completeError(response.body); 69 | } else { 70 | completer.complete(json.decode(response.body)); 71 | } 72 | }).catchError((e, s) { 73 | completer.completeError(e, s); 74 | }); 75 | return completer.future; 76 | } 77 | 78 | /// Get EOS Node Info 79 | Future getInfo() async { 80 | return this._post('/chain/get_info', {}).then((nodeInfo) { 81 | NodeInfo info = NodeInfo.fromJson(nodeInfo); 82 | return info; 83 | }); 84 | } 85 | 86 | /// Get table rows (eosio get table ...) 87 | Future>> getTableRows( 88 | String code, 89 | String scope, 90 | String table, { 91 | bool json = true, 92 | String tableKey = '', 93 | String lower = '', 94 | String upper = '', 95 | int indexPosition = 1, 96 | String keyType = '', 97 | int limit = 10, 98 | bool reverse = false, 99 | }) async { 100 | dynamic result = await this._post('/chain/get_table_rows', { 101 | 'json': json, 102 | 'code': code, 103 | 'scope': scope, 104 | 'table': table, 105 | 'table_key': tableKey, 106 | 'lower_bound': lower, 107 | 'upper_bound': upper, 108 | 'index_position': indexPosition, 109 | 'key_type': keyType, 110 | 'limit': limit, 111 | 'reverse': reverse, 112 | }); 113 | if (result is Map) { 114 | return result['rows'].cast>(); 115 | } 116 | return []; 117 | } 118 | 119 | /// Get table row (eosio get table ...) 120 | Future?> getTableRow( 121 | String code, 122 | String scope, 123 | String table, { 124 | bool json = true, 125 | String tableKey = '', 126 | String lower = '', 127 | String upper = '', 128 | int indexPosition = 1, 129 | String keyType = '', 130 | bool reverse = false, 131 | }) async { 132 | var rows = await getTableRows( 133 | code, 134 | scope, 135 | table, 136 | json: json, 137 | tableKey: tableKey, 138 | lower: lower, 139 | upper: upper, 140 | indexPosition: indexPosition, 141 | keyType: keyType, 142 | limit: 1, 143 | reverse: reverse, 144 | ); 145 | 146 | return rows.length > 0 ? rows[0] : null; 147 | } 148 | 149 | /// Get EOS Block Info 150 | Future getBlock(String blockNumOrId) async { 151 | return this._post( 152 | '/chain/get_block', {'block_num_or_id': blockNumOrId}).then((block) { 153 | return Block.fromJson(block); 154 | }); 155 | } 156 | 157 | /// Get EOS Block Header State 158 | Future getBlockHeaderState(String blockNumOrId) async { 159 | return this._post('/chain/get_block_header_state', 160 | {'block_num_or_id': blockNumOrId}).then((block) { 161 | return BlockHeaderState.fromJson(block); 162 | }); 163 | } 164 | 165 | /// Get EOS abi from account name 166 | Future getAbi(String accountName) async { 167 | return this 168 | ._post('/chain/get_abi', {'account_name': accountName}).then((abi) { 169 | return AbiResp.fromJson(abi); 170 | }); 171 | } 172 | 173 | /// Get EOS raw abi from account name 174 | Future getRawAbi(String accountName) async { 175 | return this 176 | ._post('/chain/get_raw_abi', {'account_name': accountName}).then((abi) { 177 | return AbiResp.fromJson(abi); 178 | }); 179 | } 180 | 181 | /// Get EOS raw code and abi from account name 182 | Future getRawCodeAndAbi(String accountName) async { 183 | return this._post('/chain/get_raw_code_and_abi', 184 | {'account_name': accountName}).then((abi) { 185 | return AbiResp.fromJson(abi); 186 | }); 187 | } 188 | 189 | /// Get EOS account info form the given account name 190 | Future getAccount(String accountName) async { 191 | return this._post('/chain/get_account', {'account_name': accountName}).then( 192 | (account) { 193 | return Account.fromJson(account); 194 | }); 195 | } 196 | 197 | /// Get EOS account info form the given account name 198 | Future> getCurrencyBalance(String code, String account, 199 | [String? symbol]) async { 200 | return this._post('/chain/get_currency_balance', 201 | {'code': code, 'account': account, 'symbol': symbol}).then((balance) { 202 | return (balance as List).map((e) => new Holding.fromJson(e)).toList(); 203 | }); 204 | } 205 | 206 | /// Get required key by transaction from EOS blockchain 207 | Future getRequiredKeys( 208 | Transaction transaction, List availableKeys) async { 209 | NodeInfo info = await getInfo(); 210 | Block refBlock = await getBlock((info.headBlockNum).toString()); 211 | Transaction trx = await _fullFill(transaction, refBlock); 212 | trx = await _serializeActions(trx); 213 | 214 | // raw abi to json 215 | // AbiResp abiResp = await getRawAbi(account); 216 | // print(abiResp.abi); 217 | return this._post('/chain/get_required_keys', { 218 | 'transaction': trx, 219 | 'available_keys': availableKeys 220 | }).then((requiredKeys) { 221 | return RequiredKeys.fromJson(requiredKeys); 222 | }); 223 | } 224 | 225 | /// Get EOS account actions 226 | Future getActions(String accountName, 227 | {int pos = -1, int offset = -1}) async { 228 | return this._post('/history/get_actions', { 229 | 'account_name': accountName, 230 | 'pot': pos, 231 | 'offset': offset 232 | }).then((actions) { 233 | return Actions.fromJson(actions); 234 | }); 235 | } 236 | 237 | /// Get EOS transaction 238 | Future getTransaction(String id, 239 | {int? blockNumHint}) async { 240 | return this._post('/history/get_transaction', 241 | {'id': id, 'block_num_hint': blockNumHint}).then((transaction) { 242 | return TransactionBlock.fromJson(transaction); 243 | }); 244 | } 245 | 246 | /// Get Key Accounts 247 | Future getKeyAccounts(String pubKey) async { 248 | return this._post('/history/get_key_accounts', {'public_key': pubKey}).then( 249 | (accountNames) { 250 | return AccountNames.fromJson(accountNames); 251 | }); 252 | } 253 | 254 | /// Push transaction to EOS chain 255 | Future pushTransaction(Transaction transaction, 256 | {bool broadcast = true, 257 | bool sign = true, 258 | int blocksBehind = 3, 259 | int expireSecond = 180}) async { 260 | NodeInfo info = await this.getInfo(); 261 | Block refBlock = 262 | await getBlock((info.headBlockNum! - blocksBehind).toString()); 263 | 264 | Transaction trx = await _fullFill(transaction, refBlock); 265 | PushTransactionArgs pushTransactionArgs = await _pushTransactionArgs( 266 | info.chainId!, transactionTypes['transaction']!, trx, sign); 267 | 268 | if (broadcast) { 269 | return this._post('/chain/push_transaction', { 270 | 'signatures': pushTransactionArgs.signatures, 271 | 'compression': 0, 272 | 'packed_context_free_data': '', 273 | 'packed_trx': ser.arrayToHex(pushTransactionArgs.serializedTransaction), 274 | }).then((processedTrx) { 275 | return processedTrx; 276 | }); 277 | } 278 | 279 | return pushTransactionArgs; 280 | } 281 | 282 | /// Get data needed to serialize actions in a contract */ 283 | Future _getContract(String accountName, 284 | {bool reload = false}) async { 285 | var abi = await getRawAbi(accountName); 286 | var types = ser.getTypesFromAbi(ser.createInitialTypes(), abi.abi!); 287 | var actions = new Map(); 288 | for (var act in abi.abi!.actions!) { 289 | actions[act.name] = ser.getType(types, act.type); 290 | } 291 | var result = Contract(types, actions); 292 | return result; 293 | } 294 | 295 | /// Fill the transaction withe reference block data 296 | Future _fullFill(Transaction transaction, Block refBlock) async { 297 | transaction.expiration = 298 | refBlock.timestamp!.add(Duration(seconds: expirationInSec)); 299 | transaction.refBlockNum = refBlock.blockNum! & 0xffff; 300 | transaction.refBlockPrefix = refBlock.refBlockPrefix; 301 | 302 | return transaction; 303 | } 304 | 305 | /// serialize actions in a transaction 306 | Future _serializeActions(Transaction transaction) async { 307 | for (Action action in transaction.actions!) { 308 | String account = action.account!; 309 | 310 | Contract contract = await _getContract(account); 311 | 312 | action.data = 313 | _serializeActionData(contract, account, action.name!, action.data!); 314 | } 315 | return transaction; 316 | } 317 | 318 | /// Convert action data to serialized form (hex) */ 319 | String _serializeActionData( 320 | Contract contract, String account, String name, Object data) { 321 | var action = contract.actions[name]; 322 | if (action == null) { 323 | throw "Unknown action $name in contract $account"; 324 | } 325 | var buffer = new ser.SerialBuffer(Uint8List(0)); 326 | action.serialize?.call(action, buffer, data); 327 | return ser.arrayToHex(buffer.asUint8List()); 328 | } 329 | 330 | // Future> _getTransactionAbis(Transaction transaction) async { 331 | // Set accounts = Set(); 332 | // List result = []; 333 | // 334 | // for (Action action in transaction.actions) { 335 | // accounts.add(action.account); 336 | // } 337 | // 338 | // for (String accountName in accounts) { 339 | // result.add(await this.getRawAbi(accountName)); 340 | // } 341 | // } 342 | 343 | Future _pushTransactionArgs(String chainId, 344 | Type transactionType, Transaction transaction, bool sign) async { 345 | List signatures = []; 346 | 347 | RequiredKeys requiredKeys = 348 | await getRequiredKeys(transaction, this.keys.keys.toList()); 349 | 350 | Uint8List serializedTrx = transaction.toBinary(transactionType); 351 | 352 | if (sign) { 353 | Uint8List signBuf = Uint8List.fromList(List.from(ser.stringToHex(chainId)) 354 | ..addAll(serializedTrx) 355 | ..addAll(Uint8List(32))); 356 | 357 | for (String publicKey in requiredKeys.requiredKeys!) { 358 | ecc.EOSPrivateKey pKey = this.keys[publicKey]!; 359 | signatures.add(pKey.sign(signBuf).toString()); 360 | } 361 | } 362 | 363 | return PushTransactionArgs(signatures, serializedTrx); 364 | } 365 | } 366 | 367 | class PushTransactionArgs { 368 | List signatures; 369 | Uint8List serializedTransaction; 370 | 371 | PushTransactionArgs(this.signatures, this.serializedTransaction); 372 | } 373 | -------------------------------------------------------------------------------- /lib/src/eosdart_base.dart: -------------------------------------------------------------------------------- 1 | /// A field in an abi */ 2 | class Field { 3 | /// Field name */ 4 | String name; 5 | 6 | /// Type name in string form */ 7 | String typeName; 8 | 9 | /// Type of the field */ 10 | Type? type; 11 | 12 | Field({ 13 | required this.name, 14 | this.type, 15 | required this.typeName, 16 | }); 17 | } 18 | 19 | class Type { 20 | String name; 21 | 22 | String aliasOfName; 23 | 24 | Type? arrayOf; 25 | 26 | Type? optionalOf; 27 | 28 | Type? extensionOf; 29 | 30 | String baseName; 31 | 32 | Type? base; 33 | 34 | List fields; 35 | 36 | Function? serialize; 37 | 38 | // void Function(Type self,SerialBuffer buffer, Object data, {SerializerState state,bool allowExtensions}) serialize; 39 | 40 | Function? deserialize; 41 | 42 | Type({ 43 | required this.name, 44 | required this.aliasOfName, 45 | this.arrayOf, 46 | this.optionalOf, 47 | this.extensionOf, 48 | required this.baseName, 49 | this.base, 50 | required this.fields, 51 | this.serialize, 52 | this.deserialize, 53 | }); 54 | } 55 | 56 | class Contract { 57 | Map actions; 58 | 59 | Map types; 60 | 61 | Contract(this.types, this.actions); 62 | } 63 | 64 | /// Structural representation of a symbol */ 65 | class Symbol { 66 | /// Name of the symbol, not including precision */ 67 | final String name; 68 | 69 | /// Number of digits after the decimal point */ 70 | final int precision; 71 | 72 | Symbol({ 73 | required this.name, 74 | required this.precision, 75 | }); 76 | } 77 | -------------------------------------------------------------------------------- /lib/src/jsons.dart: -------------------------------------------------------------------------------- 1 | String abiJson = ''' 2 | { 3 | "version": "eosio::abi/1.1", 4 | "structs": [ 5 | { 6 | "name": "extensions_entry", 7 | "base": "", 8 | "fields": [ 9 | { 10 | "name": "tag", 11 | "type": "uint16" 12 | }, 13 | { 14 | "name": "value", 15 | "type": "bytes" 16 | } 17 | ] 18 | }, 19 | { 20 | "name": "newaccount", 21 | "base": "", 22 | "fields": [ 23 | { 24 | "name": "creator", 25 | "type": "name" 26 | }, 27 | { 28 | "name": "name", 29 | "type": "name" 30 | }, 31 | { 32 | "name": "owner", 33 | "type": "authority" 34 | }, 35 | { 36 | "name": "active", 37 | "type": "authority" 38 | } 39 | ] 40 | }, 41 | { 42 | "name": "authority", 43 | "base": "", 44 | "fields": [ 45 | { 46 | "name": "threshold", 47 | "type": "uint32" 48 | }, 49 | { 50 | "name": "keys", 51 | "type": "key_weight[]" 52 | }, 53 | { 54 | "name": "accounts", 55 | "type": "permission_level_weight[]" 56 | }, 57 | { 58 | "name": "waits", 59 | "type": "wait_weight[]" 60 | } 61 | ] 62 | }, 63 | { 64 | "name": "key_weight", 65 | "base": "", 66 | "fields": [ 67 | { 68 | "name": "key", 69 | "type": "public_key" 70 | }, 71 | { 72 | "name": "weight", 73 | "type": "uint16" 74 | } 75 | ] 76 | }, 77 | { 78 | "name": "permission_level_weight", 79 | "base": "", 80 | "fields": [ 81 | { 82 | "name": "permission", 83 | "type": "permission_level" 84 | }, 85 | { 86 | "name": "weight", 87 | "type": "uint16" 88 | } 89 | ] 90 | }, 91 | { 92 | "name": "wait_weight", 93 | "base": "", 94 | "fields": [ 95 | { 96 | "name": "wait_sec", 97 | "type": "uint32" 98 | }, 99 | { 100 | "name": "weight", 101 | "type": "uint16" 102 | } 103 | ] 104 | }, 105 | { 106 | "name": "permission_level", 107 | "base": "", 108 | "fields": [ 109 | { 110 | "name": "actor", 111 | "type": "name" 112 | }, 113 | { 114 | "name": "permission", 115 | "type": "name" 116 | } 117 | ] 118 | }, 119 | { 120 | "name": "buyram", 121 | "base": "", 122 | "fields": [ 123 | { 124 | "name": "payer", 125 | "type": "name" 126 | }, 127 | { 128 | "name": "receiver", 129 | "type": "name" 130 | }, 131 | { 132 | "name": "quant", 133 | "type": "asset" 134 | } 135 | ] 136 | }, 137 | { 138 | "name": "sellram", 139 | "base": "", 140 | "fields": [ 141 | { 142 | "name": "account", 143 | "type": "name" 144 | }, 145 | { 146 | "name": "bytes", 147 | "type": "int64" 148 | } 149 | ] 150 | }, 151 | { 152 | "name": "delegatebw", 153 | "base": "", 154 | "fields": [ 155 | { 156 | "name": "from", 157 | "type": "name" 158 | }, 159 | { 160 | "name": "receiver", 161 | "type": "name" 162 | }, 163 | { 164 | "name": "stake_net_quantity", 165 | "type": "asset" 166 | }, 167 | { 168 | "name": "stake_cpu_quantity", 169 | "type": "asset" 170 | }, 171 | { 172 | "name": "transfer", 173 | "type": "bool" 174 | } 175 | ] 176 | }, 177 | { 178 | "name": "undelegatebw", 179 | "base": "", 180 | "fields": [ 181 | { 182 | "name": "from", 183 | "type": "name" 184 | }, 185 | { 186 | "name": "receiver", 187 | "type": "name" 188 | }, 189 | { 190 | "name": "unstake_net_quantity", 191 | "type": "asset" 192 | }, 193 | { 194 | "name": "unstake_cpu_quantity", 195 | "type": "asset" 196 | } 197 | ] 198 | }, 199 | { 200 | "name": "rentcpu", 201 | "base": "", 202 | "fields": [ 203 | { 204 | "name": "from", 205 | "type": "name" 206 | }, 207 | { 208 | "name": "receiver", 209 | "type": "name" 210 | }, 211 | { 212 | "name": "loan_payment", 213 | "type": "asset" 214 | }, 215 | { 216 | "name": "loan_fund", 217 | "type": "asset" 218 | } 219 | ] 220 | }, 221 | { 222 | "name": "rentnet", 223 | "base": "", 224 | "fields": [ 225 | { 226 | "name": "from", 227 | "type": "name" 228 | }, 229 | { 230 | "name": "receiver", 231 | "type": "name" 232 | }, 233 | { 234 | "name": "loan_payment", 235 | "type": "asset" 236 | }, 237 | { 238 | "name": "loan_fund", 239 | "type": "asset" 240 | } 241 | ] 242 | }, 243 | { 244 | "name": "powerup", 245 | "base": "", 246 | "fields": [ 247 | { 248 | "name": "payer", 249 | "type": "name" 250 | }, 251 | { 252 | "name": "receiver", 253 | "type": "name" 254 | }, 255 | { 256 | "name": "days", 257 | "type": "uint32" 258 | }, 259 | { 260 | "name": "net_frac", 261 | "type": "int64" 262 | }, 263 | { 264 | "name": "cpu_frac", 265 | "type": "int64" 266 | }, 267 | { 268 | "name": "max_payment", 269 | "type": "asset" 270 | } 271 | ] 272 | }, 273 | { 274 | "name": "voteproducer", 275 | "base": "", 276 | "fields": [ 277 | { 278 | "name": "voter", 279 | "type": "name" 280 | }, 281 | { 282 | "name": "proxy", 283 | "type": "name" 284 | }, 285 | { 286 | "name": "producers", 287 | "type": "name[]" 288 | } 289 | ] 290 | }, 291 | { 292 | "name": "type_def", 293 | "base": "", 294 | "fields": [ 295 | { 296 | "name": "new_type_name", 297 | "type": "string" 298 | }, 299 | { 300 | "name": "type", 301 | "type": "string" 302 | } 303 | ] 304 | }, 305 | { 306 | "name": "field_def", 307 | "base": "", 308 | "fields": [ 309 | { 310 | "name": "name", 311 | "type": "string" 312 | }, 313 | { 314 | "name": "type", 315 | "type": "string" 316 | } 317 | ] 318 | }, 319 | { 320 | "name": "struct_def", 321 | "base": "", 322 | "fields": [ 323 | { 324 | "name": "name", 325 | "type": "string" 326 | }, 327 | { 328 | "name": "base", 329 | "type": "string" 330 | }, 331 | { 332 | "name": "fields", 333 | "type": "field_def[]" 334 | } 335 | ] 336 | }, 337 | { 338 | "name": "action_def", 339 | "base": "", 340 | "fields": [ 341 | { 342 | "name": "name", 343 | "type": "name" 344 | }, 345 | { 346 | "name": "type", 347 | "type": "string" 348 | }, 349 | { 350 | "name": "ricardian_contract", 351 | "type": "string" 352 | } 353 | ] 354 | }, 355 | { 356 | "name": "table_def", 357 | "base": "", 358 | "fields": [ 359 | { 360 | "name": "name", 361 | "type": "name" 362 | }, 363 | { 364 | "name": "index_type", 365 | "type": "string" 366 | }, 367 | { 368 | "name": "key_names", 369 | "type": "string[]" 370 | }, 371 | { 372 | "name": "key_types", 373 | "type": "string[]" 374 | }, 375 | { 376 | "name": "type", 377 | "type": "string" 378 | } 379 | ] 380 | }, 381 | { 382 | "name": "clause_pair", 383 | "base": "", 384 | "fields": [ 385 | { 386 | "name": "id", 387 | "type": "string" 388 | }, 389 | { 390 | "name": "body", 391 | "type": "string" 392 | } 393 | ] 394 | }, 395 | { 396 | "name": "error_message", 397 | "base": "", 398 | "fields": [ 399 | { 400 | "name": "error_code", 401 | "type": "uint64" 402 | }, 403 | { 404 | "name": "error_msg", 405 | "type": "string" 406 | } 407 | ] 408 | }, 409 | { 410 | "name": "variant_def", 411 | "base": "", 412 | "fields": [ 413 | { 414 | "name": "name", 415 | "type": "string" 416 | }, 417 | { 418 | "name": "types", 419 | "type": "string[]" 420 | } 421 | ] 422 | }, 423 | { 424 | "name": "abi_def", 425 | "base": "", 426 | "fields": [ 427 | { 428 | "name": "version", 429 | "type": "string" 430 | }, 431 | { 432 | "name": "types", 433 | "type": "type_def[]" 434 | }, 435 | { 436 | "name": "structs", 437 | "type": "struct_def[]" 438 | }, 439 | { 440 | "name": "actions", 441 | "type": "action_def[]" 442 | }, 443 | { 444 | "name": "tables", 445 | "type": "table_def[]" 446 | }, 447 | { 448 | "name": "ricardian_clauses", 449 | "type": "clause_pair[]" 450 | }, 451 | { 452 | "name": "error_messages", 453 | "type": "error_message[]" 454 | }, 455 | { 456 | "name": "abi_extensions", 457 | "type": "extensions_entry[]" 458 | }, 459 | { 460 | "name": "variants", 461 | "type": "variant_def[]\$" 462 | } 463 | ] 464 | } 465 | ] 466 | } 467 | '''; 468 | 469 | String transactionJson = ''' 470 | { 471 | "version": "eosio::abi/1.0", 472 | "types": [ 473 | { 474 | "new_type_name": "account_name", 475 | "type": "name" 476 | }, 477 | { 478 | "new_type_name": "action_name", 479 | "type": "name" 480 | }, 481 | { 482 | "new_type_name": "permission_name", 483 | "type": "name" 484 | } 485 | ], 486 | "structs": [ 487 | { 488 | "name": "permission_level", 489 | "base": "", 490 | "fields": [ 491 | { 492 | "name": "actor", 493 | "type": "account_name" 494 | }, 495 | { 496 | "name": "permission", 497 | "type": "permission_name" 498 | } 499 | ] 500 | }, 501 | { 502 | "name": "action", 503 | "base": "", 504 | "fields": [ 505 | { 506 | "name": "account", 507 | "type": "account_name" 508 | }, 509 | { 510 | "name": "name", 511 | "type": "action_name" 512 | }, 513 | { 514 | "name": "authorization", 515 | "type": "permission_level[]" 516 | }, 517 | { 518 | "name": "data", 519 | "type": "bytes" 520 | } 521 | ] 522 | }, 523 | { 524 | "name": "extension", 525 | "base": "", 526 | "fields": [ 527 | { 528 | "name": "type", 529 | "type": "uint16" 530 | }, 531 | { 532 | "name": "data", 533 | "type": "bytes" 534 | } 535 | ] 536 | }, 537 | { 538 | "name": "transaction_header", 539 | "base": "", 540 | "fields": [ 541 | { 542 | "name": "expiration", 543 | "type": "time_point_sec" 544 | }, 545 | { 546 | "name": "ref_block_num", 547 | "type": "uint16" 548 | }, 549 | { 550 | "name": "ref_block_prefix", 551 | "type": "uint32" 552 | }, 553 | { 554 | "name": "max_net_usage_words", 555 | "type": "varuint32" 556 | }, 557 | { 558 | "name": "max_cpu_usage_ms", 559 | "type": "uint8" 560 | }, 561 | { 562 | "name": "delay_sec", 563 | "type": "varuint32" 564 | } 565 | ] 566 | }, 567 | { 568 | "name": "transaction", 569 | "base": "transaction_header", 570 | "fields": [ 571 | { 572 | "name": "context_free_actions", 573 | "type": "action[]" 574 | }, 575 | { 576 | "name": "actions", 577 | "type": "action[]" 578 | }, 579 | { 580 | "name": "transaction_extensions", 581 | "type": "extension[]" 582 | } 583 | ] 584 | } 585 | ] 586 | } 587 | '''; 588 | -------------------------------------------------------------------------------- /lib/src/models/abi.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'dart:typed_data'; 3 | 4 | import 'package:json_annotation/json_annotation.dart'; 5 | 6 | import './conversion_helper.dart'; 7 | import '../eosdart_base.dart'; 8 | import '../jsons.dart'; 9 | import '../numeric.dart'; 10 | import '../serialize.dart' as ser; 11 | 12 | part 'abi.g.dart'; 13 | 14 | @JsonSerializable() 15 | class AbiResp with ConversionHelper { 16 | @JsonKey(name: 'account_name') 17 | String? accountName; 18 | 19 | @JsonKey(name: 'code_hash') 20 | String? codeHash; 21 | 22 | @JsonKey(name: 'abi_hash') 23 | String? abiHash; 24 | 25 | @JsonKey(name: 'wasm') 26 | String? wasm; 27 | 28 | @JsonKey(name: 'abi', fromJson: _decodeAbi) 29 | Abi? abi; 30 | 31 | AbiResp(); 32 | 33 | factory AbiResp.fromJson(Map json) => 34 | _$AbiRespFromJson(json); 35 | 36 | Map toJson() => _$AbiRespToJson(this); 37 | 38 | static Abi? _decodeAbi(dynamic abi) { 39 | if (abi is String) { 40 | return _base64ToAbi(abi); 41 | } 42 | return Abi.fromJson(abi); 43 | } 44 | 45 | static Abi? _base64ToAbi(String base64String) { 46 | Uint8List abiBuffer = base64ToBinary(base64String); 47 | 48 | return _rawAbiToJson(abiBuffer); 49 | } 50 | 51 | /// Decodes an abi as Uint8List into json. */ 52 | static Abi? _rawAbiToJson(Uint8List rawAbi) { 53 | Map abiTypes = ser.getTypesFromAbi( 54 | ser.createInitialTypes(), Abi.fromJson(json.decode(abiJson))); 55 | try { 56 | var buffer = ser.SerialBuffer(rawAbi); 57 | var str = buffer.getString(); 58 | if (!ser.supportedAbiVersion(str)) { 59 | throw 'Unsupported abi version'; 60 | } 61 | buffer.restartRead(); 62 | var t = abiTypes['abi_def']; 63 | var b = t?.deserialize?.call(t, buffer); 64 | return Abi.fromJson(json.decode(json.encode(b))); 65 | } catch (e) { 66 | print(e.toString()); 67 | return null; 68 | } 69 | } 70 | 71 | @override 72 | String toString() => this.toJson().toString(); 73 | } 74 | 75 | @JsonSerializable() 76 | class AbiType { 77 | @JsonKey(name: 'new_type_name') 78 | String new_type_name; //new_type_name 79 | 80 | @JsonKey(name: 'type') 81 | String type; 82 | 83 | AbiType(this.new_type_name, this.type); 84 | 85 | factory AbiType.fromJson(Map json) => 86 | _$AbiTypeFromJson(json); 87 | 88 | Map toJson() => _$AbiTypeToJson(this); 89 | 90 | @override 91 | String toString() => this.toJson().toString(); 92 | } 93 | 94 | @JsonSerializable() 95 | class AbiStructField { 96 | @JsonKey(name: 'name') 97 | String name; 98 | 99 | @JsonKey(name: 'type') 100 | String type; 101 | 102 | AbiStructField(this.name, this.type); 103 | 104 | factory AbiStructField.fromJson(Map json) => 105 | _$AbiStructFieldFromJson(json); 106 | 107 | Map toJson() => _$AbiStructFieldToJson(this); 108 | 109 | @override 110 | String toString() => this.toJson().toString(); 111 | } 112 | 113 | @JsonSerializable() 114 | class AbiStruct { 115 | @JsonKey(name: 'name') 116 | String? name; 117 | 118 | @JsonKey(name: 'base') 119 | String? base; 120 | 121 | @JsonKey(name: 'fields') 122 | List? fields; 123 | 124 | AbiStruct( 125 | this.name, 126 | this.base, 127 | this.fields, 128 | ); 129 | 130 | factory AbiStruct.fromJson(Map json) => 131 | _$AbiStructFromJson(json); 132 | 133 | Map toJson() => _$AbiStructToJson(this); 134 | 135 | @override 136 | String toString() => this.toJson().toString(); 137 | } 138 | 139 | @JsonSerializable() 140 | class AbiAction { 141 | @JsonKey(name: 'name') 142 | String name; 143 | 144 | @JsonKey(name: 'type') 145 | String type; 146 | 147 | @JsonKey(name: 'ricardian_contract') 148 | String ricardian_contract; //ricardian_contract 149 | 150 | AbiAction(this.name, this.type, this.ricardian_contract); 151 | 152 | factory AbiAction.fromJson(Map json) => 153 | _$AbiActionFromJson(json); 154 | 155 | Map toJson() => _$AbiActionToJson(this); 156 | 157 | @override 158 | String toString() => this.toJson().toString(); 159 | } 160 | 161 | @JsonSerializable() 162 | class AbiTable { 163 | @JsonKey(name: 'name') 164 | String name; 165 | 166 | @JsonKey(name: 'type') 167 | String type; 168 | 169 | @JsonKey(name: 'index_type') 170 | String index_type; //index_type 171 | 172 | @JsonKey(name: 'key_names') 173 | List key_names; //key_names 174 | 175 | @JsonKey(name: 'key_types') 176 | List key_types; //key_types 177 | 178 | AbiTable( 179 | this.name, this.type, this.index_type, this.key_names, this.key_types); 180 | 181 | factory AbiTable.fromJson(Map json) => 182 | _$AbiTableFromJson(json); 183 | 184 | Map toJson() => _$AbiTableToJson(this); 185 | 186 | @override 187 | String toString() => this.toJson().toString(); 188 | } 189 | 190 | @JsonSerializable() 191 | class AbiRicardianClauses { 192 | @JsonKey(name: 'id') 193 | String id; 194 | 195 | @JsonKey(name: 'body') 196 | String body; 197 | 198 | AbiRicardianClauses(this.id, this.body); 199 | 200 | factory AbiRicardianClauses.fromJson(Map json) => 201 | _$AbiRicardianClausesFromJson(json); 202 | 203 | Map toJson() => _$AbiRicardianClausesToJson(this); 204 | 205 | @override 206 | String toString() => this.toJson().toString(); 207 | } 208 | 209 | @JsonSerializable() 210 | class AbiErrorMessages { 211 | @JsonKey(name: 'error_code') 212 | String error_code; 213 | 214 | @JsonKey(name: 'error_msg') 215 | String error_msg; 216 | 217 | AbiErrorMessages(this.error_code, this.error_msg); 218 | 219 | factory AbiErrorMessages.fromJson(Map json) => 220 | _$AbiErrorMessagesFromJson(json); 221 | 222 | Map toJson() => _$AbiErrorMessagesToJson(this); 223 | 224 | @override 225 | String toString() => this.toJson().toString(); 226 | } 227 | 228 | @JsonSerializable() 229 | class AbiExtensions { 230 | @JsonKey(name: 'tag') 231 | int tag; 232 | 233 | @JsonKey(name: 'value') 234 | String value; 235 | 236 | AbiExtensions(this.tag, this.value); 237 | 238 | factory AbiExtensions.fromJson(Map json) => 239 | _$AbiExtensionsFromJson(json); 240 | 241 | Map toJson() => _$AbiExtensionsToJson(this); 242 | 243 | @override 244 | String toString() => this.toJson().toString(); 245 | } 246 | 247 | @JsonSerializable() 248 | class AbiVariants { 249 | @JsonKey(name: 'name') 250 | String? name; 251 | 252 | @JsonKey(name: 'types') 253 | List? types; 254 | 255 | AbiVariants( 256 | this.name, 257 | this.types, 258 | ); 259 | 260 | factory AbiVariants.fromJson(Map json) => 261 | _$AbiVariantsFromJson(json); 262 | 263 | Map toJson() => _$AbiVariantsToJson(this); 264 | 265 | @override 266 | String toString() => this.toJson().toString(); 267 | } 268 | 269 | /// Structured format for abis 270 | @JsonSerializable() 271 | class Abi { 272 | @JsonKey(name: 'version') 273 | String? version; 274 | 275 | @JsonKey(name: 'types') 276 | List? types; 277 | 278 | @JsonKey(name: 'structs') 279 | List? structs; 280 | 281 | @JsonKey(name: 'actions') 282 | List? actions; 283 | 284 | @JsonKey(name: 'tables') 285 | List? tables; 286 | 287 | @JsonKey(name: 'ricardian_clauses') 288 | List? ricardian_clauses; 289 | 290 | @JsonKey(name: 'error_messages') 291 | List? error_messages; 292 | 293 | @JsonKey(name: 'abi_extensions') 294 | List? abi_extensions; 295 | 296 | @JsonKey(name: 'variants') 297 | List? variants; 298 | 299 | Abi({ 300 | this.abi_extensions, 301 | this.actions, 302 | this.error_messages, 303 | this.ricardian_clauses, 304 | this.structs, 305 | this.tables, 306 | this.types, 307 | this.variants, 308 | this.version, 309 | }); 310 | 311 | factory Abi.fromJson(Map json) => _$AbiFromJson(json); 312 | 313 | Map toJson() => _$AbiToJson(this); 314 | 315 | @override 316 | String toString() => this.toJson().toString(); 317 | } 318 | -------------------------------------------------------------------------------- /lib/src/models/abi.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'abi.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | AbiResp _$AbiRespFromJson(Map json) => AbiResp() 10 | ..accountName = json['account_name'] as String? 11 | ..codeHash = json['code_hash'] as String? 12 | ..abiHash = json['abi_hash'] as String? 13 | ..wasm = json['wasm'] as String? 14 | ..abi = AbiResp._decodeAbi(json['abi']); 15 | 16 | Map _$AbiRespToJson(AbiResp instance) => { 17 | 'account_name': instance.accountName, 18 | 'code_hash': instance.codeHash, 19 | 'abi_hash': instance.abiHash, 20 | 'wasm': instance.wasm, 21 | 'abi': instance.abi, 22 | }; 23 | 24 | AbiType _$AbiTypeFromJson(Map json) => AbiType( 25 | json['new_type_name'] as String, 26 | json['type'] as String, 27 | ); 28 | 29 | Map _$AbiTypeToJson(AbiType instance) => { 30 | 'new_type_name': instance.new_type_name, 31 | 'type': instance.type, 32 | }; 33 | 34 | AbiStructField _$AbiStructFieldFromJson(Map json) => 35 | AbiStructField( 36 | json['name'] as String, 37 | json['type'] as String, 38 | ); 39 | 40 | Map _$AbiStructFieldToJson(AbiStructField instance) => 41 | { 42 | 'name': instance.name, 43 | 'type': instance.type, 44 | }; 45 | 46 | AbiStruct _$AbiStructFromJson(Map json) => AbiStruct( 47 | json['name'] as String?, 48 | json['base'] as String?, 49 | (json['fields'] as List?) 50 | ?.map((e) => AbiStructField.fromJson(e as Map)) 51 | .toList(), 52 | ); 53 | 54 | Map _$AbiStructToJson(AbiStruct instance) => { 55 | 'name': instance.name, 56 | 'base': instance.base, 57 | 'fields': instance.fields, 58 | }; 59 | 60 | AbiAction _$AbiActionFromJson(Map json) => AbiAction( 61 | json['name'] as String, 62 | json['type'] as String, 63 | json['ricardian_contract'] as String, 64 | ); 65 | 66 | Map _$AbiActionToJson(AbiAction instance) => { 67 | 'name': instance.name, 68 | 'type': instance.type, 69 | 'ricardian_contract': instance.ricardian_contract, 70 | }; 71 | 72 | AbiTable _$AbiTableFromJson(Map json) => AbiTable( 73 | json['name'] as String, 74 | json['type'] as String, 75 | json['index_type'] as String, 76 | (json['key_names'] as List).map((e) => e as String).toList(), 77 | (json['key_types'] as List).map((e) => e as String).toList(), 78 | ); 79 | 80 | Map _$AbiTableToJson(AbiTable instance) => { 81 | 'name': instance.name, 82 | 'type': instance.type, 83 | 'index_type': instance.index_type, 84 | 'key_names': instance.key_names, 85 | 'key_types': instance.key_types, 86 | }; 87 | 88 | AbiRicardianClauses _$AbiRicardianClausesFromJson(Map json) => 89 | AbiRicardianClauses( 90 | json['id'] as String, 91 | json['body'] as String, 92 | ); 93 | 94 | Map _$AbiRicardianClausesToJson( 95 | AbiRicardianClauses instance) => 96 | { 97 | 'id': instance.id, 98 | 'body': instance.body, 99 | }; 100 | 101 | AbiErrorMessages _$AbiErrorMessagesFromJson(Map json) => 102 | AbiErrorMessages( 103 | json['error_code'] as String, 104 | json['error_msg'] as String, 105 | ); 106 | 107 | Map _$AbiErrorMessagesToJson(AbiErrorMessages instance) => 108 | { 109 | 'error_code': instance.error_code, 110 | 'error_msg': instance.error_msg, 111 | }; 112 | 113 | AbiExtensions _$AbiExtensionsFromJson(Map json) => 114 | AbiExtensions( 115 | json['tag'] as int, 116 | json['value'] as String, 117 | ); 118 | 119 | Map _$AbiExtensionsToJson(AbiExtensions instance) => 120 | { 121 | 'tag': instance.tag, 122 | 'value': instance.value, 123 | }; 124 | 125 | AbiVariants _$AbiVariantsFromJson(Map json) => AbiVariants( 126 | json['name'] as String?, 127 | (json['types'] as List?)?.map((e) => e as String).toList(), 128 | ); 129 | 130 | Map _$AbiVariantsToJson(AbiVariants instance) => 131 | { 132 | 'name': instance.name, 133 | 'types': instance.types, 134 | }; 135 | 136 | Abi _$AbiFromJson(Map json) => Abi( 137 | abi_extensions: (json['abi_extensions'] as List?) 138 | ?.map((e) => AbiExtensions.fromJson(e as Map)) 139 | .toList(), 140 | actions: (json['actions'] as List?) 141 | ?.map((e) => AbiAction.fromJson(e as Map)) 142 | .toList(), 143 | error_messages: (json['error_messages'] as List?) 144 | ?.map((e) => AbiErrorMessages.fromJson(e as Map)) 145 | .toList(), 146 | ricardian_clauses: (json['ricardian_clauses'] as List?) 147 | ?.map((e) => AbiRicardianClauses.fromJson(e as Map)) 148 | .toList(), 149 | structs: (json['structs'] as List?) 150 | ?.map((e) => AbiStruct.fromJson(e as Map)) 151 | .toList(), 152 | tables: (json['tables'] as List?) 153 | ?.map((e) => AbiTable.fromJson(e as Map)) 154 | .toList(), 155 | types: (json['types'] as List?) 156 | ?.map((e) => AbiType.fromJson(e as Map)) 157 | .toList(), 158 | variants: (json['variants'] as List?) 159 | ?.map((e) => AbiVariants.fromJson(e as Map)) 160 | .toList(), 161 | version: json['version'] as String?, 162 | ); 163 | 164 | Map _$AbiToJson(Abi instance) => { 165 | 'version': instance.version, 166 | 'types': instance.types, 167 | 'structs': instance.structs, 168 | 'actions': instance.actions, 169 | 'tables': instance.tables, 170 | 'ricardian_clauses': instance.ricardian_clauses, 171 | 'error_messages': instance.error_messages, 172 | 'abi_extensions': instance.abi_extensions, 173 | 'variants': instance.variants, 174 | }; 175 | -------------------------------------------------------------------------------- /lib/src/models/account.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | import './conversion_helper.dart'; 4 | 5 | part 'account.g.dart'; 6 | 7 | /// Represents EOS account information 8 | @JsonSerializable() 9 | class Account with ConversionHelper { 10 | @JsonKey(name: 'account_name') 11 | final String accountName; 12 | 13 | @JsonKey(name: 'head_block_num') 14 | final int headBlockNum; 15 | 16 | @JsonKey(name: 'head_block_time') 17 | DateTime? headBlockTime; 18 | 19 | @JsonKey(name: 'privileged') 20 | bool? privileged; 21 | 22 | @JsonKey(name: 'last_code_update') 23 | DateTime? lastCodeUpdate; 24 | 25 | @JsonKey(name: 'created') 26 | DateTime? created; 27 | 28 | @JsonKey(name: 'core_liquid_balance') 29 | Holding? coreLiquidBalance; 30 | 31 | @JsonKey(name: 'ram_quota', fromJson: ConversionHelper.getIntFromJson) 32 | int? ramQuota; 33 | 34 | @JsonKey(name: 'net_weight', fromJson: ConversionHelper.getIntFromJson) 35 | int? netWeight; 36 | 37 | @JsonKey(name: 'cpu_weight', fromJson: ConversionHelper.getIntFromJson) 38 | int? cpuWeight; 39 | 40 | @JsonKey(name: 'net_limit') 41 | Limit? netLimit; 42 | 43 | @JsonKey(name: 'cpu_limit') 44 | Limit? cpuLimit; 45 | 46 | @JsonKey(name: 'ram_usage', fromJson: ConversionHelper.getIntFromJson) 47 | int? ramUsage; 48 | 49 | @JsonKey(name: 'total_resources') 50 | TotalResources? totalResources; 51 | 52 | @JsonKey(name: 'permissions') 53 | List? permissions; 54 | 55 | @JsonKey(name: 'self_delegated_bandwidth') 56 | SelfDelegatedBandwidth? selfDelegatedBandwidth; 57 | 58 | @JsonKey(name: 'refund_request') 59 | RefundRequest? refundRequest; 60 | 61 | @JsonKey(name: 'voter_info') 62 | VoterInfo? voterInfo; 63 | 64 | Account(this.accountName, this.headBlockNum); 65 | 66 | factory Account.fromJson(Map json) => 67 | _$AccountFromJson(json); 68 | 69 | Map toJson() => _$AccountToJson(this); 70 | 71 | @override 72 | String toString() => this.toJson().toString(); 73 | } 74 | 75 | @JsonSerializable() 76 | class Limit with ConversionHelper { 77 | @JsonKey(name: 'used', fromJson: ConversionHelper.getIntFromJson) 78 | int? used; 79 | 80 | @JsonKey(name: 'available', fromJson: ConversionHelper.getIntFromJson) 81 | int? available; 82 | 83 | @JsonKey(name: 'max', fromJson: ConversionHelper.getIntFromJson) 84 | int? max; 85 | 86 | Limit(); 87 | 88 | factory Limit.fromJson(Map json) => _$LimitFromJson(json); 89 | 90 | Map toJson() => _$LimitToJson(this); 91 | 92 | @override 93 | String toString() => this.toJson().toString(); 94 | } 95 | 96 | // this is not using json serializer as it is customized serializer to 97 | // convert the amount currency split by space 98 | /// Structure for the JSON string format e.g. '1.0000 EOS', it splits that by 99 | /// 'amount' and 'currency' 100 | class Holding { 101 | double? amount; 102 | String? currency; 103 | 104 | Holding.fromJson(String json) { 105 | List segments = json.split(" "); 106 | if (segments.length != 2) { 107 | return; 108 | } 109 | this.amount = double.parse(segments[0]); 110 | this.currency = segments[1]; 111 | } 112 | 113 | String toJson() => '${amount} ${currency}'; 114 | 115 | @override 116 | String toString() => this.toJson().toString(); 117 | } 118 | 119 | @JsonSerializable() 120 | class Permission { 121 | @JsonKey(name: 'perm_name') 122 | String? permName; 123 | 124 | @JsonKey(name: 'parent') 125 | String? parent; 126 | 127 | @JsonKey(name: 'required_auth') 128 | RequiredAuth? requiredAuth; 129 | 130 | Permission(); 131 | 132 | factory Permission.fromJson(Map json) => 133 | _$PermissionFromJson(json); 134 | 135 | Map toJson() => _$PermissionToJson(this); 136 | 137 | @override 138 | String toString() => this.toJson().toString(); 139 | } 140 | 141 | @JsonSerializable() 142 | class RequiredAuth { 143 | @JsonKey(name: 'threshold') 144 | int? threshold; 145 | 146 | @JsonKey(name: 'keys') 147 | List? keys; 148 | 149 | @JsonKey(name: 'accounts') 150 | List? accounts; 151 | 152 | @JsonKey(name: 'waits') 153 | List? waits; 154 | 155 | RequiredAuth(); 156 | 157 | factory RequiredAuth.fromJson(Map json) => 158 | _$RequiredAuthFromJson(json); 159 | 160 | Map toJson() => _$RequiredAuthToJson(this); 161 | 162 | @override 163 | String toString() => this.toJson().toString(); 164 | } 165 | 166 | @JsonSerializable() 167 | class AuthKey { 168 | @JsonKey(name: 'key') 169 | String? key; 170 | 171 | @JsonKey(name: 'weight') 172 | int? weight; 173 | 174 | AuthKey(); 175 | 176 | factory AuthKey.fromJson(Map json) => 177 | _$AuthKeyFromJson(json); 178 | 179 | Map toJson() => _$AuthKeyToJson(this); 180 | 181 | @override 182 | String toString() => this.toJson().toString(); 183 | } 184 | 185 | @JsonSerializable() 186 | class TotalResources with ConversionHelper { 187 | @JsonKey(name: 'owner') 188 | String? owner; 189 | 190 | @JsonKey(name: 'net_weight') 191 | Holding? netWeight; 192 | 193 | @JsonKey(name: 'cpu_weight') 194 | Holding? cpuWeight; 195 | 196 | @JsonKey(name: 'ram_bytes', fromJson: ConversionHelper.getIntFromJson) 197 | int? ramBytes; 198 | 199 | TotalResources(); 200 | 201 | factory TotalResources.fromJson(Map json) => 202 | _$TotalResourcesFromJson(json); 203 | 204 | Map toJson() => _$TotalResourcesToJson(this); 205 | 206 | @override 207 | String toString() => this.toJson().toString(); 208 | } 209 | 210 | @JsonSerializable() 211 | class SelfDelegatedBandwidth { 212 | @JsonKey(name: 'from') 213 | String? from; 214 | 215 | @JsonKey(name: 'to') 216 | String? to; 217 | 218 | @JsonKey(name: 'net_weight') 219 | Holding? netWeight; 220 | 221 | @JsonKey(name: 'cpu_weight') 222 | Holding? cpuWeight; 223 | 224 | SelfDelegatedBandwidth(); 225 | 226 | factory SelfDelegatedBandwidth.fromJson(Map json) => 227 | _$SelfDelegatedBandwidthFromJson(json); 228 | 229 | Map toJson() => _$SelfDelegatedBandwidthToJson(this); 230 | 231 | @override 232 | String toString() => this.toJson().toString(); 233 | } 234 | 235 | @JsonSerializable() 236 | class RefundRequest { 237 | @JsonKey(name: 'owner') 238 | String? owner; 239 | 240 | @JsonKey(name: 'request_time') 241 | DateTime? requestTime; 242 | 243 | @JsonKey(name: 'net_amount') 244 | Holding? netAmount; 245 | 246 | @JsonKey(name: 'cpu_amount') 247 | Holding? cpuAmount; 248 | 249 | RefundRequest(); 250 | 251 | factory RefundRequest.fromJson(Map json) => 252 | _$RefundRequestFromJson(json); 253 | 254 | Map toJson() => _$RefundRequestToJson(this); 255 | 256 | @override 257 | String toString() => this.toJson().toString(); 258 | } 259 | 260 | @JsonSerializable() 261 | class VoterInfo with ConversionHelper { 262 | @JsonKey(name: 'owner') 263 | String? owner; 264 | 265 | @JsonKey(name: 'proxy') 266 | String? proxy; 267 | 268 | @JsonKey(name: 'producers') 269 | Object? producers; 270 | 271 | @JsonKey(name: 'staked', fromJson: ConversionHelper.getIntFromJson) 272 | int? staked; 273 | 274 | @JsonKey(name: 'last_vote_weight') 275 | String? lastVoteWeight; 276 | 277 | @JsonKey(name: 'proxied_vote_weight') 278 | String? proxiedVoteWeight; 279 | 280 | @JsonKey(name: 'is_proxy') 281 | int? isProxy; 282 | 283 | VoterInfo(); 284 | 285 | factory VoterInfo.fromJson(Map json) => 286 | _$VoterInfoFromJson(json); 287 | 288 | Map toJson() => _$VoterInfoToJson(this); 289 | 290 | @override 291 | String toString() => this.toJson().toString(); 292 | } 293 | -------------------------------------------------------------------------------- /lib/src/models/account.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'account.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | Account _$AccountFromJson(Map json) => Account( 10 | json['account_name'] as String, 11 | json['head_block_num'] as int, 12 | ) 13 | ..headBlockTime = json['head_block_time'] == null 14 | ? null 15 | : DateTime.parse(json['head_block_time'] as String) 16 | ..privileged = json['privileged'] as bool? 17 | ..lastCodeUpdate = json['last_code_update'] == null 18 | ? null 19 | : DateTime.parse(json['last_code_update'] as String) 20 | ..created = json['created'] == null 21 | ? null 22 | : DateTime.parse(json['created'] as String) 23 | ..coreLiquidBalance = json['core_liquid_balance'] == null 24 | ? null 25 | : Holding.fromJson(json['core_liquid_balance'] as String) 26 | ..ramQuota = ConversionHelper.getIntFromJson(json['ram_quota']) 27 | ..netWeight = ConversionHelper.getIntFromJson(json['net_weight']) 28 | ..cpuWeight = ConversionHelper.getIntFromJson(json['cpu_weight']) 29 | ..netLimit = json['net_limit'] == null 30 | ? null 31 | : Limit.fromJson(json['net_limit'] as Map) 32 | ..cpuLimit = json['cpu_limit'] == null 33 | ? null 34 | : Limit.fromJson(json['cpu_limit'] as Map) 35 | ..ramUsage = ConversionHelper.getIntFromJson(json['ram_usage']) 36 | ..totalResources = json['total_resources'] == null 37 | ? null 38 | : TotalResources.fromJson( 39 | json['total_resources'] as Map) 40 | ..permissions = (json['permissions'] as List?) 41 | ?.map((e) => Permission.fromJson(e as Map)) 42 | .toList() 43 | ..selfDelegatedBandwidth = json['self_delegated_bandwidth'] == null 44 | ? null 45 | : SelfDelegatedBandwidth.fromJson( 46 | json['self_delegated_bandwidth'] as Map) 47 | ..refundRequest = json['refund_request'] == null 48 | ? null 49 | : RefundRequest.fromJson( 50 | json['refund_request'] as Map) 51 | ..voterInfo = json['voter_info'] == null 52 | ? null 53 | : VoterInfo.fromJson(json['voter_info'] as Map); 54 | 55 | Map _$AccountToJson(Account instance) => { 56 | 'account_name': instance.accountName, 57 | 'head_block_num': instance.headBlockNum, 58 | 'head_block_time': instance.headBlockTime?.toIso8601String(), 59 | 'privileged': instance.privileged, 60 | 'last_code_update': instance.lastCodeUpdate?.toIso8601String(), 61 | 'created': instance.created?.toIso8601String(), 62 | 'core_liquid_balance': instance.coreLiquidBalance, 63 | 'ram_quota': instance.ramQuota, 64 | 'net_weight': instance.netWeight, 65 | 'cpu_weight': instance.cpuWeight, 66 | 'net_limit': instance.netLimit, 67 | 'cpu_limit': instance.cpuLimit, 68 | 'ram_usage': instance.ramUsage, 69 | 'total_resources': instance.totalResources, 70 | 'permissions': instance.permissions, 71 | 'self_delegated_bandwidth': instance.selfDelegatedBandwidth, 72 | 'refund_request': instance.refundRequest, 73 | 'voter_info': instance.voterInfo, 74 | }; 75 | 76 | Limit _$LimitFromJson(Map json) => Limit() 77 | ..used = ConversionHelper.getIntFromJson(json['used']) 78 | ..available = ConversionHelper.getIntFromJson(json['available']) 79 | ..max = ConversionHelper.getIntFromJson(json['max']); 80 | 81 | Map _$LimitToJson(Limit instance) => { 82 | 'used': instance.used, 83 | 'available': instance.available, 84 | 'max': instance.max, 85 | }; 86 | 87 | Permission _$PermissionFromJson(Map json) => Permission() 88 | ..permName = json['perm_name'] as String? 89 | ..parent = json['parent'] as String? 90 | ..requiredAuth = json['required_auth'] == null 91 | ? null 92 | : RequiredAuth.fromJson(json['required_auth'] as Map); 93 | 94 | Map _$PermissionToJson(Permission instance) => 95 | { 96 | 'perm_name': instance.permName, 97 | 'parent': instance.parent, 98 | 'required_auth': instance.requiredAuth, 99 | }; 100 | 101 | RequiredAuth _$RequiredAuthFromJson(Map json) => RequiredAuth() 102 | ..threshold = json['threshold'] as int? 103 | ..keys = (json['keys'] as List?) 104 | ?.map((e) => AuthKey.fromJson(e as Map)) 105 | .toList() 106 | ..accounts = 107 | (json['accounts'] as List?)?.map((e) => e as Object).toList() 108 | ..waits = (json['waits'] as List?)?.map((e) => e as Object).toList(); 109 | 110 | Map _$RequiredAuthToJson(RequiredAuth instance) => 111 | { 112 | 'threshold': instance.threshold, 113 | 'keys': instance.keys, 114 | 'accounts': instance.accounts, 115 | 'waits': instance.waits, 116 | }; 117 | 118 | AuthKey _$AuthKeyFromJson(Map json) => AuthKey() 119 | ..key = json['key'] as String? 120 | ..weight = json['weight'] as int?; 121 | 122 | Map _$AuthKeyToJson(AuthKey instance) => { 123 | 'key': instance.key, 124 | 'weight': instance.weight, 125 | }; 126 | 127 | TotalResources _$TotalResourcesFromJson(Map json) => 128 | TotalResources() 129 | ..owner = json['owner'] as String? 130 | ..netWeight = json['net_weight'] == null 131 | ? null 132 | : Holding.fromJson(json['net_weight'] as String) 133 | ..cpuWeight = json['cpu_weight'] == null 134 | ? null 135 | : Holding.fromJson(json['cpu_weight'] as String) 136 | ..ramBytes = ConversionHelper.getIntFromJson(json['ram_bytes']); 137 | 138 | Map _$TotalResourcesToJson(TotalResources instance) => 139 | { 140 | 'owner': instance.owner, 141 | 'net_weight': instance.netWeight, 142 | 'cpu_weight': instance.cpuWeight, 143 | 'ram_bytes': instance.ramBytes, 144 | }; 145 | 146 | SelfDelegatedBandwidth _$SelfDelegatedBandwidthFromJson( 147 | Map json) => 148 | SelfDelegatedBandwidth() 149 | ..from = json['from'] as String? 150 | ..to = json['to'] as String? 151 | ..netWeight = json['net_weight'] == null 152 | ? null 153 | : Holding.fromJson(json['net_weight'] as String) 154 | ..cpuWeight = json['cpu_weight'] == null 155 | ? null 156 | : Holding.fromJson(json['cpu_weight'] as String); 157 | 158 | Map _$SelfDelegatedBandwidthToJson( 159 | SelfDelegatedBandwidth instance) => 160 | { 161 | 'from': instance.from, 162 | 'to': instance.to, 163 | 'net_weight': instance.netWeight, 164 | 'cpu_weight': instance.cpuWeight, 165 | }; 166 | 167 | RefundRequest _$RefundRequestFromJson(Map json) => 168 | RefundRequest() 169 | ..owner = json['owner'] as String? 170 | ..requestTime = json['request_time'] == null 171 | ? null 172 | : DateTime.parse(json['request_time'] as String) 173 | ..netAmount = json['net_amount'] == null 174 | ? null 175 | : Holding.fromJson(json['net_amount'] as String) 176 | ..cpuAmount = json['cpu_amount'] == null 177 | ? null 178 | : Holding.fromJson(json['cpu_amount'] as String); 179 | 180 | Map _$RefundRequestToJson(RefundRequest instance) => 181 | { 182 | 'owner': instance.owner, 183 | 'request_time': instance.requestTime?.toIso8601String(), 184 | 'net_amount': instance.netAmount, 185 | 'cpu_amount': instance.cpuAmount, 186 | }; 187 | 188 | VoterInfo _$VoterInfoFromJson(Map json) => VoterInfo() 189 | ..owner = json['owner'] as String? 190 | ..proxy = json['proxy'] as String? 191 | ..producers = json['producers'] 192 | ..staked = ConversionHelper.getIntFromJson(json['staked']) 193 | ..lastVoteWeight = json['last_vote_weight'] as String? 194 | ..proxiedVoteWeight = json['proxied_vote_weight'] as String? 195 | ..isProxy = json['is_proxy'] as int?; 196 | 197 | Map _$VoterInfoToJson(VoterInfo instance) => { 198 | 'owner': instance.owner, 199 | 'proxy': instance.proxy, 200 | 'producers': instance.producers, 201 | 'staked': instance.staked, 202 | 'last_vote_weight': instance.lastVoteWeight, 203 | 'proxied_vote_weight': instance.proxiedVoteWeight, 204 | 'is_proxy': instance.isProxy, 205 | }; 206 | -------------------------------------------------------------------------------- /lib/src/models/action.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | import './conversion_helper.dart'; 4 | 5 | part 'action.g.dart'; 6 | 7 | @JsonSerializable() 8 | class ActionWithReceipt with ConversionHelper { 9 | @JsonKey(name: 'receipt') 10 | ActionReceipt? receipt; 11 | 12 | @JsonKey(name: 'act') 13 | Action? action; 14 | 15 | @JsonKey(name: 'context_free') 16 | bool? contextFree; 17 | 18 | @JsonKey(name: 'elapsed') 19 | int? elapsed; 20 | 21 | @JsonKey(name: 'console') 22 | String? console; 23 | 24 | @JsonKey(name: 'trx_id') 25 | String? trxId; 26 | 27 | @JsonKey(name: 'block_num', fromJson: ConversionHelper.getIntFromJson) 28 | int? blockNum; 29 | 30 | @JsonKey(name: 'block_time') 31 | DateTime? blockTime; 32 | 33 | @JsonKey(name: 'producer_block_id') 34 | String? producerBlockId; 35 | 36 | @JsonKey(name: 'account_ram_deltas') 37 | List? accountRamDeltas; 38 | 39 | @JsonKey(name: 'except') 40 | Object? except; 41 | 42 | @JsonKey(name: 'inline_traces') 43 | List? inlineTraces; 44 | 45 | ActionWithReceipt(); 46 | 47 | factory ActionWithReceipt.fromJson(Map json) => 48 | _$ActionWithReceiptFromJson(json); 49 | 50 | Map toJson() => _$ActionWithReceiptToJson(this); 51 | 52 | @override 53 | String toString() => this.toJson().toString(); 54 | } 55 | 56 | @JsonSerializable(explicitToJson: true) 57 | class Action { 58 | @JsonKey(name: 'account') 59 | String? account; 60 | 61 | @JsonKey(name: 'name') 62 | String? name; 63 | 64 | @JsonKey(name: 'authorization') 65 | List? authorization; 66 | 67 | @JsonKey(name: 'data') 68 | Object? data; 69 | 70 | // @JsonKey(name: 'hex_data') 71 | // String hexData; 72 | 73 | Action(); 74 | 75 | factory Action.fromJson(Map json) => _$ActionFromJson(json); 76 | 77 | Map toJson() => _$ActionToJson(this); 78 | 79 | @override 80 | String toString() => this.toJson().toString(); 81 | } 82 | 83 | @JsonSerializable(explicitToJson: true) 84 | class ActionArgs { 85 | @JsonKey(name: 'from') 86 | String? fromAccount; 87 | 88 | @JsonKey(name: 'to') 89 | String? toAccount; 90 | 91 | @JsonKey(name: 'quantity') 92 | String? quantity; 93 | 94 | @JsonKey(name: 'memo') 95 | String? memo; 96 | 97 | ActionArgs(); 98 | 99 | factory ActionArgs.fromJson(Map json) => 100 | _$ActionArgsFromJson(json); 101 | 102 | Map toJson() => _$ActionArgsToJson(this); 103 | 104 | @override 105 | String toString() => this.toJson().toString(); 106 | } 107 | 108 | @JsonSerializable() 109 | class ActionReceipt with ConversionHelper { 110 | @JsonKey(name: 'receiver') 111 | String? receiver; 112 | 113 | @JsonKey(name: 'act_digest') 114 | String? actDigest; 115 | 116 | @JsonKey(name: 'global_sequence', fromJson: ConversionHelper.getIntFromJson) 117 | int? globalSequence; 118 | 119 | @JsonKey(name: 'recv_sequence', fromJson: ConversionHelper.getIntFromJson) 120 | int? receiveSequence; 121 | 122 | @JsonKey(name: 'auth_sequence') 123 | List? authSequence; 124 | 125 | @JsonKey(name: 'code_sequence', fromJson: ConversionHelper.getIntFromJson) 126 | int? codeSequence; 127 | 128 | @JsonKey(name: 'abi_sequence', fromJson: ConversionHelper.getIntFromJson) 129 | int? abiSequence; 130 | 131 | ActionReceipt(); 132 | 133 | factory ActionReceipt.fromJson(Map json) => 134 | _$ActionReceiptFromJson(json); 135 | 136 | Map toJson() => _$ActionReceiptToJson(this); 137 | 138 | @override 139 | String toString() => this.toJson().toString(); 140 | } 141 | 142 | @JsonSerializable() 143 | class Authorization { 144 | @JsonKey(name: 'actor') 145 | String? actor; 146 | 147 | @JsonKey(name: 'permission') 148 | String? permission; 149 | 150 | Authorization(); 151 | 152 | factory Authorization.fromJson(Map json) => 153 | _$AuthorizationFromJson(json); 154 | 155 | Map toJson() => _$AuthorizationToJson(this); 156 | 157 | @override 158 | String toString() => this.toJson().toString(); 159 | } 160 | -------------------------------------------------------------------------------- /lib/src/models/action.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'action.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | ActionWithReceipt _$ActionWithReceiptFromJson(Map json) => 10 | ActionWithReceipt() 11 | ..receipt = json['receipt'] == null 12 | ? null 13 | : ActionReceipt.fromJson(json['receipt'] as Map) 14 | ..action = json['act'] == null 15 | ? null 16 | : Action.fromJson(json['act'] as Map) 17 | ..contextFree = json['context_free'] as bool? 18 | ..elapsed = json['elapsed'] as int? 19 | ..console = json['console'] as String? 20 | ..trxId = json['trx_id'] as String? 21 | ..blockNum = ConversionHelper.getIntFromJson(json['block_num']) 22 | ..blockTime = json['block_time'] == null 23 | ? null 24 | : DateTime.parse(json['block_time'] as String) 25 | ..producerBlockId = json['producer_block_id'] as String? 26 | ..accountRamDeltas = (json['account_ram_deltas'] as List?) 27 | ?.map((e) => e as Object) 28 | .toList() 29 | ..except = json['except'] 30 | ..inlineTraces = (json['inline_traces'] as List?) 31 | ?.map((e) => ActionWithReceipt.fromJson(e as Map)) 32 | .toList(); 33 | 34 | Map _$ActionWithReceiptToJson(ActionWithReceipt instance) => 35 | { 36 | 'receipt': instance.receipt, 37 | 'act': instance.action, 38 | 'context_free': instance.contextFree, 39 | 'elapsed': instance.elapsed, 40 | 'console': instance.console, 41 | 'trx_id': instance.trxId, 42 | 'block_num': instance.blockNum, 43 | 'block_time': instance.blockTime?.toIso8601String(), 44 | 'producer_block_id': instance.producerBlockId, 45 | 'account_ram_deltas': instance.accountRamDeltas, 46 | 'except': instance.except, 47 | 'inline_traces': instance.inlineTraces, 48 | }; 49 | 50 | Action _$ActionFromJson(Map json) => Action() 51 | ..account = json['account'] as String? 52 | ..name = json['name'] as String? 53 | ..authorization = (json['authorization'] as List?) 54 | ?.map((e) => Authorization.fromJson(e as Map)) 55 | .toList() 56 | ..data = json['data']; 57 | 58 | Map _$ActionToJson(Action instance) => { 59 | 'account': instance.account, 60 | 'name': instance.name, 61 | 'authorization': instance.authorization?.map((e) => e.toJson()).toList(), 62 | 'data': instance.data, 63 | }; 64 | 65 | ActionArgs _$ActionArgsFromJson(Map json) => ActionArgs() 66 | ..fromAccount = json['from'] as String? 67 | ..toAccount = json['to'] as String? 68 | ..quantity = json['quantity'] as String? 69 | ..memo = json['memo'] as String?; 70 | 71 | Map _$ActionArgsToJson(ActionArgs instance) => 72 | { 73 | 'from': instance.fromAccount, 74 | 'to': instance.toAccount, 75 | 'quantity': instance.quantity, 76 | 'memo': instance.memo, 77 | }; 78 | 79 | ActionReceipt _$ActionReceiptFromJson(Map json) => 80 | ActionReceipt() 81 | ..receiver = json['receiver'] as String? 82 | ..actDigest = json['act_digest'] as String? 83 | ..globalSequence = 84 | ConversionHelper.getIntFromJson(json['global_sequence']) 85 | ..receiveSequence = ConversionHelper.getIntFromJson(json['recv_sequence']) 86 | ..authSequence = (json['auth_sequence'] as List?) 87 | ?.map((e) => e as Object) 88 | .toList() 89 | ..codeSequence = ConversionHelper.getIntFromJson(json['code_sequence']) 90 | ..abiSequence = ConversionHelper.getIntFromJson(json['abi_sequence']); 91 | 92 | Map _$ActionReceiptToJson(ActionReceipt instance) => 93 | { 94 | 'receiver': instance.receiver, 95 | 'act_digest': instance.actDigest, 96 | 'global_sequence': instance.globalSequence, 97 | 'recv_sequence': instance.receiveSequence, 98 | 'auth_sequence': instance.authSequence, 99 | 'code_sequence': instance.codeSequence, 100 | 'abi_sequence': instance.abiSequence, 101 | }; 102 | 103 | Authorization _$AuthorizationFromJson(Map json) => 104 | Authorization() 105 | ..actor = json['actor'] as String? 106 | ..permission = json['permission'] as String?; 107 | 108 | Map _$AuthorizationToJson(Authorization instance) => 109 | { 110 | 'actor': instance.actor, 111 | 'permission': instance.permission, 112 | }; 113 | -------------------------------------------------------------------------------- /lib/src/models/action_block.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | import './action.dart'; 4 | import './conversion_helper.dart'; 5 | 6 | part 'action_block.g.dart'; 7 | 8 | @JsonSerializable() 9 | class Actions { 10 | @JsonKey(name: 'actions') 11 | List? actions; 12 | 13 | Actions(); 14 | 15 | factory Actions.fromJson(Map json) => 16 | _$ActionsFromJson(json); 17 | 18 | Map toJson() => _$ActionsToJson(this); 19 | 20 | @override 21 | String toString() => this.toJson().toString(); 22 | } 23 | 24 | @JsonSerializable() 25 | class ActionBlock with ConversionHelper { 26 | @JsonKey(name: 'global_action_seq', fromJson: ConversionHelper.getIntFromJson) 27 | int? globalActionSeq; 28 | 29 | @JsonKey( 30 | name: 'account_action_seq', fromJson: ConversionHelper.getIntFromJson) 31 | int? accountActionSeq; 32 | 33 | @JsonKey(name: 'block_num', fromJson: ConversionHelper.getIntFromJson) 34 | int? blockNum; 35 | 36 | @JsonKey(name: 'block_time') 37 | DateTime? blockTime; 38 | 39 | @JsonKey(name: 'action_trace') 40 | ActionWithReceipt? actionTrace; 41 | 42 | ActionBlock(); 43 | 44 | factory ActionBlock.fromJson(Map json) => 45 | _$ActionBlockFromJson(json); 46 | 47 | Map toJson() => _$ActionBlockToJson(this); 48 | 49 | @override 50 | String toString() => this.toJson().toString(); 51 | } 52 | -------------------------------------------------------------------------------- /lib/src/models/action_block.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'action_block.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | Actions _$ActionsFromJson(Map json) => Actions() 10 | ..actions = (json['actions'] as List?) 11 | ?.map((e) => ActionBlock.fromJson(e as Map)) 12 | .toList(); 13 | 14 | Map _$ActionsToJson(Actions instance) => { 15 | 'actions': instance.actions, 16 | }; 17 | 18 | ActionBlock _$ActionBlockFromJson(Map json) => ActionBlock() 19 | ..globalActionSeq = ConversionHelper.getIntFromJson(json['global_action_seq']) 20 | ..accountActionSeq = 21 | ConversionHelper.getIntFromJson(json['account_action_seq']) 22 | ..blockNum = ConversionHelper.getIntFromJson(json['block_num']) 23 | ..blockTime = json['block_time'] == null 24 | ? null 25 | : DateTime.parse(json['block_time'] as String) 26 | ..actionTrace = json['action_trace'] == null 27 | ? null 28 | : ActionWithReceipt.fromJson( 29 | json['action_trace'] as Map); 30 | 31 | Map _$ActionBlockToJson(ActionBlock instance) => 32 | { 33 | 'global_action_seq': instance.globalActionSeq, 34 | 'account_action_seq': instance.accountActionSeq, 35 | 'block_num': instance.blockNum, 36 | 'block_time': instance.blockTime?.toIso8601String(), 37 | 'action_trace': instance.actionTrace, 38 | }; 39 | -------------------------------------------------------------------------------- /lib/src/models/block.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | import './transaction.dart'; 4 | import './conversion_helper.dart'; 5 | 6 | part 'block.g.dart'; 7 | 8 | @JsonSerializable() 9 | class Block with ConversionHelper { 10 | @JsonKey(name: 'id') 11 | final String id; 12 | 13 | @JsonKey(name: 'block_num', fromJson: ConversionHelper.getIntFromJson) 14 | final int? blockNum; 15 | 16 | @JsonKey(name: 'timestamp') 17 | DateTime? timestamp; 18 | 19 | @JsonKey(name: 'producer') 20 | String? producer; 21 | 22 | @JsonKey(name: 'confirmed') 23 | int? confirmed; 24 | 25 | @JsonKey(name: 'previous') 26 | String? previous; 27 | 28 | @JsonKey(name: 'transaction_mroot') 29 | String? transactionMRoot; 30 | 31 | @JsonKey(name: 'action_mroot') 32 | String? actionMRoot; 33 | 34 | @JsonKey(name: 'schedule_version') 35 | int? scheduleVersion; 36 | 37 | @JsonKey(name: 'new_producers') 38 | Object? newProducers; 39 | 40 | @JsonKey(name: 'header_extensions') 41 | List? headerExtensions; 42 | 43 | @JsonKey(name: 'producer_signature') 44 | String? producerSignature; 45 | 46 | @JsonKey(name: 'transactions') 47 | List? transactions; 48 | 49 | @JsonKey(name: 'block_extensions') 50 | List? blockExtensions; 51 | 52 | @JsonKey(name: 'ref_block_prefix') 53 | int? refBlockPrefix; 54 | 55 | Block(this.id, this.blockNum); 56 | 57 | factory Block.fromJson(Map json) => _$BlockFromJson(json); 58 | 59 | Map toJson() => _$BlockToJson(this); 60 | 61 | @override 62 | String toString() => this.toJson().toString(); 63 | } 64 | -------------------------------------------------------------------------------- /lib/src/models/block.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'block.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | Block _$BlockFromJson(Map json) => Block( 10 | json['id'] as String, 11 | ConversionHelper.getIntFromJson(json['block_num']), 12 | ) 13 | ..timestamp = json['timestamp'] == null 14 | ? null 15 | : DateTime.parse(json['timestamp'] as String) 16 | ..producer = json['producer'] as String? 17 | ..confirmed = json['confirmed'] as int? 18 | ..previous = json['previous'] as String? 19 | ..transactionMRoot = json['transaction_mroot'] as String? 20 | ..actionMRoot = json['action_mroot'] as String? 21 | ..scheduleVersion = json['schedule_version'] as int? 22 | ..newProducers = json['new_producers'] 23 | ..headerExtensions = (json['header_extensions'] as List?) 24 | ?.map((e) => e as Object) 25 | .toList() 26 | ..producerSignature = json['producer_signature'] as String? 27 | ..transactions = (json['transactions'] as List?) 28 | ?.map((e) => TransactionReceipt.fromJson(e as Map)) 29 | .toList() 30 | ..blockExtensions = (json['block_extensions'] as List?) 31 | ?.map((e) => e as Object) 32 | .toList() 33 | ..refBlockPrefix = json['ref_block_prefix'] as int?; 34 | 35 | Map _$BlockToJson(Block instance) => { 36 | 'id': instance.id, 37 | 'block_num': instance.blockNum, 38 | 'timestamp': instance.timestamp?.toIso8601String(), 39 | 'producer': instance.producer, 40 | 'confirmed': instance.confirmed, 41 | 'previous': instance.previous, 42 | 'transaction_mroot': instance.transactionMRoot, 43 | 'action_mroot': instance.actionMRoot, 44 | 'schedule_version': instance.scheduleVersion, 45 | 'new_producers': instance.newProducers, 46 | 'header_extensions': instance.headerExtensions, 47 | 'producer_signature': instance.producerSignature, 48 | 'transactions': instance.transactions, 49 | 'block_extensions': instance.blockExtensions, 50 | 'ref_block_prefix': instance.refBlockPrefix, 51 | }; 52 | -------------------------------------------------------------------------------- /lib/src/models/block_header_state.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | import './conversion_helper.dart'; 4 | 5 | part 'block_header_state.g.dart'; 6 | 7 | @JsonSerializable() 8 | class BlockHeaderState with ConversionHelper { 9 | @JsonKey(name: 'id') 10 | String? id; 11 | 12 | @JsonKey(name: 'block_num', fromJson: ConversionHelper.getIntFromJson) 13 | int? blockNum; 14 | 15 | @JsonKey(name: 'header') 16 | Header? header; 17 | 18 | @JsonKey( 19 | name: 'dpos_proposed_irreversible_blocknum', 20 | fromJson: ConversionHelper.getIntFromJson) 21 | int? dposProposedIrreversibleBlocknum; 22 | 23 | @JsonKey( 24 | name: 'dpos_irreversible_blocknum', 25 | fromJson: ConversionHelper.getIntFromJson) 26 | int? dposIrreversibleBlocknum; 27 | 28 | @JsonKey( 29 | name: 'bft_irreversible_blocknum', 30 | fromJson: ConversionHelper.getIntFromJson) 31 | int? bftIrreversibleBlocknum; 32 | 33 | @JsonKey( 34 | name: 'pending_schedule_lib_num', 35 | fromJson: ConversionHelper.getIntFromJson) 36 | int? pendingScheduleLibNum; 37 | 38 | @JsonKey(name: 'pending_schedule_hash') 39 | String? pendingScheduleHash; 40 | 41 | @JsonKey(name: 'pending_schedule') 42 | Schedule? pendingSchedule; 43 | 44 | @JsonKey(name: 'active_schedule') 45 | Schedule? activeSchedule; 46 | 47 | @JsonKey(name: 'blockroot_merkle') 48 | BlockRootMerkle? blockrootMerkle; 49 | 50 | @JsonKey(name: 'producer_to_last_produced') 51 | List>? producerToLastProduced; 52 | 53 | @JsonKey(name: 'producer_to_last_implied_irb') 54 | List>? producerToLastImpliedIrb; 55 | 56 | @JsonKey(name: 'block_signing_key') 57 | String? blockSigningKey; 58 | 59 | @JsonKey(name: 'confirm_count') 60 | List? confirmCount; 61 | 62 | @JsonKey(name: 'confirmations') 63 | List? confirmations; 64 | 65 | BlockHeaderState(); 66 | 67 | factory BlockHeaderState.fromJson(Map json) => 68 | _$BlockHeaderStateFromJson(json); 69 | 70 | Map toJson() => _$BlockHeaderStateToJson(this); 71 | 72 | @override 73 | String toString() => this.toJson().toString(); 74 | } 75 | 76 | @JsonSerializable() 77 | class Header { 78 | @JsonKey(name: 'timestamp') 79 | DateTime? timestamp; 80 | 81 | @JsonKey(name: 'producer') 82 | String? producer; 83 | 84 | @JsonKey(name: 'confirmed') 85 | int? confirmed; 86 | 87 | @JsonKey(name: 'previous') 88 | String? previous; 89 | 90 | @JsonKey(name: 'transaction_mroot') 91 | String? transactionMRoot; 92 | 93 | @JsonKey(name: 'action_mroot') 94 | String? actionMRoot; 95 | 96 | @JsonKey(name: 'schedule_version') 97 | int? scheduleVersion; 98 | 99 | @JsonKey(name: 'header_extensions') 100 | List? headerExtensions; 101 | 102 | @JsonKey(name: 'producer_signature') 103 | String? producerSignature; 104 | 105 | Header(); 106 | 107 | factory Header.fromJson(Map json) => _$HeaderFromJson(json); 108 | 109 | Map toJson() => _$HeaderToJson(this); 110 | 111 | @override 112 | String toString() => this.toJson().toString(); 113 | } 114 | 115 | @JsonSerializable() 116 | class Schedule { 117 | @JsonKey(name: 'version') 118 | int? version; 119 | 120 | @JsonKey(name: 'producers') 121 | List? producers; 122 | 123 | Schedule(); 124 | 125 | factory Schedule.fromJson(Map json) => 126 | _$ScheduleFromJson(json); 127 | 128 | Map toJson() => _$ScheduleToJson(this); 129 | 130 | @override 131 | String toString() => this.toJson().toString(); 132 | } 133 | 134 | @JsonSerializable() 135 | class Producer { 136 | @JsonKey(name: 'producer_name') 137 | String? producerName; 138 | 139 | @JsonKey(name: 'block_signing_key') 140 | String? blockSigningKey; 141 | 142 | Producer(); 143 | 144 | factory Producer.fromJson(Map json) => 145 | _$ProducerFromJson(json); 146 | 147 | Map toJson() => _$ProducerToJson(this); 148 | 149 | @override 150 | String toString() => this.toJson().toString(); 151 | } 152 | 153 | @JsonSerializable() 154 | class BlockRootMerkle { 155 | @JsonKey(name: '_active_nodes') 156 | List? activeNodes; 157 | 158 | @JsonKey(name: '_node_count') 159 | int? nodeCount; 160 | 161 | BlockRootMerkle(); 162 | 163 | factory BlockRootMerkle.fromJson(Map json) => 164 | _$BlockRootMerkleFromJson(json); 165 | 166 | Map toJson() => _$BlockRootMerkleToJson(this); 167 | 168 | @override 169 | String toString() => this.toJson().toString(); 170 | } 171 | -------------------------------------------------------------------------------- /lib/src/models/block_header_state.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'block_header_state.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | BlockHeaderState _$BlockHeaderStateFromJson(Map json) => 10 | BlockHeaderState() 11 | ..id = json['id'] as String? 12 | ..blockNum = ConversionHelper.getIntFromJson(json['block_num']) 13 | ..header = json['header'] == null 14 | ? null 15 | : Header.fromJson(json['header'] as Map) 16 | ..dposProposedIrreversibleBlocknum = ConversionHelper.getIntFromJson( 17 | json['dpos_proposed_irreversible_blocknum']) 18 | ..dposIrreversibleBlocknum = 19 | ConversionHelper.getIntFromJson(json['dpos_irreversible_blocknum']) 20 | ..bftIrreversibleBlocknum = 21 | ConversionHelper.getIntFromJson(json['bft_irreversible_blocknum']) 22 | ..pendingScheduleLibNum = 23 | ConversionHelper.getIntFromJson(json['pending_schedule_lib_num']) 24 | ..pendingScheduleHash = json['pending_schedule_hash'] as String? 25 | ..pendingSchedule = json['pending_schedule'] == null 26 | ? null 27 | : Schedule.fromJson(json['pending_schedule'] as Map) 28 | ..activeSchedule = json['active_schedule'] == null 29 | ? null 30 | : Schedule.fromJson(json['active_schedule'] as Map) 31 | ..blockrootMerkle = json['blockroot_merkle'] == null 32 | ? null 33 | : BlockRootMerkle.fromJson( 34 | json['blockroot_merkle'] as Map) 35 | ..producerToLastProduced = (json['producer_to_last_produced'] 36 | as List?) 37 | ?.map((e) => (e as List).map((e) => e as Object).toList()) 38 | .toList() 39 | ..producerToLastImpliedIrb = (json['producer_to_last_implied_irb'] 40 | as List?) 41 | ?.map((e) => (e as List).map((e) => e as Object).toList()) 42 | .toList() 43 | ..blockSigningKey = json['block_signing_key'] as String? 44 | ..confirmCount = (json['confirm_count'] as List?) 45 | ?.map((e) => e as int) 46 | .toList() 47 | ..confirmations = (json['confirmations'] as List?) 48 | ?.map((e) => e as Object) 49 | .toList(); 50 | 51 | Map _$BlockHeaderStateToJson(BlockHeaderState instance) => 52 | { 53 | 'id': instance.id, 54 | 'block_num': instance.blockNum, 55 | 'header': instance.header, 56 | 'dpos_proposed_irreversible_blocknum': 57 | instance.dposProposedIrreversibleBlocknum, 58 | 'dpos_irreversible_blocknum': instance.dposIrreversibleBlocknum, 59 | 'bft_irreversible_blocknum': instance.bftIrreversibleBlocknum, 60 | 'pending_schedule_lib_num': instance.pendingScheduleLibNum, 61 | 'pending_schedule_hash': instance.pendingScheduleHash, 62 | 'pending_schedule': instance.pendingSchedule, 63 | 'active_schedule': instance.activeSchedule, 64 | 'blockroot_merkle': instance.blockrootMerkle, 65 | 'producer_to_last_produced': instance.producerToLastProduced, 66 | 'producer_to_last_implied_irb': instance.producerToLastImpliedIrb, 67 | 'block_signing_key': instance.blockSigningKey, 68 | 'confirm_count': instance.confirmCount, 69 | 'confirmations': instance.confirmations, 70 | }; 71 | 72 | Header _$HeaderFromJson(Map json) => Header() 73 | ..timestamp = json['timestamp'] == null 74 | ? null 75 | : DateTime.parse(json['timestamp'] as String) 76 | ..producer = json['producer'] as String? 77 | ..confirmed = json['confirmed'] as int? 78 | ..previous = json['previous'] as String? 79 | ..transactionMRoot = json['transaction_mroot'] as String? 80 | ..actionMRoot = json['action_mroot'] as String? 81 | ..scheduleVersion = json['schedule_version'] as int? 82 | ..headerExtensions = (json['header_extensions'] as List?) 83 | ?.map((e) => e as Object) 84 | .toList() 85 | ..producerSignature = json['producer_signature'] as String?; 86 | 87 | Map _$HeaderToJson(Header instance) => { 88 | 'timestamp': instance.timestamp?.toIso8601String(), 89 | 'producer': instance.producer, 90 | 'confirmed': instance.confirmed, 91 | 'previous': instance.previous, 92 | 'transaction_mroot': instance.transactionMRoot, 93 | 'action_mroot': instance.actionMRoot, 94 | 'schedule_version': instance.scheduleVersion, 95 | 'header_extensions': instance.headerExtensions, 96 | 'producer_signature': instance.producerSignature, 97 | }; 98 | 99 | Schedule _$ScheduleFromJson(Map json) => Schedule() 100 | ..version = json['version'] as int? 101 | ..producers = (json['producers'] as List?) 102 | ?.map((e) => Producer.fromJson(e as Map)) 103 | .toList(); 104 | 105 | Map _$ScheduleToJson(Schedule instance) => { 106 | 'version': instance.version, 107 | 'producers': instance.producers, 108 | }; 109 | 110 | Producer _$ProducerFromJson(Map json) => Producer() 111 | ..producerName = json['producer_name'] as String? 112 | ..blockSigningKey = json['block_signing_key'] as String?; 113 | 114 | Map _$ProducerToJson(Producer instance) => { 115 | 'producer_name': instance.producerName, 116 | 'block_signing_key': instance.blockSigningKey, 117 | }; 118 | 119 | BlockRootMerkle _$BlockRootMerkleFromJson(Map json) => 120 | BlockRootMerkle() 121 | ..activeNodes = (json['_active_nodes'] as List?) 122 | ?.map((e) => e as String) 123 | .toList() 124 | ..nodeCount = json['_node_count'] as int?; 125 | 126 | Map _$BlockRootMerkleToJson(BlockRootMerkle instance) => 127 | { 128 | '_active_nodes': instance.activeNodes, 129 | '_node_count': instance.nodeCount, 130 | }; 131 | -------------------------------------------------------------------------------- /lib/src/models/conversion_helper.dart: -------------------------------------------------------------------------------- 1 | import 'dart:typed_data'; 2 | import 'dart:convert'; 3 | 4 | mixin ConversionHelper { 5 | // Due to the javascript have limit on the integer, some of the numbers 6 | // are in String format 7 | // https://github.com/EOSIO/eos/issues/6820 8 | static int? getIntFromJson(dynamic value) { 9 | switch (value.runtimeType) { 10 | case String: 11 | return int.parse(value); 12 | default: 13 | return value as int?; 14 | } 15 | } 16 | 17 | static Uint8List base64ToBuffer(String base64String) { 18 | return Uint8List.fromList(utf8.encode(base64String)); 19 | } 20 | 21 | static String bufferToBase64(Uint8List buffer) { 22 | return utf8.decode(buffer); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /lib/src/models/node_info.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | import './conversion_helper.dart'; 4 | 5 | part 'node_info.g.dart'; 6 | 7 | @JsonSerializable() 8 | class NodeInfo with ConversionHelper { 9 | @JsonKey(name: 'server_version') 10 | String? serverVersion; 11 | 12 | @JsonKey(name: 'chain_id') 13 | String? chainId; 14 | 15 | @JsonKey(name: 'head_block_num', fromJson: ConversionHelper.getIntFromJson) 16 | int? headBlockNum; 17 | 18 | @JsonKey( 19 | name: 'last_irreversible_block_num', 20 | fromJson: ConversionHelper.getIntFromJson) 21 | int? lastIrreversibleBlockNum; 22 | 23 | @JsonKey(name: 'last_irreversible_block_id') 24 | String? lastIrreversibleBlockId; 25 | 26 | @JsonKey(name: 'head_block_time') 27 | DateTime? headBlockTime; 28 | 29 | @JsonKey(name: 'head_block_producer') 30 | String? headBlockProducer; 31 | 32 | @JsonKey( 33 | name: 'virtual_block_cpu_limit', 34 | fromJson: ConversionHelper.getIntFromJson) 35 | int? virtualBlockCpuLimit; 36 | 37 | @JsonKey( 38 | name: 'virtual_block_net_limit', 39 | fromJson: ConversionHelper.getIntFromJson) 40 | int? virtualBlockNetLimit; 41 | 42 | @JsonKey(name: 'block_cpu_limit', fromJson: ConversionHelper.getIntFromJson) 43 | int? blockCpuLimit; 44 | 45 | @JsonKey(name: 'block_net_limit', fromJson: ConversionHelper.getIntFromJson) 46 | int? blockNetLimit; 47 | 48 | @JsonKey(name: 'server_version_string') 49 | String? serverVersionString; 50 | 51 | @JsonKey(name: 'website') 52 | String? website; 53 | 54 | NodeInfo(); 55 | 56 | factory NodeInfo.fromJson(Map json) => 57 | _$NodeInfoFromJson(json); 58 | 59 | Map toJson() => _$NodeInfoToJson(this); 60 | 61 | @override 62 | String toString() => this.toJson().toString(); 63 | } 64 | -------------------------------------------------------------------------------- /lib/src/models/node_info.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'node_info.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | NodeInfo _$NodeInfoFromJson(Map json) => NodeInfo() 10 | ..serverVersion = json['server_version'] as String? 11 | ..chainId = json['chain_id'] as String? 12 | ..headBlockNum = ConversionHelper.getIntFromJson(json['head_block_num']) 13 | ..lastIrreversibleBlockNum = 14 | ConversionHelper.getIntFromJson(json['last_irreversible_block_num']) 15 | ..lastIrreversibleBlockId = json['last_irreversible_block_id'] as String? 16 | ..headBlockTime = json['head_block_time'] == null 17 | ? null 18 | : DateTime.parse(json['head_block_time'] as String) 19 | ..headBlockProducer = json['head_block_producer'] as String? 20 | ..virtualBlockCpuLimit = 21 | ConversionHelper.getIntFromJson(json['virtual_block_cpu_limit']) 22 | ..virtualBlockNetLimit = 23 | ConversionHelper.getIntFromJson(json['virtual_block_net_limit']) 24 | ..blockCpuLimit = ConversionHelper.getIntFromJson(json['block_cpu_limit']) 25 | ..blockNetLimit = ConversionHelper.getIntFromJson(json['block_net_limit']) 26 | ..serverVersionString = json['server_version_string'] as String? 27 | ..website = json['website'] as String?; 28 | 29 | Map _$NodeInfoToJson(NodeInfo instance) => { 30 | 'server_version': instance.serverVersion, 31 | 'chain_id': instance.chainId, 32 | 'head_block_num': instance.headBlockNum, 33 | 'last_irreversible_block_num': instance.lastIrreversibleBlockNum, 34 | 'last_irreversible_block_id': instance.lastIrreversibleBlockId, 35 | 'head_block_time': instance.headBlockTime?.toIso8601String(), 36 | 'head_block_producer': instance.headBlockProducer, 37 | 'virtual_block_cpu_limit': instance.virtualBlockCpuLimit, 38 | 'virtual_block_net_limit': instance.virtualBlockNetLimit, 39 | 'block_cpu_limit': instance.blockCpuLimit, 40 | 'block_net_limit': instance.blockNetLimit, 41 | 'server_version_string': instance.serverVersionString, 42 | 'website': instance.website, 43 | }; 44 | -------------------------------------------------------------------------------- /lib/src/models/primary_wrapper.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | 3 | part 'primary_wrapper.g.dart'; 4 | 5 | @JsonSerializable() 6 | class AccountNames { 7 | @JsonKey(name: 'account_names') 8 | List? accountNames; 9 | 10 | AccountNames(); 11 | 12 | factory AccountNames.fromJson(Map json) => 13 | _$AccountNamesFromJson(json); 14 | 15 | Map toJson() => _$AccountNamesToJson(this); 16 | 17 | @override 18 | String toString() => this.toJson().toString(); 19 | } 20 | 21 | @JsonSerializable() 22 | class RequiredKeys { 23 | @JsonKey(name: 'required_keys') 24 | List? requiredKeys; 25 | 26 | RequiredKeys(); 27 | 28 | factory RequiredKeys.fromJson(Map json) => 29 | _$RequiredKeysFromJson(json); 30 | 31 | Map toJson() => _$RequiredKeysToJson(this); 32 | 33 | @override 34 | String toString() => this.toJson().toString(); 35 | } 36 | -------------------------------------------------------------------------------- /lib/src/models/primary_wrapper.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'primary_wrapper.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | AccountNames _$AccountNamesFromJson(Map json) => AccountNames() 10 | ..accountNames = (json['account_names'] as List?) 11 | ?.map((e) => e as String) 12 | .toList(); 13 | 14 | Map _$AccountNamesToJson(AccountNames instance) => 15 | { 16 | 'account_names': instance.accountNames, 17 | }; 18 | 19 | RequiredKeys _$RequiredKeysFromJson(Map json) => RequiredKeys() 20 | ..requiredKeys = (json['required_keys'] as List?) 21 | ?.map((e) => e as String) 22 | .toList(); 23 | 24 | Map _$RequiredKeysToJson(RequiredKeys instance) => 25 | { 26 | 'required_keys': instance.requiredKeys, 27 | }; 28 | -------------------------------------------------------------------------------- /lib/src/models/transaction.dart: -------------------------------------------------------------------------------- 1 | import 'dart:typed_data'; 2 | import 'package:json_annotation/json_annotation.dart'; 3 | 4 | import './action.dart'; 5 | import './conversion_helper.dart'; 6 | import '../eosdart_base.dart'; 7 | import '../serialize.dart' as ser; 8 | 9 | part 'transaction.g.dart'; 10 | 11 | @JsonSerializable() 12 | class TransactionBlock with ConversionHelper { 13 | @JsonKey(name: 'id') 14 | String? id; 15 | 16 | @JsonKey(name: 'trx') 17 | TransactionWithReceipt? trx; 18 | 19 | @JsonKey(name: 'block_time') 20 | DateTime? blockTime; 21 | 22 | @JsonKey(name: 'block_num', fromJson: ConversionHelper.getIntFromJson) 23 | int? blockNum; 24 | 25 | @JsonKey( 26 | name: 'last_irreversible_block', 27 | fromJson: ConversionHelper.getIntFromJson) 28 | int? lastIrreversibleBlock; 29 | 30 | @JsonKey(name: 'traces') 31 | List? traces; 32 | 33 | TransactionBlock(); 34 | 35 | factory TransactionBlock.fromJson(Map json) => 36 | _$TransactionBlockFromJson(json); 37 | 38 | Map toJson() => _$TransactionBlockToJson(this); 39 | 40 | @override 41 | String toString() => this.toJson().toString(); 42 | } 43 | 44 | @JsonSerializable() 45 | class TransactionWithReceipt { 46 | @JsonKey(name: 'receipt') 47 | TransactionReceipt? receipt; 48 | 49 | @JsonKey(name: 'trx') 50 | Transaction? transaction; 51 | 52 | TransactionWithReceipt(); 53 | 54 | factory TransactionWithReceipt.fromJson(Map json) => 55 | _$TransactionWithReceiptFromJson(json); 56 | 57 | Map toJson() => _$TransactionWithReceiptToJson(this); 58 | 59 | @override 60 | String toString() => this.toJson().toString(); 61 | } 62 | 63 | @JsonSerializable() 64 | class TransactionReceipt with ConversionHelper { 65 | @JsonKey(name: 'status') 66 | String? status; 67 | 68 | @JsonKey(name: 'cpu_usage_us', fromJson: ConversionHelper.getIntFromJson) 69 | int? cpuUsageUs; 70 | 71 | @JsonKey(name: 'net_usage_words', fromJson: ConversionHelper.getIntFromJson) 72 | int? netUsageWords; 73 | 74 | @JsonKey(name: 'trx') 75 | Object? trx; 76 | 77 | TransactionReceipt(); 78 | 79 | factory TransactionReceipt.fromJson(Map json) => 80 | _$TransactionReceiptFromJson(json); 81 | 82 | Map toJson() => _$TransactionReceiptToJson(this); 83 | 84 | @override 85 | String toString() => this.toJson().toString(); 86 | } 87 | 88 | @JsonSerializable(explicitToJson: true) 89 | class Transaction { 90 | @JsonKey(name: 'expiration') 91 | DateTime? expiration; 92 | 93 | @JsonKey(name: 'ref_block_num') 94 | int? refBlockNum; 95 | 96 | @JsonKey(name: 'ref_block_prefix') 97 | int? refBlockPrefix; 98 | 99 | @JsonKey(name: 'max_net_usage_words') 100 | int? maxNetUsageWords = 0; 101 | 102 | @JsonKey(name: 'max_cpu_usage_ms') 103 | int? maxCpuUsageMs = 0; 104 | 105 | @JsonKey(name: 'delay_sec') 106 | int? delaySec = 0; 107 | 108 | @JsonKey(name: 'context_free_actions') 109 | List? contextFreeActions = []; 110 | 111 | @JsonKey(name: 'actions') 112 | List? actions = []; 113 | 114 | @JsonKey(name: 'transaction_extensions') 115 | List? transactionExtensions = []; 116 | 117 | @JsonKey(name: 'signatures') 118 | List? signatures = []; 119 | 120 | @JsonKey(name: 'context_free_data') 121 | List? contextFreeData = []; 122 | 123 | Transaction(); 124 | 125 | factory Transaction.fromJson(Map json) => 126 | _$TransactionFromJson(json); 127 | 128 | Map toJson() => _$TransactionToJson(this); 129 | 130 | @override 131 | String toString() => this.toJson().toString(); 132 | 133 | Uint8List toBinary(Type transactionType) { 134 | var buffer = ser.SerialBuffer(Uint8List(0)); 135 | transactionType.serialize?.call(transactionType, buffer, this.toJson()); 136 | return buffer.asUint8List(); 137 | } 138 | } 139 | 140 | @JsonSerializable() 141 | class TransactionCommitted { 142 | @JsonKey(name: 'transaction_id') 143 | String? id; 144 | 145 | @JsonKey(name: 'processed') 146 | TransactionProcessed? processed; 147 | 148 | TransactionCommitted(); 149 | 150 | factory TransactionCommitted.fromJson(Map json) => 151 | _$TransactionCommittedFromJson(json); 152 | 153 | Map toJson() => _$TransactionCommittedToJson(this); 154 | 155 | @override 156 | String toString() => this.toJson().toString(); 157 | } 158 | 159 | @JsonSerializable() 160 | class TransactionProcessed with ConversionHelper { 161 | @JsonKey(name: 'id') 162 | String? id; 163 | 164 | @JsonKey(name: 'block_num', fromJson: ConversionHelper.getIntFromJson) 165 | int? blockNum; 166 | 167 | @JsonKey(name: 'block_time') 168 | DateTime? blockTime; 169 | 170 | @JsonKey(name: 'producer_block_id', fromJson: ConversionHelper.getIntFromJson) 171 | int? producerBlockId; 172 | 173 | @JsonKey(name: 'receipt') 174 | TransactionReceipt? receipt; 175 | 176 | @JsonKey(name: 'elapsed', fromJson: ConversionHelper.getIntFromJson) 177 | int? elapsed; 178 | 179 | @JsonKey(name: 'net_usage', fromJson: ConversionHelper.getIntFromJson) 180 | int? netUsage; 181 | 182 | @JsonKey(name: 'scheduled') 183 | bool? scheduled; 184 | 185 | @JsonKey(name: 'action_traces') 186 | List? actionTraces; 187 | 188 | TransactionProcessed(); 189 | 190 | factory TransactionProcessed.fromJson(Map json) => 191 | _$TransactionProcessedFromJson(json); 192 | 193 | Map toJson() => _$TransactionProcessedToJson(this); 194 | 195 | @override 196 | String toString() => this.toJson().toString(); 197 | } 198 | -------------------------------------------------------------------------------- /lib/src/models/transaction.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'transaction.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | TransactionBlock _$TransactionBlockFromJson(Map json) => 10 | TransactionBlock() 11 | ..id = json['id'] as String? 12 | ..trx = json['trx'] == null 13 | ? null 14 | : TransactionWithReceipt.fromJson(json['trx'] as Map) 15 | ..blockTime = json['block_time'] == null 16 | ? null 17 | : DateTime.parse(json['block_time'] as String) 18 | ..blockNum = ConversionHelper.getIntFromJson(json['block_num']) 19 | ..lastIrreversibleBlock = 20 | ConversionHelper.getIntFromJson(json['last_irreversible_block']) 21 | ..traces = (json['traces'] as List?) 22 | ?.map((e) => ActionWithReceipt.fromJson(e as Map)) 23 | .toList(); 24 | 25 | Map _$TransactionBlockToJson(TransactionBlock instance) => 26 | { 27 | 'id': instance.id, 28 | 'trx': instance.trx, 29 | 'block_time': instance.blockTime?.toIso8601String(), 30 | 'block_num': instance.blockNum, 31 | 'last_irreversible_block': instance.lastIrreversibleBlock, 32 | 'traces': instance.traces, 33 | }; 34 | 35 | TransactionWithReceipt _$TransactionWithReceiptFromJson( 36 | Map json) => 37 | TransactionWithReceipt() 38 | ..receipt = json['receipt'] == null 39 | ? null 40 | : TransactionReceipt.fromJson(json['receipt'] as Map) 41 | ..transaction = json['trx'] == null 42 | ? null 43 | : Transaction.fromJson(json['trx'] as Map); 44 | 45 | Map _$TransactionWithReceiptToJson( 46 | TransactionWithReceipt instance) => 47 | { 48 | 'receipt': instance.receipt, 49 | 'trx': instance.transaction, 50 | }; 51 | 52 | TransactionReceipt _$TransactionReceiptFromJson(Map json) => 53 | TransactionReceipt() 54 | ..status = json['status'] as String? 55 | ..cpuUsageUs = ConversionHelper.getIntFromJson(json['cpu_usage_us']) 56 | ..netUsageWords = ConversionHelper.getIntFromJson(json['net_usage_words']) 57 | ..trx = json['trx']; 58 | 59 | Map _$TransactionReceiptToJson(TransactionReceipt instance) => 60 | { 61 | 'status': instance.status, 62 | 'cpu_usage_us': instance.cpuUsageUs, 63 | 'net_usage_words': instance.netUsageWords, 64 | 'trx': instance.trx, 65 | }; 66 | 67 | Transaction _$TransactionFromJson(Map json) => Transaction() 68 | ..expiration = json['expiration'] == null 69 | ? null 70 | : DateTime.parse(json['expiration'] as String) 71 | ..refBlockNum = json['ref_block_num'] as int? 72 | ..refBlockPrefix = json['ref_block_prefix'] as int? 73 | ..maxNetUsageWords = json['max_net_usage_words'] as int? 74 | ..maxCpuUsageMs = json['max_cpu_usage_ms'] as int? 75 | ..delaySec = json['delay_sec'] as int? 76 | ..contextFreeActions = (json['context_free_actions'] as List?) 77 | ?.map((e) => e as Object) 78 | .toList() 79 | ..actions = (json['actions'] as List?) 80 | ?.map((e) => Action.fromJson(e as Map)) 81 | .toList() 82 | ..transactionExtensions = (json['transaction_extensions'] as List?) 83 | ?.map((e) => e as Object) 84 | .toList() 85 | ..signatures = 86 | (json['signatures'] as List?)?.map((e) => e as String).toList() 87 | ..contextFreeData = (json['context_free_data'] as List?) 88 | ?.map((e) => e as Object) 89 | .toList(); 90 | 91 | Map _$TransactionToJson(Transaction instance) => 92 | { 93 | 'expiration': instance.expiration?.toIso8601String(), 94 | 'ref_block_num': instance.refBlockNum, 95 | 'ref_block_prefix': instance.refBlockPrefix, 96 | 'max_net_usage_words': instance.maxNetUsageWords, 97 | 'max_cpu_usage_ms': instance.maxCpuUsageMs, 98 | 'delay_sec': instance.delaySec, 99 | 'context_free_actions': instance.contextFreeActions, 100 | 'actions': instance.actions?.map((e) => e.toJson()).toList(), 101 | 'transaction_extensions': instance.transactionExtensions, 102 | 'signatures': instance.signatures, 103 | 'context_free_data': instance.contextFreeData, 104 | }; 105 | 106 | TransactionCommitted _$TransactionCommittedFromJson( 107 | Map json) => 108 | TransactionCommitted() 109 | ..id = json['transaction_id'] as String? 110 | ..processed = json['processed'] == null 111 | ? null 112 | : TransactionProcessed.fromJson( 113 | json['processed'] as Map); 114 | 115 | Map _$TransactionCommittedToJson( 116 | TransactionCommitted instance) => 117 | { 118 | 'transaction_id': instance.id, 119 | 'processed': instance.processed, 120 | }; 121 | 122 | TransactionProcessed _$TransactionProcessedFromJson( 123 | Map json) => 124 | TransactionProcessed() 125 | ..id = json['id'] as String? 126 | ..blockNum = ConversionHelper.getIntFromJson(json['block_num']) 127 | ..blockTime = json['block_time'] == null 128 | ? null 129 | : DateTime.parse(json['block_time'] as String) 130 | ..producerBlockId = 131 | ConversionHelper.getIntFromJson(json['producer_block_id']) 132 | ..receipt = json['receipt'] == null 133 | ? null 134 | : TransactionReceipt.fromJson(json['receipt'] as Map) 135 | ..elapsed = ConversionHelper.getIntFromJson(json['elapsed']) 136 | ..netUsage = ConversionHelper.getIntFromJson(json['net_usage']) 137 | ..scheduled = json['scheduled'] as bool? 138 | ..actionTraces = (json['action_traces'] as List?) 139 | ?.map((e) => ActionWithReceipt.fromJson(e as Map)) 140 | .toList(); 141 | 142 | Map _$TransactionProcessedToJson( 143 | TransactionProcessed instance) => 144 | { 145 | 'id': instance.id, 146 | 'block_num': instance.blockNum, 147 | 'block_time': instance.blockTime?.toIso8601String(), 148 | 'producer_block_id': instance.producerBlockId, 149 | 'receipt': instance.receipt, 150 | 'elapsed': instance.elapsed, 151 | 'net_usage': instance.netUsage, 152 | 'scheduled': instance.scheduled, 153 | 'action_traces': instance.actionTraces, 154 | }; 155 | -------------------------------------------------------------------------------- /lib/src/numeric.dart: -------------------------------------------------------------------------------- 1 | // ignore_for_file: parameter_assignments, prefer_final_locals, prefer_interpolation_to_compose_strings 2 | import 'dart:typed_data'; 3 | import 'package:pointycastle/pointycastle.dart'; 4 | 5 | /// @module Numeric 6 | 7 | String base58Chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'; 8 | String base64Chars = 9 | 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; 10 | 11 | // ignore: non_constant_identifier_names 12 | List create_base58_map() { 13 | var base58M = List.filled(256, -1); 14 | for (var i = 0; i < base58Chars.length; ++i) { 15 | base58M[base58Chars.codeUnitAt(i)] = i; 16 | } 17 | return base58M; 18 | } 19 | 20 | final base58Map = create_base58_map(); 21 | 22 | // ignore: non_constant_identifier_names 23 | List create_base64_map() { 24 | var base64M = List.filled(256, -1); 25 | for (var i = 0; i < base64Chars.length; ++i) { 26 | base64M[base64Chars.codeUnitAt(i)] = i; 27 | } 28 | base64M['='.codeUnitAt(0)] = 0; 29 | return base64M; 30 | } 31 | 32 | final base64Map = create_base64_map(); 33 | 34 | /// Is `bignum` a negative number? 35 | bool isNegative(Uint8List bignum) { 36 | return (bignum[bignum.length - 1] & 0x80) != 0; 37 | } 38 | 39 | /// Negate `bignum` 40 | void negate(Uint8List bignum) { 41 | var carry = 1; 42 | for (var i = 0; i < bignum.length; ++i) { 43 | var x = (~bignum[i] & 0xff) + carry; 44 | bignum[i] = x; 45 | carry = x >> 8; 46 | } 47 | } 48 | 49 | /// Convert an unsigned decimal number in `s` to a bignum 50 | /// @param size bignum size (bytes) 51 | Uint8List decimalToBinary(int size, String s) { 52 | var result = Uint8List(size); 53 | for (var i = 0; i < s.length; ++i) { 54 | var srcDigit = s.codeUnitAt(i); 55 | if (srcDigit < '0'.codeUnitAt(0) || srcDigit > '9'.codeUnitAt(0)) { 56 | throw 'invalid number'; 57 | } 58 | var carry = srcDigit - '0'.codeUnitAt(0); 59 | for (var j = 0; j < size; ++j) { 60 | var x = result[j] * 10 + carry; 61 | result[j] = x; 62 | carry = x >> 8; 63 | } 64 | if (carry != 0) { 65 | throw 'number is out of range'; 66 | } 67 | } 68 | return result; 69 | } 70 | 71 | /// Convert a signed decimal number in `s` to a bignum 72 | /// @param size bignum size (bytes) 73 | Uint8List signedDecimalToBinary(int size, String s) { 74 | var negative = s[0] == '-'; 75 | if (negative) { 76 | s = s.substring(1); 77 | // "-0" is 0 and not negative. 78 | negative = s != '0'; } 79 | var result = decimalToBinary(size, s); 80 | if (negative) { 81 | negate(result); 82 | if (!isNegative(result)) { 83 | throw 'number is out of range'; 84 | } 85 | } else if (isNegative(result)) { 86 | throw 'number is out of range'; 87 | } 88 | return result; 89 | } 90 | 91 | /// Convert `bignum` to an unsigned decimal number 92 | /// @param minDigits 0-pad result to this many digits 93 | String binaryToDecimal(Uint8List bignum, {int minDigits = 1}) { 94 | var result = List.filled(minDigits, '0'.codeUnitAt(0), growable: true); 95 | for (var i = bignum.length - 1; i >= 0; --i) { 96 | var carry = bignum[i]; 97 | for (var j = 0; j < result.length; ++j) { 98 | var x = ((result[j] - '0'.codeUnitAt(0)) << 8) + carry; 99 | result[j] = '0'.codeUnitAt(0) + x % 10; 100 | carry = (x ~/ 10) | 0; 101 | } 102 | while (carry != 0) { 103 | result.add('0'.codeUnitAt(0) + carry % 10); 104 | carry = (carry ~/ 10) | 0; 105 | } 106 | } 107 | return String.fromCharCodes(result.reversed.toList()); 108 | } 109 | 110 | /// Convert `bignum` to a signed decimal number 111 | /// @param minDigits 0-pad result to this many digits 112 | String signedBinaryToDecimal(Uint8List bignum, {int minDigits = 1}) { 113 | if (isNegative(bignum)) { 114 | var x = Uint8List.fromList(bignum.getRange(0, bignum.length).toList()); 115 | negate(x); 116 | return '-' + binaryToDecimal(x, minDigits: minDigits); 117 | } 118 | return binaryToDecimal(bignum, minDigits: minDigits); 119 | } 120 | 121 | /// Convert an unsigned base-58 number in `s` to a bignum 122 | /// @param size bignum size (bytes) 123 | Uint8List base58ToBinary(int size, String s) { 124 | var result = Uint8List(size); 125 | for (var i = 0; i < s.length; ++i) { 126 | var carry = base58Map[s.codeUnitAt(i)]; 127 | if (carry < 0) { 128 | throw 'invalid base-58 value'; 129 | } 130 | for (var j = 0; j < size; ++j) { 131 | var x = result[j] * 58 + carry; 132 | result[j] = x; 133 | carry = x >> 8; 134 | } 135 | if (carry != 0) { 136 | throw 'base-58 value is out of range'; 137 | } 138 | } 139 | return Uint8List.fromList(result.reversed.toList()); 140 | } 141 | 142 | /// Convert `bignum` to a base-58 number 143 | /// @param minDigits 0-pad result to this many digits 144 | String binaryToBase58(Uint8List bignum, {int minDigits = 1}) { 145 | var result = []; 146 | for (final byte in bignum) { 147 | var carry = byte; 148 | for (var j = 0; j < result.length; ++j) { 149 | var x = (base58Map[result[j]] << 8) + carry; 150 | result[j] = base58Chars.codeUnitAt(x % 58); 151 | carry = (x ~/ 58) | 0; 152 | } 153 | while (carry != 0) { 154 | result.add(base58Chars.codeUnitAt(carry % 58)); 155 | carry = (carry ~/ 58) | 0; 156 | } 157 | } 158 | for (final byte in bignum) { 159 | if (byte != 0) { 160 | break; 161 | } else { 162 | result.add('1'.codeUnitAt(0)); 163 | } 164 | } 165 | return String.fromCharCodes(result.reversed.toList()); 166 | } 167 | 168 | /// Convert an unsigned base-64 number in `s` to a bignum 169 | Uint8List base64ToBinary(String s) { 170 | var len = s.length; 171 | if ((len & 3) == 1 && s[len - 1] == '=') { 172 | len -= 1; 173 | } // fc appends an extra '=' 174 | if ((len & 3) != 0) { 175 | throw 'base-64 value is not padded correctly'; 176 | } 177 | var groups = len >> 2; 178 | var bytes = groups * 3; 179 | if (len > 0 && s[len - 1] == '=') { 180 | if (s[len - 2] == '=') { 181 | bytes -= 2; 182 | } else { 183 | bytes -= 1; 184 | } 185 | } 186 | var result = Uint8List(bytes); 187 | 188 | for (var group = 0; group < groups; ++group) { 189 | var digit0 = base64Map[s.codeUnitAt(group * 4 + 0)]; 190 | var digit1 = base64Map[s.codeUnitAt(group * 4 + 1)]; 191 | var digit2 = base64Map[s.codeUnitAt(group * 4 + 2)]; 192 | var digit3 = base64Map[s.codeUnitAt(group * 4 + 3)]; 193 | result[group * 3 + 0] = (digit0 << 2) | (digit1 >> 4); 194 | if (group * 3 + 1 < bytes) { 195 | result[group * 3 + 1] = ((digit1 & 15) << 4) | (digit2 >> 2); 196 | } 197 | if (group * 3 + 2 < bytes) { 198 | result[group * 3 + 2] = ((digit2 & 3) << 6) | digit3; 199 | } 200 | } 201 | return result; 202 | } 203 | 204 | /// Key types this library supports */ 205 | enum KeyType { 206 | k1, 207 | r1, 208 | } 209 | 210 | /// Public key data size, excluding type field 211 | int publicKeyDataSize = 33; 212 | 213 | /// Private key data size, excluding type field 214 | int privateKeyDataSize = 32; 215 | 216 | /// Signature data size, excluding type field 217 | int signatureDataSize = 65; 218 | 219 | /// Public key, private key, or signature in binary form 220 | class IKey { 221 | KeyType type; 222 | Uint8List data; 223 | 224 | IKey(this.type, this.data); 225 | } 226 | 227 | Uint8List digestSuffixRipemd160(Uint8List data, String suffix) { 228 | var d = Uint8List(data.length + suffix.length); 229 | for (var i = 0; i < data.length; ++i) { 230 | d[i] = data[i]; 231 | } 232 | for (var i = 0; i < suffix.length; ++i) { 233 | d[data.length + i] = suffix.codeUnitAt(i); 234 | } 235 | var dg = Digest("RIPEMD-160"); 236 | return dg.process(d); 237 | } 238 | 239 | Uint8List digestSha256X2(Uint8List data) { 240 | var dg = Digest("SHA-256"); 241 | var d1 = dg.process(data); 242 | dg.reset(); 243 | return dg.process(d1); 244 | } 245 | 246 | IKey stringToKey(String s, KeyType type, int size, String suffix) { 247 | var whole = base58ToBinary(size + 4, s); 248 | IKey result; 249 | Uint8List digest; 250 | if (suffix == '') { 251 | result = IKey(type, whole.sublist(1,size)); 252 | digest = digestSha256X2(whole.sublist(0,size)); 253 | } else { 254 | result = IKey(type, whole.sublist(0,size)); 255 | digest = digestSuffixRipemd160(result.data, suffix); 256 | } 257 | if (digest[0] != whole[size + 0] || 258 | digest[1] != whole[size + 1] || 259 | digest[2] != whole[size + 2] || 260 | digest[3] != whole[size + 3]) { 261 | throw "checksum doesn't match"; 262 | } 263 | return result; 264 | } 265 | 266 | String keyToString(IKey key, String suffix, String prefix) { 267 | var digest = digestSuffixRipemd160(key.data, suffix); 268 | var whole = Uint8List(key.data.length + 4); 269 | for (var i = 0; i < key.data.length; ++i) { 270 | whole[i] = key.data[i]; 271 | } 272 | for (var i = 0; i < 4; ++i) { 273 | whole[i + key.data.length] = digest[i]; 274 | } 275 | return prefix + binaryToBase58(whole); 276 | } 277 | 278 | /// Convert key in `s` to binary form 279 | IKey stringToPublicKey(String s) { 280 | if (s.substring(0, 3) == 'EOS') { 281 | var whole = base58ToBinary(publicKeyDataSize + 4, s.substring(3)); 282 | var key = IKey(KeyType.k1, Uint8List(publicKeyDataSize)); 283 | for (var i = 0; i < publicKeyDataSize; ++i) { 284 | key.data[i] = whole[i]; 285 | } 286 | var dg = Digest("RIPEMD-160"); 287 | var digest = dg.process(key.data); 288 | if (digest[0] != whole[publicKeyDataSize] || 289 | digest[1] != whole[34] || 290 | digest[2] != whole[35] || 291 | digest[3] != whole[36]) { 292 | throw "checksum doesn't match"; 293 | } 294 | return key; 295 | } else if (s.substring(0, 7) == 'PUB_K1_') { 296 | return stringToKey(s.substring(7), KeyType.k1, publicKeyDataSize, 'K1'); 297 | } else if (s.substring(0, 7) == 'PUB_R1_') { 298 | return stringToKey(s.substring(7), KeyType.r1, publicKeyDataSize, 'R1'); 299 | } else { 300 | throw 'unrecognized public key format'; 301 | } 302 | } 303 | 304 | /// Convert `key` to string (base-58) form 305 | String publicKeyToString(IKey key) { 306 | if (key.type == KeyType.k1 && key.data.length == publicKeyDataSize) { 307 | return keyToString(key, 'K1', 'PUB_K1_'); 308 | } else if (key.type == KeyType.r1 && key.data.length == publicKeyDataSize) { 309 | return keyToString(key, 'R1', 'PUB_R1_'); 310 | } else { 311 | throw 'unrecognized public key format'; 312 | } 313 | } 314 | 315 | /// If a key is in the legacy format (`EOS` prefix), then convert it to the new format (`PUB_K1_`). 316 | /// Leaves other formats untouched 317 | String convertLegacyPublicKey(String s) { 318 | if (s.substring(0, 3) == 'EOS') { 319 | return publicKeyToString(stringToPublicKey(s)); 320 | } 321 | return s; 322 | } 323 | 324 | /// If a key is in the legacy format (`EOS` prefix), then convert it to the new format (`PUB_K1_`). 325 | /// Leaves other formats untouched 326 | List convertLegacyPublicKeys(List keys) => 327 | keys.map((item) => convertLegacyPublicKey(item)).toList(); 328 | 329 | /// Convert key in `s` to binary form 330 | IKey stringToPrivateKey(String s) { 331 | if (s.substring(0, 7) == 'PVT_R1_') { 332 | return stringToKey(s.substring(7), KeyType.r1, privateKeyDataSize, 'R1'); 333 | } else if (s.substring(0, 7) == 'PVT_K1_') { 334 | return stringToKey(s.substring(7), KeyType.k1, privateKeyDataSize, 'K1'); 335 | } else { 336 | return stringToKey(s, KeyType.k1, privateKeyDataSize+1, ''); 337 | } 338 | } 339 | 340 | /// Convert `key` to string (base-58) form */ 341 | String privateKeyToString(IKey key) { 342 | if (key.type == KeyType.r1) { 343 | return keyToString(key, 'R1', 'PVT_R1_'); 344 | } else if (key.type == KeyType.k1) { 345 | return keyToString(key, 'K1', 'PVT_K1_'); 346 | } else { 347 | throw 'unrecognized private key format'; 348 | } 349 | } 350 | 351 | /// Convert key in `s` to binary form */ 352 | IKey stringToSignature(String s) { 353 | if (s.substring(0, 7) == 'SIG_K1_') { 354 | return stringToKey(s.substring(7), KeyType.k1, signatureDataSize, 'K1'); 355 | } else if (s.substring(0, 7) == 'SIG_R1_') { 356 | return stringToKey(s.substring(7), KeyType.r1, signatureDataSize, 'R1'); 357 | } else { 358 | throw 'unrecognized signature format'; 359 | } 360 | } 361 | 362 | /// Convert `signature` to string (base-58) form */ 363 | String signatureToString(IKey signature) { 364 | if (signature.type == KeyType.k1) { 365 | return keyToString(signature, 'K1', 'SIG_K1_'); 366 | } else if (signature.type == KeyType.r1) { 367 | return keyToString(signature, 'R1', 'SIG_R1_'); 368 | } else { 369 | throw 'unrecognized signature format'; 370 | } 371 | } 372 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: eosdart 2 | description: EOSIO-based blockchain RPC API client in Dart language 3 | version: 0.4.10 4 | homepage: https://github.com/primes-network/eosdart 5 | 6 | environment: 7 | sdk: ">=2.12.0 <3.0.0" 8 | 9 | dependencies: 10 | http: ^0.13.4 11 | json_annotation: ^4.3.0 12 | pointycastle: ^3.3.5 13 | eosdart_ecc: ^0.4.4 14 | # path: ^1.4.1 15 | 16 | dev_dependencies: 17 | test: ^1.19.2 18 | build_runner: ^2.1.4 19 | json_serializable: ^6.0.1 20 | -------------------------------------------------------------------------------- /test/eosdart_test.dart: -------------------------------------------------------------------------------- 1 | import 'dart:typed_data'; 2 | import 'package:eosdart/eosdart.dart'; 3 | import 'package:test/test.dart'; 4 | 5 | void main() { 6 | const verbose = false; 7 | group('public keys', () { 8 | test('serialize k1 old style', () { 9 | final keystring = 'EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV'; 10 | final sb = new SerialBuffer(new Uint8List(0)); 11 | sb.pushPublicKey(keystring); 12 | final serialized = sb.asUint8List(); 13 | 14 | if(verbose) { 15 | print("keystring: $keystring"); 16 | print("serialized: $serialized\n"+" ${arrayToHex(serialized)}"); 17 | } 18 | expect(serialized, 19 | [0, 2, 192, 222, 210, 188, 31, 19, 5, 251, 15, 170, 197, 230, 192, 62, 20 | 227, 161, 146, 66, 52, 152, 84, 39, 182, 22, 124, 165, 105, 209, 61, 21 | 244, 53, 207]); 22 | }); 23 | test('serialize k1 new style', () { 24 | final keystring = 'PUB_K1_6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5BoDq63'; 25 | final sb = new SerialBuffer(new Uint8List(0)); 26 | sb.pushPublicKey(keystring); 27 | final serialized = sb.asUint8List(); 28 | 29 | if(verbose) { 30 | print("keystring: $keystring"); 31 | print("serialized: $serialized\n"+" ${arrayToHex(serialized)}"); 32 | } 33 | expect(serialized, 34 | [0, 2, 192, 222, 210, 188, 31, 19, 5, 251, 15, 170, 197, 230, 192, 62, 35 | 227, 161, 146, 66, 52, 152, 84, 39, 182, 22, 124, 165, 105, 209, 61, 36 | 244, 53, 207]); 37 | }); 38 | test('deserialize k1 new style', () { 39 | final serialized = Uint8List.fromList([0, 2, 192, 222, 210, 188, 31, 19, 40 | 5, 251, 15, 170, 197, 230, 192, 62, 227, 161, 146, 66, 52, 152, 84, 39, 41 | 182, 22, 124, 165, 105, 209, 61, 244, 53, 207]); 42 | final sb = new SerialBuffer(serialized); 43 | final keystring = sb.getPublicKey(); 44 | 45 | if(verbose) { 46 | print("keystring: $keystring"); 47 | print("serialized: $serialized\n"+" ${arrayToHex(serialized)}"); 48 | } 49 | expect(keystring, 'PUB_K1_6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5BoDq63'); 50 | }); 51 | test('serialize r1 new style', () { 52 | final keystring = 'PUB_R1_6eMzJfDVWvzMTYAUWQ95JcpoY8vFL62pTFm6spim25n5wqtVWP'; 53 | final sb = new SerialBuffer(new Uint8List(0)); 54 | sb.pushPublicKey(keystring); 55 | final serialized = sb.asUint8List(); 56 | 57 | if(verbose) { 58 | print("keystring: $keystring"); 59 | print("serialized: $serialized\n"+" ${arrayToHex(serialized)}"); 60 | } 61 | expect(serialized, 62 | [1, 2, 231, 80, 174, 4, 190, 33, 189, 1, 48, 165, 223, 203, 242, 63 | 125, 16, 95, 97, 223, 20, 206, 120, 17, 207, 107, 49, 24, 30, 64 | 7, 140, 39, 8, 36]); 65 | }); 66 | test('deserialize r1 new style', () { 67 | final serialized = Uint8List.fromList( 68 | [1, 2, 231, 80, 174, 4, 190, 33, 189, 1, 48, 165, 223, 203, 242, 69 | 125, 16, 95, 97, 223, 20, 206, 120, 17, 207, 107, 49, 24, 30, 70 | 7, 140, 39, 8, 36]); 71 | final sb = new SerialBuffer(serialized); 72 | final keystring = sb.getPublicKey(); 73 | 74 | if(verbose) { 75 | print("keystring: $keystring"); 76 | print("serialized: $serialized\n"+" ${arrayToHex(serialized)}"); 77 | } 78 | expect(keystring, 'PUB_R1_6eMzJfDVWvzMTYAUWQ95JcpoY8vFL62pTFm6spim25n5wqtVWP'); 79 | }); 80 | 81 | }); 82 | 83 | group('private keys', () { 84 | test('serialize k1 old style', () { 85 | final keystring = '5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3'; 86 | final sb = new SerialBuffer(new Uint8List(0)); 87 | sb.pushPrivateKey(keystring); 88 | final serialized = sb.asUint8List(); 89 | 90 | if(verbose) { 91 | print("keystring: $keystring"); 92 | print("serialized: $serialized\n"+" ${arrayToHex(serialized)}"); 93 | } 94 | expect(serialized, 95 | [0, 210, 101, 63, 247, 203, 178, 216, 255, 18, 154, 194, 126, 245, 96 | 120, 28, 230, 139, 37, 88, 196, 26, 116, 175, 31, 45, 220, 166, 53, 97 | 203, 238, 240, 125]); 98 | }); 99 | test('serialize k1 new style', () { 100 | final keystring = 'PVT_K1_2bfGi9rYsXQSXXTvJbDAPhHLQUojjaNLomdm3cEJ1XTzMqUt3V'; 101 | final sb = new SerialBuffer(new Uint8List(0)); 102 | sb.pushPrivateKey(keystring); 103 | final serialized = sb.asUint8List(); 104 | 105 | if(verbose) { 106 | print("keystring: $keystring"); 107 | print("serialized: $serialized\n"+" ${arrayToHex(serialized)}"); 108 | } 109 | expect(serialized, 110 | [0, 210, 101, 63, 247, 203, 178, 216, 255, 18, 154, 194, 126, 245, 111 | 120, 28, 230, 139, 37, 88, 196, 26, 116, 175, 31, 45, 220, 166, 53, 112 | 203, 238, 240, 125]); 113 | }); 114 | test('deserialize k1 new style', () { 115 | final serialized = Uint8List.fromList([0, 210, 101, 63, 247, 203, 178, 116 | 216, 255, 18, 154, 194, 126, 245, 120, 28, 230, 139, 37, 88, 196, 117 | 26, 116, 175, 31, 45, 220, 166, 53, 203, 238, 240, 125]); 118 | final sb = new SerialBuffer(serialized); 119 | final keystring = sb.getPrivateKey(); 120 | 121 | if(verbose) { 122 | print("keystring: $keystring"); 123 | print("serialized: $serialized\n"+" ${arrayToHex(serialized)}"); 124 | } 125 | expect(keystring, 'PVT_K1_2bfGi9rYsXQSXXTvJbDAPhHLQUojjaNLomdm3cEJ1XTzMqUt3V'); 126 | }); 127 | test('serialize r1 new style', () { 128 | final keystring = 'PVT_R1_2JrJRQXEagWobhJbHWtP11muTWi5pgCJ6uXWhGKd2KcFBGF7mT'; 129 | final sb = new SerialBuffer(new Uint8List(0)); 130 | sb.pushPrivateKey(keystring); 131 | final serialized = sb.asUint8List(); 132 | 133 | if(verbose) { 134 | print("keystring: $keystring"); 135 | print("serialized: $serialized\n"+" ${arrayToHex(serialized)}"); 136 | } 137 | expect(serialized, 138 | [1, 172, 58, 10, 48, 178, 188, 37, 15, 234, 129, 216, 243, 182, 139 | 68, 115, 41, 18, 206, 91, 223, 230, 199, 84, 66, 41, 110, 159, 140 | 117, 45, 189, 67, 43]); 141 | }); 142 | test('deserialize r1 new style', () { 143 | final serialized = Uint8List.fromList( 144 | [1, 172, 58, 10, 48, 178, 188, 37, 15, 234, 129, 216, 243, 182, 145 | 68, 115, 41, 18, 206, 91, 223, 230, 199, 84, 66, 41, 110, 159, 146 | 117, 45, 189, 67, 43]); 147 | final sb = new SerialBuffer(serialized); 148 | final keystring = sb.getPrivateKey(); 149 | 150 | if(verbose) { 151 | print("keystring: $keystring"); 152 | print("serialized: $serialized\n"+" ${arrayToHex(serialized)}"); 153 | } 154 | expect(keystring, 'PVT_R1_2JrJRQXEagWobhJbHWtP11muTWi5pgCJ6uXWhGKd2KcFBGF7mT'); 155 | }); 156 | 157 | }); 158 | group('PR#47', () { 159 | test('roundtrip negative bignum', () { 160 | final testnumber = '-123456789'; 161 | final serialized = signedDecimalToBinary(testnumber.length, testnumber); 162 | print("serialized: $serialized\n"+" ${arrayToHex(serialized)}"); 163 | final number = signedBinaryToDecimal(serialized); 164 | expect(number, testnumber); 165 | }); 166 | }); 167 | group('EOS Client', () { 168 | late EOSClient client; 169 | 170 | setUp(() { 171 | client = EOSClient('https://eos.greymass.com', 'v1'); 172 | }); 173 | 174 | test('Get Info', () { 175 | client.getInfo().then((NodeInfo nodeInfo) { 176 | expect(nodeInfo.headBlockNum! > 0, isTrue); 177 | }); 178 | }); 179 | 180 | test('Get Abi', () { 181 | client.getAbi('eosio.token').then((AbiResp abi) { 182 | expect(abi.accountName, equals('eosio.token')); 183 | }); 184 | }); 185 | 186 | test('Get Raw Abi', () { 187 | client.getRawAbi('eosio.token').then((AbiResp abi) { 188 | expect(abi.accountName, equals('eosio.token')); 189 | expect(abi.codeHash, 190 | '01bd013c4f8be142b9cadf511f007c6ac201c068d529f01ed5661803c575befa'); 191 | expect(abi.abiHash, 192 | 'f8f677996a8ca68388bc41cf55e727949c161b624a47e497e3b2f71a0e635dad'); 193 | expect(abi.abi, isNotNull); 194 | }); 195 | }); 196 | 197 | test('Get Raw code and Abi', () { 198 | client.getRawCodeAndAbi('eosio.token').then((AbiResp abi) { 199 | expect(abi.accountName, equals('eosio.token')); 200 | expect(abi.wasm!.length > 0, isTrue); 201 | expect(abi.abi, isNotNull); 202 | }); 203 | }); 204 | 205 | test('Get Block', () { 206 | client.getBlock('43743575').then((Block block) { 207 | expect(block.blockNum! > 0, isTrue); 208 | expect(block.producer, 'zbeosbp11111'); 209 | expect(block.confirmed, 0); 210 | expect(block.transactionMRoot, 211 | '8fb685526d58dfabd05989b45b8576197acc1be59d753bb396386d5d718f9fa9'); 212 | expect(block.transactions!.length > 10, isTrue); 213 | }); 214 | }); 215 | 216 | test('Get Account', () { 217 | client.getAccount('eosio.stake').then((Account account) { 218 | expect(account.accountName, equals('eosio.stake')); 219 | expect(account.coreLiquidBalance!.amount! > 0, isTrue); 220 | }); 221 | }); 222 | 223 | test('Get currency balance', () { 224 | client 225 | .getCurrencyBalance('parslseed123', 'newdexpocket', 'SEED') 226 | .then((List tokens) { 227 | expect(tokens.length > 0, isTrue); 228 | expect(tokens[0].amount! > 0, isTrue); 229 | expect(tokens[0].currency, 'SEED'); 230 | }); 231 | }); 232 | 233 | test('Get Transaction', () { 234 | client 235 | .getTransaction( 236 | '8ca0fea82370a2dbbf2c4bd1026bf9fd98a57685bee3672c4ddbbc9be21de984') 237 | .then((TransactionBlock transaction) { 238 | expect(transaction.blockNum, 43743575); 239 | expect(transaction.trx!.receipt!.cpuUsageUs, 132); 240 | expect(transaction.trx!.receipt!.netUsageWords, 0); 241 | expect(transaction.traces!.length, 2); 242 | expect(transaction.traces![0].receipt!.receiver, 'trustdicelog'); 243 | expect(transaction.traces![0].inlineTraces!.length, 1); 244 | expect(transaction.traces![0].inlineTraces![0].receipt!.receiver, 245 | 'ge4tcnrxgyge'); 246 | }); 247 | }); 248 | }); 249 | } 250 | -------------------------------------------------------------------------------- /test/models/abi_test.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | import 'dart:convert'; 3 | 4 | import 'package:eosdart/eosdart.dart'; 5 | import 'package:test/test.dart'; 6 | 7 | void main() { 8 | group('EOS Model', () { 9 | late String abiStr; 10 | 11 | setUp(() { 12 | abiStr = File('./test/models/abi_test_data.json').readAsStringSync(); 13 | }); 14 | 15 | test('Block to JSON', () { 16 | Map nodeInfoJson = json.decode(abiStr); 17 | AbiResp abi = AbiResp.fromJson(nodeInfoJson); 18 | 19 | expect(abi.accountName, 'eosio.token'); 20 | expect(abi.codeHash, 21 | '01bd013c4f8be142b9cadf511f007c6ac201c068d529f01ed5661803c575befa'); 22 | expect(abi.abiHash, 23 | 'f8f677996a8ca68388bc41cf55e727949c161b624a47e497e3b2f71a0e635dad'); 24 | print(abi.abi!.actions); 25 | // expect(abi.abi, 26 | // 'DmVvc2lvOjphYmkvMS4wAQxhY2NvdW50X25hbWUEbmFtZQcIdHJhbnNmZXIABARmcm9tDGFjY291bnRfbmFtZQJ0bwxhY2NvdW50X25hbWUIcXVhbnRpdHkFYXNzZXQEbWVtbwZzdHJpbmcGY3JlYXRlAAIGaXNzdWVyDGFjY291bnRfbmFtZQ5tYXhpbXVtX3N1cHBseQVhc3NldAVpc3N1ZQADAnRvDGFjY291bnRfbmFtZQhxdWFudGl0eQVhc3NldARtZW1vBnN0cmluZwZyZXRpcmUAAghxdWFudGl0eQVhc3NldARtZW1vBnN0cmluZwVjbG9zZQACBW93bmVyDGFjY291bnRfbmFtZQZzeW1ib2wGc3ltYm9sB2FjY291bnQAAQdiYWxhbmNlBWFzc2V0DmN1cnJlbmN5X3N0YXRzAAMGc3VwcGx5BWFzc2V0Cm1heF9zdXBwbHkFYXNzZXQGaXNzdWVyDGFjY291bnRfbmFtZQUAAABXLTzNzQh0cmFuc2ZlcucFIyMgVHJhbnNmZXIgVGVybXMgJiBDb25kaXRpb25zCgpJLCB7e2Zyb219fSwgY2VydGlmeSB0aGUgZm9sbG93aW5nIHRvIGJlIHRydWUgdG8gdGhlIGJlc3Qgb2YgbXkga25vd2xlZGdlOgoKMS4gSSBjZXJ0aWZ5IHRoYXQge3txdWFudGl0eX19IGlzIG5vdCB0aGUgcHJvY2VlZHMgb2YgZnJhdWR1bGVudCBvciB2aW9sZW50IGFjdGl2aXRpZXMuCjIuIEkgY2VydGlmeSB0aGF0LCB0byB0aGUgYmVzdCBvZiBteSBrbm93bGVkZ2UsIHt7dG99fSBpcyBub3Qgc3VwcG9ydGluZyBpbml0aWF0aW9uIG9mIHZpb2xlbmNlIGFnYWluc3Qgb3RoZXJzLgozLiBJIGhhdmUgZGlzY2xvc2VkIGFueSBjb250cmFjdHVhbCB0ZXJtcyAmIGNvbmRpdGlvbnMgd2l0aCByZXNwZWN0IHRvIHt7cXVhbnRpdHl9fSB0byB7e3RvfX0uCgpJIHVuZGVyc3RhbmQgdGhhdCBmdW5kcyB0cmFuc2ZlcnMgYXJlIG5vdCByZXZlcnNpYmxlIGFmdGVyIHRoZSB7e3RyYW5zYWN0aW9uLmRlbGF5fX0gc2Vjb25kcyBvciBvdGhlciBkZWxheSBhcyBjb25maWd1cmVkIGJ5IHt7ZnJvbX19J3MgcGVybWlzc2lvbnMuCgpJZiB0aGlzIGFjdGlvbiBmYWlscyB0byBiZSBpcnJldmVyc2libHkgY29uZmlybWVkIGFmdGVyIHJlY2VpdmluZyBnb29kcyBvciBzZXJ2aWNlcyBmcm9tICd7e3RvfX0nLCBJIGFncmVlIHRvIGVpdGhlciByZXR1cm4gdGhlIGdvb2RzIG9yIHNlcnZpY2VzIG9yIHJlc2VuZCB7e3F1YW50aXR5fX0gaW4gYSB0aW1lbHkgbWFubmVyLgoAAAAAAKUxdgVpc3N1ZQAAAAAAqGzURQZjcmVhdGUAAAAAAKjrsroGcmV0aXJlAAAAAAAAhWlEBWNsb3NlAAIAAAA4T00RMgNpNjQBCGN1cnJlbmN5AQZ1aW50NjQHYWNjb3VudAAAAAAAkE3GA2k2NAEIY3VycmVuY3kBBnVpbnQ2NA5jdXJyZW5jeV9zdGF0cwAAAA==='); 27 | expect(abi.wasm, isEmpty); 28 | }); 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /test/models/abi_test_data.json: -------------------------------------------------------------------------------- 1 | { 2 | "account_name": "eosio.token", 3 | "code_hash": "01bd013c4f8be142b9cadf511f007c6ac201c068d529f01ed5661803c575befa", 4 | "abi_hash": "f8f677996a8ca68388bc41cf55e727949c161b624a47e497e3b2f71a0e635dad", 5 | "wasm": "", 6 | "abi": "DmVvc2lvOjphYmkvMS4wAQxhY2NvdW50X25hbWUEbmFtZQcIdHJhbnNmZXIABARmcm9tDGFjY291bnRfbmFtZQJ0bwxhY2NvdW50X25hbWUIcXVhbnRpdHkFYXNzZXQEbWVtbwZzdHJpbmcGY3JlYXRlAAIGaXNzdWVyDGFjY291bnRfbmFtZQ5tYXhpbXVtX3N1cHBseQVhc3NldAVpc3N1ZQADAnRvDGFjY291bnRfbmFtZQhxdWFudGl0eQVhc3NldARtZW1vBnN0cmluZwZyZXRpcmUAAghxdWFudGl0eQVhc3NldARtZW1vBnN0cmluZwVjbG9zZQACBW93bmVyDGFjY291bnRfbmFtZQZzeW1ib2wGc3ltYm9sB2FjY291bnQAAQdiYWxhbmNlBWFzc2V0DmN1cnJlbmN5X3N0YXRzAAMGc3VwcGx5BWFzc2V0Cm1heF9zdXBwbHkFYXNzZXQGaXNzdWVyDGFjY291bnRfbmFtZQUAAABXLTzNzQh0cmFuc2ZlcucFIyMgVHJhbnNmZXIgVGVybXMgJiBDb25kaXRpb25zCgpJLCB7e2Zyb219fSwgY2VydGlmeSB0aGUgZm9sbG93aW5nIHRvIGJlIHRydWUgdG8gdGhlIGJlc3Qgb2YgbXkga25vd2xlZGdlOgoKMS4gSSBjZXJ0aWZ5IHRoYXQge3txdWFudGl0eX19IGlzIG5vdCB0aGUgcHJvY2VlZHMgb2YgZnJhdWR1bGVudCBvciB2aW9sZW50IGFjdGl2aXRpZXMuCjIuIEkgY2VydGlmeSB0aGF0LCB0byB0aGUgYmVzdCBvZiBteSBrbm93bGVkZ2UsIHt7dG99fSBpcyBub3Qgc3VwcG9ydGluZyBpbml0aWF0aW9uIG9mIHZpb2xlbmNlIGFnYWluc3Qgb3RoZXJzLgozLiBJIGhhdmUgZGlzY2xvc2VkIGFueSBjb250cmFjdHVhbCB0ZXJtcyAmIGNvbmRpdGlvbnMgd2l0aCByZXNwZWN0IHRvIHt7cXVhbnRpdHl9fSB0byB7e3RvfX0uCgpJIHVuZGVyc3RhbmQgdGhhdCBmdW5kcyB0cmFuc2ZlcnMgYXJlIG5vdCByZXZlcnNpYmxlIGFmdGVyIHRoZSB7e3RyYW5zYWN0aW9uLmRlbGF5fX0gc2Vjb25kcyBvciBvdGhlciBkZWxheSBhcyBjb25maWd1cmVkIGJ5IHt7ZnJvbX19J3MgcGVybWlzc2lvbnMuCgpJZiB0aGlzIGFjdGlvbiBmYWlscyB0byBiZSBpcnJldmVyc2libHkgY29uZmlybWVkIGFmdGVyIHJlY2VpdmluZyBnb29kcyBvciBzZXJ2aWNlcyBmcm9tICd7e3RvfX0nLCBJIGFncmVlIHRvIGVpdGhlciByZXR1cm4gdGhlIGdvb2RzIG9yIHNlcnZpY2VzIG9yIHJlc2VuZCB7e3F1YW50aXR5fX0gaW4gYSB0aW1lbHkgbWFubmVyLgoAAAAAAKUxdgVpc3N1ZQAAAAAAqGzURQZjcmVhdGUAAAAAAKjrsroGcmV0aXJlAAAAAAAAhWlEBWNsb3NlAAIAAAA4T00RMgNpNjQBCGN1cnJlbmN5AQZ1aW50NjQHYWNjb3VudAAAAAAAkE3GA2k2NAEIY3VycmVuY3kBBnVpbnQ2NA5jdXJyZW5jeV9zdGF0cwAAAA===" 7 | } -------------------------------------------------------------------------------- /test/models/account_test.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | import 'dart:convert'; 3 | 4 | import 'package:eosdart/eosdart.dart'; 5 | import 'package:test/test.dart'; 6 | 7 | void main() { 8 | group('EOS Model', () { 9 | late String accountStr; 10 | 11 | setUp(() { 12 | accountStr = 13 | File('./test/models/account_test_data.json').readAsStringSync(); 14 | }); 15 | 16 | test('Account to JSON', () { 17 | Map accountJson = json.decode(accountStr); 18 | Account account = Account.fromJson(accountJson); 19 | 20 | expect(account.accountName, 'binancecold1'); 21 | expect(account.headBlockNum, 43498422); 22 | expect(account.headBlockTime, DateTime(2019, 2, 18, 22, 54, 16, 500)); 23 | expect(account.privileged, false); 24 | expect(account.lastCodeUpdate, DateTime(1970, 1, 1)); 25 | expect(account.created, DateTime(2018, 11, 14, 6, 58)); 26 | expect(account.coreLiquidBalance!.amount, 49254569.1575); 27 | expect(account.coreLiquidBalance!.currency, 'EOS'); 28 | expect(account.ramQuota, 20683); 29 | expect(account.netWeight, 1000500); 30 | expect(account.cpuWeight, 1001500); 31 | expect(account.netLimit!.used, 129); 32 | expect(account.netLimit!.available, 8344411498); 33 | expect(account.netLimit!.max, 8344545345); 34 | expect(account.ramUsage, 3686); 35 | expect(account.permissions, isList); 36 | expect(account.permissions!.length, 2); 37 | expect(account.permissions![0].permName, 'active'); 38 | expect(account.permissions![0].requiredAuth!.threshold, 1); 39 | expect(account.permissions![0].requiredAuth!.keys, isList); 40 | expect(account.permissions![0].requiredAuth!.keys!.length, 1); 41 | expect(account.permissions![0].requiredAuth!.keys![0].key, 42 | 'EOS5GZ7R4BsApfxKcSbHeBEeFavsu9b75ooXM6pf5fo5G4ZbSWBMX'); 43 | expect(account.permissions![0].requiredAuth!.keys![0].weight, 1); 44 | expect(account.totalResources!.owner, 'binancecold1'); 45 | expect(account.totalResources!.netWeight!.amount, 100.05); 46 | expect(account.totalResources!.netWeight!.currency, 'EOS'); 47 | expect(account.selfDelegatedBandwidth!.from, 'binancecold1'); 48 | expect(account.selfDelegatedBandwidth!.cpuWeight!.amount, 100.0); 49 | expect(account.refundRequest!.owner, 'binancecold1'); 50 | expect(account.refundRequest!.netAmount!.amount, 35.6); 51 | expect(account.voterInfo!.staked, 2000000); 52 | }); 53 | }); 54 | } 55 | -------------------------------------------------------------------------------- /test/models/account_test_data.json: -------------------------------------------------------------------------------- 1 | { 2 | "account_name": "binancecold1", 3 | "head_block_num": 43498422, 4 | "head_block_time": "2019-02-18T22:54:16.500", 5 | "privileged": false, 6 | "last_code_update": "1970-01-01T00:00:00.000", 7 | "created": "2018-11-14T06:58:00.000", 8 | "core_liquid_balance": "49254569.1575 EOS", 9 | "ram_quota": 20683, 10 | "net_weight": 1000500, 11 | "cpu_weight": 1001500, 12 | "net_limit": { 13 | "used": 129, 14 | "available": "8344411498", 15 | "max": "8344545345" 16 | }, 17 | "cpu_limit": { 18 | "used": 291, 19 | "available": 13431000, 20 | "max": 13431291 21 | }, 22 | "ram_usage": 3686, 23 | "permissions": [ 24 | { 25 | "perm_name": "active", 26 | "parent": "owner", 27 | "required_auth": { 28 | "threshold": 1, 29 | "keys": [ 30 | { 31 | "key": "EOS5GZ7R4BsApfxKcSbHeBEeFavsu9b75ooXM6pf5fo5G4ZbSWBMX", 32 | "weight": 1 33 | } 34 | ], 35 | "accounts": [], 36 | "waits": [] 37 | } 38 | }, 39 | { 40 | "perm_name": "owner", 41 | "parent": "", 42 | "required_auth": { 43 | "threshold": 1, 44 | "keys": [ 45 | { 46 | "key": "EOS5GZ7R4BsApfxKcSbHeBEeFavsu9b75ooXM6pf5fo5G4ZbSWBMX", 47 | "weight": 1 48 | } 49 | ], 50 | "accounts": [], 51 | "waits": [] 52 | } 53 | } 54 | ], 55 | "total_resources": { 56 | "owner": "binancecold1", 57 | "net_weight": "100.0500 EOS", 58 | "cpu_weight": "100.1500 EOS", 59 | "ram_bytes": 19283 60 | }, 61 | "self_delegated_bandwidth": { 62 | "from": "binancecold1", 63 | "to": "binancecold1", 64 | "net_weight": "100.0000 EOS", 65 | "cpu_weight": "100.0000 EOS" 66 | }, 67 | "refund_request": { 68 | "owner": "binancecold1", 69 | "request_time": "2019-01-31T17:45:26", 70 | "net_amount": "35.6000 EOS", 71 | "cpu_amount": "104.9000 EOS" 72 | }, 73 | "voter_info": { 74 | "owner": "binancecold1", 75 | "proxy": "", 76 | "producers": [], 77 | "staked": 2000000, 78 | "last_vote_weight": "0.00000000000000000", 79 | "proxied_vote_weight": "0.00000000000000000", 80 | "is_proxy": 0, 81 | "flags1": 0, 82 | "reserved2": 0, 83 | "reserved3": "0.0000 EOS" 84 | } 85 | } -------------------------------------------------------------------------------- /test/models/action_test.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | import 'dart:convert'; 3 | 4 | import 'package:eosdart/eosdart.dart'; 5 | import 'package:test/test.dart'; 6 | 7 | void main() { 8 | group('EOS Model', () { 9 | late String actionStr; 10 | 11 | setUp(() { 12 | actionStr = 13 | File('./test/models/action_test_data.json').readAsStringSync(); 14 | }); 15 | 16 | test('Action to JSON', () { 17 | Map actionJson = json.decode(actionStr); 18 | ActionBlock action = ActionBlock.fromJson(actionJson); 19 | 20 | expect(action.globalActionSeq, 4587073327); 21 | expect(action.accountActionSeq, 165); 22 | expect(action.actionTrace!.receipt!.receiveSequence, 159); 23 | expect(action.actionTrace!.action!.account, 'zosdiscounts'); 24 | expect( 25 | action.actionTrace!.action!.authorization![0].actor, 'airdropsdac3'); 26 | expect(action.actionTrace!.contextFree, false); 27 | expect(action.actionTrace!.blockNum, 40066073); 28 | }); 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /test/models/action_test_data.json: -------------------------------------------------------------------------------- 1 | { 2 | "global_action_seq": "4587073327", 3 | "account_action_seq": 165, 4 | "block_num": 40066073, 5 | "block_time": "2019-01-30T01:21:04.000", 6 | "action_trace": { 7 | "receipt": { 8 | "receiver": "arkisawesome", 9 | "act_digest": "70854861314c73c94501c6ef0124170e0d58e62991d560928aad1b9a5c09b328", 10 | "global_sequence": "4587073327", 11 | "recv_sequence": 159, 12 | "auth_sequence": [ 13 | [ 14 | "airdropsdac3", 15 | 209916 16 | ] 17 | ], 18 | "code_sequence": 1, 19 | "abi_sequence": 1 20 | }, 21 | "act": { 22 | "account": "zosdiscounts", 23 | "name": "transfer", 24 | "authorization": [ 25 | { 26 | "actor": "airdropsdac3", 27 | "permission": "airdrop" 28 | } 29 | ], 30 | "data": { 31 | "from": "airdropsdac3", 32 | "to": "arkisawesome", 33 | "quantity": "140.0000 ZOS", 34 | "memo": "Win 100,000 ZOS + 10 EOS!!! (1) Send 1 ZOS to zosresponses (2) Write a catchy slogan in the memo field (3) Checkout https://medium.com/@airdropsdac/zos-airdrop-claim-your-tokens-and-enter-to-win-100-000-zos-16e8713d55d7 for more info!" 35 | }, 36 | "hex_data": "309049b8d29bae33a024c58a1bece035c05c150000000000045a4f5300000000ea0157696e203130302c303030205a4f53202b20313020454f53212121202831292053656e642031205a4f5320746f207a6f73726573706f6e7365732028322920577269746520612063617463687920736c6f67616e20696e20746865206d656d6f206669656c642028332920436865636b6f75742068747470733a2f2f6d656469756d2e636f6d2f4061697264726f70736461632f7a6f732d61697264726f702d636c61696d2d796f75722d746f6b656e732d616e642d656e7465722d746f2d77696e2d3130302d3030302d7a6f732d31366538373133643535643720666f72206d6f726520696e666f21" 37 | }, 38 | "context_free": false, 39 | "elapsed": 14, 40 | "console": "", 41 | "trx_id": "8add9a4b84e9a9512dc06c1ff5b72ad341e0fbd277813d8511a9d7fa9529204a", 42 | "block_num": 40066073, 43 | "block_time": "2019-01-30T01:21:04.000", 44 | "producer_block_id": "02635c198d6d22a1668336542be1bc3a97b5554a01f009a6689a9ed369a1dd5a", 45 | "account_ram_deltas": [], 46 | "except": null, 47 | "inline_traces": [] 48 | } 49 | } -------------------------------------------------------------------------------- /test/models/block_header_state_test.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | import 'dart:convert'; 3 | 4 | import 'package:eosdart/eosdart.dart'; 5 | import 'package:test/test.dart'; 6 | 7 | void main() { 8 | group('EOS Model', () { 9 | late String stateStr; 10 | 11 | setUp(() { 12 | stateStr = File('./test/models/block_header_state_test_data.json') 13 | .readAsStringSync(); 14 | }); 15 | 16 | test('Block header state to JSON', () { 17 | Map stateJson = json.decode(stateStr); 18 | BlockHeaderState headerState = BlockHeaderState.fromJson(stateJson); 19 | 20 | expect(headerState.id, 21 | '02a5e504b8d20cd2b3c08ba623dfbb3f98b34a7e8c6cbba81e7b4e25382def4d'); 22 | expect(headerState.blockNum, 44426500); 23 | expect(headerState.header!.timestamp, 24 | DateTime(2019, 02, 24, 07, 55, 01, 500)); 25 | expect(headerState.header!.producer, 'starteosiobp'); 26 | expect(headerState.header!.confirmed, 0); 27 | expect(headerState.header!.previous, 28 | '02a5e503fa636e7a35d9fa04df9c2ab7860864acff3d835b6c1ec1259b7867e2'); 29 | expect(headerState.header!.transactionMRoot, 30 | '1553f3e25495670bfd8879b0e972575051d012cb2b7793db9d3ebeec126909b6'); 31 | expect(headerState.header!.actionMRoot, 32 | '1351f42a98c3877fd406c8ab0e0c45c43b2b8cd2ea1bc1a325353cc8efc76aa4'); 33 | expect(headerState.dposProposedIrreversibleBlocknum, 44426340); 34 | expect(headerState.dposIrreversibleBlocknum, 44426172); 35 | expect(headerState.pendingScheduleLibNum, 44118384); 36 | expect(headerState.pendingSchedule!.version, 703); 37 | expect(headerState.activeSchedule!.version, 703); 38 | expect(headerState.activeSchedule!.producers!.length > 10, isTrue); 39 | expect(headerState.activeSchedule!.producers![0].producerName, 40 | 'atticlabeosb'); 41 | expect(headerState.activeSchedule!.producers![0].blockSigningKey, 42 | 'EOS7PfA3A4UdfMu2wKbuXdbHn8EWAxbMnFoFWui4X2zsr2oPwdQJP'); 43 | expect(headerState.blockrootMerkle!.activeNodes!.length > 10, isTrue); 44 | expect(headerState.blockrootMerkle!.activeNodes![0], 45 | '02a5e503fa636e7a35d9fa04df9c2ab7860864acff3d835b6c1ec1259b7867e2'); 46 | expect(headerState.blockrootMerkle!.nodeCount, 44426499); 47 | expect(headerState.producerToLastProduced!.length > 10, isTrue); 48 | expect(headerState.producerToLastImpliedIrb!.length > 10, isTrue); 49 | expect(headerState.blockSigningKey, 50 | 'EOS4wZZXm994byKANLuwHD6tV3R3Mu3ktc41aSVXCBaGnXJZJ4pwF'); 51 | expect(headerState.confirmCount!.length > 10, isTrue); 52 | }); 53 | }); 54 | } 55 | -------------------------------------------------------------------------------- /test/models/block_header_state_test_data.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "02a5e504b8d20cd2b3c08ba623dfbb3f98b34a7e8c6cbba81e7b4e25382def4d", 3 | "block_num": 44426500, 4 | "header": { 5 | "timestamp": "2019-02-24T07:55:01.500", 6 | "producer": "starteosiobp", 7 | "confirmed": 0, 8 | "previous": "02a5e503fa636e7a35d9fa04df9c2ab7860864acff3d835b6c1ec1259b7867e2", 9 | "transaction_mroot": "1553f3e25495670bfd8879b0e972575051d012cb2b7793db9d3ebeec126909b6", 10 | "action_mroot": "1351f42a98c3877fd406c8ab0e0c45c43b2b8cd2ea1bc1a325353cc8efc76aa4", 11 | "schedule_version": 703, 12 | "header_extensions": [], 13 | "producer_signature": "SIG_K1_K8jtcYkonAVtHZGpAVPYAciNmSCXSfX1o1KUctFtygmzwy7NmgX38m2JHtexRacrCGVm8HoT46fQ6mC2j87CjuW7cWEDUo" 14 | }, 15 | "dpos_proposed_irreversible_blocknum": 44426340, 16 | "dpos_irreversible_blocknum": 44426172, 17 | "bft_irreversible_blocknum": 0, 18 | "pending_schedule_lib_num": 44118384, 19 | "pending_schedule_hash": "fc7a63f73bf5301a106dc50427202f1993b092addbeb74caf3e8387a048d5dce", 20 | "pending_schedule": { 21 | "version": 703, 22 | "producers": [] 23 | }, 24 | "active_schedule": { 25 | "version": 703, 26 | "producers": [ 27 | { 28 | "producer_name": "atticlabeosb", 29 | "block_signing_key": "EOS7PfA3A4UdfMu2wKbuXdbHn8EWAxbMnFoFWui4X2zsr2oPwdQJP" 30 | }, 31 | { 32 | "producer_name": "bitfinexeos1", 33 | "block_signing_key": "EOS4tkw7LgtURT3dvG3kQ4D1sg3aAtPDymmoatpuFkQMc7wzZdKxc" 34 | }, 35 | { 36 | "producer_name": "cochainworld", 37 | "block_signing_key": "EOS5QDSQyh96SmktA28dteEchc1QCVdqKYG4YVDHGGATMYxqy33wi" 38 | }, 39 | { 40 | "producer_name": "eos42freedom", 41 | "block_signing_key": "EOS4tw7vH62TcVtMgm2tjXzn9hTuHEBbGPUK2eos42ssY7ip4LTzu" 42 | }, 43 | { 44 | "producer_name": "eosauthority", 45 | "block_signing_key": "EOS4va3CTmAcAAXsT26T3EBWqYHgQLshyxsozYRgxWm9tjmy17pVV" 46 | }, 47 | { 48 | "producer_name": "eosbeijingbp", 49 | "block_signing_key": "EOS5dGpcEhwB4VEhhXEcqtZs9EQj5HeetuXDnsAGVHMXHAFdMjbdj" 50 | }, 51 | { 52 | "producer_name": "eosbixinboot", 53 | "block_signing_key": "EOS7QC1XfAtkYeLjbHQjcDWVqUsxuSJ3YRhNyG93VAv2u3uHopGVp" 54 | }, 55 | { 56 | "producer_name": "eoscanadacom", 57 | "block_signing_key": "EOS7eycxAbCtKyfoJc8uRZcmt1AmArjXcz8aonLUTzahk5rHc18NJ" 58 | }, 59 | { 60 | "producer_name": "eoscannonchn", 61 | "block_signing_key": "EOS73cTi9V7PNg4ujW5QzoTfRSdhH44MPiUJkUV6m3oGwj7RX7kML" 62 | }, 63 | { 64 | "producer_name": "eosflytomars", 65 | "block_signing_key": "EOS6Agpfp38bTyRjJDmB4Qb1EpQSq7wnEAsALXgXE7KFSzKjokkFD" 66 | }, 67 | { 68 | "producer_name": "eoshenzhenio", 69 | "block_signing_key": "EOS8EJrMphgHJx5EkHQ4ryodbvnocZEC1xp5T1FnRsT7XtzYA1FE7" 70 | }, 71 | { 72 | "producer_name": "eoshuobipool", 73 | "block_signing_key": "EOS5XKswW26cR5VQeDGwgNb5aixv1AMcKkdDNrC59KzNSBfnH6TR7" 74 | }, 75 | { 76 | "producer_name": "eosiosg11111", 77 | "block_signing_key": "EOS7zVBQMhV7dZ5zRQwBgDmmbFCHA6YcmwW6Dq5CePGpqLR1ZsVAc" 78 | }, 79 | { 80 | "producer_name": "eoslaomaocom", 81 | "block_signing_key": "EOS8QgURqo875qu3a8vgZ58qBeu2cTehe9zAWRfpdCXAQipicu1Fi" 82 | }, 83 | { 84 | "producer_name": "eosliquideos", 85 | "block_signing_key": "EOS4v1n2j5kXbCum8LLEc8zQLpeLK9rKVFmsUgLCWgMDN38P6PcrW" 86 | }, 87 | { 88 | "producer_name": "eosnewyorkio", 89 | "block_signing_key": "EOS6GVX8eUqC1gN1293B3ivCNbifbr1BT6gzTFaQBXzWH9QNKVM4X" 90 | }, 91 | { 92 | "producer_name": "eosriobrazil", 93 | "block_signing_key": "EOS7RioGoHQnhv2fJEiciP9Q7J8JgfJYFcyofVkmCqMop8Q1PzgqP" 94 | }, 95 | { 96 | "producer_name": "eosswedenorg", 97 | "block_signing_key": "EOS7SGSBsWhSob6TEric6u3TGodcc1uXFcqSrquJ3Etuqcbb3VnNY" 98 | }, 99 | { 100 | "producer_name": "jedaaaaaaaaa", 101 | "block_signing_key": "EOS6nB9Ar5sghWjqk27bszCiA9zxQtXZCaAaEkf2nwUm9iP5MEJTT" 102 | }, 103 | { 104 | "producer_name": "starteosiobp", 105 | "block_signing_key": "EOS4wZZXm994byKANLuwHD6tV3R3Mu3ktc41aSVXCBaGnXJZJ4pwF" 106 | }, 107 | { 108 | "producer_name": "zbeosbp11111", 109 | "block_signing_key": "EOS7rhgVPWWyfMqjSbNdndtCK8Gkza3xnDbUupsPLMZ6gjfQ4nX81" 110 | } 111 | ] 112 | }, 113 | "blockroot_merkle": { 114 | "_active_nodes": [ 115 | "02a5e503fa636e7a35d9fa04df9c2ab7860864acff3d835b6c1ec1259b7867e2", 116 | "be3c3ba0267523e0ccc02acfe114ffb73ab8558ea1a7281bf11e8ac434952c09", 117 | "bf48ef699813b4bc59e85a60fdb8cb0443131030ace6298d049223da276a9886", 118 | "6b22cdf303cf88fdd80d834c37a23d7aa5f2a7d731d6b7917661dda2c33ab7d1", 119 | "8e3711278530ce9e8f5eb727db2667ed605416f0dca913c9deff740f5b47a1fb", 120 | "c1f92f36f46723e3ee73dc277fdead5545ce999a7e796747233a81e1f609256a", 121 | "355075ea7d6fdbb7aa1739a43ee7ef837c2ecc29301dae398b3c6b197cf2b8f5", 122 | "78be23f7a6bc9831a46f995e30b5e412e694efcef0557364dcebd2a06be21631", 123 | "53b775e1cfad63224bda0cbe63c746383d929687540abb87ca338e03a8c22db3", 124 | "941b121bb4ff9a8c5746b5efd6630cb8011d53ec179a7e44357020d08ce66313", 125 | "e2be3eabd6080ca50923544c05c66ce9ebbdd616183bef5c8fe6d712c2c82cc8", 126 | "36c8843a98a39574386a47ab7798f37c6232161e575934061281b13aab0fbe45", 127 | "75a5d5084895186fc85a73a66181d8e84a45df65d3f857d35763ab6f8822ca1e" 128 | ], 129 | "_node_count": 44426499 130 | }, 131 | "producer_to_last_produced": [ 132 | [ 133 | "atticlabeosb", 134 | 44426280 135 | ], 136 | [ 137 | "bitfinexeos1", 138 | 44426292 139 | ], 140 | [ 141 | "cochainworld", 142 | 44426304 143 | ], 144 | [ 145 | "eos42freedom", 146 | 44426316 147 | ], 148 | [ 149 | "eosauthority", 150 | 44426328 151 | ], 152 | [ 153 | "eosbeijingbp", 154 | 44426340 155 | ], 156 | [ 157 | "eosbixinboot", 158 | 44426352 159 | ], 160 | [ 161 | "eoscanadacom", 162 | 44426364 163 | ], 164 | [ 165 | "eoscannonchn", 166 | 44426376 167 | ], 168 | [ 169 | "eosflytomars", 170 | 44426388 171 | ], 172 | [ 173 | "eoshenzhenio", 174 | 44426400 175 | ], 176 | [ 177 | "eoshuobipool", 178 | 44426412 179 | ], 180 | [ 181 | "eosiosg11111", 182 | 44426424 183 | ], 184 | [ 185 | "eoslaomaocom", 186 | 44426436 187 | ], 188 | [ 189 | "eosliquideos", 190 | 44426448 191 | ], 192 | [ 193 | "eosnewyorkio", 194 | 44426460 195 | ], 196 | [ 197 | "eosriobrazil", 198 | 44426472 199 | ], 200 | [ 201 | "eosswedenorg", 202 | 44426484 203 | ], 204 | [ 205 | "jedaaaaaaaaa", 206 | 44426496 207 | ], 208 | [ 209 | "starteosiobp", 210 | 44426500 211 | ], 212 | [ 213 | "zbeosbp11111", 214 | 44426268 215 | ] 216 | ], 217 | "producer_to_last_implied_irb": [ 218 | [ 219 | "atticlabeosb", 220 | 44426112 221 | ], 222 | [ 223 | "bitfinexeos1", 224 | 44426124 225 | ], 226 | [ 227 | "cochainworld", 228 | 44426136 229 | ], 230 | [ 231 | "eos42freedom", 232 | 44426148 233 | ], 234 | [ 235 | "eosauthority", 236 | 44426160 237 | ], 238 | [ 239 | "eosbeijingbp", 240 | 44426172 241 | ], 242 | [ 243 | "eosbixinboot", 244 | 44426184 245 | ], 246 | [ 247 | "eoscanadacom", 248 | 44426196 249 | ], 250 | [ 251 | "eoscannonchn", 252 | 44426208 253 | ], 254 | [ 255 | "eosflytomars", 256 | 44426220 257 | ], 258 | [ 259 | "eoshenzhenio", 260 | 44426232 261 | ], 262 | [ 263 | "eoshuobipool", 264 | 44426244 265 | ], 266 | [ 267 | "eosiosg11111", 268 | 44426256 269 | ], 270 | [ 271 | "eoslaomaocom", 272 | 44426268 273 | ], 274 | [ 275 | "eosliquideos", 276 | 44426280 277 | ], 278 | [ 279 | "eosnewyorkio", 280 | 44426292 281 | ], 282 | [ 283 | "eosriobrazil", 284 | 44426304 285 | ], 286 | [ 287 | "eosswedenorg", 288 | 44426316 289 | ], 290 | [ 291 | "jedaaaaaaaaa", 292 | 44426328 293 | ], 294 | [ 295 | "starteosiobp", 296 | 44426340 297 | ], 298 | [ 299 | "zbeosbp11111", 300 | 44426100 301 | ] 302 | ], 303 | "block_signing_key": "EOS4wZZXm994byKANLuwHD6tV3R3Mu3ktc41aSVXCBaGnXJZJ4pwF", 304 | "confirm_count": [ 305 | 1, 306 | 1, 307 | 1, 308 | 1, 309 | 1, 310 | 1, 311 | 1, 312 | 1, 313 | 1, 314 | 1, 315 | 1, 316 | 1, 317 | 2, 318 | 2, 319 | 2, 320 | 2, 321 | 2, 322 | 2, 323 | 2, 324 | 2, 325 | 2, 326 | 2, 327 | 2, 328 | 2, 329 | 3, 330 | 3, 331 | 3, 332 | 3, 333 | 3, 334 | 3, 335 | 3, 336 | 3, 337 | 3, 338 | 3, 339 | 3, 340 | 3, 341 | 4, 342 | 4, 343 | 4, 344 | 4, 345 | 4, 346 | 4, 347 | 4, 348 | 4, 349 | 4, 350 | 4, 351 | 4, 352 | 4, 353 | 5, 354 | 5, 355 | 5, 356 | 5, 357 | 5, 358 | 5, 359 | 5, 360 | 5, 361 | 5, 362 | 5, 363 | 5, 364 | 5, 365 | 6, 366 | 6, 367 | 6, 368 | 6, 369 | 6, 370 | 6, 371 | 6, 372 | 6, 373 | 6, 374 | 6, 375 | 6, 376 | 6, 377 | 7, 378 | 7, 379 | 7, 380 | 7, 381 | 7, 382 | 7, 383 | 7, 384 | 7, 385 | 7, 386 | 7, 387 | 7, 388 | 7, 389 | 8, 390 | 8, 391 | 8, 392 | 8, 393 | 8, 394 | 8, 395 | 8, 396 | 8, 397 | 8, 398 | 8, 399 | 8, 400 | 8, 401 | 9, 402 | 9, 403 | 9, 404 | 9, 405 | 9, 406 | 9, 407 | 9, 408 | 9, 409 | 9, 410 | 9, 411 | 9, 412 | 9, 413 | 10, 414 | 10, 415 | 10, 416 | 10, 417 | 10, 418 | 10, 419 | 10, 420 | 10, 421 | 10, 422 | 10, 423 | 10, 424 | 10, 425 | 11, 426 | 11, 427 | 11, 428 | 11, 429 | 11, 430 | 11, 431 | 11, 432 | 11, 433 | 11, 434 | 11, 435 | 11, 436 | 11, 437 | 12, 438 | 12, 439 | 12, 440 | 12, 441 | 12, 442 | 12, 443 | 12, 444 | 12, 445 | 12, 446 | 12, 447 | 12, 448 | 12, 449 | 13, 450 | 13, 451 | 13, 452 | 13, 453 | 13, 454 | 13, 455 | 13, 456 | 13, 457 | 13, 458 | 13, 459 | 13, 460 | 13, 461 | 14, 462 | 14, 463 | 14, 464 | 14 465 | ], 466 | "confirmations": [] 467 | } -------------------------------------------------------------------------------- /test/models/block_test.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | import 'dart:convert'; 3 | 4 | import 'package:eosdart/eosdart.dart'; 5 | import 'package:test/test.dart'; 6 | 7 | void main() { 8 | group('EOS Model', () { 9 | late String blockStr; 10 | 11 | setUp(() { 12 | blockStr = File('./test/models/block_test_data.json').readAsStringSync(); 13 | }); 14 | 15 | test('Block to JSON', () { 16 | Map nodeInfoJson = json.decode(blockStr); 17 | Block block = Block.fromJson(nodeInfoJson); 18 | 19 | expect(block.blockNum, 44072766); 20 | expect(block.producer, 'eosbeijingbp'); 21 | expect(block.id, 22 | '02a07f3e8e112558b58e7027ae614336cf77b45980df9693219f77e7a2d0349e'); 23 | expect(block.refBlockPrefix, 661687989); 24 | expect(block.transactions!.length > 10, isTrue); 25 | expect(block.transactions![0].status, 'executed'); 26 | expect(block.transactions![0].cpuUsageUs, 444); 27 | expect(block.transactions![0].netUsageWords, 0); 28 | }); 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /test/models/node_info_test.dart: -------------------------------------------------------------------------------- 1 | import 'dart:io'; 2 | import 'dart:convert'; 3 | 4 | import 'package:eosdart/eosdart.dart'; 5 | import 'package:test/test.dart'; 6 | 7 | void main() { 8 | group('EOS Model', () { 9 | late String nodeInfoStr; 10 | 11 | setUp(() { 12 | nodeInfoStr = 13 | File('./test/models/node_info_test_data.json').readAsStringSync(); 14 | }); 15 | 16 | test('NodeInfo to JSON', () { 17 | Map nodeInfoJson = json.decode(nodeInfoStr); 18 | NodeInfo nodeInfo = NodeInfo.fromJson(nodeInfoJson); 19 | 20 | expect(nodeInfo.serverVersion, '3fddb727'); 21 | expect(nodeInfo.chainId, 22 | 'aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906'); 23 | expect(nodeInfo.headBlockNum, 43567300); 24 | expect(nodeInfo.virtualBlockNetLimit, 1048576000); 25 | }); 26 | }); 27 | } 28 | -------------------------------------------------------------------------------- /test/models/node_info_test_data.json: -------------------------------------------------------------------------------- 1 | { 2 | "server_version": "3fddb727", 3 | "chain_id": "aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906", 4 | "head_block_num": 43567300, 5 | "last_irreversible_block_num": 43566965, 6 | "last_irreversible_block_id": "0298c7753b38d7c16490698129e1c4cd752298c725a2936ec333e6df8cef3614", 7 | "head_block_id": "0298c8c427cec934071f7d463cd0c5838d6a8b620f146269f0b0ec72070a5212", 8 | "head_block_time": "2019-02-19T08:29:05.000", 9 | "head_block_producer": "eoshuobipool", 10 | "virtual_block_cpu_limit": 200000000, 11 | "virtual_block_net_limit": 1048576000, 12 | "block_cpu_limit": 200000, 13 | "block_net_limit": 1048576, 14 | "server_version_string": "v1.6.0", 15 | "website": "https://eosflare.io" 16 | } -------------------------------------------------------------------------------- /test/models/transaction_test.dart: -------------------------------------------------------------------------------- 1 | import 'dart:convert'; 2 | import 'dart:io'; 3 | 4 | import 'package:eosdart/eosdart.dart'; 5 | import 'package:test/test.dart'; 6 | 7 | void main() { 8 | group('EOS Model', () { 9 | test('Transaction to JSON 1', () { 10 | String transactionStr = 11 | File('./test/models/transaction_test_data1.json').readAsStringSync(); 12 | Map transactionJson = json.decode(transactionStr); 13 | TransactionBlock transaction = TransactionBlock.fromJson(transactionJson); 14 | 15 | expect(transaction.id, 16 | '58d0e48048a03cff57af924ab606726793c31607a501112b088896fc0a0f70ec'); 17 | expect(transaction.trx!.receipt!.status, 'executed'); 18 | expect(transaction.trx!.receipt!.cpuUsageUs, 303); 19 | expect(transaction.trx!.receipt!.netUsageWords, 13); 20 | expect(transaction.blockTime, DateTime(2019, 2, 22, 6, 45, 7)); 21 | expect(transaction.blockNum, 44072766); 22 | expect(transaction.lastIrreversibleBlock, 44075018); 23 | expect(transaction.traces!.length, 1); 24 | expect(transaction.traces![0].receipt!.receiver, 'pretonarts11'); 25 | expect(transaction.traces![0].action!.account, 'pretonarts11'); 26 | expect(transaction.traces![0].action!.name, 'chooseserver'); 27 | expect(transaction.traces![0].producerBlockId, 28 | '02a07f3e8e112558b58e7027ae614336cf77b45980df9693219f77e7a2d0349e'); 29 | }); 30 | 31 | test('Transaction to JSON 2', () { 32 | String transactionStr = 33 | File('./test/models/transaction_test_data2.json').readAsStringSync(); 34 | Map transactionJson = json.decode(transactionStr); 35 | TransactionBlock transaction = TransactionBlock.fromJson(transactionJson); 36 | 37 | expect(transaction.id, 38 | '83875faeb054ba20b20f392418e3a0002c4bb1c36cc4e3fde15cbd0963da8a15'); 39 | expect(transaction.trx!.receipt!.status, 'executed'); 40 | expect(transaction.trx!.receipt!.cpuUsageUs, 444); 41 | expect(transaction.trx!.receipt!.netUsageWords, 0); 42 | expect(transaction.blockTime, DateTime(2019, 2, 22, 6, 45, 7)); 43 | expect(transaction.blockNum, 44072766); 44 | expect(transaction.lastIrreversibleBlock, 44075150); 45 | expect(transaction.traces!.length, 2); 46 | expect(transaction.traces![0].receipt!.receiver, 'xuxxxxxxxxxx'); 47 | expect(transaction.traces![0].action!.account, 'eosio.token'); 48 | expect(transaction.traces![0].action!.name, 'transfer'); 49 | expect(transaction.traces![0].producerBlockId, 50 | '02a07f3e8e112558b58e7027ae614336cf77b45980df9693219f77e7a2d0349e'); 51 | }); 52 | 53 | test('Transaction Commited', () { 54 | String transactionStr = 55 | File('./test/models/transaction_test_data3.json').readAsStringSync(); 56 | Map transactionJson = json.decode(transactionStr); 57 | TransactionCommitted transaction = 58 | TransactionCommitted.fromJson(transactionJson); 59 | 60 | expect(transaction.id, 61 | '91b55122107079cb4eafb165511bac77b8a790c3d4008c5f7cd7cfa1236c0876'); 62 | expect(transaction.processed!.blockNum, 729864); 63 | expect(transaction.processed!.blockTime, 64 | DateTime(2019, 11, 14, 8, 10, 37, 500)); 65 | expect(transaction.processed!.producerBlockId, null); 66 | expect(transaction.processed!.receipt!.status, 'executed'); 67 | expect(transaction.processed!.receipt!.cpuUsageUs, 384); 68 | expect(transaction.processed!.receipt!.netUsageWords, 16); 69 | expect(transaction.processed!.elapsed, 384); 70 | expect(transaction.processed!.netUsage, 128); 71 | expect(transaction.processed!.scheduled, false); 72 | expect(transaction.processed!.actionTraces!.isNotEmpty, true); 73 | expect( 74 | transaction.processed!.actionTraces!.first.action!.name, 'transfer'); 75 | expect(transaction.processed!.actionTraces!.first.action!.data.toString(), 76 | '{from: account1, to: account2, quantity: 1.00000000 EOS, memo: }'); 77 | expect(transaction.processed!.actionTraces!.first.action!.account, 78 | 'eosio.token'); 79 | }); 80 | }); 81 | } 82 | -------------------------------------------------------------------------------- /test/models/transaction_test_data1.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "58d0e48048a03cff57af924ab606726793c31607a501112b088896fc0a0f70ec", 3 | "trx": { 4 | "receipt": { 5 | "status": "executed", 6 | "cpu_usage_us": 303, 7 | "net_usage_words": 13, 8 | "trx": [ 9 | 1, 10 | { 11 | "signatures": [ 12 | "SIG_K1_KZERLy3K8xahj2Bzf94BPt9hfhMEpkbiB5aQtJT4Mgkgx3VkwqoanzXDfusutDeurd3YFXHYaJCwKfn9FPhyXayF9zjhjr" 13 | ], 14 | "compression": "none", 15 | "packed_context_free_data": "", 16 | "packed_trx": "a79a6f5cdf7db8a3423800000000011002ced74c9ad5ad70d5be0a2b4c694301e0bd63f64c96846200000000a8ed32320be0bd63f64c96846202313300" 17 | } 18 | ] 19 | }, 20 | "trx": { 21 | "expiration": "2019-02-22T06:45:59", 22 | "ref_block_num": 32223, 23 | "ref_block_prefix": 943891384, 24 | "max_net_usage_words": 0, 25 | "max_cpu_usage_ms": 0, 26 | "delay_sec": 0, 27 | "context_free_actions": [], 28 | "actions": [ 29 | { 30 | "account": "pretonarts11", 31 | "name": "chooseserver", 32 | "authorization": [ 33 | { 34 | "actor": "ge2dgnbqgiyy", 35 | "permission": "active" 36 | } 37 | ], 38 | "data": { 39 | "user": "ge2dgnbqgiyy", 40 | "serverid": "13" 41 | }, 42 | "hex_data": "e0bd63f64c968462023133" 43 | } 44 | ], 45 | "transaction_extensions": [], 46 | "signatures": [ 47 | "SIG_K1_KZERLy3K8xahj2Bzf94BPt9hfhMEpkbiB5aQtJT4Mgkgx3VkwqoanzXDfusutDeurd3YFXHYaJCwKfn9FPhyXayF9zjhjr" 48 | ], 49 | "context_free_data": [] 50 | } 51 | }, 52 | "block_time": "2019-02-22T06:45:07.000", 53 | "block_num": 44072766, 54 | "last_irreversible_block": 44075018, 55 | "traces": [ 56 | { 57 | "receipt": { 58 | "receiver": "pretonarts11", 59 | "act_digest": "4c8bb559328eb26fac4c771613560b335b725588e0295a2c19882a8088545b71", 60 | "global_sequence": "5193818719", 61 | "recv_sequence": 164884, 62 | "auth_sequence": [ 63 | [ 64 | "ge2dgnbqgiyy", 65 | 15474 66 | ] 67 | ], 68 | "code_sequence": 4, 69 | "abi_sequence": 2 70 | }, 71 | "act": { 72 | "account": "pretonarts11", 73 | "name": "chooseserver", 74 | "authorization": [ 75 | { 76 | "actor": "ge2dgnbqgiyy", 77 | "permission": "active" 78 | } 79 | ], 80 | "data": { 81 | "user": "ge2dgnbqgiyy", 82 | "serverid": "13" 83 | }, 84 | "hex_data": "e0bd63f64c968462023133" 85 | }, 86 | "context_free": false, 87 | "elapsed": 229, 88 | "console": "", 89 | "trx_id": "58d0e48048a03cff57af924ab606726793c31607a501112b088896fc0a0f70ec", 90 | "block_num": 44072766, 91 | "block_time": "2019-02-22T06:45:07.000", 92 | "producer_block_id": "02a07f3e8e112558b58e7027ae614336cf77b45980df9693219f77e7a2d0349e", 93 | "account_ram_deltas": [], 94 | "except": null, 95 | "inline_traces": [] 96 | } 97 | ] 98 | } -------------------------------------------------------------------------------- /test/models/transaction_test_data2.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "83875faeb054ba20b20f392418e3a0002c4bb1c36cc4e3fde15cbd0963da8a15", 3 | "trx": { 4 | "receipt": { 5 | "status": "executed", 6 | "cpu_usage_us": 444, 7 | "net_usage_words": 0, 8 | "trx": [ 9 | 0, 10 | "83875faeb054ba20b20f392418e3a0002c4bb1c36cc4e3fde15cbd0963da8a15" 11 | ] 12 | } 13 | }, 14 | "block_time": "2019-02-22T06:45:07.000", 15 | "block_num": 44072766, 16 | "last_irreversible_block": 44075150, 17 | "traces": [ 18 | { 19 | "receipt": { 20 | "receiver": "xuxxxxxxxxxx", 21 | "act_digest": "dba1dca5b663b7ff9d3ddde05d48d8eadb2ea04809895b338ba53369a330f267", 22 | "global_sequence": "5193818684", 23 | "recv_sequence": 918, 24 | "auth_sequence": [ 25 | [ 26 | "steamiobank1", 27 | 148685 28 | ] 29 | ], 30 | "code_sequence": 2, 31 | "abi_sequence": 2 32 | }, 33 | "act": { 34 | "account": "eosio.token", 35 | "name": "transfer", 36 | "authorization": [ 37 | { 38 | "actor": "steamiobank1", 39 | "permission": "active" 40 | } 41 | ], 42 | "data": { 43 | "from": "steamiobank1", 44 | "to": "xuxxxxxxxxxx", 45 | "quantity": "0.0005 EOS", 46 | "memo": "Bet id: 10629. Referral reward! [https://betsteam.io]" 47 | }, 48 | "hex_data": "10e034873a6954c6d07befbdf7debbee050000000000000004454f5300000000354265742069643a2031303632392e20526566657272616c2072657761726421205b68747470733a2f2f626574737465616d2e696f5d" 49 | }, 50 | "context_free": false, 51 | "elapsed": 5, 52 | "console": "", 53 | "trx_id": "83875faeb054ba20b20f392418e3a0002c4bb1c36cc4e3fde15cbd0963da8a15", 54 | "block_num": 44072766, 55 | "block_time": "2019-02-22T06:45:07.000", 56 | "producer_block_id": "02a07f3e8e112558b58e7027ae614336cf77b45980df9693219f77e7a2d0349e", 57 | "account_ram_deltas": [], 58 | "except": null, 59 | "inline_traces": [] 60 | }, 61 | { 62 | "receipt": { 63 | "receiver": "xellllllllll", 64 | "act_digest": "504c6756e40c2563c845cd53cc9761e56e746a3e403c06a4e0b98fed492d7cdf", 65 | "global_sequence": "5193818686", 66 | "recv_sequence": 2028, 67 | "auth_sequence": [ 68 | [ 69 | "steamiodice1", 70 | 82419 71 | ] 72 | ], 73 | "code_sequence": 27, 74 | "abi_sequence": 27 75 | }, 76 | "act": { 77 | "account": "steamiodice1", 78 | "name": "receipt", 79 | "authorization": [ 80 | { 81 | "actor": "steamiodice1", 82 | "permission": "active" 83 | } 84 | ], 85 | "data": { 86 | "bet_id": 10629, 87 | "player": "xellllllllll", 88 | "bet_amt": "0.5000 EOS", 89 | "payout": "0.0000 EOS", 90 | "seed": "0", 91 | "user_seed": "0", 92 | "roll_under": 50, 93 | "random_roll": 63 94 | }, 95 | "hex_data": "852900000000000010638c31c618a3ea881300000000000004454f5300000000000000000000000004454f53000000000130013032000000000000003f00000000000000" 96 | }, 97 | "context_free": false, 98 | "elapsed": 6, 99 | "console": "", 100 | "trx_id": "83875faeb054ba20b20f392418e3a0002c4bb1c36cc4e3fde15cbd0963da8a15", 101 | "block_num": 44072766, 102 | "block_time": "2019-02-22T06:45:07.000", 103 | "producer_block_id": "02a07f3e8e112558b58e7027ae614336cf77b45980df9693219f77e7a2d0349e", 104 | "account_ram_deltas": [], 105 | "except": null, 106 | "inline_traces": [] 107 | } 108 | ] 109 | } -------------------------------------------------------------------------------- /test/models/transaction_test_data3.json: -------------------------------------------------------------------------------- 1 | { 2 | "transaction_id": "91b55122107079cb4eafb165511bac77b8a790c3d4008c5f7cd7cfa1236c0876", 3 | "processed": { 4 | "id": "91b55122107079cb4eafb165511bac77b8a790c3d4008c5f7cd7cfa1236c0876", 5 | "block_num": 729864, 6 | "block_time": "2019-11-14T08:10:37.500", 7 | "producer_block_id": null, 8 | "receipt": { 9 | "status": "executed", 10 | "cpu_usage_us": 384, 11 | "net_usage_words": 16 12 | }, 13 | "elapsed": 384, 14 | "net_usage": 128, 15 | "scheduled": false, 16 | "action_traces": [ 17 | { 18 | "action_ordinal": 1, 19 | "creator_action_ordinal": 0, 20 | "closest_unnotified_ancestor_action_ordinal": 0, 21 | "receipt": { 22 | "receiver": "eosio.token", 23 | "act_digest": "ad1d4e88a882fd1e43ecdb44dc2fd70b2387146ed96aa88c6276c894e23eba1e", 24 | "global_sequence": 1302793, 25 | "recv_sequence": 650832, 26 | "auth_sequence": [ 27 | [ 28 | "account1", 29 | 106 30 | ] 31 | ], 32 | "code_sequence": 27, 33 | "abi_sequence": 1 34 | }, 35 | "receiver": "eosio.token", 36 | "act": { 37 | "account": "eosio.token", 38 | "name": "transfer", 39 | "authorization": [ 40 | { 41 | "actor": "account1", 42 | "permission": "active" 43 | } 44 | ], 45 | "data": { 46 | "from": "account1", 47 | "to": "account2", 48 | "quantity": "1.00000000 EOS", 49 | "memo": "" 50 | }, 51 | "hex_data": "0000d00a5ce5b6790000d00ae0abd23400e1f50500000000084353480000000000" 52 | }, 53 | "context_free": false, 54 | "elapsed": 155, 55 | "console": "", 56 | "trx_id": "91b55122107079cb4eafb165511bac77b8a790c3d4008c5f7cd7cfa1236c0876", 57 | "block_num": 729864, 58 | "block_time": "2019-11-14T08:10:37.500", 59 | "producer_block_id": null, 60 | "account_ram_deltas": [ 61 | { 62 | "account": "eosio.token", 63 | "delta": 878 64 | } 65 | ], 66 | "except": null, 67 | "error_code": null, 68 | "inline_traces": [ 69 | { 70 | "action_ordinal": 2, 71 | "creator_action_ordinal": 1, 72 | "closest_unnotified_ancestor_action_ordinal": 1, 73 | "receipt": { 74 | "receiver": "account1", 75 | "act_digest": "ad1d4e88a882fd1e43ecdb44dc2fd70b2387146ed96aa88c6276c894e23eba1e", 76 | "global_sequence": 1302794, 77 | "recv_sequence": 39, 78 | "auth_sequence": [ 79 | [ 80 | "account1", 81 | 107 82 | ] 83 | ], 84 | "code_sequence": 27, 85 | "abi_sequence": 1 86 | }, 87 | "receiver": "account1", 88 | "act": { 89 | "account": "eosio.token", 90 | "name": "transfer", 91 | "authorization": [ 92 | { 93 | "actor": "account1", 94 | "permission": "active" 95 | } 96 | ], 97 | "data": { 98 | "from": "account1", 99 | "to": "account2", 100 | "quantity": "1.00000000 EOS", 101 | "memo": "" 102 | }, 103 | "hex_data": "0000d00a5ce5b6790000d00ae0abd23400e1f50500000000084353480000000000" 104 | }, 105 | "context_free": false, 106 | "elapsed": 4, 107 | "console": "", 108 | "trx_id": "91b55122107079cb4eafb165511bac77b8a790c3d4008c5f7cd7cfa1236c0876", 109 | "block_num": 729864, 110 | "block_time": "2019-11-14T08:10:37.500", 111 | "producer_block_id": null, 112 | "account_ram_deltas": [], 113 | "except": null, 114 | "error_code": null, 115 | "inline_traces": [] 116 | }, 117 | { 118 | "action_ordinal": 3, 119 | "creator_action_ordinal": 1, 120 | "closest_unnotified_ancestor_action_ordinal": 1, 121 | "receipt": { 122 | "receiver": "account2", 123 | "act_digest": "ad1d4e88a882fd1e43ecdb44dc2fd70b2387146ed96aa88c6276c894e23eba1e", 124 | "global_sequence": 1302795, 125 | "recv_sequence": 37, 126 | "auth_sequence": [ 127 | [ 128 | "account1", 129 | 108 130 | ] 131 | ], 132 | "code_sequence": 27, 133 | "abi_sequence": 1 134 | }, 135 | "receiver": "account2", 136 | "act": { 137 | "account": "eosio.token", 138 | "name": "transfer", 139 | "authorization": [ 140 | { 141 | "actor": "account1", 142 | "permission": "active" 143 | } 144 | ], 145 | "data": { 146 | "from": "account1", 147 | "to": "account2", 148 | "quantity": "1.00000000 EOS", 149 | "memo": "" 150 | }, 151 | "hex_data": "0000d00a5ce5b6790000d00ae0abd23400e1f50500000000084353480000000000" 152 | }, 153 | "context_free": false, 154 | "elapsed": 6, 155 | "console": "", 156 | "trx_id": "91b55122107079cb4eafb165511bac77b8a790c3d4008c5f7cd7cfa1236c0876", 157 | "block_num": 729864, 158 | "block_time": "2019-11-14T08:10:37.500", 159 | "producer_block_id": null, 160 | "account_ram_deltas": [], 161 | "except": null, 162 | "error_code": null, 163 | "inline_traces": [] 164 | } 165 | ] 166 | } 167 | ], 168 | "account_ram_delta": null, 169 | "except": null, 170 | "error_code": null 171 | } 172 | } --------------------------------------------------------------------------------