use crate::utils::{
helpers::{get_manifest_path, parse_balance},
signer::create_signer,
};
use contract_extrinsics::{
BalanceVariant, ErrorVariant, ExtrinsicOptsBuilder, InstantiateCommandBuilder, InstantiateExec,
TokenMetadata,
};
use ink_env::{DefaultEnvironment, Environment};
use sp_core::Bytes;
use sp_weights::Weight;
use std::path::PathBuf;
use subxt::PolkadotConfig as DefaultConfig;
use subxt_signer::sr25519::Keypair;
pub struct UpOpts {
pub path: Option<PathBuf>,
pub constructor: String,
pub args: Vec<String>,
pub value: String,
pub gas_limit: Option<u64>,
pub proof_size: Option<u64>,
pub salt: Option<Bytes>,
pub url: url::Url,
pub suri: String,
}
pub async fn set_up_deployment(
up_opts: UpOpts,
) -> anyhow::Result<InstantiateExec<DefaultConfig, DefaultEnvironment, Keypair>> {
let manifest_path = get_manifest_path(&up_opts.path)?;
let token_metadata = TokenMetadata::query::<DefaultConfig>(&up_opts.url).await?;
let signer = create_signer(&up_opts.suri)?;
let extrinsic_opts = ExtrinsicOptsBuilder::new(signer)
.manifest_path(Some(manifest_path))
.url(up_opts.url.clone())
.done();
let value: BalanceVariant<<DefaultEnvironment as Environment>::Balance> =
parse_balance(&up_opts.value)?;
let instantiate_exec: InstantiateExec<DefaultConfig, DefaultEnvironment, Keypair> =
InstantiateCommandBuilder::new(extrinsic_opts)
.constructor(up_opts.constructor.clone())
.args(up_opts.args.clone())
.value(value.denominate_balance(&token_metadata)?)
.gas_limit(up_opts.gas_limit)
.proof_size(up_opts.proof_size)
.salt(up_opts.salt.clone())
.done()
.await?;
return Ok(instantiate_exec);
}
pub async fn dry_run_gas_estimate_instantiate(
instantiate_exec: &InstantiateExec<DefaultConfig, DefaultEnvironment, Keypair>,
) -> anyhow::Result<Weight> {
let instantiate_result = instantiate_exec.instantiate_dry_run().await?;
match instantiate_result.result {
Ok(_) => {
let ref_time = instantiate_exec
.args()
.gas_limit()
.unwrap_or_else(|| instantiate_result.gas_required.ref_time());
let proof_size = instantiate_exec
.args()
.proof_size()
.unwrap_or_else(|| instantiate_result.gas_required.proof_size());
Ok(Weight::from_parts(ref_time, proof_size))
},
Err(ref _err) => {
Err(anyhow::anyhow!(
"Pre-submission dry-run failed. Add gas_limit and proof_size manually to skip this step."
))
},
}
}
pub async fn instantiate_smart_contract(
instantiate_exec: InstantiateExec<DefaultConfig, DefaultEnvironment, Keypair>,
gas_limit: Weight,
) -> anyhow::Result<String, ErrorVariant> {
let instantiate_result = instantiate_exec.instantiate(Some(gas_limit)).await?;
Ok(instantiate_result.contract_address.to_string())
}