1#![allow(unexpected_cfgs)]
8
9use crate::nyxd::contract_traits::{NymContractsProvider, TypedNymContracts};
10use crate::nyxd::cosmwasm_client::types::{
11 ChangeAdminResult, ContractCodeId, ExecuteResult, InstantiateOptions, InstantiateResult,
12 MigrateResult, SequenceResponse, SimulateResponse, UploadResult,
13};
14use crate::nyxd::cosmwasm_client::MaybeSigningClient;
15use crate::nyxd::error::NyxdError;
16use crate::nyxd::fee::DEFAULT_SIMULATED_GAS_MULTIPLIER;
17use crate::signing::direct_wallet::DirectSecp256k1HdWallet;
18use crate::signing::signer::NoSigner;
19use crate::signing::signer::OfflineSigner;
20use crate::signing::tx_signer::TxSigner;
21use crate::signing::AccountData;
22use crate::{DirectSigningReqwestRpcNyxdClient, QueryReqwestRpcNyxdClient};
23use async_trait::async_trait;
24use cosmrs::tendermint::{abci, evidence::Evidence, Genesis};
25use cosmrs::tx::{Raw, SignDoc};
26use cosmwasm_std::Addr;
27use nym_contracts_common::build_information::CONTRACT_BUILD_INFO_STORAGE_KEY;
28use nym_contracts_common::ContractBuildInformation;
29use nym_network_defaults::{ChainDetails, NymNetworkDetails};
30use serde::{de::DeserializeOwned, Serialize};
31use std::fmt::Debug;
32use std::time::SystemTime;
33use tendermint_rpc::endpoint::*;
34use tendermint_rpc::{Error as TendermintRpcError, Order};
35use url::Url;
36
37pub use crate::nyxd::{
38 cosmwasm_client::{
39 client_traits::{CosmWasmClient, SigningCosmWasmClient},
40 module_traits::{self, StakingQueryClient},
41 },
42 fee::Fee,
43};
44pub use crate::rpc::TendermintRpcClient;
45pub use bip39;
46pub use coin::Coin;
47pub use cosmrs::{
48 bank::MsgSend,
49 bip32, cosmwasm,
50 crypto::PublicKey,
51 query::{PageRequest, PageResponse},
52 tendermint::{
53 abci::{response::DeliverTx, types::ExecTxResult, Event, EventAttribute},
54 block::Height,
55 hash::{self, Algorithm, Hash},
56 validator::Info as TendermintValidatorInfo,
57 Time as TendermintTime,
58 },
59 tx::{self, Msg},
60 AccountId, Any, Coin as CosmosCoin, Denom, Gas,
61};
62pub use cosmwasm_std::Coin as CosmWasmCoin;
63pub use cw2;
64pub use cw3;
65pub use cw4;
66pub use cw_controllers;
67pub use fee::{gas_price::GasPrice, GasAdjustable, GasAdjustment};
68pub use prost::Name;
69pub use tendermint_rpc::endpoint::block::Response as BlockResponse;
70pub use tendermint_rpc::{
71 endpoint::{tx::Response as TxResponse, validators::Response as ValidatorResponse},
72 query::Query,
73 Paging, Request, Response, SimpleRequest,
74};
75
76pub use nym_ecash_contract_common;
77pub use nym_mixnet_contract_common;
78pub use nym_multisig_contract_common;
79pub use nym_network_monitors_contract_common;
80pub use nym_performance_contract_common;
81pub use nym_vesting_contract_common;
82
83#[cfg(feature = "http-client")]
84use crate::http_client;
85#[cfg(feature = "http-client")]
86use crate::{DirectSigningHttpRpcNyxdClient, QueryHttpRpcNyxdClient};
87#[cfg(feature = "http-client")]
88use cosmrs::rpc::{HttpClient, HttpClientUrl};
89
90pub mod coin;
91pub mod contract_traits;
92pub mod cosmwasm_client;
93pub mod error;
94pub mod fee;
95pub mod helpers;
96
97#[derive(Debug, Clone)]
98pub struct Config {
99 pub(crate) chain_details: ChainDetails,
100 pub(crate) contracts: TypedNymContracts,
101 pub(crate) gas_price: GasPrice,
102 pub(crate) simulated_gas_multiplier: f32,
103}
104
105impl Config {
106 pub fn try_from_nym_network_details(details: &NymNetworkDetails) -> Result<Self, NyxdError> {
107 Ok(Config {
108 chain_details: details.chain_details.clone(),
109 contracts: TypedNymContracts::try_from(details.contracts.clone())?,
110 gas_price: details.try_into()?,
111 simulated_gas_multiplier: DEFAULT_SIMULATED_GAS_MULTIPLIER,
112 })
113 }
114
115 pub fn with_simulated_gas_multplier(mut self, simulated_gas_multiplier: f32) -> Self {
116 self.simulated_gas_multiplier = simulated_gas_multiplier;
117 self
118 }
119}
120
121impl TryFrom<NymNetworkDetails> for Config {
122 type Error = NyxdError;
123
124 fn try_from(value: NymNetworkDetails) -> Result<Self, Self::Error> {
125 Config::try_from_nym_network_details(&value)
126 }
127}
128
129#[derive(Debug)]
130pub struct NyxdClient<C, S = NoSigner> {
131 client: MaybeSigningClient<C, S>,
132 config: Config,
133}
134
135#[cfg(feature = "http-client")]
137impl NyxdClient<HttpClient> {
138 pub fn connect<U>(config: Config, endpoint: U) -> Result<QueryHttpRpcNyxdClient, NyxdError>
139 where
140 U: TryInto<HttpClientUrl, Error = TendermintRpcError>,
141 {
142 let client = http_client(endpoint)?;
143
144 Ok(NyxdClient {
145 client: MaybeSigningClient::new(client, (&config).into()),
146 config,
147 })
148 }
149
150 pub fn connect_with_network_details<U>(
151 endpoint: U,
152 network_details: NymNetworkDetails,
153 ) -> Result<QueryHttpRpcNyxdClient, NyxdError>
154 where
155 U: TryInto<HttpClientUrl, Error = TendermintRpcError>,
156 {
157 let config = Config::try_from_nym_network_details(&network_details)?;
158 Self::connect(config, endpoint)
159 }
160
161 pub fn connect_to_default_env<U>(endpoint: U) -> Result<QueryHttpRpcNyxdClient, NyxdError>
162 where
163 U: TryInto<HttpClientUrl, Error = TendermintRpcError>,
164 {
165 Self::connect_with_network_details(endpoint, NymNetworkDetails::new_from_env())
166 }
167}
168
169#[allow(deprecated)]
170impl NyxdClient<crate::ReqwestRpcClient> {
171 pub fn connect_reqwest(
172 config: Config,
173 endpoint: Url,
174 ) -> Result<QueryReqwestRpcNyxdClient, NyxdError> {
175 let client = crate::ReqwestRpcClient::new(endpoint);
176
177 Ok(NyxdClient {
178 client: MaybeSigningClient::new(client, (&config).into()),
179 config,
180 })
181 }
182}
183
184impl<C> NyxdClient<C> {
185 pub fn new(config: Config, client: C) -> Self {
186 NyxdClient {
187 client: MaybeSigningClient::new(client, (&config).into()),
188 config,
189 }
190 }
191}
192
193#[cfg(feature = "http-client")]
195impl NyxdClient<HttpClient, DirectSecp256k1HdWallet> {
196 pub fn connect_with_mnemonic<U>(
197 config: Config,
198 endpoint: U,
199 mnemonic: bip39::Mnemonic,
200 ) -> Result<DirectSigningHttpRpcNyxdClient, NyxdError>
201 where
202 U: TryInto<HttpClientUrl, Error = TendermintRpcError>,
203 {
204 let client = http_client(endpoint)?;
205
206 let prefix = &config.chain_details.bech32_account_prefix;
207 let wallet = DirectSecp256k1HdWallet::checked_from_mnemonic(prefix, mnemonic)?;
208 Ok(Self::connect_with_signer(config, client, wallet))
209 }
210
211 pub fn connect_with_mnemonic_and_network_details<U>(
212 endpoint: U,
213 network_details: NymNetworkDetails,
214 mnemonic: bip39::Mnemonic,
215 ) -> Result<DirectSigningHttpRpcNyxdClient, NyxdError>
216 where
217 U: TryInto<HttpClientUrl, Error = TendermintRpcError>,
218 {
219 let config = Config::try_from_nym_network_details(&network_details)?;
220 Self::connect_with_mnemonic(config, endpoint, mnemonic)
221 }
222}
223
224#[allow(deprecated)]
225impl NyxdClient<crate::ReqwestRpcClient, DirectSecp256k1HdWallet> {
226 pub fn connect_reqwest_with_mnemonic(
227 config: Config,
228 endpoint: Url,
229 mnemonic: bip39::Mnemonic,
230 ) -> DirectSigningReqwestRpcNyxdClient {
231 let client = crate::ReqwestRpcClient::new(endpoint);
232
233 let prefix = &config.chain_details.bech32_account_prefix;
234 let wallet = DirectSecp256k1HdWallet::from_mnemonic(prefix, mnemonic);
235 Self::connect_with_signer(config, client, wallet)
236 }
237}
238
239impl<C, S> NyxdClient<C, S>
240where
241 S: OfflineSigner,
242{
243 pub fn connect_with_signer(config: Config, client: C, signer: S) -> NyxdClient<C, S> {
244 NyxdClient {
245 client: MaybeSigningClient::new_signing(client, signer, (&config).into()),
246 config,
247 }
248 }
249}
250
251#[cfg(feature = "http-client")]
252impl<S> NyxdClient<HttpClient, S> {
253 pub fn change_endpoint<U>(&mut self, new_endpoint: U) -> Result<(), NyxdError>
254 where
255 U: TryInto<HttpClientUrl, Error = TendermintRpcError>,
256 {
257 self.client.change_endpoint(new_endpoint)
258 }
259}
260
261impl<C, S> NyxdClient<C, S> {
263 pub fn new_signing(config: Config, client: C, signer: S) -> Self
264 where
265 S: OfflineSigner,
266 {
267 NyxdClient {
268 client: MaybeSigningClient::new_signing(client, signer, (&config).into()),
269 config,
270 }
271 }
272
273 pub fn clone_query_client(&self) -> NyxdClient<C>
274 where
275 C: Clone,
276 {
277 NyxdClient {
278 client: self.client.clone_query_client(),
279 config: self.config.clone(),
280 }
281 }
282
283 pub fn current_config(&self) -> &Config {
284 &self.config
285 }
286
287 pub fn current_chain_details(&self) -> &ChainDetails {
288 &self.config.chain_details
289 }
290
291 pub fn set_mixnet_contract_address(&mut self, address: AccountId) {
292 self.config.contracts.mixnet_contract_address = Some(address);
293 }
294
295 pub fn set_vesting_contract_address(&mut self, address: AccountId) {
296 self.config.contracts.vesting_contract_address = Some(address);
297 }
298
299 pub fn set_ecash_contract_address(&mut self, address: AccountId) {
300 self.config.contracts.ecash_contract_address = Some(address);
301 }
302
303 pub fn set_multisig_contract_address(&mut self, address: AccountId) {
304 self.config.contracts.multisig_contract_address = Some(address);
305 }
306
307 pub fn set_node_families_contract_address(&mut self, address: AccountId) {
308 self.config.contracts.node_families_contract_address = Some(address);
309 }
310
311 pub fn set_simulated_gas_multiplier(&mut self, multiplier: f32) {
312 self.config.simulated_gas_multiplier = multiplier;
313 }
314
315 pub fn get_nym_contracts(&self) -> TypedNymContracts {
316 self.config.contracts.clone()
317 }
318}
319
320impl<C, S> NymContractsProvider for NyxdClient<C, S> {
321 fn mixnet_contract_address(&self) -> Option<&AccountId> {
322 self.config.contracts.mixnet_contract_address.as_ref()
323 }
324
325 fn vesting_contract_address(&self) -> Option<&AccountId> {
326 self.config.contracts.vesting_contract_address.as_ref()
327 }
328
329 fn performance_contract_address(&self) -> Option<&AccountId> {
330 self.config.contracts.performance_contract_address.as_ref()
331 }
332 fn network_monitors_contract_address(&self) -> Option<&AccountId> {
333 self.config
334 .contracts
335 .network_monitors_contract_address
336 .as_ref()
337 }
338
339 fn node_families_contract_address(&self) -> Option<&AccountId> {
340 self.config
341 .contracts
342 .node_families_contract_address
343 .as_ref()
344 }
345
346 fn ecash_contract_address(&self) -> Option<&AccountId> {
347 self.config.contracts.ecash_contract_address.as_ref()
348 }
349
350 fn dkg_contract_address(&self) -> Option<&AccountId> {
351 self.config.contracts.coconut_dkg_contract_address.as_ref()
352 }
353
354 fn group_contract_address(&self) -> Option<&AccountId> {
355 self.config.contracts.group_contract_address.as_ref()
356 }
357
358 fn multisig_contract_address(&self) -> Option<&AccountId> {
359 self.config.contracts.multisig_contract_address.as_ref()
360 }
361}
362
363impl<C, S> NyxdClient<C, S>
365where
366 C: TendermintRpcClient + Send + Sync,
367 S: Send + Sync,
368{
369 pub async fn get_account_public_key(
370 &self,
371 address: &AccountId,
372 ) -> Result<Option<cosmrs::crypto::PublicKey>, NyxdError> {
373 if let Some(account) = self.client.get_account(address).await? {
374 let base_account = account.try_get_base_account()?;
375 return Ok(base_account.pubkey);
376 }
377
378 Ok(None)
379 }
380
381 pub async fn get_current_block_timestamp(&self) -> Result<TendermintTime, NyxdError> {
382 self.get_block_timestamp(None).await
383 }
384
385 pub async fn get_block_timestamp(
386 &self,
387 height: Option<u32>,
388 ) -> Result<TendermintTime, NyxdError> {
389 Ok(self.client.get_block(height).await?.block.header.time)
390 }
391
392 pub async fn get_block(&self, height: Option<u32>) -> Result<BlockResponse, NyxdError> {
393 self.client.get_block(height).await
394 }
395
396 pub async fn get_current_block_height(&self) -> Result<Height, NyxdError> {
397 self.client.get_height().await
398 }
399
400 pub async fn get_block_hash(&self, height: u32) -> Result<Hash, NyxdError> {
406 self.client
407 .get_block(Some(height))
408 .await
409 .map(|block| block.block_id.hash)
410 }
411
412 pub async fn try_get_cw2_contract_version(
413 &self,
414 contract_address: &AccountId,
415 ) -> Option<cw2::ContractVersion> {
416 let raw_info = self
417 .query_contract_raw(contract_address, b"contract_info".to_vec())
418 .await
419 .ok()?;
420
421 serde_json::from_slice(&raw_info).ok()
422 }
423
424 pub async fn try_get_contract_build_information(
425 &self,
426 contract_address: &AccountId,
427 ) -> Option<ContractBuildInformation> {
428 let raw_info = self
429 .query_contract_raw(
430 contract_address,
431 CONTRACT_BUILD_INFO_STORAGE_KEY.as_bytes().to_vec(),
432 )
433 .await
434 .ok()?;
435
436 serde_json::from_slice(&raw_info).ok()
437 }
438}
439
440impl<C, S> NyxdClient<C, S>
442where
443 C: TendermintRpcClient + Send + Sync,
444 S: OfflineSigner + Send + Sync,
445 NyxdError: From<<S as OfflineSigner>::Error>,
446{
447 pub fn signing_account(&self) -> Result<&AccountData, NyxdError> {
448 Ok(self.find_account(&self.address())?)
449 }
450
451 pub fn address(&self) -> AccountId {
452 self.client.signer_addresses()[0].clone()
453 }
454
455 pub fn mix_coin(&self, amount: u128) -> Coin {
456 Coin::new(amount, &self.config.chain_details.mix_denom.base)
457 }
458
459 pub fn mix_coins(&self, amount: u128) -> Vec<Coin> {
460 vec![self.mix_coin(amount)]
461 }
462
463 pub fn cw_address(&self) -> Addr {
464 Addr::unchecked(self.address().as_ref())
467 }
468
469 pub async fn account_sequence(&self) -> Result<SequenceResponse, NyxdError> {
470 self.client.get_sequence(&self.address()).await
471 }
472
473 pub fn wrap_contract_execute_message<M>(
474 &self,
475 contract_address: &AccountId,
476 msg: &M,
477 funds: Vec<Coin>,
478 ) -> Result<cosmwasm::MsgExecuteContract, NyxdError>
479 where
480 M: ?Sized + Serialize,
481 {
482 Ok(cosmwasm::MsgExecuteContract {
483 sender: self.address(),
484 contract: contract_address.clone(),
485 msg: serde_json::to_vec(msg)?,
486 funds: funds.into_iter().map(Into::into).collect(),
487 })
488 }
489
490 pub async fn simulate<I, M>(
491 &self,
492 messages: I,
493 memo: impl Into<String> + Send + 'static,
494 ) -> Result<SimulateResponse, NyxdError>
495 where
496 I: IntoIterator<Item = M> + Send,
497 M: Msg,
498 {
499 self.client
500 .simulate(
501 &self.address(),
502 messages
503 .into_iter()
504 .map(|msg| msg.into_any())
505 .collect::<Result<Vec<_>, _>>()
506 .map_err(|_| {
507 NyxdError::SerializationError("custom simulate messages".to_owned())
508 })?,
509 memo,
510 )
511 .await
512 }
513
514 pub async fn send(
516 &self,
517 recipient: &AccountId,
518 amount: Vec<Coin>,
519 memo: impl Into<String> + Send + 'static,
520 fee: Option<Fee>,
521 ) -> Result<TxResponse, NyxdError> {
522 let fee = fee.unwrap_or(Fee::Auto(Some(self.config.simulated_gas_multiplier)));
523 self.client
524 .send_tokens(&self.address(), recipient, amount, fee, memo)
525 .await
526 }
527
528 pub async fn send_multiple(
530 &self,
531 msgs: Vec<(AccountId, Vec<Coin>)>,
532 memo: impl Into<String> + Send + 'static,
533 fee: Option<Fee>,
534 ) -> Result<TxResponse, NyxdError> {
535 let fee = fee.unwrap_or(Fee::Auto(Some(self.config.simulated_gas_multiplier)));
536 self.client
537 .send_tokens_multiple(&self.address(), msgs, fee, memo)
538 .await
539 }
540
541 pub async fn grant_allowance(
543 &self,
544 grantee: &AccountId,
545 spend_limit: Vec<Coin>,
546 expiration: Option<SystemTime>,
547 allowed_messages: Vec<String>,
548 memo: impl Into<String> + Send + 'static,
549 fee: Option<Fee>,
550 ) -> Result<TxResponse, NyxdError> {
551 let fee = fee.unwrap_or(Fee::Auto(Some(self.config.simulated_gas_multiplier)));
552 self.client
553 .grant_allowance(
554 &self.address(),
555 grantee,
556 spend_limit,
557 expiration,
558 allowed_messages,
559 fee,
560 memo,
561 )
562 .await
563 }
564
565 pub async fn revoke_allowance(
567 &self,
568 grantee: &AccountId,
569 memo: impl Into<String> + Send + 'static,
570 fee: Option<Fee>,
571 ) -> Result<TxResponse, NyxdError> {
572 let fee = fee.unwrap_or(Fee::Auto(Some(self.config.simulated_gas_multiplier)));
573 self.client
574 .revoke_allowance(&self.address(), grantee, fee, memo)
575 .await
576 }
577
578 pub async fn execute<M>(
579 &self,
580 contract_address: &AccountId,
581 msg: &M,
582 fee: Option<Fee>,
583 memo: impl Into<String> + Send + 'static,
584 funds: Vec<Coin>,
585 ) -> Result<ExecuteResult, NyxdError>
586 where
587 M: ?Sized + Serialize + Sync,
588 {
589 let fee = fee.unwrap_or(Fee::Auto(Some(self.config.simulated_gas_multiplier)));
590 self.client
591 .execute(&self.address(), contract_address, msg, fee, memo, funds)
592 .await
593 }
594
595 pub async fn execute_multiple<I, M>(
596 &self,
597 contract_address: &AccountId,
598 msgs: I,
599 fee: Option<Fee>,
600 memo: impl Into<String> + Send + 'static,
601 ) -> Result<ExecuteResult, NyxdError>
602 where
603 I: IntoIterator<Item = (M, Vec<Coin>)> + Send,
604 M: Serialize,
605 {
606 let fee = fee.unwrap_or(Fee::Auto(Some(self.config.simulated_gas_multiplier)));
607 self.client
608 .execute_multiple(&self.address(), contract_address, msgs, fee, memo)
609 .await
610 }
611
612 pub async fn upload(
613 &self,
614 wasm_code: Vec<u8>,
615 memo: impl Into<String> + Send + 'static,
616 fee: Option<Fee>,
617 ) -> Result<UploadResult, NyxdError> {
618 let fee = fee.unwrap_or(Fee::Auto(Some(self.config.simulated_gas_multiplier)));
619 self.client
620 .upload(&self.address(), wasm_code, fee, memo)
621 .await
622 }
623
624 pub async fn instantiate<M>(
625 &self,
626 code_id: ContractCodeId,
627 msg: &M,
628 label: String,
629 memo: impl Into<String> + Send + 'static,
630 options: Option<InstantiateOptions>,
631 fee: Option<Fee>,
632 ) -> Result<InstantiateResult, NyxdError>
633 where
634 M: ?Sized + Serialize + Sync,
635 {
636 let fee = fee.unwrap_or(Fee::Auto(Some(self.config.simulated_gas_multiplier)));
637 self.client
638 .instantiate(&self.address(), code_id, msg, label, fee, memo, options)
639 .await
640 }
641
642 pub async fn update_admin(
643 &self,
644 contract_address: &AccountId,
645 new_admin: &AccountId,
646 memo: impl Into<String> + Send + 'static,
647 fee: Option<Fee>,
648 ) -> Result<ChangeAdminResult, NyxdError> {
649 let fee = fee.unwrap_or(Fee::Auto(Some(self.config.simulated_gas_multiplier)));
650 self.client
651 .update_admin(&self.address(), contract_address, new_admin, fee, memo)
652 .await
653 }
654
655 pub async fn clear_admin(
656 &self,
657 contract_address: &AccountId,
658 memo: impl Into<String> + Send + 'static,
659 fee: Option<Fee>,
660 ) -> Result<ChangeAdminResult, NyxdError> {
661 let fee = fee.unwrap_or(Fee::Auto(Some(self.config.simulated_gas_multiplier)));
662 self.client
663 .clear_admin(&self.address(), contract_address, fee, memo)
664 .await
665 }
666
667 pub async fn migrate<M>(
668 &self,
669 contract_address: &AccountId,
670 code_id: ContractCodeId,
671 msg: &M,
672 memo: impl Into<String> + Send + 'static,
673 fee: Option<Fee>,
674 ) -> Result<MigrateResult, NyxdError>
675 where
676 M: ?Sized + Serialize + Sync,
677 {
678 let fee = fee.unwrap_or(Fee::Auto(Some(self.config.simulated_gas_multiplier)));
679 self.client
680 .migrate(&self.address(), contract_address, code_id, fee, msg, memo)
681 .await
682 }
683}
684
685#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
688#[cfg_attr(not(target_arch = "wasm32"), async_trait)]
689impl<C, S> TendermintRpcClient for NyxdClient<C, S>
690where
691 C: TendermintRpcClient + Send + Sync,
692 S: Send + Sync,
693{
694 async fn abci_info(&self) -> Result<abci::response::Info, TendermintRpcError> {
695 self.client.abci_info().await
696 }
697
698 async fn abci_query<V>(
699 &self,
700 path: Option<String>,
701 data: V,
702 height: Option<Height>,
703 prove: bool,
704 ) -> Result<abci_query::AbciQuery, TendermintRpcError>
705 where
706 V: Into<Vec<u8>> + Send,
707 {
708 self.client.abci_query(path, data, height, prove).await
709 }
710
711 async fn block<H>(&self, height: H) -> Result<block::Response, TendermintRpcError>
712 where
713 H: Into<Height> + Send,
714 {
715 self.client.block(height).await
716 }
717
718 async fn block_by_hash(
719 &self,
720 hash: Hash,
721 ) -> Result<block_by_hash::Response, TendermintRpcError> {
722 self.client.block_by_hash(hash).await
723 }
724
725 async fn latest_block(&self) -> Result<block::Response, TendermintRpcError> {
726 self.client.latest_block().await
727 }
728
729 async fn header<H>(&self, height: H) -> Result<header::Response, TendermintRpcError>
730 where
731 H: Into<Height> + Send,
732 {
733 self.client.header(height).await
734 }
735
736 async fn header_by_hash(
737 &self,
738 hash: Hash,
739 ) -> Result<header_by_hash::Response, TendermintRpcError> {
740 self.client.header_by_hash(hash).await
741 }
742
743 async fn block_results<H>(
744 &self,
745 height: H,
746 ) -> Result<block_results::Response, TendermintRpcError>
747 where
748 H: Into<Height> + Send,
749 {
750 self.client.block_results(height).await
751 }
752
753 async fn latest_block_results(&self) -> Result<block_results::Response, TendermintRpcError> {
754 self.client.latest_block_results().await
755 }
756
757 async fn block_search(
758 &self,
759 query: Query,
760 page: u32,
761 per_page: u8,
762 order: Order,
763 ) -> Result<block_search::Response, TendermintRpcError> {
764 self.client.block_search(query, page, per_page, order).await
765 }
766
767 async fn blockchain<H>(
768 &self,
769 min: H,
770 max: H,
771 ) -> Result<blockchain::Response, TendermintRpcError>
772 where
773 H: Into<Height> + Send,
774 {
775 self.client.blockchain(min, max).await
776 }
777
778 async fn broadcast_tx_async<T>(
779 &self,
780 tx: T,
781 ) -> Result<broadcast::tx_async::Response, TendermintRpcError>
782 where
783 T: Into<Vec<u8>> + Send,
784 {
785 TendermintRpcClient::broadcast_tx_async(&self.client, tx).await
786 }
787
788 async fn broadcast_tx_sync<T>(
789 &self,
790 tx: T,
791 ) -> Result<broadcast::tx_sync::Response, TendermintRpcError>
792 where
793 T: Into<Vec<u8>> + Send,
794 {
795 TendermintRpcClient::broadcast_tx_sync(&self.client, tx).await
796 }
797
798 async fn broadcast_tx_commit<T>(
799 &self,
800 tx: T,
801 ) -> Result<broadcast::tx_commit::Response, TendermintRpcError>
802 where
803 T: Into<Vec<u8>> + Send,
804 {
805 TendermintRpcClient::broadcast_tx_commit(&self.client, tx).await
806 }
807
808 async fn commit<H>(&self, height: H) -> Result<commit::Response, TendermintRpcError>
809 where
810 H: Into<Height> + Send,
811 {
812 self.client.commit(height).await
813 }
814
815 async fn consensus_params<H>(
816 &self,
817 height: H,
818 ) -> Result<consensus_params::Response, TendermintRpcError>
819 where
820 H: Into<Height> + Send,
821 {
822 self.client.consensus_params(height).await
823 }
824
825 async fn consensus_state(&self) -> Result<consensus_state::Response, TendermintRpcError> {
826 self.client.consensus_state().await
827 }
828
829 async fn validators<H>(
830 &self,
831 height: H,
832 paging: Paging,
833 ) -> Result<validators::Response, TendermintRpcError>
834 where
835 H: Into<Height> + Send,
836 {
837 TendermintRpcClient::validators(&self.client, height, paging).await
838 }
839
840 async fn latest_consensus_params(
841 &self,
842 ) -> Result<consensus_params::Response, TendermintRpcError> {
843 self.client.latest_consensus_params().await
844 }
845
846 async fn latest_commit(&self) -> Result<commit::Response, TendermintRpcError> {
847 self.client.latest_commit().await
848 }
849
850 async fn health(&self) -> Result<(), TendermintRpcError> {
851 self.client.health().await
852 }
853
854 async fn genesis<AppState>(&self) -> Result<Genesis<AppState>, TendermintRpcError>
855 where
856 AppState: Debug + Serialize + DeserializeOwned + Send,
857 {
858 self.client.genesis().await
859 }
860
861 async fn net_info(&self) -> Result<net_info::Response, TendermintRpcError> {
862 self.client.net_info().await
863 }
864
865 async fn status(&self) -> Result<status::Response, TendermintRpcError> {
866 self.client.status().await
867 }
868
869 async fn broadcast_evidence(
870 &self,
871 e: Evidence,
872 ) -> Result<evidence::Response, TendermintRpcError> {
873 self.client.broadcast_evidence(e).await
874 }
875
876 async fn tx(&self, hash: Hash, prove: bool) -> Result<TxResponse, TendermintRpcError> {
877 self.client.tx(hash, prove).await
878 }
879
880 async fn tx_search(
881 &self,
882 query: Query,
883 prove: bool,
884 page: u32,
885 per_page: u8,
886 order: Order,
887 ) -> Result<tx_search::Response, TendermintRpcError> {
888 self.client
889 .tx_search(query, prove, page, per_page, order)
890 .await
891 }
892
893 #[cfg(any(
894 feature = "tendermint-rpc-http-client",
895 feature = "tendermint-rpc-websocket-client"
896 ))]
897 async fn wait_until_healthy<T>(&self, timeout: T) -> Result<(), TendermintRpcError>
898 where
899 T: Into<core::time::Duration> + Send,
900 {
901 self.client.wait_until_healthy(timeout).await
902 }
903
904 async fn perform<R>(&self, request: R) -> Result<R::Output, TendermintRpcError>
905 where
906 R: SimpleRequest,
907 {
908 self.client.perform(request).await
909 }
910}
911
912impl<C, S> OfflineSigner for NyxdClient<C, S>
913where
914 S: OfflineSigner,
915{
916 type Error = S::Error;
917
918 fn get_accounts(&self) -> &[AccountData] {
919 self.client.get_accounts()
920 }
921
922 fn sign_direct_with_account(
923 &self,
924 signer: &AccountData,
925 sign_doc: SignDoc,
926 ) -> Result<Raw, Self::Error> {
927 self.client.sign_direct_with_account(signer, sign_doc)
928 }
929}
930
931#[async_trait]
932impl<C, S> SigningCosmWasmClient for NyxdClient<C, S>
933where
934 C: TendermintRpcClient + Send + Sync,
935 S: TxSigner + Send + Sync,
936 NyxdError: From<S::Error>,
937{
938 fn gas_price(&self) -> &GasPrice {
939 self.client.gas_price()
940 }
941
942 fn simulated_gas_multiplier(&self) -> f32 {
943 self.client.simulated_gas_multiplier()
944 }
945}