Interface Collection
Follow the same process as for a single contract to generate the interfaces for your contract.
Now that you have your contract interfaces you can export a comprehensive wrapper of your application that can easily be used by others.
The idea is simple. If you can provide an easy way for others to deploy your contracts/application to their environments, then you’re making it extremely easy for them to use and build on your application.
As an example we will create a deployment for the Abstract smart-contract framework.
The deployment
The deployment can be represented by a struct containing all the contracts that are uploaded and instantiated when the protocol is deployed.
// Our Abstract deployment
pub struct Abstract<Chain> {
pub ans_host: AnsHost<Chain>,
pub version_control: VersionControl<Chain>,
}
Implementing Deploy
Now we can implement the cw_orch::Deploy
trait for the Abstract
struct.
use cw_orch::prelude::*;
use cw_orch::error::CwOrchError;
use cw_multi_test::ContractWrapper;
use abstract_interface::{AnsHost, VersionControl};
pub struct Abstract<Chain: CwEnv> {
pub ans_host: AnsHost<Chain>,
pub version_control: VersionControl<Chain>,
}
impl<Chain: CwEnv> cw_orch::Deploy<Chain> for Abstract<Chain> {
// We don't have a custom error type
type Error = CwOrchError;
type DeployData = semver::Version;
fn store_on(chain: Chain) -> Result<Self, Self::Error> {
// "abstract" is a reserved keyword in rust!
let mut abstrct = Abstract::new(chain);
// Upload the contracts to the chain
abstrct.ans_host.upload()?;
abstrct.version_control.upload()?;
Ok(abstrct)
}
fn deploy_on(chain: Chain, version: semver::Version) -> Result<Self, CwOrchError> {
// ########### Upload ##############
let abstrct = Self::store_on(chain)?;
// ########### Instantiate ##############
abstrct.ans_host.instantiate(
&abstract_core::ans_host::InstantiateMsg {},
Some(sender),
None,
)?;
abstrct.version_control.instantiate(
&abstract_core::version_control::InstantiateMsg {},
Some(sender),
None,
)?;
// ...
Ok(abstrct)
}
fn load_from(chain: Chain) -> Result<Self, Self::Error> {
let abstrct = Self::new(chain);
Ok(abstrct)
}
}
Now Abstract
is an application that can be deployed to a mock and real environment with one line of code.
fn setup_test(mock: Mock) -> Result<(), CwOrchError> {
let version = "1.0.0".parse().unwrap();
// Deploy abstract
let abstract_ = Abstract::deploy_on(mock.clone(), version)?;
}
And then when setting up your own deployment you can load these applications to access their contracts (for accessing configuration, addresses, …)
impl<Chain: CwEnv> cw_orch::Deploy<Chain> for MyApplication<Chain> {
/// ...
fn deploy_on(chain: Chain, _data: Empty) -> Result<Self, CwOrchError> {
let abstract_: Abstract = Abstract::load_from(chain)?;
/// ... do stuff with Abstract
}
}