1use std::{fmt::Debug, ops::DerefMut};
2
3use super::super::senders::Wallet;
4use crate::{
5 queriers::{Bank, CosmWasmBase, Node},
6 senders::{builder::SenderBuilder, query::QuerySender},
7 CosmTxResponse, DaemonAsyncBase, DaemonBuilder, DaemonError, DaemonState,
8};
9use cosmwasm_std::{Addr, Coin};
10use cw_orch_core::{
11 contract::{interface_traits::Uploadable, WasmPath},
12 environment::{ChainInfoOwned, ChainState, DefaultQueriers, QueryHandler, TxHandler},
13};
14use cw_orch_traits::stargate::Stargate;
15use serde::Serialize;
16use tokio::runtime::Handle;
17use tonic::transport::Channel;
18
19use crate::senders::tx::TxSender;
20
21pub type Daemon = DaemonBase<Wallet>;
22
23#[derive(Clone)]
24pub struct DaemonBase<Sender> {
49 pub daemon: DaemonAsyncBase<Sender>,
50 pub rt_handle: Handle,
52}
53
54impl<Sender> DaemonBase<Sender> {
55 pub fn builder(chain: impl Into<ChainInfoOwned>) -> DaemonBuilder {
57 DaemonBuilder::new(chain)
58 }
59
60 pub fn sender_mut(&mut self) -> &mut Sender {
62 self.daemon.sender_mut()
63 }
64
65 pub fn sender(&self) -> &Sender {
67 self.daemon.sender()
68 }
69
70 pub fn new_sender<T: SenderBuilder>(
73 self,
74 sender_options: T,
75 ) -> DaemonBase<<T as SenderBuilder>::Sender> {
76 let new_daemon = self
77 .rt_handle
78 .block_on(self.daemon.new_sender(sender_options));
79 DaemonBase {
80 daemon: new_daemon,
81 rt_handle: self.rt_handle.clone(),
82 }
83 }
84
85 pub fn flush_state(&mut self) -> Result<(), DaemonError> {
88 self.daemon.flush_state()
89 }
90
91 pub fn chain_info(&self) -> &ChainInfoOwned {
93 self.daemon.chain_info()
94 }
95}
96
97impl<Sender: QuerySender> DaemonBase<Sender> {
98 pub fn channel(&self) -> Channel {
100 self.daemon.sender().channel()
101 }
102
103 pub fn rebuild(&self) -> DaemonBuilder {
107 DaemonBuilder {
108 state: Some(self.state()),
109 chain: self.daemon.chain_info().clone(),
110 deployment_id: Some(self.daemon.state.deployment_id.clone()),
111 state_path: None,
112 write_on_change: None,
113 handle: Some(self.rt_handle.clone()),
114 mnemonic: None,
115 is_test: false,
117 load_network: false,
119 }
120 }
121}
122
123impl Daemon {
125 #[deprecated = "Use `self.sender_mut().set_authz_granter(granter)` or change the sender builder options instead"]
126 pub fn authz_granter(&mut self, granter: &Addr) -> &mut Self {
128 self.sender_mut().set_authz_granter(granter);
129 self
130 }
131
132 #[deprecated = "Use `self.sender_mut().set_fee_granter(granter)` or change the sender builder options instead"]
133 pub fn fee_granter(&mut self, granter: &Addr) -> &mut Self {
135 self.sender_mut().set_fee_granter(granter);
136 self
137 }
138}
139
140impl<Sender> ChainState for DaemonBase<Sender> {
141 type Out = DaemonState;
142
143 fn state(&self) -> Self::Out {
144 self.daemon.state.clone()
145 }
146
147 fn can_load_state_from_state_file(&self) -> bool {
148 true
149 }
150}
151
152impl<Sender: TxSender> TxHandler for DaemonBase<Sender> {
154 type Response = CosmTxResponse;
155 type Error = DaemonError;
156 type ContractSource = WasmPath;
157 type Sender = Sender;
158
159 fn sender(&self) -> &Self::Sender {
160 self.daemon.sender()
161 }
162
163 fn sender_addr(&self) -> Addr {
164 self.daemon.sender_addr()
165 }
166
167 fn set_sender(&mut self, sender: Self::Sender) {
170 let mut daemon_sender = self.daemon.sender_mut();
171 (*daemon_sender.deref_mut()) = sender;
172 }
173
174 fn upload<T: Uploadable>(&self, uploadable: &T) -> Result<Self::Response, DaemonError> {
175 self.rt_handle.block_on(self.daemon.upload(uploadable))
176 }
177
178 fn execute<E: Serialize>(
179 &self,
180 exec_msg: &E,
181 coins: &[cosmwasm_std::Coin],
182 contract_address: &Addr,
183 ) -> Result<Self::Response, DaemonError> {
184 self.rt_handle
185 .block_on(self.daemon.execute(exec_msg, coins, contract_address))
186 }
187
188 fn instantiate<I: Serialize + Debug>(
189 &self,
190 code_id: u64,
191 init_msg: &I,
192 label: Option<&str>,
193 admin: Option<&Addr>,
194 coins: &[Coin],
195 ) -> Result<Self::Response, DaemonError> {
196 self.rt_handle.block_on(
197 self.daemon
198 .instantiate(code_id, init_msg, label, admin, coins),
199 )
200 }
201
202 fn migrate<M: Serialize + Debug>(
203 &self,
204 migrate_msg: &M,
205 new_code_id: u64,
206 contract_address: &Addr,
207 ) -> Result<Self::Response, DaemonError> {
208 self.rt_handle.block_on(
209 self.daemon
210 .migrate(migrate_msg, new_code_id, contract_address),
211 )
212 }
213
214 fn instantiate2<I: Serialize + Debug>(
215 &self,
216 code_id: u64,
217 init_msg: &I,
218 label: Option<&str>,
219 admin: Option<&Addr>,
220 coins: &[cosmwasm_std::Coin],
221 salt: cosmwasm_std::Binary,
222 ) -> Result<Self::Response, Self::Error> {
223 self.rt_handle.block_on(
224 self.daemon
225 .instantiate2(code_id, init_msg, label, admin, coins, salt),
226 )
227 }
228
229 fn upload_with_access_config<T: Uploadable>(
230 &self,
231 contract_source: &T,
232 access_config: Option<cw_orch_core::environment::AccessConfig>,
233 ) -> Result<Self::Response, Self::Error> {
234 self.rt_handle.block_on(
235 self.daemon
236 .upload_with_access_config(contract_source, access_config),
237 )
238 }
239
240 fn bank_send(
241 &self,
242 receiver: &Addr,
243 amount: &[cosmwasm_std::Coin],
244 ) -> Result<Self::Response, Self::Error> {
245 self.rt_handle
246 .block_on(self.sender().bank_send(receiver, amount))
247 .map_err(Into::into)
248 .map(Into::into)
249 }
250}
251
252impl<Sender: TxSender> Stargate for DaemonBase<Sender> {
253 fn commit_any(
254 &self,
255 msgs: Vec<prost_types::Any>,
256 memo: Option<&str>,
257 ) -> Result<Self::Response, Self::Error> {
258 self.rt_handle
259 .block_on(
260 self.sender().commit_tx_any(
261 msgs.iter()
262 .map(|msg| cosmrs::Any {
263 type_url: msg.type_url.clone(),
264 value: msg.value.clone(),
265 })
266 .collect(),
267 memo,
268 ),
269 )
270 .map_err(Into::into)
271 }
272}
273
274impl<Sender: QuerySender> QueryHandler for DaemonBase<Sender> {
275 type Error = DaemonError;
276
277 fn wait_blocks(&self, amount: u64) -> Result<(), DaemonError> {
278 self.rt_handle.block_on(self.daemon.wait_blocks(amount))?;
279
280 Ok(())
281 }
282
283 fn wait_seconds(&self, secs: u64) -> Result<(), DaemonError> {
284 self.rt_handle.block_on(self.daemon.wait_seconds(secs))?;
285
286 Ok(())
287 }
288
289 fn next_block(&self) -> Result<(), DaemonError> {
290 self.rt_handle.block_on(self.daemon.next_block())?;
291
292 Ok(())
293 }
294}
295
296impl<Sender: QuerySender> DefaultQueriers for DaemonBase<Sender> {
297 type Bank = Bank;
298 type Wasm = CosmWasmBase<Sender>;
299 type Node = Node;
300}