1use ckb_jsonrpc_types::{
2    Alert, BannedAddr, Block, BlockNumber, BlockReward, BlockTemplate, BlockView, Capacity,
3    CellOutputWithOutPoint, CellTransaction, CellWithStatus, ChainInfo, Cycle, DryRunResult,
4    EpochNumber, EpochView, EstimateResult, HeaderView, LiveCell, LocalNode, LockHashIndexState,
5    OutPoint, PeerState, RemoteNode, Timestamp, Transaction, TransactionWithStatus, TxPoolInfo,
6    Uint64, Version,
7};
8use ckb_types::core::BlockNumber as CoreBlockNumber;
9use ckb_types::{packed::Byte32, prelude::*, H256};
10use simple_jsonrpc_client::*;
11
12jsonrpc!(pub struct Rpc {
13    pub fn get_block(&self, _hash: H256) -> Option<BlockView>;
14    pub fn get_fork_block(&self, _hash: H256) -> Option<BlockView>;
15    pub fn get_block_by_number(&self, _number: BlockNumber) -> Option<BlockView>;
16    pub fn get_header(&self, _hash: H256) -> Option<HeaderView>;
17    pub fn get_header_by_number(&self, _number: BlockNumber) -> Option<HeaderView>;
18    pub fn get_transaction(&self, _hash: H256) -> Option<TransactionWithStatus>;
19    pub fn get_block_hash(&self, _number: BlockNumber) -> Option<H256>;
20    pub fn get_tip_header(&self) -> HeaderView;
21    pub fn get_cells_by_lock_hash(
22        &self,
23        _lock_hash: H256,
24        _from: BlockNumber,
25        _to: BlockNumber
26    ) -> Vec<CellOutputWithOutPoint>;
27    pub fn get_live_cell(&self, _out_point: OutPoint, _with_data: bool) -> CellWithStatus;
28    pub fn get_tip_block_number(&self) -> BlockNumber;
29    pub fn get_current_epoch(&self) -> EpochView;
30    pub fn get_epoch_by_number(&self, number: EpochNumber) -> Option<EpochView>;
31
32    pub fn local_node_info(&self) -> LocalNode;
33    pub fn get_peers(&self) -> Vec<RemoteNode>;
34    pub fn get_banned_addresses(&self) -> Vec<BannedAddr>;
35    pub fn set_ban(
36        &self,
37        address: String,
38        command: String,
39        ban_time: Option<Timestamp>,
40        absolute: Option<bool>,
41        reason: Option<String>
42    ) -> ();
43
44    pub fn get_block_template(
45        &self,
46        bytes_limit: Option<Uint64>,
47        proposals_limit: Option<Uint64>,
48        max_version: Option<Version>
49    ) -> BlockTemplate;
50    pub fn submit_block(&self, _work_id: String, _data: Block) -> H256;
51    pub fn get_blockchain_info(&self) -> ChainInfo;
52    pub fn get_peers_state(&self) -> Vec<PeerState>;
53    pub fn compute_transaction_hash(&self, tx: Transaction) -> H256;
54    pub fn dry_run_transaction(&self, _tx: Transaction) -> DryRunResult;
55    pub fn send_transaction(&self, tx: Transaction) -> H256;
56    pub fn tx_pool_info(&self) -> TxPoolInfo;
57
58    pub fn send_alert(&self, alert: Alert) -> ();
59
60    pub fn add_node(&self, peer_id: String, address: String) -> ();
61    pub fn remove_node(&self, peer_id: String) -> ();
62    pub fn process_block_without_verify(&self, _data: Block) -> Option<H256>;
63
64    pub fn get_live_cells_by_lock_hash(&self, lock_hash: H256, page: Uint64, per_page: Uint64, reverse_order: Option<bool>) -> Vec<LiveCell>;
65    pub fn get_transactions_by_lock_hash(&self, lock_hash: H256, page: Uint64, per_page: Uint64, reverse_order: Option<bool>) -> Vec<CellTransaction>;
66    pub fn index_lock_hash(&self, lock_hash: H256, index_from: Option<BlockNumber>) -> LockHashIndexState;
67    pub fn deindex_lock_hash(&self, lock_hash: H256) -> ();
68    pub fn get_lock_hash_index_states(&self) -> Vec<LockHashIndexState>;
69    pub fn calculate_dao_maximum_withdraw(&self, _out_point: OutPoint, _hash: H256) -> Capacity;
70    pub fn get_cellbase_output_capacity_details(&self, _hash: H256) -> Option<BlockReward>;
71    pub fn broadcast_transaction(&self, tx: Transaction, cycles: Cycle) -> H256;
72    pub fn estimate_fee_rate(&self, expect_confirm_blocks: Uint64) -> EstimateResult;
73});
74
75pub struct RpcClient {
77    rpc: Rpc,
78}
79
80impl RpcClient {
81    pub fn new(uri: &str) -> Self {
82        let client = reqwest::blocking::Client::builder()
83            .gzip(true)
84            .timeout(::std::time::Duration::from_secs(30))
85            .build()
86            .expect("reqwest client");
87        Self {
88            rpc: Rpc::new(uri, client),
89        }
90    }
91
92    pub fn inner(&self) -> &Rpc {
93        &self.rpc
94    }
95
96    pub fn get_blockchain_info(&self) -> ChainInfo {
97        self.inner()
98            .get_blockchain_info()
99            .expect("rpc call get_blockchain_info")
100    }
101
102    pub fn send_transaction(&self, tx: Transaction) -> Byte32 {
103        self.inner()
104            .send_transaction(tx)
105            .expect("rpc call send_transaction")
106            .pack()
107    }
108
109    pub fn get_transaction(&self, tx_hash: H256) -> Option<TransactionWithStatus> {
110        self.inner()
111            .get_transaction(tx_hash)
112            .expect("rpc call get_transaction")
113    }
114
115    pub fn get_live_cells_by_lock_hash(
116        &self,
117        lock_hash: Byte32,
118        page: u64,
119        per_page: u64,
120        reverse_order: Option<bool>,
121    ) -> Vec<LiveCell> {
122        self.inner()
123            .get_live_cells_by_lock_hash(
124                lock_hash.unpack(),
125                page.into(),
126                per_page.into(),
127                reverse_order,
128            )
129            .expect("rpc call get_live_cells_by_lock_hash")
130    }
131
132    pub fn get_transactions_by_lock_hash(
133        &self,
134        lock_hash: Byte32,
135        page: u64,
136        per_page: u64,
137        reverse_order: Option<bool>,
138    ) -> Vec<CellTransaction> {
139        self.inner()
140            .get_transactions_by_lock_hash(
141                lock_hash.unpack(),
142                page.into(),
143                per_page.into(),
144                reverse_order,
145            )
146            .expect("rpc call get_transactions_by_lock_hash")
147    }
148
149    pub fn index_lock_hash(
150        &self,
151        lock_hash: Byte32,
152        index_from: Option<CoreBlockNumber>,
153    ) -> LockHashIndexState {
154        self.inner()
155            .index_lock_hash(lock_hash.unpack(), index_from.map(Into::into))
156            .expect("rpc call index_lock_hash")
157    }
158
159    pub fn deindex_lock_hash(&self, lock_hash: Byte32) {
160        self.inner()
161            .deindex_lock_hash(lock_hash.unpack())
162            .expect("rpc call deindex_lock_hash")
163    }
164
165    pub fn get_lock_hash_index_states(&self) -> Vec<LockHashIndexState> {
166        self.inner()
167            .get_lock_hash_index_states()
168            .expect("rpc call get_lock_hash_index_states")
169    }
170
171    pub fn get_block_by_number(&self, n: BlockNumber) -> Option<BlockView> {
172        self.inner()
173            .get_block_by_number(n)
174            .expect("rpc call get_block_by_number")
175    }
176}