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")]
82#[derive(Default)]
83pub enum IndexerSearchMode {
84 /// Mode `prefix` search with prefix
85 #[default]
86 Prefix,
87 /// Mode `exact` search with exact match
88 Exact,
89 /// Mode `partial` search with partial match
90 Partial,
91}
92
93/// A array represent (half-open) range bounded inclusively below and exclusively above [start, end).
94///
95/// ## Examples
96///
97/// | JSON | range |
98/// | -------------------------| ---------------------------- |
99/// | ["0x0", "0x2"] | [0, 2) |
100/// | ["0x0", "0x174876e801"] | [0, 100000000001) |
101///
102#[derive(Deserialize, Default, JsonSchema)]
103#[serde(transparent)]
104pub struct IndexerRange {
105 inner: [Uint64; 2],
106}
107
108impl IndexerRange {
109 /// Construct new range
110 pub fn new<U>(start: U, end: U) -> Self
111 where
112 U: Into<Uint64>,
113 {
114 IndexerRange {
115 inner: [start.into(), end.into()],
116 }
117 }
118
119 /// Return the lower bound of the range (inclusive).
120 pub fn start(&self) -> Uint64 {
121 self.inner[0]
122 }
123
124 /// Return the upper bound of the range (exclusive).
125 pub fn end(&self) -> Uint64 {
126 self.inner[1]
127 }
128}
129
130/// IndexerSearchKeyFilter represent indexer params `filter`
131#[derive(Deserialize, Default, JsonSchema)]
132pub struct IndexerSearchKeyFilter {
133 /// if search script type is lock, filter cells by type script prefix, and vice versa
134 pub script: Option<Script>,
135 /// filter cells by script len range
136 pub script_len_range: Option<IndexerRange>,
137 /// filter cells by output data
138 pub output_data: Option<JsonBytes>,
139 /// output data filter mode, optional default is `prefix`
140 pub output_data_filter_mode: Option<IndexerSearchMode>,
141 /// filter cells by output data len range
142 pub output_data_len_range: Option<IndexerRange>,
143 /// filter cells by output capacity range
144 pub output_capacity_range: Option<IndexerRange>,
145 /// filter cells by block number range
146 pub block_range: Option<IndexerRange>,
147}
148
149/// ScriptType `Lock` | `Type`
150#[derive(Deserialize, JsonSchema)]
151#[serde(rename_all = "snake_case")]
152pub enum IndexerScriptType {
153 /// Lock
154 Lock,
155 /// Type
156 Type,
157}
158
159/// Order Desc | Asc
160#[derive(Deserialize, JsonSchema)]
161#[serde(rename_all = "snake_case")]
162pub enum IndexerOrder {
163 /// Descending order
164 Desc,
165 /// Ascending order
166 Asc,
167}
168
169/// Cells capacity
170#[derive(Serialize, JsonSchema)]
171pub struct IndexerCellsCapacity {
172 /// total capacity
173 pub capacity: Capacity,
174 /// indexed tip block hash
175 pub block_hash: H256,
176 /// indexed tip block number
177 pub block_number: BlockNumber,
178}
179
180/// Indexer Transaction Object
181#[derive(Serialize, JsonSchema, Debug)]
182#[serde(untagged)]
183pub enum IndexerTx {
184 /// # Ungrouped format represent as `IndexerTxWithCell`
185 ///
186 /// ## Fields
187 ///
188 /// `IndexerCellType` is equivalent to `"input" | "output"`.
189 ///
190 /// `IndexerTxWithCell` is a JSON object with the following fields.
191 /// * `tx_hash`: [`H256`] - transaction hash
192 /// * `block_number`: [`BlockNumber`] - the number of the transaction committed in the block
193 /// * `tx_index`: [`Uint32`] - the position index of the transaction committed in the block
194 /// * `io_index`: [`Uint32`] - the position index of the cell in the transaction inputs or outputs
195 /// * `io_type`: [`IndexerCellType`] - io type
196 ///
197 Ungrouped(IndexerTxWithCell),
198 /// # Grouped format represent as `IndexerTxWithCells`
199 ///
200 /// ## Fields
201 ///
202 /// `IndexerCellType` is equivalent to `"input" | "output"`.
203 ///
204 /// `IndexerTxWithCells` is a JSON object with the following fields.
205 /// * `tx_hash`: [`H256`] - transaction hash
206 /// * `block_number`: [`BlockNumber`] - the number of the transaction committed in the block
207 /// * `tx_index`: [`Uint32`]- the position index of the transaction committed in the block
208 /// * `cells`: Array <(IndexerCellType, Uint32)>
209 ///
210 Grouped(IndexerTxWithCells),
211}
212
213impl IndexerTx {
214 /// Return tx hash
215 pub fn tx_hash(&self) -> H256 {
216 match self {
217 IndexerTx::Ungrouped(tx) => tx.tx_hash.clone(),
218 IndexerTx::Grouped(tx) => tx.tx_hash.clone(),
219 }
220 }
221}
222
223/// Ungrouped Tx inner type
224#[derive(Serialize, JsonSchema, Debug)]
225pub struct IndexerTxWithCell {
226 /// transaction hash
227 pub tx_hash: H256,
228 /// the number of the transaction committed in the block
229 pub block_number: BlockNumber,
230 /// the position index of the transaction committed in the block
231 pub tx_index: Uint32,
232 /// the position index of the cell in the transaction inputs or outputs
233 pub io_index: Uint32,
234 /// io type
235 pub io_type: IndexerCellType,
236}
237
238/// Grouped Tx inner type
239#[derive(Serialize, JsonSchema, Debug)]
240pub struct IndexerTxWithCells {
241 /// transaction hash
242 pub tx_hash: H256,
243 /// the number of the transaction committed in the block
244 pub block_number: BlockNumber,
245 /// the position index of the transaction committed in the block
246 pub tx_index: Uint32,
247 /// Array [(io_type, io_index)]
248 pub cells: Vec<(IndexerCellType, Uint32)>,
249}
250
251/// Cell type
252#[derive(Serialize, Clone, JsonSchema, Debug)]
253#[serde(rename_all = "snake_case")]
254pub enum IndexerCellType {
255 /// Input
256 Input,
257 /// Output
258 Output,
259}