use abstract_interface::{
AdapterDeployer, AppDeployer, DeployStrategy, RegisteredModule, RegistryQueryFns,
ServiceDeployer, StandaloneDeployer,
};
use cw_orch::{contract::Contract, prelude::*};
use serde::Serialize;
use crate::{
account::Account, client::AbstractClientResult, infrastructure::Infrastructure,
AbstractClientError, Environment,
};
use abstract_std::registry::NamespaceResponse;
pub struct Publisher<Chain: CwEnv> {
account: Account<Chain>,
}
impl<Chain: CwEnv> Publisher<Chain> {
pub fn new(account: &Account<Chain>) -> AbstractClientResult<Self> {
let namespace = account
.infrastructure()?
.registry
.namespaces(vec![account.id()?])?;
if namespace.namespaces.is_empty() {
return Err(AbstractClientError::NoNamespace {
account: account.id()?,
});
}
Ok(Self {
account: account.clone(),
})
}
pub fn new_with_namespace(
account: Account<Chain>,
namespace: &str,
) -> AbstractClientResult<Self> {
let namespace_response = account
.infrastructure()?
.registry
.namespace(namespace.try_into()?)?;
if let NamespaceResponse::Claimed(namespace_info) = namespace_response {
if namespace_info.account_id != account.id()? {
return Err(AbstractClientError::NamespaceClaimed {
namespace: namespace.to_string(),
account_id: namespace_info.account_id,
});
}
} else {
account.claim_namespace(namespace)?;
}
Ok(Self { account })
}
pub fn publish_app<
M: ContractInstance<Chain> + RegisteredModule + From<Contract<Chain>> + AppDeployer<Chain>,
>(
&self,
) -> AbstractClientResult<()> {
let contract = Contract::new(M::module_id().to_owned(), self.account.environment());
let app: M = contract.into();
app.deploy(M::module_version().parse()?, DeployStrategy::Try)
.map_err(Into::into)
}
pub fn publish_standalone<
M: ContractInstance<Chain>
+ RegisteredModule
+ From<Contract<Chain>>
+ StandaloneDeployer<Chain>,
>(
&self,
) -> AbstractClientResult<()> {
let contract = Contract::new(M::module_id().to_owned(), self.account.environment());
let standalone: M = contract.into();
standalone
.deploy(M::module_version().parse()?, DeployStrategy::Try)
.map_err(Into::into)
}
pub fn publish_adapter<
CustomInitMsg: Serialize,
M: ContractInstance<Chain>
+ RegisteredModule
+ From<Contract<Chain>>
+ AdapterDeployer<Chain, CustomInitMsg>,
>(
&self,
init_msg: CustomInitMsg,
) -> AbstractClientResult<M> {
let contract = Contract::new(M::module_id().to_owned(), self.account.environment());
let adapter: M = contract.into();
adapter.deploy(M::module_version().parse()?, init_msg, DeployStrategy::Try)?;
Ok(adapter)
}
pub fn publish_service<
M: ContractInstance<Chain> + RegisteredModule + From<Contract<Chain>> + ServiceDeployer<Chain>,
>(
&self,
init_msg: &<M as InstantiableContract>::InstantiateMsg,
) -> AbstractClientResult<()> {
let contract = Contract::new(M::module_id().to_owned(), self.account.environment());
let service: M = contract.into();
service
.deploy(M::module_version().parse()?, init_msg, DeployStrategy::Try)
.map_err(Into::into)
}
pub fn account(&self) -> &Account<Chain> {
&self.account
}
}