use std::fmt::Debug;
use super::super::{sender::Wallet, DaemonAsync};
use crate::{
queriers::{Bank, CosmWasm, Node},
CosmTxResponse, DaemonBuilder, DaemonError, DaemonState,
};
use cosmwasm_std::{Addr, Coin};
use cw_orch_core::{
contract::{interface_traits::Uploadable, WasmPath},
environment::{ChainState, DefaultQueriers, QueryHandler, TxHandler},
};
use cw_orch_traits::stargate::Stargate;
use serde::Serialize;
use tokio::runtime::Handle;
use tonic::transport::Channel;
#[derive(Clone)]
pub struct Daemon {
pub daemon: DaemonAsync,
pub rt_handle: Handle,
}
impl Daemon {
pub fn builder() -> DaemonBuilder {
DaemonBuilder::default()
}
pub fn channel(&self) -> Channel {
self.daemon.sender.grpc_channel.clone()
}
pub fn wallet(&self) -> Wallet {
self.daemon.sender.clone()
}
pub fn rebuild(&self) -> DaemonBuilder {
let mut builder = DaemonBuilder {
state: Some(self.state()),
..Default::default()
};
builder
.chain(self.daemon.sender.chain_info.clone())
.sender((*self.daemon.sender).clone());
builder
}
pub fn flush_state(&mut self) -> Result<(), DaemonError> {
self.daemon.flush_state()
}
}
impl ChainState for Daemon {
type Out = DaemonState;
fn state(&self) -> Self::Out {
self.daemon.state.clone()
}
}
impl TxHandler for Daemon {
type Response = CosmTxResponse;
type Error = DaemonError;
type ContractSource = WasmPath;
type Sender = Wallet;
fn sender(&self) -> Addr {
self.daemon.sender.address().unwrap()
}
fn set_sender(&mut self, sender: Self::Sender) {
self.daemon.sender = sender
}
fn upload<T: Uploadable>(&self, uploadable: &T) -> Result<Self::Response, DaemonError> {
self.rt_handle.block_on(self.daemon.upload(uploadable))
}
fn execute<E: Serialize>(
&self,
exec_msg: &E,
coins: &[cosmwasm_std::Coin],
contract_address: &Addr,
) -> Result<Self::Response, DaemonError> {
self.rt_handle
.block_on(self.daemon.execute(exec_msg, coins, contract_address))
}
fn instantiate<I: Serialize + Debug>(
&self,
code_id: u64,
init_msg: &I,
label: Option<&str>,
admin: Option<&Addr>,
coins: &[Coin],
) -> Result<Self::Response, DaemonError> {
self.rt_handle.block_on(
self.daemon
.instantiate(code_id, init_msg, label, admin, coins),
)
}
fn migrate<M: Serialize + Debug>(
&self,
migrate_msg: &M,
new_code_id: u64,
contract_address: &Addr,
) -> Result<Self::Response, DaemonError> {
self.rt_handle.block_on(
self.daemon
.migrate(migrate_msg, new_code_id, contract_address),
)
}
fn instantiate2<I: Serialize + Debug>(
&self,
code_id: u64,
init_msg: &I,
label: Option<&str>,
admin: Option<&Addr>,
coins: &[cosmwasm_std::Coin],
salt: cosmwasm_std::Binary,
) -> Result<Self::Response, Self::Error> {
self.rt_handle.block_on(
self.daemon
.instantiate2(code_id, init_msg, label, admin, coins, salt),
)
}
}
impl Stargate for Daemon {
fn commit_any<R>(
&self,
msgs: Vec<prost_types::Any>,
memo: Option<&str>,
) -> Result<Self::Response, Self::Error> {
self.rt_handle.block_on(
self.wallet().commit_tx_any(
msgs.iter()
.map(|msg| cosmrs::Any {
type_url: msg.type_url.clone(),
value: msg.value.clone(),
})
.collect(),
memo,
),
)
}
}
impl QueryHandler for Daemon {
type Error = DaemonError;
fn wait_blocks(&self, amount: u64) -> Result<(), DaemonError> {
self.rt_handle.block_on(self.daemon.wait_blocks(amount))?;
Ok(())
}
fn wait_seconds(&self, secs: u64) -> Result<(), DaemonError> {
self.rt_handle.block_on(self.daemon.wait_seconds(secs))?;
Ok(())
}
fn next_block(&self) -> Result<(), DaemonError> {
self.rt_handle.block_on(self.daemon.next_block())?;
Ok(())
}
}
impl DefaultQueriers for Daemon {
type Bank = Bank;
type Wasm = CosmWasm;
type Node = Node;
}