Skip to main content

nym_validator_client/nyxd/
mod.rs

1// Copyright 2021 - Nym Technologies SA <contact@nymtech.net>
2// SPDX-License-Identifier: Apache-2.0
3
4// TEMPORARY WORKAROUND:
5// those features are expected as the below should only get activated whenever
6// the corresponding features in tendermint-rpc are enabled transitively
7#![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// terrible name, but can't really change it because it will break so many uses
136#[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// terrible name, but can't really change it because it will break so many uses
194#[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
261// no trait bounds
262impl<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
363// queries
364impl<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    /// Obtains the hash of a block specified by the provided height.
401    ///
402    /// # Arguments
403    ///
404    /// * `height`: height of the block for which we want to obtain the hash.
405    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
440// signing
441impl<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        // the call to unchecked is fine here as we're converting directly from `AccountId`
465        // which must have been a valid bech32 address
466        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    /// Send funds from one address to another
515    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    /// Send funds from one address to multiple others
529    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    /// Grant a fee allowance from one address to another
542    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    /// Revoke a fee allowance from one address to another
566    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// ugh. is there a way to avoid that nasty trait implementation?
686
687#[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}