1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
use crate::error::RPCError;
use async_trait::async_trait;
use ckb_jsonrpc_types::{
IndexerCell, IndexerCellsCapacity, IndexerOrder, IndexerPagination, IndexerSearchKey,
IndexerTip, IndexerTx, JsonBytes, Uint32,
};
use ckb_rich_indexer::AsyncRichIndexerHandle;
use jsonrpc_core::Result;
use jsonrpc_utils::rpc;
/// RPC Module Rich Indexer.
#[rpc(openrpc)]
#[async_trait]
pub trait RichIndexerRpc {
/// Returns the indexed tip.
///
/// ## Returns
/// * block_hash - indexed tip block hash
/// * block_number - indexed tip block number
///
/// ## Examples
///
/// Same as CKB Indexer.
#[rpc(name = "get_indexer_tip")]
async fn get_indexer_tip(&self) -> Result<Option<IndexerTip>>;
/// Returns the live cells collection by the lock or type script.
///
/// The difference from the original CKB Indexer is that the `script_search_mode` parameter accepts the `partial` enumeration value. This implies that a partial search can be conducted on the `args` of the `script`.
///
/// ## Params
///
/// * search_key:
/// - script - Script, supports prefix search
/// - script_type - enum, lock | type
/// - script_search_mode - enum, prefix | exact | partial
/// - filter - filter cells by following conditions, all conditions are optional
/// - script: if search script type is lock, filter cells by type script prefix, and vice versa
/// - script_len_range: [u64; 2], filter cells by script len range, [inclusive, exclusive]
/// - output_data: filter cells by output data
/// - output_data_filter_mode: enum, prefix | exact | partial
/// - output_data_len_range: [u64; 2], filter cells by output data len range, [inclusive, exclusive]
/// - output_capacity_range: [u64; 2], filter cells by output capacity range, [inclusive, exclusive]
/// - block_range: [u64; 2], filter cells by block number range, [inclusive, exclusive]
/// - with_data - bool, optional default is `true`, if with_data is set to false, the field of returning cell.output_data is null in the result
/// * order: enum, asc | desc
/// * limit: result size limit
/// * after: pagination parameter, optional
///
/// ## Returns
///
/// If the number of objects is less than the requested `limit`, it indicates that these are the last page of get_cells.
///
/// * objects:
/// - output: the fields of an output cell
/// - output_data: the cell data
/// - out_point: reference to a cell via transaction hash and output index
/// - block_number: the number of the transaction committed in the block
/// - tx_index: the position index of the transaction committed in the block
/// * last_cursor: pagination parameter
///
/// ## Examples
///
/// Same as CKB Indexer.
#[rpc(name = "get_cells")]
async fn get_cells(
&self,
search_key: IndexerSearchKey,
order: IndexerOrder,
limit: Uint32,
after: Option<JsonBytes>,
) -> Result<IndexerPagination<IndexerCell>>;
/// Returns the transactions collection by the lock or type script.
///
/// The difference from the original CKB Indexer is that both the `script_search_mode` and `output_data_filter_mode` in `filter` can accept the `partial` enumeration value. This implies that a partial search can be conducted on both the `args` of the `script` and the cell `output_data`.
///
/// * search_key:
/// - script - Script, supports prefix search when group_by_transaction is false
/// - script_type - enum, lock | type
/// - script_search_mode - enum, prefix | exact | partial
/// - filter - filter cells by following conditions, all conditions are optional
/// - script: if search script type is lock, filter cells by type script, and vice versa
/// - script_len_range: [u64; 2], filter cells by script len range, [inclusive, exclusive]
/// - output_data: filter cells by output data
/// - output_data_filter_mode: enum, prefix | exact | partial
/// - output_data_len_range: [u64; 2], filter cells by output data len range, [inclusive, exclusive]
/// - output_capacity_range: [u64; 2], filter cells by output capacity range, [inclusive, exclusive]
/// - block_range: [u64; 2], filter cells by block number range, [inclusive, exclusive]
/// - group_by_transaction - bool, optional default is `false`, if group_by_transaction is set to true, the returning objects will be grouped by the tx hash
/// * order: enum, asc | desc
/// * limit: result size limit
/// * after: pagination parameter, optional
///
/// ## Returns
///
/// If the number of objects is less than the requested `limit`, it indicates that these are the last page of get_transactions.
///
/// * objects - enum, ungrouped TxWithCell | grouped TxWithCells
/// - TxWithCell:
/// - tx_hash: transaction hash,
/// - block_number: the number of the transaction committed in the block
/// - tx_index: the position index of the transaction committed in the block
/// - io_type: enum, input | output
/// - io_index: the position index of the cell in the transaction inputs or outputs
/// - TxWithCells:
/// - tx_hash: transaction hash,
/// - block_number: the number of the transaction committed in the block
/// - tx_index: the position index of the transaction committed in the block
/// - cells: Array [[io_type, io_index]]
/// * last_cursor - pagination parameter
///
/// ## Examples
///
/// Same as CKB Indexer.
#[rpc(name = "get_transactions")]
async fn get_transactions(
&self,
search_key: IndexerSearchKey,
order: IndexerOrder,
limit: Uint32,
after: Option<JsonBytes>,
) -> Result<IndexerPagination<IndexerTx>>;
/// Returns the live cells capacity by the lock or type script.
///
/// The difference from the original CKB Indexer is that the `script_search_mode` parameter accepts the `partial` enumeration value. This implies that a partial search can be conducted on the `args` of the `script`.
///
/// ## Parameters
///
/// * search_key:
/// - script - Script
/// - script_type - enum, lock | type
/// - script_search_mode - enum, prefix | exact | partial
/// - filter - filter cells by following conditions, all conditions are optional
/// - script: if search script type is lock, filter cells by type script prefix, and vice versa
/// - script_len_range: [u64; 2], filter cells by script len range, [inclusive, exclusive]
/// - output_data: filter cells by output data
/// - output_data_filter_mode: enum, prefix | exact | partial
/// - output_data_len_range: [u64; 2], filter cells by output data len range, [inclusive, exclusive]
/// - output_capacity_range: [u64; 2], filter cells by output capacity range, [inclusive, exclusive]
/// - block_range: [u64; 2], filter cells by block number range, [inclusive, exclusive]
///
/// ## Returns
///
/// * capacity - total capacity
/// * block_hash - indexed tip block hash
/// * block_number - indexed tip block number
///
/// ## Examples
///
/// Same as CKB Indexer.
#[rpc(name = "get_cells_capacity")]
async fn get_cells_capacity(
&self,
search_key: IndexerSearchKey,
) -> Result<Option<IndexerCellsCapacity>>;
}
#[derive(Clone)]
pub(crate) struct RichIndexerRpcImpl {
pub(crate) handle: AsyncRichIndexerHandle,
}
impl RichIndexerRpcImpl {
pub fn new(handle: AsyncRichIndexerHandle) -> Self {
RichIndexerRpcImpl { handle }
}
}
#[async_trait]
impl RichIndexerRpc for RichIndexerRpcImpl {
async fn get_indexer_tip(&self) -> Result<Option<IndexerTip>> {
self.handle
.get_indexer_tip()
.await
.map_err(|e| RPCError::custom(RPCError::Indexer, e))
}
async fn get_cells(
&self,
search_key: IndexerSearchKey,
order: IndexerOrder,
limit: Uint32,
after: Option<JsonBytes>,
) -> Result<IndexerPagination<IndexerCell>> {
self.handle
.get_cells(search_key, order, limit, after)
.await
.map_err(|e| RPCError::custom(RPCError::Indexer, e))
}
async fn get_transactions(
&self,
search_key: IndexerSearchKey,
order: IndexerOrder,
limit: Uint32,
after: Option<JsonBytes>,
) -> Result<IndexerPagination<IndexerTx>> {
self.handle
.get_transactions(search_key, order, limit, after)
.await
.map_err(|e| RPCError::custom(RPCError::Indexer, e))
}
async fn get_cells_capacity(
&self,
search_key: IndexerSearchKey,
) -> Result<Option<IndexerCellsCapacity>> {
self.handle
.get_cells_capacity(search_key)
.await
.map_err(|e| RPCError::custom(RPCError::Indexer, e))
}
}