odra_cli/
utils.rs

1use odra::{
2    contract_def::HasIdent,
3    host::{Deployer, HostEnv, InstallConfig},
4    prelude::Addressable,
5    OdraContract
6};
7
8use crate::{ContractProvider, DeployedContractsContainer};
9
10const DEFAULT_CONTRACTS_FILE: &str = "resources/contracts.toml";
11
12/// Logs a message to the console.
13pub fn log<T: ToString>(msg: T) {
14    prettycli::info(&msg.to_string());
15}
16
17/// Returns the default contracts file path, checking for ODRA_CASPER_LIVENET_CHAIN_NAME
18/// environment variable. If the variable exists, returns `resources/{network_name}-contracts.toml`,
19/// otherwise returns the default contracts file path.
20pub(crate) fn get_default_contracts_file() -> String {
21    if let Ok(network_name) = std::env::var("ODRA_CASPER_LIVENET_CHAIN_NAME") {
22        format!("resources/{}-contracts.toml", network_name)
23    } else {
24        DEFAULT_CONTRACTS_FILE.to_string()
25    }
26}
27
28/// Trait that extends the functionality of OdraContract to include deployment capabilities.
29pub trait DeployerExt: Sized {
30    /// Contract that implements OdraContract and Deployer for Self
31    type Contract: OdraContract + 'static + Deployer<Self::Contract>;
32
33    /// Load an existing contract instance from container or deploy a new one.
34    fn load_or_deploy(
35        env: &HostEnv,
36        args: <<Self as DeployerExt>::Contract as OdraContract>::InitArgs,
37        container: &mut DeployedContractsContainer,
38        gas: u64
39    ) -> Result<<<Self as DeployerExt>::Contract as OdraContract>::HostRef, crate::deploy::Error>
40    {
41        if let Ok(contract) = container.contract_ref::<Self::Contract>(env) {
42            prettycli::info(&format!(
43                "Using existing contract {} at address {:?}",
44                <Self::Contract as OdraContract>::HostRef::ident(),
45                contract.address()
46            ));
47            Ok(contract)
48        } else {
49            env.set_gas(gas);
50            let contract = Self::Contract::try_deploy(env, args)?;
51            container.add_contract(&contract)?;
52            Ok(contract)
53        }
54    }
55
56    /// Load an existing contract instance from container or deploy a new one with a custom configuration.
57    fn load_or_deploy_with_cfg(
58        env: &HostEnv,
59        package_name: Option<String>,
60        args: <<Self as DeployerExt>::Contract as OdraContract>::InitArgs,
61        cfg: InstallConfig,
62        container: &mut DeployedContractsContainer,
63        gas: u64
64    ) -> Result<<<Self as DeployerExt>::Contract as OdraContract>::HostRef, crate::deploy::Error>
65    {
66        if let Ok(contract) =
67            container.contract_ref_named::<Self::Contract>(env, package_name.clone())
68        {
69            prettycli::info(&format!(
70                "Using existing contract {} at address {:?}",
71                <Self::Contract as OdraContract>::HostRef::ident(),
72                contract.address()
73            ));
74            Ok(contract)
75        } else {
76            env.set_gas(gas);
77            let contract = Self::Contract::try_deploy_with_cfg(env, args, cfg)?;
78            container.add_contract_named(&contract, package_name)?;
79            Ok(contract)
80        }
81    }
82}
83
84impl<T: OdraContract + Deployer<T> + 'static> DeployerExt for T {
85    type Contract = T;
86}