ckb_jsonrpc_types/indexer.rs
1use crate::{BlockNumber, Capacity, CellOutput, JsonBytes, OutPoint, Script, Uint32, Uint64};
2use ckb_types::H256;
3use schemars::JsonSchema;
4use serde::{Deserialize, Serialize};
5
6/// Indexer tip information
7#[derive(Serialize, JsonSchema)]
8pub struct IndexerTip {
9 /// indexed tip block hash
10 pub block_hash: H256,
11 /// indexed tip block number
12 pub block_number: BlockNumber,
13}
14
15/// Live cell
16#[derive(Serialize, JsonSchema)]
17pub struct IndexerCell {
18 /// the fields of an output cell
19 pub output: CellOutput,
20 /// the cell data
21 pub output_data: Option<JsonBytes>,
22 /// reference to a cell via transaction hash and output index
23 pub out_point: OutPoint,
24 /// the number of the transaction committed in the block
25 pub block_number: BlockNumber,
26 /// the position index of the transaction committed in the block
27 pub tx_index: Uint32,
28}
29
30/// IndexerPagination wraps objects array and last_cursor to provide paging
31#[derive(Serialize, JsonSchema)]
32pub struct IndexerPagination<T> {
33 /// objects collection
34 pub objects: Vec<T>,
35 /// pagination parameter
36 pub last_cursor: JsonBytes,
37}
38
39impl<T> IndexerPagination<T> {
40 /// Construct new IndexerPagination
41 pub fn new(objects: Vec<T>, last_cursor: JsonBytes) -> Self {
42 IndexerPagination {
43 objects,
44 last_cursor,
45 }
46 }
47}
48
49/// SearchKey represent indexer support params
50#[derive(Deserialize, JsonSchema)]
51pub struct IndexerSearchKey {
52 /// Script
53 pub script: Script,
54 /// Script Type
55 pub script_type: IndexerScriptType,
56 /// Script search mode, optional default is `prefix`, means search script with prefix
57 pub script_search_mode: Option<IndexerSearchMode>,
58 /// filter cells by following conditions, all conditions are optional
59 pub filter: Option<IndexerSearchKeyFilter>,
60 /// bool, optional default is `true`, if with_data is set to false, the field of returning cell.output_data is null in the result
61 pub with_data: Option<bool>,
62 /// bool, optional default is `false`, if group_by_transaction is set to true, the returning objects will be grouped by the tx hash
63 pub group_by_transaction: Option<bool>,
64}
65
66impl Default for IndexerSearchKey {
67 fn default() -> Self {
68 Self {
69 script: Script::default(),
70 script_type: IndexerScriptType::Lock,
71 script_search_mode: None,
72 filter: None,
73 with_data: None,
74 group_by_transaction: None,
75 }
76 }
77}
78
79/// IndexerSearchMode represent search mode, default is prefix search
80#[derive(Deserialize, PartialEq, Eq, JsonSchema, Clone, Copy)]
81#[serde(rename_all = "snake_case")]
82pub enum IndexerSearchMode {
83 /// Mode `prefix` search with prefix
84 Prefix,
85 /// Mode `exact` search with exact match
86 Exact,
87 /// Mode `partial` search with partial match
88 Partial,
89}
90
91impl Default for IndexerSearchMode {
92 fn default() -> Self {
93 Self::Prefix
94 }
95}
96
97/// A array represent (half-open) range bounded inclusively below and exclusively above [start, end).
98///
99/// ## Examples
100///
101/// | JSON | range |
102/// | -------------------------| ---------------------------- |
103/// | ["0x0", "0x2"] | [0, 2) |
104/// | ["0x0", "0x174876e801"] | [0, 100000000001) |
105///
106#[derive(Deserialize, Default, JsonSchema)]
107#[serde(transparent)]
108pub struct IndexerRange {
109 inner: [Uint64; 2],
110}
111
112impl IndexerRange {
113 /// Construct new range
114 pub fn new<U>(start: U, end: U) -> Self
115 where
116 U: Into<Uint64>,
117 {
118 IndexerRange {
119 inner: [start.into(), end.into()],
120 }
121 }
122
123 /// Return the lower bound of the range (inclusive).
124 pub fn start(&self) -> Uint64 {
125 self.inner[0]
126 }
127
128 /// Return the upper bound of the range (exclusive).
129 pub fn end(&self) -> Uint64 {
130 self.inner[1]
131 }
132}
133
134/// IndexerSearchKeyFilter represent indexer params `filter`
135#[derive(Deserialize, Default, JsonSchema)]
136pub struct IndexerSearchKeyFilter {
137 /// if search script type is lock, filter cells by type script prefix, and vice versa
138 pub script: Option<Script>,
139 /// filter cells by script len range
140 pub script_len_range: Option<IndexerRange>,
141 /// filter cells by output data
142 pub output_data: Option<JsonBytes>,
143 /// output data filter mode, optional default is `prefix`
144 pub output_data_filter_mode: Option<IndexerSearchMode>,
145 /// filter cells by output data len range
146 pub output_data_len_range: Option<IndexerRange>,
147 /// filter cells by output capacity range
148 pub output_capacity_range: Option<IndexerRange>,
149 /// filter cells by block number range
150 pub block_range: Option<IndexerRange>,
151}
152
153/// ScriptType `Lock` | `Type`
154#[derive(Deserialize, JsonSchema)]
155#[serde(rename_all = "snake_case")]
156pub enum IndexerScriptType {
157 /// Lock
158 Lock,
159 /// Type
160 Type,
161}
162
163/// Order Desc | Asc
164#[derive(Deserialize, JsonSchema)]
165#[serde(rename_all = "snake_case")]
166pub enum IndexerOrder {
167 /// Descending order
168 Desc,
169 /// Ascending order
170 Asc,
171}
172
173/// Cells capacity
174#[derive(Serialize, JsonSchema)]
175pub struct IndexerCellsCapacity {
176 /// total capacity
177 pub capacity: Capacity,
178 /// indexed tip block hash
179 pub block_hash: H256,
180 /// indexed tip block number
181 pub block_number: BlockNumber,
182}
183
184/// Indexer Transaction Object
185#[derive(Serialize, JsonSchema, Debug)]
186#[serde(untagged)]
187pub enum IndexerTx {
188 /// # Ungrouped format represent as `IndexerTxWithCell`
189 ///
190 /// ## Fields
191 ///
192 /// `IndexerCellType` is equivalent to `"input" | "output"`.
193 ///
194 /// `IndexerTxWithCell` is a JSON object with the following fields.
195 /// * `tx_hash`: [`H256`] - transaction hash
196 /// * `block_number`: [`BlockNumber`] - the number of the transaction committed in the block
197 /// * `tx_index`: [`Uint32`] - the position index of the transaction committed in the block
198 /// * `io_index`: [`Uint32`] - the position index of the cell in the transaction inputs or outputs
199 /// * `io_type`: [`IndexerCellType`] - io type
200 ///
201 Ungrouped(IndexerTxWithCell),
202 /// # Grouped format represent as `IndexerTxWithCells`
203 ///
204 /// ## Fields
205 ///
206 /// `IndexerCellType` is equivalent to `"input" | "output"`.
207 ///
208 /// `IndexerTxWithCells` is a JSON object with the following fields.
209 /// * `tx_hash`: [`H256`] - transaction hash
210 /// * `block_number`: [`BlockNumber`] - the number of the transaction committed in the block
211 /// * `tx_index`: [`Uint32`]- the position index of the transaction committed in the block
212 /// * `cells`: Array <(IndexerCellType, Uint32)>
213 ///
214 Grouped(IndexerTxWithCells),
215}
216
217impl IndexerTx {
218 /// Return tx hash
219 pub fn tx_hash(&self) -> H256 {
220 match self {
221 IndexerTx::Ungrouped(tx) => tx.tx_hash.clone(),
222 IndexerTx::Grouped(tx) => tx.tx_hash.clone(),
223 }
224 }
225}
226
227/// Ungrouped Tx inner type
228#[derive(Serialize, JsonSchema, Debug)]
229pub struct IndexerTxWithCell {
230 /// transaction hash
231 pub tx_hash: H256,
232 /// the number of the transaction committed in the block
233 pub block_number: BlockNumber,
234 /// the position index of the transaction committed in the block
235 pub tx_index: Uint32,
236 /// the position index of the cell in the transaction inputs or outputs
237 pub io_index: Uint32,
238 /// io type
239 pub io_type: IndexerCellType,
240}
241
242/// Grouped Tx inner type
243#[derive(Serialize, JsonSchema, Debug)]
244pub struct IndexerTxWithCells {
245 /// transaction hash
246 pub tx_hash: H256,
247 /// the number of the transaction committed in the block
248 pub block_number: BlockNumber,
249 /// the position index of the transaction committed in the block
250 pub tx_index: Uint32,
251 /// Array [(io_type, io_index)]
252 pub cells: Vec<(IndexerCellType, Uint32)>,
253}
254
255/// Cell type
256#[derive(Serialize, Clone, JsonSchema, Debug)]
257#[serde(rename_all = "snake_case")]
258pub enum IndexerCellType {
259 /// Input
260 Input,
261 /// Output
262 Output,
263}