1#![allow(missing_docs)]
4
5use serde::{Deserialize, Serialize};
6use std::collections::HashMap;
7
8#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
13pub struct StatusResponse {
14 pub network: String,
15 pub version: String,
16 pub commit: String,
17 pub node_info: NodeInfo,
18}
19
20#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
21pub struct NodeInfo {
22 pub id: String,
23 pub listen_addr: String,
24 pub network: String,
25 pub version: String,
26 pub channels: String,
27 pub moniker: String,
28 pub other: HashMap<String, serde_json::Value>,
29}
30
31#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
32pub struct QueryResponse<T> {
33 pub result: T,
34 pub height: i64,
35 pub proof: Option<serde_json::Value>,
36}
37
38#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
39pub struct TransactionResponse {
40 pub txid: String,
41 pub hash: String,
42 pub height: i64,
43 pub index: i32,
44 pub tx: serde_json::Value,
45 pub tx_result: TransactionResult,
46}
47
48#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
49pub struct TransactionResult {
50 pub code: i32,
51 pub data: Option<String>,
52 pub log: String,
53 pub info: String,
54 pub gas_wanted: String,
55 pub gas_used: String,
56 pub events: Vec<Event>,
57 pub codespace: String,
58}
59
60#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
61pub struct Event {
62 #[serde(rename = "type")]
63 pub event_type: String,
64 pub attributes: Vec<Attribute>,
65}
66
67#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
68pub struct Attribute {
69 pub key: String,
70 pub value: String,
71 pub index: bool,
72}
73
74#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
75pub struct SignedTransaction {
76 pub body: serde_json::Value,
77 pub signatures: Vec<Signature>,
78}
79
80#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
81pub struct Signature {
82 pub public_key: String,
83 pub signature: String,
84 #[serde(rename = "type")]
85 pub signature_type: String,
86}
87
88#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
89pub struct Account {
90 pub url: String,
91 #[serde(rename = "type")]
92 pub account_type: String,
93 pub data: serde_json::Value,
94 pub credits: Option<i64>,
95 pub nonce: Option<i64>,
96}
97
98#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
99#[serde(rename_all = "camelCase")]
100pub struct FaucetResponse {
101 #[serde(default, alias = "transactionHash", alias = "hash")]
103 pub txid: String,
104 #[serde(default)]
105 pub link: String,
106 #[serde(default)]
107 pub account: String,
108 #[serde(default)]
109 pub amount: String,
110 #[serde(default, alias = "simpleHash")]
112 pub simple_hash: Option<String>,
113}
114
115#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
117#[serde(rename_all = "camelCase")]
118pub struct MerkleReceiptEntry {
119 #[serde(default)]
121 pub right: bool,
122 #[serde(with = "hex::serde")]
124 pub hash: Vec<u8>,
125}
126
127#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
130#[serde(rename_all = "camelCase")]
131pub struct MerkleReceipt {
132 #[serde(with = "hex::serde")]
134 pub start: Vec<u8>,
135 #[serde(default)]
137 pub start_index: i64,
138 #[serde(with = "hex::serde")]
140 pub end: Vec<u8>,
141 #[serde(default)]
143 pub end_index: i64,
144 #[serde(with = "hex::serde")]
146 pub anchor: Vec<u8>,
147 #[serde(default)]
149 pub entries: Vec<MerkleReceiptEntry>,
150}
151
152impl MerkleReceipt {
153 pub fn new() -> Self {
155 Self {
156 start: Vec::new(),
157 start_index: 0,
158 end: Vec::new(),
159 end_index: 0,
160 anchor: Vec::new(),
161 entries: Vec::new(),
162 }
163 }
164
165 pub fn validate(&self) -> Result<(), crate::errors::Error> {
167 use crate::errors::ValidationError;
168
169 if !self.start.is_empty() && self.start.len() != 32 {
171 return Err(ValidationError::InvalidHash {
172 expected: 32,
173 actual: self.start.len(),
174 }.into());
175 }
176
177 if !self.end.is_empty() && self.end.len() != 32 {
179 return Err(ValidationError::InvalidHash {
180 expected: 32,
181 actual: self.end.len(),
182 }.into());
183 }
184
185 if !self.anchor.is_empty() && self.anchor.len() != 32 {
187 return Err(ValidationError::InvalidHash {
188 expected: 32,
189 actual: self.anchor.len(),
190 }.into());
191 }
192
193 for (i, entry) in self.entries.iter().enumerate() {
195 if entry.hash.len() != 32 {
196 return Err(ValidationError::InvalidFieldValue {
197 field: format!("entries[{}].hash", i),
198 reason: format!("expected 32 bytes, got {}", entry.hash.len()),
199 }.into());
200 }
201 }
202
203 if self.start_index < 0 {
205 return Err(ValidationError::OutOfRange {
206 field: "startIndex".to_string(),
207 min: "0".to_string(),
208 max: "i64::MAX".to_string(),
209 }.into());
210 }
211
212 if self.end_index < 0 {
214 return Err(ValidationError::OutOfRange {
215 field: "endIndex".to_string(),
216 min: "0".to_string(),
217 max: "i64::MAX".to_string(),
218 }.into());
219 }
220
221 if self.end_index < self.start_index {
223 return Err(ValidationError::InvalidFieldValue {
224 field: "endIndex".to_string(),
225 reason: format!("endIndex ({}) must be >= startIndex ({})", self.end_index, self.start_index),
226 }.into());
227 }
228
229 Ok(())
230 }
231
232 pub fn verify(&self) -> Result<bool, crate::errors::Error> {
235 use sha2::{Sha256, Digest};
236
237 self.validate()?;
238
239 if self.start.is_empty() || self.anchor.is_empty() {
240 return Ok(false);
241 }
242
243 let mut current: [u8; 32] = self.start.clone().try_into()
244 .map_err(|_| crate::errors::Error::General("Invalid start hash length".to_string()))?;
245
246 for entry in &self.entries {
248 let entry_hash: [u8; 32] = entry.hash.clone().try_into()
249 .map_err(|_| crate::errors::Error::General("Invalid entry hash length".to_string()))?;
250
251 let mut hasher = Sha256::new();
252 if entry.right {
253 hasher.update(¤t);
255 hasher.update(&entry_hash);
256 } else {
257 hasher.update(&entry_hash);
259 hasher.update(¤t);
260 }
261 current = hasher.finalize().into();
262 }
263
264 Ok(current.as_slice() == self.anchor.as_slice())
266 }
267
268 pub fn is_empty(&self) -> bool {
270 self.start.is_empty() && self.end.is_empty() && self.anchor.is_empty() && self.entries.is_empty()
271 }
272}
273
274impl Default for MerkleReceipt {
275 fn default() -> Self {
276 Self::new()
277 }
278}
279
280impl std::hash::Hash for MerkleReceipt {
281 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
282 self.start.hash(state);
283 self.start_index.hash(state);
284 self.end.hash(state);
285 self.end_index.hash(state);
286 self.anchor.hash(state);
287 self.entries.hash(state);
288 }
289}
290
291#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
293pub struct V3SubmitRequest {
294 pub envelope: TransactionEnvelope,
295}
296
297#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
298pub struct V3SubmitResponse {
299 pub hash: String,
300 pub result: SubmitResult,
301}
302
303#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
304pub struct SubmitResult {
305 pub code: i32,
306 pub message: String,
307 pub data: Option<serde_json::Value>,
308}
309
310#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
311pub struct TransactionEnvelope {
312 pub transaction: serde_json::Value,
313 pub signatures: Vec<V3Signature>,
314 pub metadata: Option<serde_json::Value>,
315}
316
317#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
318pub struct V3Signature {
319 pub public_key: Vec<u8>,
320 pub signature: Vec<u8>,
321 pub timestamp: i64,
322 pub vote: Option<String>,
323}
324
325#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
331#[serde(rename_all = "camelCase")]
332pub struct V3NodeInfo {
333 #[serde(default)]
335 pub peer_id: String,
336 #[serde(default)]
338 pub network: String,
339 #[serde(default)]
341 pub services: Vec<ServiceAddress>,
342 #[serde(default)]
344 pub version: String,
345 #[serde(default)]
347 pub commit: String,
348}
349
350#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
352#[serde(rename_all = "camelCase")]
353pub struct ServiceAddress {
354 #[serde(rename = "type")]
356 pub service_type: String,
357 #[serde(skip_serializing_if = "Option::is_none")]
359 pub argument: Option<String>,
360}
361
362#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
364#[serde(rename_all = "camelCase")]
365pub struct NodeInfoOptions {
366 #[serde(skip_serializing_if = "Option::is_none")]
368 pub peer_id: Option<String>,
369}
370
371#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
373#[serde(rename_all = "camelCase")]
374pub struct V3ConsensusStatus {
375 #[serde(default)]
377 pub ok: bool,
378 #[serde(skip_serializing_if = "Option::is_none")]
380 pub last_block: Option<LastBlock>,
381 #[serde(default)]
383 pub version: String,
384 #[serde(default)]
386 pub commit: String,
387 #[serde(default)]
389 pub node_key_hash: String,
390 #[serde(default)]
392 pub validator_key_hash: String,
393 #[serde(default)]
395 pub partition_id: String,
396 #[serde(default)]
398 pub partition_type: String,
399 #[serde(default)]
401 pub peers: Vec<ConsensusPeerInfo>,
402}
403
404#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
406#[serde(rename_all = "camelCase")]
407pub struct LastBlock {
408 #[serde(default)]
410 pub height: i64,
411 #[serde(default)]
413 pub time: String,
414 #[serde(default)]
416 pub chain_root: String,
417 #[serde(default)]
419 pub state_root: String,
420 #[serde(default)]
422 pub directory_anchor_height: u64,
423}
424
425#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
427#[serde(rename_all = "camelCase")]
428pub struct ConsensusPeerInfo {
429 #[serde(default)]
431 pub node_id: String,
432 #[serde(default)]
434 pub host: String,
435 #[serde(default)]
437 pub port: u64,
438}
439
440#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
442#[serde(rename_all = "camelCase")]
443pub struct ConsensusStatusOptions {
444 #[serde(skip_serializing_if = "Option::is_none")]
446 pub node_id: Option<String>,
447 #[serde(skip_serializing_if = "Option::is_none")]
449 pub partition: Option<String>,
450 #[serde(skip_serializing_if = "Option::is_none")]
452 pub include_peers: Option<bool>,
453 #[serde(skip_serializing_if = "Option::is_none")]
455 pub include_accumulate: Option<bool>,
456}
457
458#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
460#[serde(rename_all = "camelCase")]
461pub struct V3NetworkStatus {
462 #[serde(skip_serializing_if = "Option::is_none")]
464 pub oracle: Option<AcmeOracle>,
465 #[serde(skip_serializing_if = "Option::is_none")]
467 pub globals: Option<serde_json::Value>,
468 #[serde(skip_serializing_if = "Option::is_none")]
470 pub network: Option<serde_json::Value>,
471 #[serde(skip_serializing_if = "Option::is_none")]
473 pub routing: Option<serde_json::Value>,
474 #[serde(skip_serializing_if = "Option::is_none")]
476 pub executor_version: Option<String>,
477 #[serde(default)]
479 pub directory_height: u64,
480 #[serde(default)]
482 pub major_block_height: u64,
483 #[serde(default)]
485 pub bvn_executor_versions: Vec<PartitionExecutorVersion>,
486}
487
488#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
490#[serde(rename_all = "camelCase")]
491pub struct AcmeOracle {
492 #[serde(default)]
494 pub price: u64,
495}
496
497#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
499#[serde(rename_all = "camelCase")]
500pub struct PartitionExecutorVersion {
501 #[serde(default)]
503 pub partition: String,
504 #[serde(default)]
506 pub version: String,
507}
508
509#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
511#[serde(rename_all = "camelCase")]
512pub struct NetworkStatusOptions {
513 #[serde(skip_serializing_if = "Option::is_none")]
515 pub partition: Option<String>,
516}
517
518#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
520#[serde(rename_all = "camelCase")]
521pub struct V3Metrics {
522 #[serde(default)]
524 pub tps: f64,
525}
526
527#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
529#[serde(rename_all = "camelCase")]
530pub struct MetricsOptions {
531 #[serde(skip_serializing_if = "Option::is_none")]
533 pub partition: Option<String>,
534 #[serde(skip_serializing_if = "Option::is_none")]
536 pub span: Option<u64>,
537}
538
539#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
541#[serde(rename_all = "camelCase")]
542pub struct V3Submission {
543 #[serde(skip_serializing_if = "Option::is_none")]
545 pub status: Option<serde_json::Value>,
546 #[serde(default)]
548 pub success: bool,
549 #[serde(default)]
551 pub message: String,
552}
553
554#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
556#[serde(rename_all = "camelCase")]
557pub struct SubmitOptions {
558 #[serde(skip_serializing_if = "Option::is_none")]
560 pub verify: Option<bool>,
561 #[serde(skip_serializing_if = "Option::is_none")]
563 pub wait: Option<bool>,
564}
565
566#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
568#[serde(rename_all = "camelCase")]
569pub struct ValidateOptions {
570 #[serde(skip_serializing_if = "Option::is_none")]
572 pub full: Option<bool>,
573}
574
575#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
577#[serde(rename_all = "camelCase")]
578pub struct V3FaucetOptions {
579 #[serde(skip_serializing_if = "Option::is_none")]
581 pub token: Option<String>,
582}
583
584#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
586#[serde(rename_all = "camelCase")]
587pub struct V3SnapshotInfo {
588 #[serde(skip_serializing_if = "Option::is_none")]
590 pub header: Option<serde_json::Value>,
591 #[serde(skip_serializing_if = "Option::is_none")]
593 pub consensus_info: Option<serde_json::Value>,
594}
595
596#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
598#[serde(rename_all = "camelCase")]
599pub struct ListSnapshotsOptions {
600 #[serde(skip_serializing_if = "Option::is_none")]
602 pub node_id: Option<String>,
603 #[serde(skip_serializing_if = "Option::is_none")]
605 pub partition: Option<String>,
606}
607
608#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
610#[serde(rename_all = "camelCase")]
611pub struct FindServiceOptions {
612 #[serde(skip_serializing_if = "Option::is_none")]
614 pub network: Option<String>,
615 #[serde(skip_serializing_if = "Option::is_none")]
617 pub service: Option<ServiceAddress>,
618 #[serde(skip_serializing_if = "Option::is_none")]
620 pub known: Option<bool>,
621 #[serde(skip_serializing_if = "Option::is_none")]
623 pub timeout: Option<u64>,
624}
625
626#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
628#[serde(rename_all = "camelCase")]
629pub struct FindServiceResult {
630 #[serde(default)]
632 pub peer_id: String,
633 #[serde(default)]
635 pub status: String,
636 #[serde(default)]
638 pub addresses: Vec<String>,
639}
640
641#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
643#[serde(rename_all = "camelCase")]
644pub struct SubscribeOptions {
645 #[serde(skip_serializing_if = "Option::is_none")]
647 pub partition: Option<String>,
648 #[serde(skip_serializing_if = "Option::is_none")]
650 pub account: Option<String>,
651}
652
653#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
659#[serde(rename_all = "camelCase")]
660pub struct RangeOptions {
661 #[serde(skip_serializing_if = "Option::is_none")]
663 pub start: Option<u64>,
664 #[serde(skip_serializing_if = "Option::is_none")]
666 pub count: Option<u64>,
667 #[serde(skip_serializing_if = "Option::is_none")]
669 pub expand: Option<bool>,
670 #[serde(skip_serializing_if = "Option::is_none")]
672 pub from_end: Option<bool>,
673}
674
675#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
677#[serde(rename_all = "camelCase")]
678pub struct ReceiptOptions {
679 #[serde(skip_serializing_if = "Option::is_none")]
681 pub for_any: Option<bool>,
682 #[serde(skip_serializing_if = "Option::is_none")]
684 pub for_height: Option<u64>,
685}
686
687#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
689#[serde(rename_all = "camelCase")]
690pub struct DefaultQuery {
691 #[serde(skip_serializing_if = "Option::is_none")]
693 pub include_receipt: Option<ReceiptOptions>,
694}
695
696#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
698#[serde(rename_all = "camelCase")]
699pub struct ChainQuery {
700 #[serde(skip_serializing_if = "Option::is_none")]
702 pub name: Option<String>,
703 #[serde(skip_serializing_if = "Option::is_none")]
705 pub index: Option<u64>,
706 #[serde(skip_serializing_if = "Option::is_none")]
708 pub entry: Option<String>,
709 #[serde(skip_serializing_if = "Option::is_none")]
711 pub range: Option<RangeOptions>,
712 #[serde(skip_serializing_if = "Option::is_none")]
714 pub include_receipt: Option<ReceiptOptions>,
715}
716
717impl ChainQuery {
718 pub fn validate(&self) -> Result<(), crate::errors::Error> {
720 let has_name = self.name.is_some();
721 let has_index = self.index.is_some();
722 let has_entry = self.entry.is_some();
723 let has_range = self.range.is_some();
724
725 if has_range && (has_index || has_entry) {
726 return Err(crate::errors::ValidationError::InvalidFieldValue {
727 field: "range".to_string(),
728 reason: "range is mutually exclusive with index and entry".to_string(),
729 }.into());
730 }
731
732 if !has_name && (has_index || has_entry || has_range) {
733 return Err(crate::errors::ValidationError::RequiredFieldMissing(
734 "name is required when querying by index, entry, or range".to_string(),
735 ).into());
736 }
737
738 Ok(())
739 }
740}
741
742#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
744#[serde(rename_all = "camelCase")]
745pub struct DataQuery {
746 #[serde(skip_serializing_if = "Option::is_none")]
748 pub index: Option<u64>,
749 #[serde(skip_serializing_if = "Option::is_none")]
751 pub entry: Option<String>,
752 #[serde(skip_serializing_if = "Option::is_none")]
754 pub range: Option<RangeOptions>,
755}
756
757impl DataQuery {
758 pub fn validate(&self) -> Result<(), crate::errors::Error> {
760 let has_index = self.index.is_some();
761 let has_entry = self.entry.is_some();
762 let has_range = self.range.is_some();
763
764 if has_range && (has_index || has_entry) {
765 return Err(crate::errors::ValidationError::InvalidFieldValue {
766 field: "range".to_string(),
767 reason: "range is mutually exclusive with index and entry".to_string(),
768 }.into());
769 }
770
771 Ok(())
772 }
773}
774
775#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
777#[serde(rename_all = "camelCase")]
778pub struct DirectoryQuery {
779 #[serde(skip_serializing_if = "Option::is_none")]
781 pub range: Option<RangeOptions>,
782}
783
784#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
786#[serde(rename_all = "camelCase")]
787pub struct PendingQuery {
788 #[serde(skip_serializing_if = "Option::is_none")]
790 pub range: Option<RangeOptions>,
791}
792
793#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Default)]
795#[serde(rename_all = "camelCase")]
796pub struct BlockQuery {
797 #[serde(skip_serializing_if = "Option::is_none")]
799 pub minor: Option<u64>,
800 #[serde(skip_serializing_if = "Option::is_none")]
802 pub major: Option<u64>,
803 #[serde(skip_serializing_if = "Option::is_none")]
805 pub minor_range: Option<RangeOptions>,
806 #[serde(skip_serializing_if = "Option::is_none")]
808 pub major_range: Option<RangeOptions>,
809 #[serde(skip_serializing_if = "Option::is_none")]
811 pub entry_range: Option<RangeOptions>,
812 #[serde(skip_serializing_if = "Option::is_none")]
814 pub omit_empty: Option<bool>,
815}
816
817impl BlockQuery {
818 pub fn validate(&self) -> Result<(), crate::errors::Error> {
820 let has_minor = self.minor.is_some();
821 let has_major = self.major.is_some();
822 let has_minor_range = self.minor_range.is_some();
823 let has_major_range = self.major_range.is_some();
824 let has_entry_range = self.entry_range.is_some();
825
826 if !has_minor && !has_major && !has_minor_range && !has_major_range {
827 return Err(crate::errors::ValidationError::RequiredFieldMissing(
828 "minor, major, minor_range, or major_range must be specified".to_string(),
829 ).into());
830 }
831 if has_minor && has_major {
832 return Err(crate::errors::ValidationError::InvalidFieldValue {
833 field: "minor/major".to_string(),
834 reason: "minor and major are mutually exclusive".to_string(),
835 }.into());
836 }
837 if has_minor_range && has_major_range {
838 return Err(crate::errors::ValidationError::InvalidFieldValue {
839 field: "minor_range/major_range".to_string(),
840 reason: "minor_range and major_range are mutually exclusive".to_string(),
841 }.into());
842 }
843 if has_minor && (has_minor_range || has_major_range) {
844 return Err(crate::errors::ValidationError::InvalidFieldValue {
845 field: "minor".to_string(),
846 reason: "minor is mutually exclusive with minor_range and major_range".to_string(),
847 }.into());
848 }
849 if has_major && has_major_range {
850 return Err(crate::errors::ValidationError::InvalidFieldValue {
851 field: "major".to_string(),
852 reason: "major and major_range are mutually exclusive".to_string(),
853 }.into());
854 }
855 if has_entry_range && (has_major || has_minor_range || has_major_range) {
856 return Err(crate::errors::ValidationError::InvalidFieldValue {
857 field: "entry_range".to_string(),
858 reason: "entry_range is mutually exclusive with major, minor_range, and major_range".to_string(),
859 }.into());
860 }
861
862 Ok(())
863 }
864}
865
866#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
868#[serde(rename_all = "camelCase")]
869pub struct AnchorSearchQuery {
870 pub anchor: String,
872 #[serde(skip_serializing_if = "Option::is_none")]
874 pub include_receipt: Option<ReceiptOptions>,
875}
876
877#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
879#[serde(rename_all = "camelCase")]
880pub struct PublicKeySearchQuery {
881 pub public_key: String,
883 #[serde(rename = "type")]
885 pub signature_type: String,
886}
887
888#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
890#[serde(rename_all = "camelCase")]
891pub struct PublicKeyHashSearchQuery {
892 pub public_key_hash: String,
894}
895
896#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
898#[serde(rename_all = "camelCase")]
899pub struct DelegateSearchQuery {
900 pub delegate: String,
902}
903
904#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
906#[serde(rename_all = "camelCase")]
907pub struct MessageHashSearchQuery {
908 pub hash: String,
910}
911
912#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
914#[serde(tag = "queryType", rename_all = "camelCase")]
915pub enum V3Query {
916 #[serde(rename = "default")]
918 Default(DefaultQuery),
919 #[serde(rename = "chain")]
921 Chain(ChainQuery),
922 #[serde(rename = "data")]
924 Data(DataQuery),
925 #[serde(rename = "directory")]
927 Directory(DirectoryQuery),
928 #[serde(rename = "pending")]
930 Pending(PendingQuery),
931 #[serde(rename = "block")]
933 Block(BlockQuery),
934 #[serde(rename = "anchorSearch")]
936 AnchorSearch(AnchorSearchQuery),
937 #[serde(rename = "publicKeySearch")]
939 PublicKeySearch(PublicKeySearchQuery),
940 #[serde(rename = "publicKeyHashSearch")]
942 PublicKeyHashSearch(PublicKeyHashSearchQuery),
943 #[serde(rename = "delegateSearch")]
945 DelegateSearch(DelegateSearchQuery),
946 #[serde(rename = "messageHashSearch")]
948 MessageHashSearch(MessageHashSearchQuery),
949}
950
951impl V3Query {
952 pub fn validate(&self) -> Result<(), crate::errors::Error> {
954 match self {
955 V3Query::Chain(q) => q.validate(),
956 V3Query::Data(q) => q.validate(),
957 V3Query::Block(q) => q.validate(),
958 _ => Ok(()),
959 }
960 }
961}