Skip to main content

qorechain/query/
typed.rs

1//! Typed query clients for the QoreChain modules that expose a gRPC `Query`
2//! service (bridge, crossvm, lightnode, multilayer, pqc, qca, rdk, reputation,
3//! rlconsensus, svm).
4//!
5//! Rather than pull in a gRPC transport, the queries ride the chain RPC's
6//! `abci_query` method (the same JSON-RPC transport as [`JsonRpcClient`]): the
7//! ABCI path is the gRPC method name (`/qorechain.<module>.v1.Query/<Method>`),
8//! the request is the prost-encoded query message (hex), and the response value
9//! is the base64-encoded prost-encoded response message. Each method below
10//! returns the strongly typed prost response decoded from that value, so callers
11//! get real typed results without a gRPC dependency.
12
13use crate::error::{Error, Result};
14use crate::proto::qorechain;
15use crate::query::JsonRpcClient;
16use base64::engine::general_purpose::STANDARD as BASE64;
17use base64::Engine;
18use prost::Message;
19use serde_json::json;
20
21/// A typed query client over the chain RPC `abci_query` transport.
22#[derive(Debug, Clone)]
23pub struct TypedQueryClient {
24    rpc: JsonRpcClient,
25}
26
27impl TypedQueryClient {
28    /// Creates a typed query client targeting the chain RPC URL.
29    pub fn new(rpc_url: impl Into<String>) -> Self {
30        Self {
31            rpc: JsonRpcClient::new(rpc_url),
32        }
33    }
34
35    /// Wraps an existing [`JsonRpcClient`].
36    pub fn with_rpc(rpc: JsonRpcClient) -> Self {
37        Self { rpc }
38    }
39
40    /// Performs a typed ABCI gRPC query: encodes `req`, calls `abci_query` for
41    /// the gRPC `path`, and decodes the response value into `Resp`.
42    async fn grpc_query<Req: Message, Resp: Message + Default>(
43        &self,
44        path: &str,
45        req: &Req,
46    ) -> Result<Resp> {
47        let data_hex = hex::encode(req.encode_to_vec());
48        let params = json!({
49            "path": path,
50            "data": data_hex,
51            "prove": false,
52        });
53        let result = self.rpc.call("abci_query", params).await?;
54        let response = &result["response"];
55        // A non-zero ABCI code indicates a query error.
56        if let Some(code) = response["code"].as_u64() {
57            if code != 0 {
58                let log = response["log"].as_str().unwrap_or("query failed");
59                return Err(Error::InvalidResponse(format!(
60                    "abci_query {path} failed (code {code}): {log}"
61                )));
62            }
63        }
64        let value_b64 = response["value"].as_str().unwrap_or("");
65        let bytes = if value_b64.is_empty() {
66            Vec::new()
67        } else {
68            BASE64
69                .decode(value_b64)
70                .map_err(|e| Error::InvalidResponse(format!("decode abci value: {e}")))?
71        };
72        Resp::decode(bytes.as_slice())
73            .map_err(|e| Error::InvalidResponse(format!("decode {path} response: {e}")))
74    }
75
76    // --- pqc ---
77
78    /// Queries `qorechain.pqc.v1.Query/Account`.
79    pub async fn pqc_account(
80        &self,
81        address: impl Into<String>,
82    ) -> Result<qorechain::pqc::v1::QueryAccountResponse> {
83        self.grpc_query(
84            "/qorechain.pqc.v1.Query/Account",
85            &qorechain::pqc::v1::QueryAccountRequest {
86                address: address.into(),
87            },
88        )
89        .await
90    }
91
92    // --- crossvm ---
93
94    /// Queries `qorechain.crossvm.v1.Query/Params`.
95    pub async fn crossvm_params(&self) -> Result<qorechain::crossvm::v1::QueryParamsResponse> {
96        self.grpc_query(
97            "/qorechain.crossvm.v1.Query/Params",
98            &qorechain::crossvm::v1::QueryParamsRequest {},
99        )
100        .await
101    }
102
103    /// Queries `qorechain.crossvm.v1.Query/PendingMessages`.
104    pub async fn crossvm_pending_messages(
105        &self,
106    ) -> Result<qorechain::crossvm::v1::QueryPendingMessagesResponse> {
107        self.grpc_query(
108            "/qorechain.crossvm.v1.Query/PendingMessages",
109            &qorechain::crossvm::v1::QueryPendingMessagesRequest {},
110        )
111        .await
112    }
113
114    /// Queries `qorechain.crossvm.v1.Query/Message`.
115    pub async fn crossvm_message(
116        &self,
117        id: impl Into<String>,
118    ) -> Result<qorechain::crossvm::v1::QueryMessageResponse> {
119        self.grpc_query(
120            "/qorechain.crossvm.v1.Query/Message",
121            &qorechain::crossvm::v1::QueryMessageRequest { id: id.into() },
122        )
123        .await
124    }
125
126    // --- lightnode ---
127
128    /// Queries `qorechain.lightnode.v1.Query/LightNode`.
129    pub async fn lightnode(
130        &self,
131        address: impl Into<String>,
132    ) -> Result<qorechain::lightnode::v1::QueryLightNodeResponse> {
133        self.grpc_query(
134            "/qorechain.lightnode.v1.Query/LightNode",
135            &qorechain::lightnode::v1::QueryLightNodeRequest {
136                address: address.into(),
137            },
138        )
139        .await
140    }
141
142    /// Queries `qorechain.lightnode.v1.Query/LightNodes`.
143    pub async fn lightnodes(&self) -> Result<qorechain::lightnode::v1::QueryLightNodesResponse> {
144        self.grpc_query(
145            "/qorechain.lightnode.v1.Query/LightNodes",
146            &qorechain::lightnode::v1::QueryLightNodesRequest {},
147        )
148        .await
149    }
150
151    /// Queries `qorechain.lightnode.v1.Query/Params`.
152    pub async fn lightnode_params(&self) -> Result<qorechain::lightnode::v1::QueryParamsResponse> {
153        self.grpc_query(
154            "/qorechain.lightnode.v1.Query/Params",
155            &qorechain::lightnode::v1::QueryParamsRequest {},
156        )
157        .await
158    }
159
160    /// Queries `qorechain.lightnode.v1.Query/Rewards`.
161    pub async fn lightnode_rewards(
162        &self,
163        address: impl Into<String>,
164    ) -> Result<qorechain::lightnode::v1::QueryRewardsResponse> {
165        self.grpc_query(
166            "/qorechain.lightnode.v1.Query/Rewards",
167            &qorechain::lightnode::v1::QueryRewardsRequest {
168                address: address.into(),
169            },
170        )
171        .await
172    }
173
174    /// Queries `qorechain.lightnode.v1.Query/Stats`.
175    pub async fn lightnode_stats(&self) -> Result<qorechain::lightnode::v1::QueryStatsResponse> {
176        self.grpc_query(
177            "/qorechain.lightnode.v1.Query/Stats",
178            &qorechain::lightnode::v1::QueryStatsRequest {},
179        )
180        .await
181    }
182
183    // --- svm ---
184
185    /// Queries `qorechain.svm.v1.Query/Slot`.
186    pub async fn svm_slot(&self) -> Result<qorechain::svm::v1::QuerySlotResponse> {
187        self.grpc_query(
188            "/qorechain.svm.v1.Query/Slot",
189            &qorechain::svm::v1::QuerySlotRequest {},
190        )
191        .await
192    }
193
194    /// Queries `qorechain.svm.v1.Query/Account`.
195    pub async fn svm_account(
196        &self,
197        address: impl Into<String>,
198    ) -> Result<qorechain::svm::v1::QueryAccountResponse> {
199        self.grpc_query(
200            "/qorechain.svm.v1.Query/Account",
201            &qorechain::svm::v1::QueryAccountRequest {
202                address: address.into(),
203            },
204        )
205        .await
206    }
207
208    /// Queries `qorechain.svm.v1.Query/Program`.
209    pub async fn svm_program(
210        &self,
211        address: impl Into<String>,
212    ) -> Result<qorechain::svm::v1::QueryProgramResponse> {
213        self.grpc_query(
214            "/qorechain.svm.v1.Query/Program",
215            &qorechain::svm::v1::QueryProgramRequest {
216                address: address.into(),
217            },
218        )
219        .await
220    }
221
222    // --- reputation ---
223
224    /// Queries `qorechain.reputation.v1.Query/Params`.
225    pub async fn reputation_params(
226        &self,
227    ) -> Result<qorechain::reputation::v1::QueryParamsResponse> {
228        self.grpc_query(
229            "/qorechain.reputation.v1.Query/Params",
230            &qorechain::reputation::v1::QueryParamsRequest {},
231        )
232        .await
233    }
234
235    // --- qca ---
236
237    /// Queries `qorechain.qca.v1.Query/Config`.
238    pub async fn qca_config(&self) -> Result<qorechain::qca::v1::QueryConfigResponse> {
239        self.grpc_query(
240            "/qorechain.qca.v1.Query/Config",
241            &qorechain::qca::v1::QueryConfigRequest {},
242        )
243        .await
244    }
245
246    // --- rlconsensus ---
247
248    /// Queries `qorechain.rlconsensus.v1.Query/AgentStatus`.
249    pub async fn rlconsensus_agent_status(
250        &self,
251    ) -> Result<qorechain::rlconsensus::v1::QueryAgentStatusResponse> {
252        self.grpc_query(
253            "/qorechain.rlconsensus.v1.Query/AgentStatus",
254            &qorechain::rlconsensus::v1::QueryAgentStatusRequest {},
255        )
256        .await
257    }
258
259    /// Queries `qorechain.rlconsensus.v1.Query/Params`.
260    pub async fn rlconsensus_params(
261        &self,
262    ) -> Result<qorechain::rlconsensus::v1::QueryParamsResponse> {
263        self.grpc_query(
264            "/qorechain.rlconsensus.v1.Query/Params",
265            &qorechain::rlconsensus::v1::QueryParamsRequest {},
266        )
267        .await
268    }
269
270    /// Queries `qorechain.rlconsensus.v1.Query/Observation`.
271    pub async fn rlconsensus_observation(
272        &self,
273    ) -> Result<qorechain::rlconsensus::v1::QueryObservationResponse> {
274        self.grpc_query(
275            "/qorechain.rlconsensus.v1.Query/Observation",
276            &qorechain::rlconsensus::v1::QueryObservationRequest {},
277        )
278        .await
279    }
280
281    /// Queries `qorechain.rlconsensus.v1.Query/Reward`.
282    pub async fn rlconsensus_reward(
283        &self,
284    ) -> Result<qorechain::rlconsensus::v1::QueryRewardResponse> {
285        self.grpc_query(
286            "/qorechain.rlconsensus.v1.Query/Reward",
287            &qorechain::rlconsensus::v1::QueryRewardRequest {},
288        )
289        .await
290    }
291
292    /// Queries `qorechain.rlconsensus.v1.Query/Policy`.
293    pub async fn rlconsensus_policy(
294        &self,
295    ) -> Result<qorechain::rlconsensus::v1::QueryPolicyResponse> {
296        self.grpc_query(
297            "/qorechain.rlconsensus.v1.Query/Policy",
298            &qorechain::rlconsensus::v1::QueryPolicyRequest {},
299        )
300        .await
301    }
302
303    // --- multilayer ---
304
305    /// Queries `qorechain.multilayer.v1.Query/Params`.
306    pub async fn multilayer_params(
307        &self,
308    ) -> Result<qorechain::multilayer::v1::QueryParamsResponse> {
309        self.grpc_query(
310            "/qorechain.multilayer.v1.Query/Params",
311            &qorechain::multilayer::v1::QueryParamsRequest {},
312        )
313        .await
314    }
315
316    /// Queries `qorechain.multilayer.v1.Query/Layer`.
317    pub async fn multilayer_layer(
318        &self,
319        layer_id: impl Into<String>,
320    ) -> Result<qorechain::multilayer::v1::QueryLayerResponse> {
321        self.grpc_query(
322            "/qorechain.multilayer.v1.Query/Layer",
323            &qorechain::multilayer::v1::QueryLayerRequest {
324                layer_id: layer_id.into(),
325            },
326        )
327        .await
328    }
329
330    /// Queries `qorechain.multilayer.v1.Query/Layers`.
331    pub async fn multilayer_layers(
332        &self,
333    ) -> Result<qorechain::multilayer::v1::QueryLayersResponse> {
334        self.grpc_query(
335            "/qorechain.multilayer.v1.Query/Layers",
336            &qorechain::multilayer::v1::QueryLayersRequest {},
337        )
338        .await
339    }
340
341    /// Queries `qorechain.multilayer.v1.Query/Anchor` — the latest state anchor
342    /// for a layer.
343    pub async fn multilayer_anchor(
344        &self,
345        layer_id: impl Into<String>,
346    ) -> Result<qorechain::multilayer::v1::QueryAnchorResponse> {
347        self.grpc_query(
348            "/qorechain.multilayer.v1.Query/Anchor",
349            &qorechain::multilayer::v1::QueryAnchorRequest {
350                layer_id: layer_id.into(),
351            },
352        )
353        .await
354    }
355
356    /// Queries `qorechain.multilayer.v1.Query/Anchors` — all state anchors for a
357    /// layer (newest first).
358    pub async fn multilayer_anchors(
359        &self,
360        layer_id: impl Into<String>,
361    ) -> Result<qorechain::multilayer::v1::QueryAnchorsResponse> {
362        self.grpc_query(
363            "/qorechain.multilayer.v1.Query/Anchors",
364            &qorechain::multilayer::v1::QueryAnchorsRequest {
365                layer_id: layer_id.into(),
366            },
367        )
368        .await
369    }
370
371    /// Queries `qorechain.multilayer.v1.Query/RoutingStats`.
372    pub async fn multilayer_routing_stats(
373        &self,
374    ) -> Result<qorechain::multilayer::v1::QueryRoutingStatsView> {
375        self.grpc_query(
376            "/qorechain.multilayer.v1.Query/RoutingStats",
377            &qorechain::multilayer::v1::QueryRoutingStatsRequest {},
378        )
379        .await
380    }
381
382    // --- amm ---
383
384    /// Queries `qorechain.amm.v1.Query/Params`.
385    pub async fn amm_params(&self) -> Result<qorechain::amm::v1::QueryParamsResponse> {
386        self.grpc_query(
387            "/qorechain.amm.v1.Query/Params",
388            &qorechain::amm::v1::QueryParamsRequest {},
389        )
390        .await
391    }
392
393    /// Queries `qorechain.amm.v1.Query/Pool`.
394    pub async fn amm_pool(&self, pool_id: u64) -> Result<qorechain::amm::v1::QueryPoolResponse> {
395        self.grpc_query(
396            "/qorechain.amm.v1.Query/Pool",
397            &qorechain::amm::v1::QueryPoolRequest { pool_id },
398        )
399        .await
400    }
401
402    /// Queries `qorechain.amm.v1.Query/Pools`.
403    pub async fn amm_pools(&self) -> Result<qorechain::amm::v1::QueryPoolsResponse> {
404        self.grpc_query(
405            "/qorechain.amm.v1.Query/Pools",
406            &qorechain::amm::v1::QueryPoolsRequest {},
407        )
408        .await
409    }
410
411    /// Queries `qorechain.amm.v1.Query/PoolByDenoms`.
412    pub async fn amm_pool_by_denoms(
413        &self,
414        denom_a: impl Into<String>,
415        denom_b: impl Into<String>,
416    ) -> Result<qorechain::amm::v1::QueryPoolByDenomsResponse> {
417        self.grpc_query(
418            "/qorechain.amm.v1.Query/PoolByDenoms",
419            &qorechain::amm::v1::QueryPoolByDenomsRequest {
420                denom_a: denom_a.into(),
421                denom_b: denom_b.into(),
422            },
423        )
424        .await
425    }
426
427    /// Queries `qorechain.amm.v1.Query/LPBalance`.
428    pub async fn amm_lp_balance(
429        &self,
430        pool_id: u64,
431        address: impl Into<String>,
432    ) -> Result<qorechain::amm::v1::QueryLpBalanceResponse> {
433        self.grpc_query(
434            "/qorechain.amm.v1.Query/LPBalance",
435            &qorechain::amm::v1::QueryLpBalanceRequest {
436                pool_id,
437                address: address.into(),
438            },
439        )
440        .await
441    }
442
443    /// Queries `qorechain.amm.v1.Query/QuoteExactIn`.
444    pub async fn amm_quote_exact_in(
445        &self,
446        pool_id: u64,
447        denom_in: impl Into<String>,
448        amount_in: impl Into<String>,
449    ) -> Result<qorechain::amm::v1::QueryQuoteExactInResponse> {
450        self.grpc_query(
451            "/qorechain.amm.v1.Query/QuoteExactIn",
452            &qorechain::amm::v1::QueryQuoteExactInRequest {
453                pool_id,
454                denom_in: denom_in.into(),
455                amount_in: amount_in.into(),
456            },
457        )
458        .await
459    }
460
461    /// Queries `qorechain.amm.v1.Query/QuoteExactOut`.
462    pub async fn amm_quote_exact_out(
463        &self,
464        pool_id: u64,
465        denom_out: impl Into<String>,
466        amount_out: impl Into<String>,
467    ) -> Result<qorechain::amm::v1::QueryQuoteExactOutResponse> {
468        self.grpc_query(
469            "/qorechain.amm.v1.Query/QuoteExactOut",
470            &qorechain::amm::v1::QueryQuoteExactOutRequest {
471                pool_id,
472                denom_out: denom_out.into(),
473                amount_out: amount_out.into(),
474            },
475        )
476        .await
477    }
478
479    // --- license ---
480
481    /// Queries `qorechain.license.v1.Query/Check`.
482    pub async fn license_check(
483        &self,
484        grantee: impl Into<String>,
485        feature_id: impl Into<String>,
486    ) -> Result<qorechain::license::v1::QueryCheckResponse> {
487        self.grpc_query(
488            "/qorechain.license.v1.Query/Check",
489            &qorechain::license::v1::QueryCheckRequest {
490                grantee: grantee.into(),
491                feature_id: feature_id.into(),
492            },
493        )
494        .await
495    }
496
497    /// Queries `qorechain.license.v1.Query/Holders`.
498    pub async fn license_holders(
499        &self,
500        feature_id: impl Into<String>,
501    ) -> Result<qorechain::license::v1::QueryHoldersResponse> {
502        self.grpc_query(
503            "/qorechain.license.v1.Query/Holders",
504            &qorechain::license::v1::QueryHoldersRequest {
505                feature_id: feature_id.into(),
506            },
507        )
508        .await
509    }
510
511    /// Queries `qorechain.license.v1.Query/List`.
512    pub async fn license_list(
513        &self,
514        grantee: impl Into<String>,
515    ) -> Result<qorechain::license::v1::QueryListResponse> {
516        self.grpc_query(
517            "/qorechain.license.v1.Query/List",
518            &qorechain::license::v1::QueryListRequest {
519                grantee: grantee.into(),
520            },
521        )
522        .await
523    }
524
525    // --- abstractaccount ---
526
527    /// Queries `qorechain.abstractaccount.v1.Query/Config`.
528    pub async fn abstractaccount_config(
529        &self,
530    ) -> Result<qorechain::abstractaccount::v1::QueryConfigResponse> {
531        self.grpc_query(
532            "/qorechain.abstractaccount.v1.Query/Config",
533            &qorechain::abstractaccount::v1::QueryConfigRequest {},
534        )
535        .await
536    }
537
538    /// Queries `qorechain.abstractaccount.v1.Query/Account`.
539    pub async fn abstractaccount_account(
540        &self,
541        address: impl Into<String>,
542    ) -> Result<qorechain::abstractaccount::v1::QueryAccountResponse> {
543        self.grpc_query(
544            "/qorechain.abstractaccount.v1.Query/Account",
545            &qorechain::abstractaccount::v1::QueryAccountRequest {
546                address: address.into(),
547            },
548        )
549        .await
550    }
551
552    /// Queries `qorechain.abstractaccount.v1.Query/Accounts`.
553    pub async fn abstractaccount_accounts(
554        &self,
555    ) -> Result<qorechain::abstractaccount::v1::QueryAccountsResponse> {
556        self.grpc_query(
557            "/qorechain.abstractaccount.v1.Query/Accounts",
558            &qorechain::abstractaccount::v1::QueryAccountsRequest {},
559        )
560        .await
561    }
562
563    /// Queries `qorechain.abstractaccount.v1.Query/PermissionSchema` — the
564    /// canonical authenticator permission taxonomy (v3.1.85), so clients validate
565    /// scopes without hardcoding strings and detect drift via `schema_version`.
566    pub async fn abstractaccount_permission_schema(
567        &self,
568    ) -> Result<qorechain::abstractaccount::v1::QueryPermissionSchemaResponse> {
569        self.grpc_query(
570            "/qorechain.abstractaccount.v1.Query/PermissionSchema",
571            &qorechain::abstractaccount::v1::QueryPermissionSchemaRequest {},
572        )
573        .await
574    }
575
576    // --- rdk ---
577
578    /// Queries `qorechain.rdk.v1.Query/Params`.
579    pub async fn rdk_params(&self) -> Result<qorechain::rdk::v1::QueryParamsResponse> {
580        self.grpc_query(
581            "/qorechain.rdk.v1.Query/Params",
582            &qorechain::rdk::v1::QueryParamsRequest {},
583        )
584        .await
585    }
586
587    /// Queries `qorechain.rdk.v1.Query/Rollup`.
588    pub async fn rdk_rollup(
589        &self,
590        rollup_id: impl Into<String>,
591    ) -> Result<qorechain::rdk::v1::QueryRollupResponse> {
592        self.grpc_query(
593            "/qorechain.rdk.v1.Query/Rollup",
594            &qorechain::rdk::v1::QueryRollupRequest {
595                rollup_id: rollup_id.into(),
596            },
597        )
598        .await
599    }
600
601    /// Queries `qorechain.rdk.v1.Query/Rollups`.
602    pub async fn rdk_rollups(&self) -> Result<qorechain::rdk::v1::QueryRollupsResponse> {
603        self.grpc_query(
604            "/qorechain.rdk.v1.Query/Rollups",
605            &qorechain::rdk::v1::QueryRollupsRequest {},
606        )
607        .await
608    }
609
610    /// Queries `qorechain.rdk.v1.Query/Batch`.
611    pub async fn rdk_batch(
612        &self,
613        rollup_id: impl Into<String>,
614        batch_index: u64,
615    ) -> Result<qorechain::rdk::v1::QueryBatchResponse> {
616        self.grpc_query(
617            "/qorechain.rdk.v1.Query/Batch",
618            &qorechain::rdk::v1::QueryBatchRequest {
619                rollup_id: rollup_id.into(),
620                batch_index,
621            },
622        )
623        .await
624    }
625
626    /// Queries `qorechain.rdk.v1.Query/LatestBatch`.
627    pub async fn rdk_latest_batch(
628        &self,
629        rollup_id: impl Into<String>,
630    ) -> Result<qorechain::rdk::v1::QueryLatestBatchResponse> {
631        self.grpc_query(
632            "/qorechain.rdk.v1.Query/LatestBatch",
633            &qorechain::rdk::v1::QueryLatestBatchRequest {
634                rollup_id: rollup_id.into(),
635            },
636        )
637        .await
638    }
639
640    // --- bridge ---
641
642    /// Queries `qorechain.bridge.v1.Query/Config`.
643    pub async fn bridge_config(&self) -> Result<qorechain::bridge::v1::QueryConfigResponse> {
644        self.grpc_query(
645            "/qorechain.bridge.v1.Query/Config",
646            &qorechain::bridge::v1::QueryConfigRequest {},
647        )
648        .await
649    }
650
651    /// Queries `qorechain.bridge.v1.Query/ChainConfig`.
652    pub async fn bridge_chain_config(
653        &self,
654        chain_id: impl Into<String>,
655    ) -> Result<qorechain::bridge::v1::QueryChainConfigResponse> {
656        self.grpc_query(
657            "/qorechain.bridge.v1.Query/ChainConfig",
658            &qorechain::bridge::v1::QueryChainConfigRequest {
659                chain_id: chain_id.into(),
660            },
661        )
662        .await
663    }
664
665    /// Queries `qorechain.bridge.v1.Query/ChainConfigs`.
666    pub async fn bridge_chain_configs(
667        &self,
668    ) -> Result<qorechain::bridge::v1::QueryChainConfigsResponse> {
669        self.grpc_query(
670            "/qorechain.bridge.v1.Query/ChainConfigs",
671            &qorechain::bridge::v1::QueryChainConfigsRequest {},
672        )
673        .await
674    }
675
676    /// Queries `qorechain.bridge.v1.Query/Validator`.
677    pub async fn bridge_validator(
678        &self,
679        address: impl Into<String>,
680    ) -> Result<qorechain::bridge::v1::QueryValidatorResponse> {
681        self.grpc_query(
682            "/qorechain.bridge.v1.Query/Validator",
683            &qorechain::bridge::v1::QueryValidatorRequest {
684                address: address.into(),
685            },
686        )
687        .await
688    }
689
690    /// Queries `qorechain.bridge.v1.Query/Validators`.
691    pub async fn bridge_validators(
692        &self,
693    ) -> Result<qorechain::bridge::v1::QueryValidatorsResponse> {
694        self.grpc_query(
695            "/qorechain.bridge.v1.Query/Validators",
696            &qorechain::bridge::v1::QueryValidatorsRequest {},
697        )
698        .await
699    }
700
701    /// Queries `qorechain.bridge.v1.Query/Operation`.
702    pub async fn bridge_operation(
703        &self,
704        id: impl Into<String>,
705    ) -> Result<qorechain::bridge::v1::QueryOperationResponse> {
706        self.grpc_query(
707            "/qorechain.bridge.v1.Query/Operation",
708            &qorechain::bridge::v1::QueryOperationRequest { id: id.into() },
709        )
710        .await
711    }
712
713    /// Queries `qorechain.bridge.v1.Query/Operations`.
714    pub async fn bridge_operations(
715        &self,
716    ) -> Result<qorechain::bridge::v1::QueryOperationsResponse> {
717        self.grpc_query(
718            "/qorechain.bridge.v1.Query/Operations",
719            &qorechain::bridge::v1::QueryOperationsRequest {},
720        )
721        .await
722    }
723}