use crate::{
api::{
generated::api::gear::{calls::UploadProgram, Event as GearEvent},
signer::Signer,
Api,
},
result::Result,
};
use std::{fs, path::PathBuf};
use structopt::StructOpt;
#[derive(StructOpt, Debug)]
pub struct Create {
code: PathBuf,
#[structopt(default_value = "0x")]
salt: String,
#[structopt(default_value = "0x")]
init_payload: String,
#[structopt(default_value = "0")]
gas_limit: u64,
#[structopt(default_value = "0")]
value: u128,
}
impl Create {
pub async fn exec(&self, signer: Signer) -> Result<()> {
let events = signer.events().await?;
tokio::try_join!(
self.submit_program(&signer),
Api::wait_for(events, |event| {
matches!(event, GearEvent::MessageEnqueued { .. })
})
)?;
Ok(())
}
async fn submit_program(&self, api: &Signer) -> Result<()> {
let gas = if self.gas_limit == 0 {
api.get_init_gas_spent(
fs::read(&self.code)?.into(),
hex::decode(&self.init_payload.trim_start_matches("0x"))?.into(),
0,
None,
)
.await?
.min_limit
} else {
self.gas_limit
};
let gas_limit = api.cmp_gas_limit(gas).await?;
api.submit_program(UploadProgram {
code: fs::read(&self.code)?,
salt: hex::decode(&self.salt.trim_start_matches("0x"))?,
init_payload: hex::decode(&self.init_payload.trim_start_matches("0x"))?,
gas_limit,
value: self.value,
})
.await?;
Ok(())
}
}