use crate::{
log::print_if_log_disabled,
sender::{SenderBuilder, SenderOptions},
DaemonAsync, DaemonBuilder, GrpcChannel,
};
use std::sync::Arc;
use bitcoin::secp256k1::All;
use super::{error::DaemonError, sender::Sender, state::DaemonState};
use cw_orch_core::environment::ChainInfoOwned;
pub const DEFAULT_DEPLOYMENT: &str = "default";
#[derive(Clone, Default)]
pub struct DaemonAsyncBuilder {
pub(crate) chain: Option<ChainInfoOwned>,
pub(crate) deployment_id: Option<String>,
pub(crate) state_path: Option<String>,
pub(crate) sender: Option<SenderBuilder<All>>,
pub(crate) sender_options: SenderOptions,
pub(crate) state: Option<DaemonState>,
}
impl DaemonAsyncBuilder {
pub fn chain(&mut self, chain: impl Into<ChainInfoOwned>) -> &mut Self {
self.chain = Some(chain.into());
self
}
pub fn deployment_id(&mut self, deployment_id: impl Into<String>) -> &mut Self {
self.deployment_id = Some(deployment_id.into());
self
}
pub fn mnemonic(&mut self, mnemonic: impl ToString) -> &mut Self {
self.sender = Some(SenderBuilder::Mnemonic(mnemonic.to_string()));
self
}
pub fn sender(&mut self, wallet: Sender<All>) -> &mut Self {
self.sender = Some(SenderBuilder::Sender(wallet));
self
}
pub fn authz_granter(&mut self, granter: impl ToString) -> &mut Self {
self.sender_options.set_authz_granter(granter);
self
}
pub fn fee_granter(&mut self, granter: impl ToString) -> &mut Self {
self.sender_options.set_fee_granter(granter);
self
}
pub fn hd_index(&mut self, index: u32) -> &mut Self {
self.sender_options.hd_index = Some(index);
self
}
pub fn state(&mut self, state: DaemonState) -> &mut Self {
self.state = Some(state);
self
}
#[allow(unused)]
pub(crate) fn state_path(&mut self, path: impl ToString) -> &mut Self {
self.state_path = Some(path.to_string());
self
}
pub async fn build(&self) -> Result<DaemonAsync, DaemonError> {
let chain_info = self
.chain
.clone()
.ok_or(DaemonError::BuilderMissing("chain information".into()))?;
let deployment_id = self
.deployment_id
.clone()
.unwrap_or(DEFAULT_DEPLOYMENT.to_string());
let state = match &self.state {
Some(state) => {
let mut state = state.clone();
state.chain_data = chain_info.clone();
state.deployment_id = deployment_id;
state
}
None => {
let json_file_path = self
.state_path
.clone()
.unwrap_or(DaemonState::state_file_path()?);
DaemonState::new(json_file_path, chain_info.clone(), deployment_id, false)?
}
};
let sender_options = self.sender_options.clone();
let sender = match self.sender.clone() {
Some(sender) => match sender {
SenderBuilder::Mnemonic(mnemonic) => Sender::from_mnemonic_with_options(
chain_info.clone(),
GrpcChannel::connect(&chain_info.grpc_urls, &chain_info.chain_id).await?,
&mnemonic,
sender_options,
)?,
SenderBuilder::Sender(mut sender) => {
sender.set_options(self.sender_options.clone());
sender
}
},
None => Sender::new_with_options(
chain_info.clone(),
GrpcChannel::connect(&chain_info.grpc_urls, &chain_info.chain_id).await?,
sender_options,
)?,
};
let daemon = DaemonAsync {
state,
sender: Arc::new(sender),
};
print_if_log_disabled()?;
Ok(daemon)
}
}
impl From<DaemonBuilder> for DaemonAsyncBuilder {
fn from(value: DaemonBuilder) -> Self {
DaemonAsyncBuilder {
chain: value.chain,
deployment_id: value.deployment_id,
sender_options: value.sender_options,
sender: value.sender,
state: value.state,
state_path: value.state_path,
}
}
}