diff --git a/bin/sozo/src/commands/execute.rs b/bin/sozo/src/commands/execute.rs index 11253b16ae..a3726c475e 100644 --- a/bin/sozo/src/commands/execute.rs +++ b/bin/sozo/src/commands/execute.rs @@ -22,7 +22,7 @@ use crate::utils; pub struct ExecuteArgs { #[arg( - help = "The calls to be executed. Each call should include the address or tag, entrypoint, and calldata." + help = "The address or the tag (ex: dojo_examples:actions) of the contract to be executed." )] pub calls: Vec, @@ -40,28 +40,6 @@ pub struct ExecuteArgs { pub transaction: TransactionOptions, } -// #[derive(Debug, Args)] -// pub struct CallArgs { -// #[arg( -// help = "The address or the tag (ex: dojo_examples:actions) of the contract to be executed." -// )] -// pub tag_or_address: ResourceDescriptor, - -// #[arg(help = "The name of the entrypoint to be executed.")] -// pub entrypoint: String, - -// #[arg(short, long)] -// #[arg(help = "The calldata to be passed to the system. Comma separated values e.g., \ -// 0x12345,128,u256:9999999999. Sozo supports some prefixes that you can use to \ -// automatically parse some types. The supported prefixes are: -// - u256: A 256-bit unsigned integer. -// - sstr: A cairo short string. -// - str: A cairo string (ByteArray). -// - int: A signed integer. -// - no prefix: A cairo felt or any type that fit into one felt.")] -// pub calldata: Option, -// } - #[derive(Debug)] pub struct CallArgs { pub tag_or_address: ResourceDescriptor, @@ -73,7 +51,7 @@ impl CallArgs { fn from_string(s: &str) -> Result { let parts: Vec<&str> = s.split(',').collect(); if parts.len() < 2 { - return Err(anyhow!("Invalid call format")); + return Err(anyhow!("Invalid call format. Expected format: ,,,,...")); } Ok(CallArgs { @@ -84,21 +62,24 @@ impl CallArgs { } } +fn resolve_contract_address( + descriptor: &ResourceDescriptor, + world_diff: &WorldDiff, +) -> Result
{ + match descriptor { + ResourceDescriptor::Address(address) => Ok(*address), + ResourceDescriptor::Tag(tag) => { + let selector = naming::compute_selector_from_tag(tag); + world_diff + .get_contract_address(selector) + .ok_or_else(|| anyhow!("Contract {descriptor} not found in the world diff.")) + } + ResourceDescriptor::Name(_) => { + unimplemented!("Expected to be a resolved tag with default namespace.") + } + } +} -// impl CallArgs { -// fn from_string(s: &str) -> Result { -// let parts: Vec<&str> = s.split(',').collect(); -// if parts.len() < 2 { -// return Err(anyhow!("Invalid call format")); -// } - -// Ok(CallArgs { -// tag_or_address: parts[0].parse()?, -// entrypoint: parts[1].to_string(), -// calldata: if parts.len() > 2 { Some(parts[2..].join(",")) } else { None }, -// }) -// } -// } impl ExecuteArgs { pub fn run(self, config: &Config) -> Result<()> { @@ -130,6 +111,8 @@ impl ExecuteArgs { ) .await?; + let mut invoker = Invoker::new(&account, txn_config); + let call_args_list: Vec = self.calls.iter() .map(|s| CallArgs::from_string(s)) .collect::>>()?; @@ -137,17 +120,7 @@ impl ExecuteArgs { for call_args in call_args_list { let descriptor = call_args.tag_or_address.ensure_namespace(&profile_config.namespace.default); - let contract_address = match &descriptor { - ResourceDescriptor::Address(address) => Some(*address), - ResourceDescriptor::Tag(tag) => { - let selector = naming::compute_selector_from_tag(tag); - world_diff.get_contract_address(selector) - } - ResourceDescriptor::Name(_) => { - unimplemented!("Expected to be a resolved tag with default namespace.") - } - } - .ok_or_else(|| anyhow!("Contract {descriptor} not found in the world diff."))?; + let contract_address = resolve_contract_address(&descriptor, &world_diff)?; trace!( contract=?descriptor, @@ -168,11 +141,12 @@ impl ExecuteArgs { selector: snutils::get_selector_from_name(&call_args.entrypoint)?, }; - let invoker = Invoker::new(&account, txn_config); - let tx_result = invoker.invoke(call).await?; + invoker.add_call(call); - println!("{}", tx_result); + } + let tx_result = invoker.invoke().await?; + println!("{}", tx_result); Ok(())