use crate::senders::builder::SenderBuilder;
use crate::{DaemonAsyncBuilder, DaemonBase, DaemonState, Wallet, RUNTIME};
use cw_orch_core::environment::ChainInfoOwned;
use super::super::error::DaemonError;
#[derive(Clone)]
pub struct DaemonBuilder {
pub(crate) chain: ChainInfoOwned,
pub(crate) handle: Option<tokio::runtime::Handle>,
pub(crate) deployment_id: Option<String>,
pub(crate) state_path: Option<String>,
pub(crate) state: Option<DaemonState>,
pub(crate) write_on_change: Option<bool>,
pub(crate) is_test: bool,
pub(crate) load_network: bool,
pub(crate) mnemonic: Option<String>,
}
impl DaemonBuilder {
pub fn new(chain: impl Into<ChainInfoOwned>) -> Self {
Self {
chain: chain.into(),
handle: None,
deployment_id: None,
state_path: None,
state: None,
write_on_change: None,
mnemonic: None,
is_test: false,
load_network: true,
}
}
pub fn handle(&mut self, handle: &tokio::runtime::Handle) -> &mut Self {
self.handle = Some(handle.clone());
self
}
pub fn deployment_id(&mut self, deployment_id: impl Into<String>) -> &mut Self {
self.deployment_id = Some(deployment_id.into());
self
}
pub fn grpc_url(&mut self, url: impl Into<String>) -> &mut Self {
self.chain.grpc_urls = vec![url.into()];
self
}
pub fn mnemonic(&mut self, mnemonic: impl Into<String>) -> &mut Self {
self.mnemonic = Some(mnemonic.into());
self
}
pub fn gas(&mut self, gas_denom: Option<&str>, gas_price: Option<f64>) -> &mut Self {
if let Some(denom) = gas_denom {
self.chain.gas_denom = denom.to_string()
}
if let Some(price) = gas_price {
self.chain.gas_price = price;
}
self
}
pub fn state(&mut self, state: DaemonState) -> &mut Self {
self.state = Some(state);
self
}
pub fn write_on_change(&mut self, write_on_change: bool) -> &mut Self {
self.write_on_change = Some(write_on_change);
self
}
pub fn chain(&mut self, chain: impl Into<ChainInfoOwned>) -> &mut Self {
self.chain = chain.into();
self
}
pub fn is_test(&mut self, is_test: bool) -> &mut Self {
self.is_test = is_test;
self
}
pub fn load_network(&mut self, load_network: bool) -> &mut Self {
self.load_network = load_network;
self
}
pub fn build(&self) -> Result<DaemonBase<Wallet>, DaemonError> {
let rt_handle = self
.handle
.clone()
.unwrap_or_else(|| RUNTIME.handle().clone());
let builder = self.clone();
let daemon = rt_handle.block_on(DaemonAsyncBuilder::from(builder).build())?;
Ok(DaemonBase { rt_handle, daemon })
}
pub fn build_sender<T: SenderBuilder>(
&self,
sender_options: T,
) -> Result<DaemonBase<T::Sender>, DaemonError> {
let rt_handle = self
.handle
.clone()
.unwrap_or_else(|| RUNTIME.handle().clone());
let builder = self.clone();
let daemon =
rt_handle.block_on(DaemonAsyncBuilder::from(builder).build_sender(sender_options))?;
Ok(DaemonBase { rt_handle, daemon })
}
#[allow(unused)]
pub(crate) fn state_path(&mut self, path: impl ToString) -> &mut Self {
self.state_path = Some(path.to_string());
self
}
}
#[cfg(test)]
mod test {
use cw_orch_core::environment::TxHandler;
use cw_orch_networks::networks::JUNO_1;
use crate::{DaemonBase, DaemonBuilder, Wallet};
pub const DUMMY_MNEMONIC:&str = "chapter wrist alcohol shine angry noise mercy simple rebel recycle vehicle wrap morning giraffe lazy outdoor noise blood ginger sort reunion boss crowd dutch";
#[test]
#[serial_test::serial]
fn grpc_override() {
let mut chain = JUNO_1;
chain.grpc_urls = &[];
let daemon = DaemonBuilder::new(chain)
.mnemonic(DUMMY_MNEMONIC)
.grpc_url(JUNO_1.grpc_urls[0])
.build()
.unwrap();
assert_eq!(daemon.daemon.sender().chain_info.grpc_urls.len(), 1);
assert_eq!(
daemon.daemon.sender().chain_info.grpc_urls[0],
JUNO_1.grpc_urls[0].to_string(),
);
}
#[test]
#[serial_test::serial]
fn fee_amount_override() {
let fee_amount = 1.3238763;
let daemon = DaemonBuilder::new(JUNO_1)
.mnemonic(DUMMY_MNEMONIC)
.gas(None, Some(fee_amount))
.build()
.unwrap();
println!("chain {:?}", daemon.daemon.sender().chain_info);
assert_eq!(daemon.daemon.sender().chain_info.gas_price, fee_amount);
}
#[test]
#[serial_test::serial]
fn fee_denom_override() {
let token = "my_token";
let daemon = DaemonBuilder::new(JUNO_1)
.mnemonic(DUMMY_MNEMONIC)
.gas(Some(token), None)
.build()
.unwrap();
assert_eq!(
daemon.daemon.sender().chain_info.gas_denom,
token.to_string()
);
}
#[test]
#[serial_test::serial]
fn fee_override() {
let fee_amount = 1.3238763;
let token = "my_token";
let daemon = DaemonBuilder::new(JUNO_1)
.mnemonic(DUMMY_MNEMONIC)
.gas(Some(token), Some(fee_amount))
.build()
.unwrap();
assert_eq!(
daemon.daemon.sender().chain_info.gas_denom,
token.to_string()
);
assert_eq!(daemon.daemon.sender().chain_info.gas_price, fee_amount);
}
#[test]
#[serial_test::serial]
fn hd_index_re_generates_sender() -> anyhow::Result<()> {
let daemon = DaemonBuilder::new(JUNO_1)
.mnemonic(DUMMY_MNEMONIC)
.is_test(true)
.build()
.unwrap();
let indexed_daemon: DaemonBase<Wallet> = daemon
.rebuild()
.build_sender(daemon.sender().options().hd_index(56))?;
assert_ne!(daemon.sender_addr(), indexed_daemon.sender_addr());
Ok(())
}
}