From bd1fe3a5d9b27b5e9af11218b08e504abf352548 Mon Sep 17 00:00:00 2001 From: Ammar Arif Date: Fri, 29 Dec 2023 02:29:52 +0800 Subject: [PATCH] feat(sozo): wait for tx to be accepted (#1341) --- crates/sozo/src/commands/auth.rs | 4 ++++ crates/sozo/src/commands/execute.rs | 4 ++++ crates/sozo/src/commands/options/account.rs | 2 +- crates/sozo/src/commands/options/transaction.rs | 7 +++++++ crates/sozo/src/commands/register.rs | 4 ++++ crates/sozo/src/ops/auth.rs | 12 +++++++++--- crates/sozo/src/ops/execute.rs | 14 ++++++++++---- crates/sozo/src/ops/migration/migration_test.rs | 2 +- crates/sozo/src/ops/register.rs | 12 +++++++++--- 9 files changed, 49 insertions(+), 12 deletions(-) diff --git a/crates/sozo/src/commands/auth.rs b/crates/sozo/src/commands/auth.rs index 44dea9df7b..b6584a840b 100644 --- a/crates/sozo/src/commands/auth.rs +++ b/crates/sozo/src/commands/auth.rs @@ -6,6 +6,7 @@ use starknet::core::types::FieldElement; use super::options::account::AccountOptions; use super::options::starknet::StarknetOptions; +use super::options::transaction::TransactionOptions; use super::options::world::WorldOptions; use crate::ops::auth; @@ -33,6 +34,9 @@ pub enum AuthCommand { #[command(flatten)] account: AccountOptions, + + #[command(flatten)] + transaction: TransactionOptions, }, } diff --git a/crates/sozo/src/commands/execute.rs b/crates/sozo/src/commands/execute.rs index a2110a0231..6eeeada678 100644 --- a/crates/sozo/src/commands/execute.rs +++ b/crates/sozo/src/commands/execute.rs @@ -6,6 +6,7 @@ use starknet::core::types::FieldElement; use super::options::account::AccountOptions; use super::options::starknet::StarknetOptions; +use super::options::transaction::TransactionOptions; use crate::ops::execute; #[derive(Debug, Args)] @@ -29,6 +30,9 @@ pub struct ExecuteArgs { #[command(flatten)] pub account: AccountOptions, + + #[command(flatten)] + pub transaction: TransactionOptions, } impl ExecuteArgs { diff --git a/crates/sozo/src/commands/options/account.rs b/crates/sozo/src/commands/options/account.rs index 9936eebe81..7aa027a7bc 100644 --- a/crates/sozo/src/commands/options/account.rs +++ b/crates/sozo/src/commands/options/account.rs @@ -42,7 +42,7 @@ impl AccountOptions { env_metadata: Option<&Environment>, ) -> Result> where - P: Provider + Send + Sync + 'static, + P: Provider + Send + Sync, { let account_address = self.account_address(env_metadata)?; let signer = self.signer(env_metadata)?; diff --git a/crates/sozo/src/commands/options/transaction.rs b/crates/sozo/src/commands/options/transaction.rs index e1e4a6a94b..23874ac93d 100644 --- a/crates/sozo/src/commands/options/transaction.rs +++ b/crates/sozo/src/commands/options/transaction.rs @@ -11,6 +11,13 @@ pub struct TransactionOptions { the estimated fee which will be used as the max fee for the transaction. \ (max_fee = estimated_fee * multiplier)")] pub fee_estimate_multiplier: Option, + + #[arg(short, long)] + #[arg(help = "Wait until the transaction is accepted by the sequencer, returning the receipt.")] + #[arg(long_help = "Wait until the transaction is accepted by the sequencer, returning the \ + receipt. This will poll the transaction status until it gets accepted or \ + rejected by the sequencer.")] + pub wait: bool, } impl From for TxConfig { diff --git a/crates/sozo/src/commands/register.rs b/crates/sozo/src/commands/register.rs index 74cfa2ae22..6ff53cdfd6 100644 --- a/crates/sozo/src/commands/register.rs +++ b/crates/sozo/src/commands/register.rs @@ -6,6 +6,7 @@ use starknet::core::types::FieldElement; use super::options::account::AccountOptions; use super::options::starknet::StarknetOptions; +use super::options::transaction::TransactionOptions; use super::options::world::WorldOptions; use crate::ops::register; @@ -33,6 +34,9 @@ pub enum RegisterCommand { #[command(flatten)] account: AccountOptions, + + #[command(flatten)] + transaction: TransactionOptions, }, } diff --git a/crates/sozo/src/ops/auth.rs b/crates/sozo/src/ops/auth.rs index e2757f59e6..369313ee30 100644 --- a/crates/sozo/src/ops/auth.rs +++ b/crates/sozo/src/ops/auth.rs @@ -2,16 +2,17 @@ use anyhow::{Context, Result}; use dojo_world::contracts::cairo_utils; use dojo_world::contracts::world::WorldContract; use dojo_world::metadata::Environment; +use dojo_world::utils::TransactionWaiter; use crate::commands::auth::AuthCommand; pub async fn execute(command: AuthCommand, env_metadata: Option) -> Result<()> { match command { - AuthCommand::Writer { model, contract, world, starknet, account } => { + AuthCommand::Writer { model, contract, world, starknet, account, transaction } => { let world_address = world.address(env_metadata.as_ref())?; let provider = starknet.provider(env_metadata.as_ref())?; - let account = account.account(provider, env_metadata.as_ref()).await?; + let account = account.account(&provider, env_metadata.as_ref()).await?; let world = WorldContract::new(world_address, &account); let res = world @@ -20,7 +21,12 @@ pub async fn execute(command: AuthCommand, env_metadata: Option) -> .await .with_context(|| "Failed to send transaction")?; - println!("Transaction: {:#x}", res.transaction_hash); + if transaction.wait { + let receipt = TransactionWaiter::new(res.transaction_hash, &provider).await?; + println!("{}", serde_json::to_string_pretty(&receipt)?); + } else { + println!("Transaction hash: {:#x}", res.transaction_hash); + } } } diff --git a/crates/sozo/src/ops/execute.rs b/crates/sozo/src/ops/execute.rs index 9cc727badc..868f69993c 100644 --- a/crates/sozo/src/ops/execute.rs +++ b/crates/sozo/src/ops/execute.rs @@ -1,6 +1,7 @@ use anyhow::{Context, Result}; use dojo_world::metadata::Environment; use dojo_world::migration::strategy::generate_salt; +use dojo_world::utils::TransactionWaiter; use starknet::accounts::{Account, Call}; use starknet::core::types::{BlockId, BlockTag, FieldElement, FunctionCall}; use starknet::core::utils::{get_contract_address, get_selector_from_name}; @@ -10,7 +11,7 @@ use starknet::providers::Provider; use crate::commands::execute::ExecuteArgs; pub async fn execute(args: ExecuteArgs, env_metadata: Option) -> Result<()> { - let ExecuteArgs { contract, entrypoint, calldata, starknet, account } = args; + let ExecuteArgs { contract, entrypoint, calldata, starknet, account, transaction } = args; let provider = starknet.provider(env_metadata.as_ref())?; @@ -42,19 +43,24 @@ pub async fn execute(args: ExecuteArgs, env_metadata: Option) -> Re ) }; - let account = account.account(provider, env_metadata.as_ref()).await?; + let account = account.account(&provider, env_metadata.as_ref()).await?; let res = account .execute(vec![Call { calldata, to: contract_address, - selector: get_selector_from_name(&entrypoint).unwrap(), + selector: get_selector_from_name(&entrypoint)?, }]) .send() .await .with_context(|| "Failed to send transaction")?; - println!("Transaction: {:#x}", res.transaction_hash); + if transaction.wait { + let receipt = TransactionWaiter::new(res.transaction_hash, &provider).await?; + println!("{}", serde_json::to_string_pretty(&receipt)?); + } else { + println!("Transaction hash: {:#x}", res.transaction_hash); + } Ok(()) } diff --git a/crates/sozo/src/ops/migration/migration_test.rs b/crates/sozo/src/ops/migration/migration_test.rs index 3e1966208a..02742afd16 100644 --- a/crates/sozo/src/ops/migration/migration_test.rs +++ b/crates/sozo/src/ops/migration/migration_test.rs @@ -88,7 +88,7 @@ async fn migrate_with_small_fee_multiplier_will_fail() { &ws, &migration, &account, - Some(TransactionOptions { fee_estimate_multiplier: Some(0.2f64) }), + Some(TransactionOptions { fee_estimate_multiplier: Some(0.2f64), wait: false }), ) .await .is_err() diff --git a/crates/sozo/src/ops/register.rs b/crates/sozo/src/ops/register.rs index 5906a90fc6..c0d37d8199 100644 --- a/crates/sozo/src/ops/register.rs +++ b/crates/sozo/src/ops/register.rs @@ -1,17 +1,18 @@ use anyhow::{Context, Result}; use dojo_world::contracts::WorldContract; use dojo_world::metadata::Environment; +use dojo_world::utils::TransactionWaiter; use starknet::accounts::Account; use crate::commands::register::RegisterCommand; pub async fn execute(command: RegisterCommand, env_metadata: Option) -> Result<()> { match command { - RegisterCommand::Model { models, world, starknet, account } => { + RegisterCommand::Model { models, world, starknet, account, transaction } => { let world_address = world.address(env_metadata.as_ref())?; let provider = starknet.provider(env_metadata.as_ref())?; - let account = account.account(provider, env_metadata.as_ref()).await?; + let account = account.account(&provider, env_metadata.as_ref()).await?; let world = WorldContract::new(world_address, &account); let calls = models @@ -25,7 +26,12 @@ pub async fn execute(command: RegisterCommand, env_metadata: Option .await .with_context(|| "Failed to send transaction")?; - println!("Models registered at transaction: {:#x}", res.transaction_hash) + if transaction.wait { + let receipt = TransactionWaiter::new(res.transaction_hash, &provider).await?; + println!("{}", serde_json::to_string_pretty(&receipt)?); + } else { + println!("Transaction hash: {:#x}", res.transaction_hash); + } } } Ok(())