From eeb3c039e4d34bfee8bc90fad188df2553aeb6a8 Mon Sep 17 00:00:00 2001 From: Nikolaus Heger Date: Sun, 11 Jan 2026 20:49:03 +0800 Subject: [PATCH 01/10] add high security example --- scripts/high_security_example.sh | 54 ++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 scripts/high_security_example.sh diff --git a/scripts/high_security_example.sh b/scripts/high_security_example.sh new file mode 100644 index 0000000..5101878 --- /dev/null +++ b/scripts/high_security_example.sh @@ -0,0 +1,54 @@ +#!/bin/bash + +# High Security Example Script +# This script demonstrates the high security features of the Quantus blockchain. +# It sets up a guardian for an account and demonstrates the reversible transfer functionality. +# It also demonstrates the recovery pallet functionality. + +# set this to your binary +alias quantus="./target/release/quantus --node-url ws://127.0.0.1:9944" + +# Alice sets charlie as her guardian with a 1 hour delay +quantus high-security set --from crystal_alice --interceptor crystal_charlie --delay-seconds 3600 + +# Check the status of the high security +quantus high-security status --account crystal_alice + +# fail case 1 Alice sets bob as her interceptor - this should fail because alice already has a guardian +quantus high-security set --from crystal_alice --interceptor crystal_bob --delay-seconds 3600 + +# fail case 2 could also try to send a normal tx - should fail +quantus send --from crystal_alice --to crystal_bob --amount 9999 + +# fail case 3 also send a reversible with a different delay more or less - should fail +quantus reversible schedule-transfer-with-delay --from crystal_alice --to crystal_bob --amount 555 --delay-seconds 90 + +# Check balances of Alice and Charlie +quantus balance --address crystal_alice +quantus balance --address crystal_charlie + +# Alice sends a reversible transfer to bob over 500000 coins of quantus over 1 hour delay +quantus reversible schedule-transfer-with-delay --from crystal_alice --to crystal_bob --amount 500000 --delay 3600 + +# Alice should be able to cancel the reversible transfer +# quantus reversible cancel --tx-id --from crystal_alice + +# Charlie intercepts the transfer and sends it to himself +quantus reversible schedule-transfer-with-delay --from crystal_charlie --to crystal_charlie --amount 555 --delay 3600 + +# Check balances of Alice, Bob, and Charlie +quantus balance --address crystal_alice +quantus balance --address crystal_bob +quantus balance --address crystal_charlie + +# Charlie pulls all money from Alice's account +# this is simply done by charlie making a transfer on behalf of alice which sends all money to charlie +# We need to use the proxy pallet for this +# because Charlie is a guardian for alice, charlie is also a recoverer through the recovery pallet. +# so we can use the recovery pallet to send all money to charlie +quantus recovery recover-all --rescuer crystal_charlie --lost crystal_alice --dest crystal_charlie + +# Check balances of Alice, Bob, and Charlie +quantus balance --address crystal_alice +quantus balance --address crystal_bob +quantus balance --address crystal_charlie \ No newline at end of file From 6b2d984df50f0eacc5df80bf57af99a937193532 Mon Sep 17 00:00:00 2001 From: Nikolaus Heger Date: Sun, 11 Jan 2026 20:50:39 +0800 Subject: [PATCH 02/10] replace finalize with execution mode, make fast execution default --- src/cli/batch.rs | 8 ++-- src/cli/common.rs | 83 ++++++++++++++++++++++++++++++-------- src/cli/generic_call.rs | 78 ++++++++++++++++++++++------------- src/cli/high_security.rs | 4 +- src/cli/mod.rs | 50 ++++++++++++++--------- src/cli/preimage.rs | 29 ++++++++----- src/cli/recovery.rs | 16 ++++---- src/cli/referenda.rs | 42 ++++++++++--------- src/cli/reversible.rs | 21 +++++----- src/cli/runtime.rs | 10 ++--- src/cli/scheduler.rs | 8 ++-- src/cli/send.rs | 18 ++++----- src/cli/storage.rs | 17 +++++--- src/cli/tech_collective.rs | 29 +++++++------ src/cli/tech_referenda.rs | 59 +++++++++++++++------------ src/cli/treasury.rs | 40 +++++++++++------- src/main.rs | 13 +++++- 17 files changed, 329 insertions(+), 196 deletions(-) diff --git a/src/cli/batch.rs b/src/cli/batch.rs index 4c7819f..b1b84c8 100644 --- a/src/cli/batch.rs +++ b/src/cli/batch.rs @@ -63,7 +63,7 @@ pub enum BatchCommands { pub async fn handle_batch_command( command: BatchCommands, node_url: &str, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> Result<()> { match command { BatchCommands::Send { @@ -86,7 +86,7 @@ pub async fn handle_batch_command( count, to, amount, - finalized, + execution_mode, ) .await, BatchCommands::Config { limits, info } => @@ -105,7 +105,7 @@ async fn handle_batch_send_command( count: Option, to: Option, amount: Option, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> Result<()> { // Create quantus chain client let quantus_client = QuantusClient::new(node_url).await?; @@ -166,7 +166,7 @@ async fn handle_batch_send_command( // Submit batch transaction let tx_hash = - batch_transfer(&quantus_client, &keypair, transfers, tip_amount, finalized).await?; + batch_transfer(&quantus_client, &keypair, transfers, tip_amount, execution_mode).await?; log_print!( "βœ… {} Batch transaction submitted! Hash: {:?}", diff --git a/src/cli/common.rs b/src/cli/common.rs index 7328737..b1932e6 100644 --- a/src/cli/common.rs +++ b/src/cli/common.rs @@ -7,6 +7,18 @@ use subxt::{ OnlineClient, }; +#[derive(Debug, Clone, Copy)] +pub struct ExecutionMode { + pub finalized: bool, + pub wait_for_transaction: bool, +} + +impl Default for ExecutionMode { + fn default() -> Self { + Self { finalized: false, wait_for_transaction: false } + } +} + /// Resolve address - if it's a wallet name, return the wallet's address /// If it's already an SS58 address, return it as is pub fn resolve_address(address_or_wallet_name: &str) -> Result { @@ -117,12 +129,13 @@ pub async fn get_incremented_nonce_with_client( /// /// By default (finalized=false), waits until transaction is in the best block (fast) /// With finalized=true, waits until transaction is in a finalized block (slow in PoW chains) +/// With wait_for_transaction=false, returns immediately after submission without waiting pub async fn submit_transaction( quantus_client: &crate::chain::client::QuantusClient, from_keypair: &crate::wallet::QuantumKeyPair, call: Call, tip: Option, - finalized: bool, + execution_mode: ExecutionMode, ) -> crate::error::Result where Call: subxt::tx::Payload, @@ -215,7 +228,12 @@ where crate::log_verbose!("πŸ“‹ Transaction submitted: {:?}", tx_progress); let tx_hash = tx_progress.extrinsic_hash(); - wait_tx_inclusion(&mut tx_progress, finalized).await?; + + if !execution_mode.wait_for_transaction { + return Ok(tx_hash); + } + + wait_tx_inclusion(&mut tx_progress, execution_mode.finalized).await?; return Ok(tx_hash); }, @@ -259,7 +277,7 @@ pub async fn submit_transaction_with_nonce( call: Call, tip: Option, nonce: u32, - finalized: bool, + execution_mode: ExecutionMode, ) -> crate::error::Result where Call: subxt::tx::Payload, @@ -301,7 +319,12 @@ where Ok(mut tx_progress) => { let tx_hash = tx_progress.extrinsic_hash(); log_verbose!("βœ… Transaction submitted successfully: {:?}", tx_hash); - wait_tx_inclusion(&mut tx_progress, finalized).await?; + + if !execution_mode.wait_for_transaction { + return Ok(tx_hash); + } + + wait_tx_inclusion(&mut tx_progress, execution_mode.finalized).await?; Ok(tx_hash) }, Err(e) => { @@ -324,46 +347,54 @@ async fn wait_tx_inclusion( ) -> Result<()> { use indicatif::{ProgressBar, ProgressStyle}; - // Create spinner (only in non-verbose mode) + let start_time = std::time::Instant::now(); + let spinner = if !crate::log::is_verbose() { let pb = ProgressBar::new_spinner(); pb.set_style( ProgressStyle::default_spinner() .tick_chars("⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏") - .template("{spinner:.cyan} {msg} {elapsed:.dim}") + .template("{spinner:.cyan} {msg}") .unwrap(), ); if finalized { - pb.set_message("Waiting for finalized block..."); + pb.set_message("Waiting for finalized block... (0s)"); } else { - pb.set_message("Waiting for block inclusion..."); + pb.set_message("Waiting for block inclusion... (0s)"); } - pb.enable_steady_tick(std::time::Duration::from_millis(100)); + pb.enable_steady_tick(std::time::Duration::from_millis(500)); Some(pb) } else { None }; while let Some(Ok(status)) = tx_progress.next().await { - crate::log_verbose!(" Transaction status: {:?}", status); + let elapsed_secs = start_time.elapsed().as_secs(); + crate::log_verbose!(" Transaction status: {:?} (elapsed: {}s)", status, elapsed_secs); match status { TxStatus::Validated => if let Some(ref pb) = spinner { - pb.set_message("Transaction validated βœ“"); + pb.set_message(format!("Transaction validated βœ“ ({}s)", elapsed_secs)); }, TxStatus::InBestBlock(block_hash) => { crate::log_verbose!(" Transaction included in block: {:?}", block_hash); if finalized { if let Some(ref pb) = spinner { - pb.set_message("In best block, waiting for finalization..."); + pb.set_message(format!( + "In best block, waiting for finalization... ({}s)", + elapsed_secs + )); } continue; } else { if let Some(pb) = spinner { - pb.finish_with_message("βœ… Transaction included in block!"); + pb.finish_with_message(format!( + "βœ… Transaction included in block! ({}s)", + elapsed_secs + )); } break; }; @@ -371,18 +402,36 @@ async fn wait_tx_inclusion( TxStatus::InFinalizedBlock(block_hash) => { crate::log_verbose!(" Transaction finalized in block: {:?}", block_hash); if let Some(pb) = spinner { - pb.finish_with_message("βœ… Transaction finalized!"); + pb.finish_with_message(format!( + "βœ… Transaction finalized! ({}s)", + elapsed_secs + )); } break; }, TxStatus::Error { message } | TxStatus::Invalid { message } => { - crate::log_error!(" Transaction error: {}", message); + crate::log_error!(" Transaction error: {} (elapsed: {}s)", message, elapsed_secs); if let Some(pb) = spinner { - pb.finish_with_message("❌ Transaction error!"); + pb.finish_with_message(format!("❌ Transaction error! ({}s)", elapsed_secs)); } break; }, - _ => continue, + _ => { + if let Some(ref pb) = spinner { + if finalized { + pb.set_message(format!( + "Waiting for finalized block... ({}s)", + elapsed_secs + )); + } else { + pb.set_message(format!( + "Waiting for block inclusion... ({}s)", + elapsed_secs + )); + } + } + continue; + }, } } diff --git a/src/cli/generic_call.rs b/src/cli/generic_call.rs index 242341f..fe2049a 100644 --- a/src/cli/generic_call.rs +++ b/src/cli/generic_call.rs @@ -15,7 +15,7 @@ pub async fn execute_generic_call( args: Vec, from_keypair: &QuantumKeyPair, tip: Option, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> crate::error::Result { log_print!("πŸš€ Executing generic call"); log_print!("Pallet: {}", pallet.bright_green()); @@ -60,7 +60,7 @@ pub async fn execute_generic_call( &args, false, tip_amount, - finalized, + execution_mode, ) .await?, ("Balances", "transfer_keep_alive") => @@ -70,30 +70,36 @@ pub async fn execute_generic_call( &args, true, tip_amount, - finalized, + execution_mode, ) .await?, // System pallet calls ("System", "remark") => - submit_system_remark(quantus_client, from_keypair, &args, tip_amount, finalized).await?, + submit_system_remark(quantus_client, from_keypair, &args, tip_amount, execution_mode) + .await?, // Sudo pallet calls ("Sudo", "sudo") => submit_sudo_call(quantus_client, from_keypair, &args).await?, // TechCollective pallet calls ("TechCollective", "add_member") => - submit_tech_collective_add_member(quantus_client, from_keypair, &args, finalized) + submit_tech_collective_add_member(quantus_client, from_keypair, &args, execution_mode) .await?, ("TechCollective", "remove_member") => - submit_tech_collective_remove_member(quantus_client, from_keypair, &args, finalized) - .await?, + submit_tech_collective_remove_member( + quantus_client, + from_keypair, + &args, + execution_mode, + ) + .await?, ("TechCollective", "vote") => - submit_tech_collective_vote(quantus_client, from_keypair, &args, finalized).await?, + submit_tech_collective_vote(quantus_client, from_keypair, &args, execution_mode).await?, // ReversibleTransfers pallet calls ("ReversibleTransfers", "schedule_transfer") => - submit_reversible_transfer(quantus_client, from_keypair, &args, finalized).await?, + submit_reversible_transfer(quantus_client, from_keypair, &args, execution_mode).await?, // Scheduler pallet calls ("Scheduler", "schedule") => @@ -135,7 +141,7 @@ async fn submit_balance_transfer( args: &[Value], keep_alive: bool, tip: Option, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> crate::error::Result { if args.len() != 2 { return Err(QuantusError::Generic( @@ -170,7 +176,7 @@ async fn submit_balance_transfer( from_keypair, transfer_call, tip, - finalized, + execution_mode, ) .await } else { @@ -183,7 +189,7 @@ async fn submit_balance_transfer( from_keypair, transfer_call, tip, - finalized, + execution_mode, ) .await } @@ -195,7 +201,7 @@ async fn submit_system_remark( from_keypair: &QuantumKeyPair, args: &[Value], tip: Option, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> crate::error::Result { if args.len() != 1 { return Err(QuantusError::Generic( @@ -214,7 +220,7 @@ async fn submit_system_remark( from_keypair, remark_call, tip, - finalized, + execution_mode, ) .await } @@ -238,7 +244,7 @@ async fn submit_tech_collective_add_member( quantus_client: &crate::chain::client::QuantusClient, from_keypair: &QuantumKeyPair, args: &[Value], - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> crate::error::Result { if args.len() != 1 { return Err(QuantusError::Generic( @@ -265,8 +271,14 @@ async fn submit_tech_collective_add_member( }, )); - crate::cli::common::submit_transaction(quantus_client, from_keypair, sudo_call, None, finalized) - .await + crate::cli::common::submit_transaction( + quantus_client, + from_keypair, + sudo_call, + None, + execution_mode, + ) + .await } /// Submit tech collective remove member @@ -274,7 +286,7 @@ async fn submit_tech_collective_remove_member( quantus_client: &crate::chain::client::QuantusClient, from_keypair: &QuantumKeyPair, args: &[Value], - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> crate::error::Result { if args.len() != 1 { return Err(QuantusError::Generic( @@ -302,8 +314,14 @@ async fn submit_tech_collective_remove_member( }, )); - crate::cli::common::submit_transaction(quantus_client, from_keypair, sudo_call, None, finalized) - .await + crate::cli::common::submit_transaction( + quantus_client, + from_keypair, + sudo_call, + None, + execution_mode, + ) + .await } /// Submit tech collective vote @@ -311,7 +329,7 @@ async fn submit_tech_collective_vote( quantus_client: &crate::chain::client::QuantusClient, from_keypair: &QuantumKeyPair, args: &[Value], - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> crate::error::Result { if args.len() != 2 { return Err(QuantusError::Generic( @@ -324,8 +342,14 @@ async fn submit_tech_collective_vote( let vote_call = quantus_subxt::api::tx().tech_collective().vote(referendum_index, aye); - crate::cli::common::submit_transaction(quantus_client, from_keypair, vote_call, None, finalized) - .await + crate::cli::common::submit_transaction( + quantus_client, + from_keypair, + vote_call, + None, + execution_mode, + ) + .await } /// Submit reversible transfer @@ -333,7 +357,7 @@ async fn submit_reversible_transfer( quantus_client: &crate::chain::client::QuantusClient, from_keypair: &QuantumKeyPair, args: &[Value], - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> crate::error::Result { if args.len() != 2 { return Err(QuantusError::Generic( @@ -367,7 +391,7 @@ async fn submit_reversible_transfer( from_keypair, schedule_call, None, - finalized, + execution_mode, ) .await } @@ -406,13 +430,13 @@ pub async fn handle_generic_call( keypair: &QuantumKeyPair, tip: Option, node_url: &str, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> crate::error::Result<()> { log_print!("πŸš€ Generic Call"); let quantus_client = crate::chain::client::QuantusClient::new(node_url).await?; - execute_generic_call(&quantus_client, pallet, call, args, keypair, tip, finalized).await?; + execute_generic_call(&quantus_client, pallet, call, args, keypair, tip, execution_mode).await?; Ok(()) } diff --git a/src/cli/high_security.rs b/src/cli/high_security.rs index ed2ae18..ac971d2 100644 --- a/src/cli/high_security.rs +++ b/src/cli/high_security.rs @@ -48,7 +48,7 @@ pub enum HighSecurityCommands { pub async fn handle_high_security_command( command: HighSecurityCommands, node_url: &str, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> crate::error::Result<()> { let quantus_client = crate::chain::client::QuantusClient::new(node_url).await?; @@ -165,7 +165,7 @@ pub async fn handle_high_security_command( &keypair, tx_call, None, - finalized, + execution_mode, ) .await?; diff --git a/src/cli/mod.rs b/src/cli/mod.rs index 5232cf3..a5c768e 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -244,7 +244,7 @@ pub async fn execute_command( command: Commands, node_url: &str, verbose: bool, - finalized: bool, + execution_mode: common::ExecutionMode, ) -> crate::error::Result<()> { match command { Commands::Wallet(wallet_cmd) => wallet::handle_wallet_command(wallet_cmd, node_url).await, @@ -258,39 +258,43 @@ pub async fn execute_command( password_file, tip, nonce, - finalized, + execution_mode, ) .await, Commands::Batch(batch_cmd) => - batch::handle_batch_command(batch_cmd, node_url, finalized).await, + batch::handle_batch_command(batch_cmd, node_url, execution_mode).await, Commands::Reversible(reversible_cmd) => - reversible::handle_reversible_command(reversible_cmd, node_url, finalized).await, + reversible::handle_reversible_command(reversible_cmd, node_url, execution_mode).await, Commands::HighSecurity(hs_cmd) => - high_security::handle_high_security_command(hs_cmd, node_url, finalized).await, + high_security::handle_high_security_command(hs_cmd, node_url, execution_mode).await, Commands::Recovery(recovery_cmd) => - recovery::handle_recovery_command(recovery_cmd, node_url, finalized).await, + recovery::handle_recovery_command(recovery_cmd, node_url, execution_mode).await, Commands::Scheduler(scheduler_cmd) => - scheduler::handle_scheduler_command(scheduler_cmd, node_url, finalized).await, + scheduler::handle_scheduler_command(scheduler_cmd, node_url, execution_mode).await, Commands::Storage(storage_cmd) => - storage::handle_storage_command(storage_cmd, node_url, finalized).await, + storage::handle_storage_command(storage_cmd, node_url, execution_mode).await, Commands::TechCollective(tech_collective_cmd) => tech_collective::handle_tech_collective_command( tech_collective_cmd, node_url, - finalized, + execution_mode, ) .await, Commands::Preimage(preimage_cmd) => - preimage::handle_preimage_command(preimage_cmd, node_url, finalized).await, + preimage::handle_preimage_command(preimage_cmd, node_url, execution_mode).await, Commands::TechReferenda(tech_referenda_cmd) => - tech_referenda::handle_tech_referenda_command(tech_referenda_cmd, node_url, finalized) - .await, + tech_referenda::handle_tech_referenda_command( + tech_referenda_cmd, + node_url, + execution_mode, + ) + .await, Commands::Referenda(referenda_cmd) => - referenda::handle_referenda_command(referenda_cmd, node_url, finalized).await, + referenda::handle_referenda_command(referenda_cmd, node_url, execution_mode).await, Commands::Treasury(treasury_cmd) => - treasury::handle_treasury_command(treasury_cmd, node_url, finalized).await, + treasury::handle_treasury_command(treasury_cmd, node_url, execution_mode).await, Commands::Runtime(runtime_cmd) => - runtime::handle_runtime_command(runtime_cmd, node_url, finalized).await, + runtime::handle_runtime_command(runtime_cmd, node_url, execution_mode).await, Commands::Call { pallet, call, @@ -313,7 +317,7 @@ pub async fn execute_command( offline, call_data_only, node_url, - finalized, + execution_mode, ) .await, Commands::Balance { address } => { @@ -378,7 +382,7 @@ async fn handle_generic_call_command( offline: bool, call_data_only: bool, node_url: &str, - finalized: bool, + execution_mode: common::ExecutionMode, ) -> crate::error::Result<()> { // For now, we only support live submission (not offline or call-data-only) if offline { @@ -403,8 +407,16 @@ async fn handle_generic_call_command( vec![] }; - generic_call::handle_generic_call(&pallet, &call, args_vec, &keypair, tip, node_url, finalized) - .await + generic_call::handle_generic_call( + &pallet, + &call, + args_vec, + &keypair, + tip, + node_url, + execution_mode, + ) + .await } /// Handle developer subcommands diff --git a/src/cli/preimage.rs b/src/cli/preimage.rs index 267f91a..1a5206e 100644 --- a/src/cli/preimage.rs +++ b/src/cli/preimage.rs @@ -70,7 +70,7 @@ pub enum PreimageCommands { pub async fn handle_preimage_command( command: PreimageCommands, node_url: &str, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> crate::error::Result<()> { let quantus_client = crate::chain::client::QuantusClient::new(node_url).await?; @@ -85,14 +85,21 @@ pub async fn handle_preimage_command( list_preimages(&quantus_client).await?; }, PreimageCommands::Request { hash, from } => { - request_preimage(&quantus_client, &hash, &from, finalized).await?; + request_preimage(&quantus_client, &hash, &from, execution_mode).await?; }, PreimageCommands::Note { content, from } => { - note_preimage(&quantus_client, &content, &from, finalized).await?; + note_preimage(&quantus_client, &content, &from, execution_mode).await?; }, PreimageCommands::Create { wasm_file, from, password, password_file } => { - create_preimage(&quantus_client, wasm_file, &from, password, password_file, finalized) - .await?; + create_preimage( + &quantus_client, + wasm_file, + &from, + password, + password_file, + execution_mode, + ) + .await?; }, } @@ -295,7 +302,7 @@ async fn request_preimage( quantus_client: &crate::chain::client::QuantusClient, hash_str: &str, from_str: &str, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> crate::error::Result<()> { let preimage_hash = parse_hash(hash_str)?; @@ -314,7 +321,7 @@ async fn request_preimage( &keypair, request_call, None, - finalized, + execution_mode, ) .await?; log_print!("βœ… Preimage request transaction submitted: {:?}", tx_hash); @@ -331,7 +338,7 @@ async fn note_preimage( quantus_client: &crate::chain::client::QuantusClient, content_str: &str, from_str: &str, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> crate::error::Result<()> { let content = hex::decode(content_str.trim_start_matches("0x")) .map_err(|e| QuantusError::Generic(format!("Invalid hex content: {}", e)))?; @@ -351,7 +358,7 @@ async fn note_preimage( &keypair, note_call, None, - finalized, + execution_mode, ) .await?; log_print!("βœ… Preimage note transaction submitted: {:?}", tx_hash); @@ -370,7 +377,7 @@ async fn create_preimage( from_str: &str, password: Option, password_file: Option, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> crate::error::Result<()> { use qp_poseidon::PoseidonHasher; @@ -415,7 +422,7 @@ async fn create_preimage( &keypair, note_preimage_tx, None, - finalized, + execution_mode, ) .await?; log_print!("βœ… Preimage transaction submitted: {:?}", preimage_tx_hash); diff --git a/src/cli/recovery.rs b/src/cli/recovery.rs index 57f7792..14dd05d 100644 --- a/src/cli/recovery.rs +++ b/src/cli/recovery.rs @@ -169,7 +169,7 @@ pub enum RecoveryCommands { pub async fn handle_recovery_command( command: RecoveryCommands, node_url: &str, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> crate::error::Result<()> { let quantus_client = crate::chain::client::QuantusClient::new(node_url).await?; @@ -195,7 +195,7 @@ pub async fn handle_recovery_command( &rescuer_key, call, None, - finalized, + execution_mode, ) .await .map_err(|e| { @@ -230,7 +230,7 @@ pub async fn handle_recovery_command( &friend_key, call, None, - finalized, + execution_mode, ) .await .map_err(|e| { @@ -258,7 +258,7 @@ pub async fn handle_recovery_command( &rescuer_key, call, None, - finalized, + execution_mode, ) .await .map_err(|e| { @@ -368,7 +368,7 @@ pub async fn handle_recovery_command( &rescuer_key, call, None, - finalized, + execution_mode, ) .await { @@ -479,7 +479,7 @@ pub async fn handle_recovery_command( &rescuer_key, call, None, - finalized, + execution_mode, ) .await { @@ -508,7 +508,7 @@ pub async fn handle_recovery_command( &lost_key, call, None, - finalized, + execution_mode, ) .await .map_err(|e| { @@ -538,7 +538,7 @@ pub async fn handle_recovery_command( &rescuer_key, call, None, - finalized, + execution_mode, ) .await .map_err(|e| { diff --git a/src/cli/referenda.rs b/src/cli/referenda.rs index 75f7be5..04f4416 100644 --- a/src/cli/referenda.rs +++ b/src/cli/referenda.rs @@ -173,7 +173,7 @@ pub enum ReferendaCommands { pub async fn handle_referenda_command( command: ReferendaCommands, node_url: &str, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> crate::error::Result<()> { let quantus_client = crate::chain::client::QuantusClient::new(node_url).await?; @@ -186,7 +186,7 @@ pub async fn handle_referenda_command( password, password_file, &origin, - finalized, + execution_mode, ) .await, ReferendaCommands::Submit { preimage_hash, from, password, password_file, origin } => @@ -197,7 +197,7 @@ pub async fn handle_referenda_command( password, password_file, &origin, - finalized, + execution_mode, ) .await, ReferendaCommands::List => list_proposals(&quantus_client).await, @@ -211,7 +211,7 @@ pub async fn handle_referenda_command( &from, password, password_file, - finalized, + execution_mode, ) .await, ReferendaCommands::Vote { @@ -232,7 +232,7 @@ pub async fn handle_referenda_command( &from, password, password_file, - finalized, + execution_mode, ) .await, ReferendaCommands::RefundSubmissionDeposit { index, from, password, password_file } => @@ -242,7 +242,7 @@ pub async fn handle_referenda_command( &from, password, password_file, - finalized, + execution_mode, ) .await, ReferendaCommands::RefundDecisionDeposit { index, from, password, password_file } => @@ -252,7 +252,7 @@ pub async fn handle_referenda_command( &from, password, password_file, - finalized, + execution_mode, ) .await, ReferendaCommands::Config => get_config(&quantus_client).await, @@ -267,7 +267,7 @@ async fn submit_remark_proposal( password: Option, password_file: Option, origin_type: &str, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> crate::error::Result<()> { use qp_poseidon::PoseidonHasher; @@ -301,7 +301,8 @@ async fn submit_remark_proposal( log_print!("πŸ“ Submitting preimage..."); let note_preimage_tx = quantus_subxt::api::tx().preimage().note_preimage(bounded_bytes); let preimage_tx_hash = - submit_transaction(quantus_client, &keypair, note_preimage_tx, None, finalized).await?; + submit_transaction(quantus_client, &keypair, note_preimage_tx, None, execution_mode) + .await?; log_print!("βœ… Preimage transaction submitted: {:?}", preimage_tx_hash); // Wait for preimage transaction confirmation @@ -358,7 +359,7 @@ async fn submit_remark_proposal( quantus_subxt::api::tx().referenda().submit(origin_caller, proposal, enactment); let tx_hash = - submit_transaction(quantus_client, &keypair, submit_call, None, finalized).await?; + submit_transaction(quantus_client, &keypair, submit_call, None, execution_mode).await?; log_print!( "βœ… {} Referendum proposal submitted! Hash: {:?}", "SUCCESS".bright_green().bold(), @@ -377,7 +378,7 @@ async fn submit_proposal( password: Option, password_file: Option, origin_type: &str, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> crate::error::Result<()> { log_print!("πŸ“ Submitting Proposal to Referenda"); log_print!(" πŸ”— Preimage hash: {}", preimage_hash.bright_cyan()); @@ -475,7 +476,7 @@ async fn submit_proposal( quantus_subxt::api::tx().referenda().submit(origin_caller, proposal, enactment); let tx_hash = - submit_transaction(quantus_client, &keypair, submit_call, None, finalized).await?; + submit_transaction(quantus_client, &keypair, submit_call, None, execution_mode).await?; log_print!( "βœ… {} Referendum proposal submitted! Hash: {:?}", "SUCCESS".bright_green().bold(), @@ -685,7 +686,7 @@ async fn place_decision_deposit( from: &str, password: Option, password_file: Option, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> crate::error::Result<()> { log_print!("πŸ“‹ Placing decision deposit for Referendum #{}", index); log_print!(" πŸ”‘ Placed by: {}", from.bright_yellow()); @@ -694,7 +695,7 @@ async fn place_decision_deposit( let deposit_call = quantus_subxt::api::tx().referenda().place_decision_deposit(index); let tx_hash = - submit_transaction(quantus_client, &keypair, deposit_call, None, finalized).await?; + submit_transaction(quantus_client, &keypair, deposit_call, None, execution_mode).await?; log_success!("βœ… Decision deposit placed! Hash: {:?}", tx_hash.to_string().bright_yellow()); Ok(()) } @@ -709,7 +710,7 @@ async fn vote_on_referendum( from: &str, password: Option, password_file: Option, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> crate::error::Result<()> { log_print!("πŸ—³οΈ Voting on Referendum #{}", index); log_print!(" πŸ“Š Vote: {}", if aye { "AYE βœ…".bright_green() } else { "NAY ❌".bright_red() }); @@ -741,7 +742,8 @@ async fn vote_on_referendum( }; let vote_call = quantus_subxt::api::tx().conviction_voting().vote(index, vote); - let tx_hash = submit_transaction(quantus_client, &keypair, vote_call, None, finalized).await?; + let tx_hash = + submit_transaction(quantus_client, &keypair, vote_call, None, execution_mode).await?; log_print!( "βœ… {} Vote transaction submitted! Hash: {:?}", @@ -799,7 +801,7 @@ async fn refund_submission_deposit( from: &str, password: Option, password_file: Option, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> crate::error::Result<()> { log_print!("πŸ’° Refunding submission deposit for Referendum #{}", index); log_print!(" πŸ”‘ Refund to: {}", from.bright_yellow()); @@ -811,7 +813,7 @@ async fn refund_submission_deposit( let refund_call = quantus_subxt::api::tx().referenda().refund_submission_deposit(index); let tx_hash = - submit_transaction(quantus_client, &keypair, refund_call, None, finalized).await?; + submit_transaction(quantus_client, &keypair, refund_call, None, execution_mode).await?; log_print!( "βœ… {} Refund transaction submitted! Hash: {:?}", "SUCCESS".bright_green().bold(), @@ -829,7 +831,7 @@ async fn refund_decision_deposit( from: &str, password: Option, password_file: Option, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> crate::error::Result<()> { log_print!("πŸ’° Refunding decision deposit for Referendum #{}", index); log_print!(" πŸ”‘ Refund to: {}", from.bright_yellow()); @@ -841,7 +843,7 @@ async fn refund_decision_deposit( let refund_call = quantus_subxt::api::tx().referenda().refund_decision_deposit(index); let tx_hash = - submit_transaction(quantus_client, &keypair, refund_call, None, finalized).await?; + submit_transaction(quantus_client, &keypair, refund_call, None, execution_mode).await?; log_print!( "βœ… {} Refund transaction submitted! Hash: {:?}", "SUCCESS".bright_green().bold(), diff --git a/src/cli/reversible.rs b/src/cli/reversible.rs index 29b6dd8..63d5ed0 100644 --- a/src/cli/reversible.rs +++ b/src/cli/reversible.rs @@ -111,7 +111,7 @@ pub async fn schedule_transfer( from_keypair: &crate::wallet::QuantumKeyPair, to_address: &str, amount: u128, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> Result { log_verbose!("πŸ”„ Creating reversible transfer..."); log_verbose!(" From: {}", from_keypair.to_account_id_ss58check().bright_cyan()); @@ -141,7 +141,7 @@ pub async fn schedule_transfer( from_keypair, transfer_call, None, - finalized, + execution_mode, ) .await?; @@ -155,7 +155,7 @@ pub async fn cancel_transaction( quantus_client: &crate::chain::client::QuantusClient, from_keypair: &crate::wallet::QuantumKeyPair, tx_id: &str, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> Result { log_verbose!("❌ Cancelling reversible transfer..."); log_verbose!(" Transaction ID: {}", tx_id.bright_yellow()); @@ -176,7 +176,7 @@ pub async fn cancel_transaction( from_keypair, cancel_call, None, - finalized, + execution_mode, ) .await?; @@ -193,7 +193,7 @@ pub async fn schedule_transfer_with_delay( amount: u128, delay: u64, unit_blocks: bool, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> Result { let unit_str = if unit_blocks { "blocks" } else { "seconds" }; log_verbose!("πŸ”„ Creating reversible transfer with custom delay ..."); @@ -233,7 +233,7 @@ pub async fn schedule_transfer_with_delay( from_keypair, transfer_call, None, - finalized, + execution_mode, ) .await?; @@ -246,7 +246,7 @@ pub async fn schedule_transfer_with_delay( pub async fn handle_reversible_command( command: ReversibleCommands, node_url: &str, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> Result<()> { log_print!("πŸ”„ Reversible Transfers"); @@ -286,7 +286,7 @@ pub async fn handle_reversible_command( &keypair, &resolved_address, raw_amount, - finalized, + execution_mode, ) .await?; @@ -310,7 +310,8 @@ pub async fn handle_reversible_command( let keypair = crate::wallet::load_keypair_from_wallet(&from, password, password_file)?; // Submit cancel transaction - let tx_hash = cancel_transaction(&quantus_client, &keypair, &tx_id, finalized).await?; + let tx_hash = + cancel_transaction(&quantus_client, &keypair, &tx_id, execution_mode).await?; log_print!( "βœ… {} Cancel transaction submitted! Hash: {:?}", @@ -360,7 +361,7 @@ pub async fn handle_reversible_command( raw_amount, delay, unit_blocks, - finalized, + execution_mode, ) .await?; diff --git a/src/cli/runtime.rs b/src/cli/runtime.rs index 39db259..08ed810 100644 --- a/src/cli/runtime.rs +++ b/src/cli/runtime.rs @@ -49,7 +49,7 @@ pub async fn update_runtime( wasm_code: Vec, from_keypair: &QuantumKeyPair, force: bool, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> crate::error::Result { log_verbose!("πŸ”„ Updating runtime..."); @@ -96,7 +96,7 @@ pub async fn update_runtime( log_print!("πŸ“‘ Submitting runtime update transaction..."); log_print!("⏳ This may take longer than usual due to WASM size..."); - if !finalized { + if !execution_mode.finalized { log_print!( "πŸ’‘ Note: Waiting for best block (not finalized) due to PoW chain characteristics" ); @@ -107,7 +107,7 @@ pub async fn update_runtime( from_keypair, sudo_call, None, - finalized, + execution_mode, ) .await?; @@ -158,7 +158,7 @@ pub async fn calculate_wasm_hash(wasm_code: &[u8]) -> crate::error::Result crate::error::Result<()> { let quantus_client = crate::chain::client::QuantusClient::new(node_url).await?; @@ -195,7 +195,7 @@ pub async fn handle_runtime_command( log_print!("πŸ“Š WASM file size: {} bytes", wasm_code.len()); // Update runtime - update_runtime(&quantus_client, wasm_code, &keypair, force, finalized).await?; + update_runtime(&quantus_client, wasm_code, &keypair, force, execution_mode).await?; log_success!("πŸŽ‰ Runtime update completed!"); log_print!( diff --git a/src/cli/scheduler.rs b/src/cli/scheduler.rs index c1777a9..e89a1cd 100644 --- a/src/cli/scheduler.rs +++ b/src/cli/scheduler.rs @@ -106,7 +106,7 @@ async fn schedule_remark( quantus_client: &crate::chain::client::QuantusClient, after: u32, from: &str, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> Result<()> { use quantus_subxt::api; @@ -133,7 +133,7 @@ async fn schedule_remark( &keypair, schedule_tx, None, - finalized, + execution_mode, ) .await?; log_success!("πŸ“© Schedule extrinsic submitted: {:?}", tx_hash); @@ -145,7 +145,7 @@ async fn schedule_remark( pub async fn handle_scheduler_command( command: SchedulerCommands, node_url: &str, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> Result<()> { log_print!("πŸ—“οΈ Scheduler"); @@ -167,6 +167,6 @@ pub async fn handle_scheduler_command( }, SchedulerCommands::Agenda { range } => list_agenda_range(&quantus_client, &range).await, SchedulerCommands::ScheduleRemark { after, from } => - schedule_remark(&quantus_client, after, &from, finalized).await, + schedule_remark(&quantus_client, after, &from, execution_mode).await, } } diff --git a/src/cli/send.rs b/src/cli/send.rs index 05a9d95..55317c0 100644 --- a/src/cli/send.rs +++ b/src/cli/send.rs @@ -156,9 +156,9 @@ pub async fn transfer( to_address: &str, amount: u128, tip: Option, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> Result { - transfer_with_nonce(quantus_client, from_keypair, to_address, amount, tip, None, finalized) + transfer_with_nonce(quantus_client, from_keypair, to_address, amount, tip, None, execution_mode) .await } @@ -170,7 +170,7 @@ pub async fn transfer_with_nonce( amount: u128, tip: Option, nonce: Option, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> Result { log_verbose!("πŸš€ Creating transfer transaction..."); log_verbose!(" From: {}", from_keypair.to_account_id_ss58check().bright_cyan()); @@ -212,7 +212,7 @@ pub async fn transfer_with_nonce( transfer_call, Some(tip_to_use), manual_nonce, - finalized, + execution_mode, ) .await? } else { @@ -221,7 +221,7 @@ pub async fn transfer_with_nonce( from_keypair, transfer_call, Some(tip_to_use), - finalized, + execution_mode, ) .await? }; @@ -237,7 +237,7 @@ pub async fn batch_transfer( from_keypair: &crate::wallet::QuantumKeyPair, transfers: Vec<(String, u128)>, // (to_address, amount) pairs tip: Option, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> Result { log_verbose!("πŸš€ Creating batch transfer transaction with {} transfers...", transfers.len()); log_verbose!(" From: {}", from_keypair.to_account_id_ss58check().bright_cyan()); @@ -317,7 +317,7 @@ pub async fn batch_transfer( from_keypair, batch_call, Some(tip_to_use), - finalized, + execution_mode, ) .await?; @@ -338,7 +338,7 @@ pub async fn handle_send_command( password_file: Option, tip: Option, nonce: Option, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> Result<()> { // Create quantus chain client let quantus_client = QuantusClient::new(node_url).await?; @@ -397,7 +397,7 @@ pub async fn handle_send_command( amount, tip_amount, nonce, - finalized, + execution_mode, ) .await?; diff --git a/src/cli/storage.rs b/src/cli/storage.rs index 9cf7a62..2ad0ce0 100644 --- a/src/cli/storage.rs +++ b/src/cli/storage.rs @@ -257,7 +257,7 @@ pub async fn set_storage_value( from_keypair: &crate::wallet::QuantumKeyPair, storage_key: Vec, value_bytes: Vec, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> crate::error::Result { log_verbose!("✍️ Creating set_storage transaction..."); @@ -275,7 +275,7 @@ pub async fn set_storage_value( from_keypair, sudo_call, None, - finalized, + execution_mode, ) .await?; @@ -805,7 +805,7 @@ async fn get_storage_by_parts( pub async fn handle_storage_command( command: StorageCommands, node_url: &str, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> crate::error::Result<()> { log_print!("πŸ—„οΈ Storage"); @@ -906,9 +906,14 @@ pub async fn handle_storage_command( }; // 4. Submit the set storage transaction - let tx_hash = - set_storage_value(&quantus_client, &keypair, storage_key, value_bytes, finalized) - .await?; + let tx_hash = set_storage_value( + &quantus_client, + &keypair, + storage_key, + value_bytes, + execution_mode, + ) + .await?; log_print!( "βœ… {} Set storage transaction submitted! Hash: {:?}", diff --git a/src/cli/tech_collective.rs b/src/cli/tech_collective.rs index 9568106..6234b6f 100644 --- a/src/cli/tech_collective.rs +++ b/src/cli/tech_collective.rs @@ -106,7 +106,7 @@ pub async fn add_member( quantus_client: &crate::chain::client::QuantusClient, from_keypair: &crate::wallet::QuantumKeyPair, who_address: &str, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> crate::error::Result { log_verbose!("πŸ›οΈ Adding member to Tech Collective..."); log_verbose!(" Member: {}", who_address.bright_cyan()); @@ -136,7 +136,7 @@ pub async fn add_member( from_keypair, sudo_call, None, - finalized, + execution_mode, ) .await?; @@ -150,7 +150,7 @@ pub async fn remove_member( quantus_client: &crate::chain::client::QuantusClient, from_keypair: &crate::wallet::QuantumKeyPair, who_address: &str, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> crate::error::Result { log_verbose!("πŸ›οΈ Removing member from Tech Collective..."); log_verbose!(" Member: {}", who_address.bright_cyan()); @@ -181,7 +181,7 @@ pub async fn remove_member( from_keypair, sudo_call, None, - finalized, + execution_mode, ) .await?; @@ -196,7 +196,7 @@ pub async fn vote_on_referendum( from_keypair: &crate::wallet::QuantumKeyPair, referendum_index: u32, aye: bool, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> crate::error::Result { log_verbose!("πŸ—³οΈ Voting on referendum..."); log_verbose!(" Referendum: {}", referendum_index); @@ -212,7 +212,7 @@ pub async fn vote_on_referendum( from_keypair, vote_call, None, - finalized, + execution_mode, ) .await?; @@ -352,7 +352,7 @@ pub async fn get_sudo_account( pub async fn handle_tech_collective_command( command: TechCollectiveCommands, node_url: &str, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> crate::error::Result<()> { log_print!("πŸ›οΈ Tech Collective"); @@ -368,7 +368,7 @@ pub async fn handle_tech_collective_command( let keypair = crate::wallet::load_keypair_from_wallet(&from, password, password_file)?; // Submit transaction - let tx_hash = add_member(&quantus_client, &keypair, &who, finalized).await?; + let tx_hash = add_member(&quantus_client, &keypair, &who, execution_mode).await?; log_print!( "βœ… {} Add member transaction submitted! Hash: {:?}", @@ -386,7 +386,7 @@ pub async fn handle_tech_collective_command( let keypair = crate::wallet::load_keypair_from_wallet(&from, password, password_file)?; // Submit transaction - let tx_hash = remove_member(&quantus_client, &keypair, &who, finalized).await?; + let tx_hash = remove_member(&quantus_client, &keypair, &who, execution_mode).await?; log_print!( "βœ… {} Remove member transaction submitted! Hash: {:?}", @@ -407,9 +407,14 @@ pub async fn handle_tech_collective_command( let keypair = crate::wallet::load_keypair_from_wallet(&from, password, password_file)?; // Submit transaction - let tx_hash = - vote_on_referendum(&quantus_client, &keypair, referendum_index, aye, finalized) - .await?; + let tx_hash = vote_on_referendum( + &quantus_client, + &keypair, + referendum_index, + aye, + execution_mode, + ) + .await?; log_print!( "βœ… {} Vote transaction submitted! Hash: {:?}", diff --git a/src/cli/tech_referenda.rs b/src/cli/tech_referenda.rs index 682bc2d..6fc8860 100644 --- a/src/cli/tech_referenda.rs +++ b/src/cli/tech_referenda.rs @@ -187,7 +187,7 @@ pub enum TechReferendaCommands { pub async fn handle_tech_referenda_command( command: TechReferendaCommands, node_url: &str, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> crate::error::Result<()> { let quantus_client = crate::chain::client::QuantusClient::new(node_url).await?; @@ -199,7 +199,7 @@ pub async fn handle_tech_referenda_command( &from, password, password_file, - finalized, + execution_mode, ) .await, TechReferendaCommands::SubmitWithPreimage { wasm_file, from, password, password_file } => @@ -209,7 +209,7 @@ pub async fn handle_tech_referenda_command( &from, password, password_file, - finalized, + execution_mode, ) .await, TechReferendaCommands::List => list_proposals(&quantus_client).await, @@ -223,15 +223,18 @@ pub async fn handle_tech_referenda_command( &from, password, password_file, - finalized, + execution_mode, ) .await, TechReferendaCommands::Cancel { index, from, password, password_file } => - cancel_proposal(&quantus_client, index, &from, password, password_file, finalized).await, + cancel_proposal(&quantus_client, index, &from, password, password_file, execution_mode) + .await, TechReferendaCommands::Kill { index, from, password, password_file } => - kill_proposal(&quantus_client, index, &from, password, password_file, finalized).await, + kill_proposal(&quantus_client, index, &from, password, password_file, execution_mode) + .await, TechReferendaCommands::Nudge { index, from, password, password_file } => - nudge_proposal(&quantus_client, index, &from, password, password_file, finalized).await, + nudge_proposal(&quantus_client, index, &from, password, password_file, execution_mode) + .await, TechReferendaCommands::RefundSubmissionDeposit { index, from, password, password_file } => refund_submission_deposit( &quantus_client, @@ -239,7 +242,7 @@ pub async fn handle_tech_referenda_command( &from, password, password_file, - finalized, + execution_mode, ) .await, TechReferendaCommands::RefundDecisionDeposit { index, from, password, password_file } => @@ -249,7 +252,7 @@ pub async fn handle_tech_referenda_command( &from, password, password_file, - finalized, + execution_mode, ) .await, TechReferendaCommands::Config => get_config(&quantus_client).await, @@ -263,7 +266,7 @@ async fn submit_runtime_upgrade( from: &str, password: Option, password_file: Option, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> crate::error::Result<()> { log_print!("πŸ“ Submitting Runtime Upgrade Proposal to Tech Referenda"); log_print!(" πŸ”— Preimage hash: {}", preimage_hash.bright_cyan()); @@ -337,7 +340,7 @@ async fn submit_runtime_upgrade( .submit(origin_caller, proposal, enactment); let tx_hash = - submit_transaction(quantus_client, &keypair, submit_call, None, finalized).await?; + submit_transaction(quantus_client, &keypair, submit_call, None, execution_mode).await?; log_print!( "βœ… {} Runtime upgrade proposal submitted! Hash: {:?}", "SUCCESS".bright_green().bold(), @@ -355,7 +358,7 @@ async fn submit_runtime_upgrade_with_preimage( from: &str, password: Option, password_file: Option, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> crate::error::Result<()> { use qp_poseidon::PoseidonHasher; @@ -403,7 +406,8 @@ async fn submit_runtime_upgrade_with_preimage( log_print!("πŸ“ Submitting preimage..."); let note_preimage_tx = quantus_subxt::api::tx().preimage().note_preimage(bounded_bytes); let preimage_tx_hash = - submit_transaction(quantus_client, &keypair, note_preimage_tx, None, finalized).await?; + submit_transaction(quantus_client, &keypair, note_preimage_tx, None, execution_mode) + .await?; log_print!("βœ… Preimage transaction submitted: {:?}", preimage_tx_hash); // Wait for preimage transaction confirmation @@ -437,7 +441,7 @@ async fn submit_runtime_upgrade_with_preimage( .submit(origin_caller, proposal, enactment); let tx_hash = - submit_transaction(quantus_client, &keypair, submit_call, None, finalized).await?; + submit_transaction(quantus_client, &keypair, submit_call, None, execution_mode).await?; log_print!( "βœ… {} Runtime upgrade proposal submitted! Hash: {:?}", "SUCCESS".bright_green().bold(), @@ -574,7 +578,7 @@ async fn place_decision_deposit( from: &str, password: Option, password_file: Option, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> crate::error::Result<()> { log_print!("πŸ“‹ Placing decision deposit for Tech Referendum #{}", index); log_print!(" πŸ”‘ Placed by: {}", from.bright_yellow()); @@ -583,7 +587,7 @@ async fn place_decision_deposit( let deposit_call = quantus_subxt::api::tx().tech_referenda().place_decision_deposit(index); let tx_hash = - submit_transaction(quantus_client, &keypair, deposit_call, None, finalized).await?; + submit_transaction(quantus_client, &keypair, deposit_call, None, execution_mode).await?; log_success!("βœ… Decision deposit placed! Hash: {:?}", tx_hash.to_string().bright_yellow()); Ok(()) } @@ -595,7 +599,7 @@ async fn cancel_proposal( from: &str, password: Option, password_file: Option, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> crate::error::Result<()> { log_print!("❌ Cancelling Tech Referendum #{}", index); log_print!(" πŸ”‘ Cancelled by: {}", from.bright_yellow()); @@ -608,7 +612,8 @@ async fn cancel_proposal( }); let sudo_call = quantus_subxt::api::tx().sudo().sudo(inner); - let tx_hash = submit_transaction(quantus_client, &keypair, sudo_call, None, finalized).await?; + let tx_hash = + submit_transaction(quantus_client, &keypair, sudo_call, None, execution_mode).await?; log_success!("βœ… Referendum cancelled! Hash: {:?}", tx_hash.to_string().bright_yellow()); Ok(()) } @@ -620,7 +625,7 @@ async fn kill_proposal( from: &str, password: Option, password_file: Option, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> crate::error::Result<()> { log_print!("πŸ’€ Killing Tech Referendum #{}", index); log_print!(" πŸ”‘ Killed by: {}", from.bright_yellow()); @@ -633,7 +638,8 @@ async fn kill_proposal( }); let sudo_call = quantus_subxt::api::tx().sudo().sudo(inner); - let tx_hash = submit_transaction(quantus_client, &keypair, sudo_call, None, finalized).await?; + let tx_hash = + submit_transaction(quantus_client, &keypair, sudo_call, None, execution_mode).await?; log_success!("βœ… Referendum killed! Hash: {:?}", tx_hash.to_string().bright_yellow()); Ok(()) } @@ -645,7 +651,7 @@ async fn nudge_proposal( from: &str, password: Option, password_file: Option, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> crate::error::Result<()> { log_print!("πŸ”„ Nudging Tech Referendum #{}", index); log_print!(" πŸ”‘ Nudged by: {}", from.bright_yellow()); @@ -657,7 +663,8 @@ async fn nudge_proposal( ); let sudo_call = quantus_subxt::api::tx().sudo().sudo(inner); - let tx_hash = submit_transaction(quantus_client, &keypair, sudo_call, None, finalized).await?; + let tx_hash = + submit_transaction(quantus_client, &keypair, sudo_call, None, execution_mode).await?; log_success!("βœ… Referendum nudged! Hash: {:?}", tx_hash.to_string().bright_yellow()); Ok(()) } @@ -708,7 +715,7 @@ async fn refund_submission_deposit( from: &str, password: Option, password_file: Option, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> crate::error::Result<()> { log_print!("πŸ’° Refunding submission deposit for Tech Referendum #{}", index); log_print!(" πŸ”‘ Refund to: {}", from.bright_yellow()); @@ -720,7 +727,7 @@ async fn refund_submission_deposit( let refund_call = quantus_subxt::api::tx().tech_referenda().refund_submission_deposit(index); let tx_hash = - submit_transaction(quantus_client, &keypair, refund_call, None, finalized).await?; + submit_transaction(quantus_client, &keypair, refund_call, None, execution_mode).await?; log_print!( "βœ… {} Refund transaction submitted! Hash: {:?}", "SUCCESS".bright_green().bold(), @@ -739,7 +746,7 @@ async fn refund_decision_deposit( from: &str, password: Option, password_file: Option, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> crate::error::Result<()> { log_print!("πŸ’° Refunding decision deposit for Tech Referendum #{}", index); log_print!(" πŸ”‘ Refund to: {}", from.bright_yellow()); @@ -751,7 +758,7 @@ async fn refund_decision_deposit( let refund_call = quantus_subxt::api::tx().tech_referenda().refund_decision_deposit(index); let tx_hash = - submit_transaction(quantus_client, &keypair, refund_call, None, finalized).await?; + submit_transaction(quantus_client, &keypair, refund_call, None, execution_mode).await?; log_print!( "βœ… {} Refund transaction submitted! Hash: {:?}", "SUCCESS".bright_green().bold(), diff --git a/src/cli/treasury.rs b/src/cli/treasury.rs index 5306148..e910bea 100644 --- a/src/cli/treasury.rs +++ b/src/cli/treasury.rs @@ -117,7 +117,7 @@ pub enum TreasuryCommands { pub async fn handle_treasury_command( command: TreasuryCommands, node_url: &str, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> crate::error::Result<()> { let quantus_client = crate::chain::client::QuantusClient::new(node_url).await?; @@ -141,14 +141,22 @@ pub async fn handle_treasury_command( &from, password, password_file, - finalized, + execution_mode, ) .await, TreasuryCommands::Payout { index, from, password, password_file } => - payout_spend(&quantus_client, index, &from, password, password_file, finalized).await, - TreasuryCommands::CheckStatus { index, from, password, password_file } => - check_spend_status(&quantus_client, index, &from, password, password_file, finalized) + payout_spend(&quantus_client, index, &from, password, password_file, execution_mode) .await, + TreasuryCommands::CheckStatus { index, from, password, password_file } => + check_spend_status( + &quantus_client, + index, + &from, + password, + password_file, + execution_mode, + ) + .await, TreasuryCommands::ListSpends => list_spends(&quantus_client).await, TreasuryCommands::SpendSudo { beneficiary, amount, from, password, password_file } => spend_sudo( @@ -158,7 +166,7 @@ pub async fn handle_treasury_command( &from, password, password_file, - finalized, + execution_mode, ) .await, } @@ -303,7 +311,7 @@ async fn submit_spend_referendum( from: &str, password: Option, password_file: Option, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> crate::error::Result<()> { use qp_poseidon::PoseidonHasher; use sp_core::crypto::{AccountId32 as SpAccountId32, Ss58Codec}; @@ -358,7 +366,7 @@ async fn submit_spend_referendum( // Submit preimage let preimage_call = quantus_subxt::api::tx().preimage().note_preimage(encoded_call.clone()); let preimage_tx_hash = - submit_transaction(quantus_client, &keypair, preimage_call, None, finalized).await?; + submit_transaction(quantus_client, &keypair, preimage_call, None, execution_mode).await?; log_print!("βœ… Preimage created {:?}", preimage_tx_hash); @@ -401,7 +409,7 @@ async fn submit_spend_referendum( let submit_call = quantus_subxt::api::tx().referenda().submit(origin_caller, proposal, enactment); let submit_tx_hash = - submit_transaction(quantus_client, &keypair, submit_call, None, finalized).await?; + submit_transaction(quantus_client, &keypair, submit_call, None, execution_mode).await?; log_print!( "βœ… {} Treasury spend referendum submitted! {:?}", @@ -428,7 +436,7 @@ async fn payout_spend( from: &str, password: Option, password_file: Option, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> crate::error::Result<()> { log_print!("πŸ’Έ Paying out Treasury Spend #{}", index); @@ -439,7 +447,7 @@ async fn payout_spend( let payout_call = quantus_subxt::api::tx().treasury_pallet().payout(index); let tx_hash = - submit_transaction(quantus_client, &keypair, payout_call, None, finalized).await?; + submit_transaction(quantus_client, &keypair, payout_call, None, execution_mode).await?; log_print!( "βœ… {} Payout transaction submitted! Hash: {:?}", "SUCCESS".bright_green().bold(), @@ -459,7 +467,7 @@ async fn check_spend_status( from: &str, password: Option, password_file: Option, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> crate::error::Result<()> { log_print!("πŸ” Checking Treasury Spend #{} status", index); @@ -469,7 +477,8 @@ async fn check_spend_status( // Create check_status call let check_call = quantus_subxt::api::tx().treasury_pallet().check_status(index); - let tx_hash = submit_transaction(quantus_client, &keypair, check_call, None, finalized).await?; + let tx_hash = + submit_transaction(quantus_client, &keypair, check_call, None, execution_mode).await?; log_print!( "βœ… {} Check status transaction submitted! Hash: {:?}", "SUCCESS".bright_green().bold(), @@ -538,7 +547,7 @@ async fn spend_sudo( from: &str, password: Option, password_file: Option, - finalized: bool, + execution_mode: crate::cli::common::ExecutionMode, ) -> crate::error::Result<()> { use sp_core::crypto::{AccountId32 as SpAccountId32, Ss58Codec}; @@ -580,7 +589,8 @@ async fn spend_sudo( // Submit transaction log_print!("πŸ“‘ Submitting sudo transaction..."); - let tx_hash = submit_transaction(quantus_client, &keypair, sudo_call, None, finalized).await?; + let tx_hash = + submit_transaction(quantus_client, &keypair, sudo_call, None, execution_mode).await?; log_print!( "βœ… {} Sudo transaction submitted! Hash: {:?}", "SUCCESS".bright_green().bold(), diff --git a/src/main.rs b/src/main.rs index 7367aca..ff07b3c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -40,6 +40,11 @@ struct Cli { /// NOTE: waiting for finalized transaction may take a while in PoW chain #[arg(long, global = true, default_value = "false")] finalized_tx: bool, + + /// Wait for transaction validation/inclusion before returning + /// Default: false (fire and forget - return immediately with hash) + #[arg(long, global = true, default_value = "false")] + wait_for_transaction: bool, } #[tokio::main] @@ -60,8 +65,14 @@ async fn main() -> Result<(), QuantusError> { log_print!("⚠️ Warning: Waiting for finalized block may take a while in PoW chain."); } + // Create execution mode from CLI args + let execution_mode = cli::common::ExecutionMode { + finalized: cli.finalized_tx, + wait_for_transaction: cli.wait_for_transaction, + }; + // Execute the command - match cli::execute_command(cli.command, &cli.node_url, cli.verbose, cli.finalized_tx).await { + match cli::execute_command(cli.command, &cli.node_url, cli.verbose, execution_mode).await { Ok(_) => { log_verbose!(""); log_verbose!("Command executed successfully!"); From c85686e722457e408fc48ac71bcfaa101b994707 Mon Sep 17 00:00:00 2001 From: Nikolaus Heger Date: Sun, 11 Jan 2026 21:44:04 +0800 Subject: [PATCH 03/10] actual instant transactions also fmt --- src/chain/client.rs | 4 +- src/chain/quantus_subxt.rs | 4 +- src/cli/batch.rs | 10 +- src/cli/block.rs | 14 ++- src/cli/common.rs | 176 +++++++++++++++++++++--------------- src/cli/generic_call.rs | 45 +++++---- src/cli/mod.rs | 80 +++++++++------- src/cli/referenda.rs | 49 ++++++---- src/cli/referenda_decode.rs | 5 +- src/cli/reversible.rs | 5 +- src/cli/scheduler.rs | 5 +- src/cli/storage.rs | 25 +++-- src/cli/tech_collective.rs | 5 +- src/cli/tech_referenda.rs | 45 +++++---- src/cli/treasury.rs | 20 ++-- src/cli/wallet.rs | 10 +- src/main.rs | 2 +- 17 files changed, 300 insertions(+), 204 deletions(-) diff --git a/src/chain/client.rs b/src/chain/client.rs index 910d192..efc728d 100644 --- a/src/chain/client.rs +++ b/src/chain/client.rs @@ -65,8 +65,8 @@ impl QuantusClient { } // Provide helpful hints for common URL issues - if node_url.starts_with("ws://") && - (node_url.contains("a.i.res.fm") || node_url.contains("a.t.res.fm")) + if node_url.starts_with("ws://") + && (node_url.contains("a.i.res.fm") || node_url.contains("a.t.res.fm")) { log_verbose!( "πŸ’‘ Hint: Remote nodes typically require secure WebSocket connections (wss://)" diff --git a/src/chain/quantus_subxt.rs b/src/chain/quantus_subxt.rs index a94a0d2..d2c9f6d 100644 --- a/src/chain/quantus_subxt.rs +++ b/src/chain/quantus_subxt.rs @@ -1995,8 +1995,8 @@ pub mod api { .only_these_pallets(&PALLETS) .only_these_runtime_apis(&RUNTIME_APIS) .hash(); - runtime_metadata_hash == - [ + runtime_metadata_hash + == [ 194u8, 46u8, 30u8, 103u8, 67u8, 25u8, 224u8, 42u8, 104u8, 224u8, 105u8, 213u8, 149u8, 58u8, 199u8, 151u8, 221u8, 215u8, 141u8, 247u8, 109u8, 85u8, 204u8, 202u8, 96u8, 104u8, 173u8, 94u8, 198u8, 124u8, 113u8, 174u8, diff --git a/src/cli/batch.rs b/src/cli/batch.rs index b1b84c8..0449979 100644 --- a/src/cli/batch.rs +++ b/src/cli/batch.rs @@ -75,7 +75,7 @@ pub async fn handle_batch_command( count, to, amount, - } => + } => { handle_batch_send_command( from, node_url, @@ -88,9 +88,11 @@ pub async fn handle_batch_command( amount, execution_mode, ) - .await, - BatchCommands::Config { limits, info } => - handle_batch_config_command(node_url, limits, info).await, + .await + }, + BatchCommands::Config { limits, info } => { + handle_batch_config_command(node_url, limits, info).await + }, } } diff --git a/src/cli/block.rs b/src/cli/block.rs index a5c6b1c..b085592 100644 --- a/src/cli/block.rs +++ b/src/cli/block.rs @@ -79,7 +79,7 @@ pub async fn handle_block_command( extrinsics_details, events, all, - } => + } => { handle_block_analyze_command( number, hash, @@ -91,9 +91,11 @@ pub async fn handle_block_command( all, node_url, ) - .await, - BlockCommands::List { start, end, step } => - handle_block_list_command(start, end, step, node_url).await, + .await + }, + BlockCommands::List { start, end, step } => { + handle_block_list_command(start, end, step, node_url).await + }, } } @@ -138,7 +140,9 @@ async fn handle_block_analyze_command( })?; (block_num, hash) } else { - return Err(QuantusError::Generic("Must specify --number, --hash, or --latest".to_string())); + return Err(QuantusError::Generic( + "Must specify --number, --hash, or --latest".to_string(), + )); }; log_print!("πŸ“¦ Block #{} - {:#x}", block_number, block_hash); diff --git a/src/cli/common.rs b/src/cli/common.rs index b1932e6..1211920 100644 --- a/src/cli/common.rs +++ b/src/cli/common.rs @@ -151,6 +151,11 @@ where loop { attempt += 1; + crate::log_print!( + "submit transaction with wait for transaction: {}", + execution_mode.wait_for_transaction + ); + // Get fresh nonce for each attempt, or increment if we have a previous nonce let nonce = if let Some(prev_nonce) = current_nonce { // After first failure, try with incremented nonce @@ -191,13 +196,13 @@ where } // Try to get chain parameters from the client - let genesis_hash = quantus_client.get_genesis_hash().await?; - let (spec_version, transaction_version) = quantus_client.get_runtime_version().await?; + // let genesis_hash = quantus_client.get_genesis_hash().await?; + // let (spec_version, transaction_version) = quantus_client.get_runtime_version().await?; - log_verbose!("πŸ” Chain parameters:"); - log_verbose!(" Genesis hash: {:?}", genesis_hash); - log_verbose!(" Spec version: {}", spec_version); - log_verbose!(" Transaction version: {}", transaction_version); + // log_verbose!("πŸ” Chain parameters:"); + // log_verbose!(" Genesis hash: {:?}", genesis_hash); + // log_verbose!(" Spec version: {}", spec_version); + // log_verbose!(" Transaction version: {}", transaction_version); // For now, just use the default params let params = params_builder.build(); @@ -217,55 +222,69 @@ where log_verbose!("πŸ” Additional debugging:"); log_verbose!(" Call type: {:?}", std::any::type_name::()); - // Submit the transaction with fresh nonce and optional tip - match quantus_client - .client() - .tx() - .sign_and_submit_then_watch(&call, &signer, params) - .await - { - Ok(mut tx_progress) => { - crate::log_verbose!("πŸ“‹ Transaction submitted: {:?}", tx_progress); + if execution_mode.wait_for_transaction { + match quantus_client + .client() + .tx() + .sign_and_submit_then_watch(&call, &signer, params) + .await + { + Ok(mut tx_progress) => { + crate::log_verbose!("πŸ“‹ Transaction submitted: {:?}", tx_progress); - let tx_hash = tx_progress.extrinsic_hash(); + let tx_hash = tx_progress.extrinsic_hash(); - if !execution_mode.wait_for_transaction { - return Ok(tx_hash); - } + if !execution_mode.wait_for_transaction { + return Ok(tx_hash); + } - wait_tx_inclusion(&mut tx_progress, execution_mode.finalized).await?; + wait_tx_inclusion(&mut tx_progress, execution_mode.finalized).await?; - return Ok(tx_hash); - }, - Err(e) => { - let error_msg = format!("{e:?}"); - - // Check if it's a retryable error - let is_retryable = error_msg.contains("Priority is too low") || - error_msg.contains("Transaction is outdated") || - error_msg.contains("Transaction is temporarily banned") || - error_msg.contains("Transaction has a bad signature") || - error_msg.contains("Invalid Transaction"); - - if is_retryable && attempt < 5 { - log_verbose!( - "⚠️ Transaction error detected (attempt {}/5): {}", - attempt, - error_msg - ); - - // Exponential backoff: 2s, 4s, 8s, 16s - let delay = std::cmp::min(2u64.pow(attempt as u32), 16); - log_verbose!("⏳ Waiting {} seconds before retry...", delay); - tokio::time::sleep(tokio::time::Duration::from_secs(delay)).await; - continue; - } else { - log_verbose!("❌ Final error after {} attempts: {}", attempt, error_msg); + return Ok(tx_hash); + }, + Err(e) => { + let error_msg = format!("{e:?}"); + + // Check if it's a retryable error + let is_retryable = error_msg.contains("Priority is too low") + || error_msg.contains("Transaction is outdated") + || error_msg.contains("Transaction is temporarily banned") + || error_msg.contains("Transaction has a bad signature") + || error_msg.contains("Invalid Transaction"); + + if is_retryable && attempt < 5 { + log_verbose!( + "⚠️ Transaction error detected (attempt {}/5): {}", + attempt, + error_msg + ); + + // Exponential backoff: 2s, 4s, 8s, 16s + let delay = std::cmp::min(2u64.pow(attempt as u32), 16); + log_verbose!("⏳ Waiting {} seconds before retry...", delay); + tokio::time::sleep(tokio::time::Duration::from_secs(delay)).await; + continue; + } else { + log_verbose!("❌ Final error after {} attempts: {}", attempt, error_msg); + return Err(crate::error::QuantusError::NetworkError(format!( + "Failed to submit transaction: {e:?}" + ))); + } + }, + } + } else { + match quantus_client.client().tx().sign_and_submit(&call, &signer, params).await { + Ok(tx_hash) => { + crate::log_print!("βœ… Transaction submitted: {:?}", tx_hash); + return Ok(tx_hash); + }, + Err(e) => { + log_error!("❌ Failed to submit transaction: {e:?}"); return Err(crate::error::QuantusError::NetworkError(format!( "Failed to submit transaction: {e:?}" ))); - } - }, + }, + } } } } @@ -309,30 +328,42 @@ where log_verbose!("πŸ”’ Using manual nonce: {}", nonce); log_verbose!("πŸ“€ Submitting transaction with manual nonce..."); + crate::log_print!("submit with wait for transaction: {}", execution_mode.wait_for_transaction); // Submit the transaction with manual nonce - match quantus_client - .client() - .tx() - .sign_and_submit_then_watch(&call, &signer, params) - .await - { - Ok(mut tx_progress) => { - let tx_hash = tx_progress.extrinsic_hash(); - log_verbose!("βœ… Transaction submitted successfully: {:?}", tx_hash); - - if !execution_mode.wait_for_transaction { - return Ok(tx_hash); - } - wait_tx_inclusion(&mut tx_progress, execution_mode.finalized).await?; - Ok(tx_hash) - }, - Err(e) => { - log_error!("❌ Failed to submit transaction with manual nonce {}: {e:?}", nonce); - Err(crate::error::QuantusError::NetworkError(format!( - "Failed to submit transaction with nonce {nonce}: {e:?}" - ))) - }, + if execution_mode.wait_for_transaction { + match quantus_client + .client() + .tx() + .sign_and_submit_then_watch(&call, &signer, params) + .await + { + Ok(mut tx_progress) => { + let tx_hash = tx_progress.extrinsic_hash(); + crate::log_print!("βœ… Transaction submitted: {:?}", tx_hash); + wait_tx_inclusion(&mut tx_progress, execution_mode.finalized).await?; + Ok(tx_hash) + }, + Err(e) => { + log_error!("❌ Failed to submit transaction with manual nonce {}: {e:?}", nonce); + Err(crate::error::QuantusError::NetworkError(format!( + "Failed to submit transaction with nonce {nonce}: {e:?}" + ))) + }, + } + } else { + match quantus_client.client().tx().sign_and_submit(&call, &signer, params).await { + Ok(tx_hash) => { + crate::log_print!("βœ… Transaction submitted: {:?}", tx_hash); + Ok(tx_hash) + }, + Err(e) => { + log_error!("❌ Failed to submit transaction: {e:?}"); + Err(crate::error::QuantusError::NetworkError(format!( + "Failed to submit transaction: {e:?}" + ))) + }, + } } } @@ -375,10 +406,11 @@ async fn wait_tx_inclusion( crate::log_verbose!(" Transaction status: {:?} (elapsed: {}s)", status, elapsed_secs); match status { - TxStatus::Validated => + TxStatus::Validated => { if let Some(ref pb) = spinner { pb.set_message(format!("Transaction validated βœ“ ({}s)", elapsed_secs)); - }, + } + }, TxStatus::InBestBlock(block_hash) => { crate::log_verbose!(" Transaction included in block: {:?}", block_hash); if finalized { diff --git a/src/cli/generic_call.rs b/src/cli/generic_call.rs index fe2049a..a33f1e6 100644 --- a/src/cli/generic_call.rs +++ b/src/cli/generic_call.rs @@ -53,7 +53,7 @@ pub async fn execute_generic_call( let tx_hash = match (pallet, call) { // Balances pallet calls - ("Balances", "transfer_allow_death") => + ("Balances", "transfer_allow_death") => { submit_balance_transfer( quantus_client, from_keypair, @@ -62,8 +62,9 @@ pub async fn execute_generic_call( tip_amount, execution_mode, ) - .await?, - ("Balances", "transfer_keep_alive") => + .await? + }, + ("Balances", "transfer_keep_alive") => { submit_balance_transfer( quantus_client, from_keypair, @@ -72,40 +73,48 @@ pub async fn execute_generic_call( tip_amount, execution_mode, ) - .await?, + .await? + }, // System pallet calls - ("System", "remark") => + ("System", "remark") => { submit_system_remark(quantus_client, from_keypair, &args, tip_amount, execution_mode) - .await?, + .await? + }, // Sudo pallet calls ("Sudo", "sudo") => submit_sudo_call(quantus_client, from_keypair, &args).await?, // TechCollective pallet calls - ("TechCollective", "add_member") => + ("TechCollective", "add_member") => { submit_tech_collective_add_member(quantus_client, from_keypair, &args, execution_mode) - .await?, - ("TechCollective", "remove_member") => + .await? + }, + ("TechCollective", "remove_member") => { submit_tech_collective_remove_member( quantus_client, from_keypair, &args, execution_mode, ) - .await?, - ("TechCollective", "vote") => - submit_tech_collective_vote(quantus_client, from_keypair, &args, execution_mode).await?, + .await? + }, + ("TechCollective", "vote") => { + submit_tech_collective_vote(quantus_client, from_keypair, &args, execution_mode).await? + }, // ReversibleTransfers pallet calls - ("ReversibleTransfers", "schedule_transfer") => - submit_reversible_transfer(quantus_client, from_keypair, &args, execution_mode).await?, + ("ReversibleTransfers", "schedule_transfer") => { + submit_reversible_transfer(quantus_client, from_keypair, &args, execution_mode).await? + }, // Scheduler pallet calls - ("Scheduler", "schedule") => - submit_scheduler_schedule(quantus_client, from_keypair, &args).await?, - ("Scheduler", "cancel") => - submit_scheduler_cancel(quantus_client, from_keypair, &args).await?, + ("Scheduler", "schedule") => { + submit_scheduler_schedule(quantus_client, from_keypair, &args).await? + }, + ("Scheduler", "cancel") => { + submit_scheduler_cancel(quantus_client, from_keypair, &args).await? + }, // Generic fallback for unknown calls (_, _) => { diff --git a/src/cli/mod.rs b/src/cli/mod.rs index a5c768e..22af008 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -248,7 +248,7 @@ pub async fn execute_command( ) -> crate::error::Result<()> { match command { Commands::Wallet(wallet_cmd) => wallet::handle_wallet_command(wallet_cmd, node_url).await, - Commands::Send { from, to, amount, password, password_file, tip, nonce } => + Commands::Send { from, to, amount, password, password_file, tip, nonce } => { send::handle_send_command( from, to, @@ -260,41 +260,54 @@ pub async fn execute_command( nonce, execution_mode, ) - .await, - Commands::Batch(batch_cmd) => - batch::handle_batch_command(batch_cmd, node_url, execution_mode).await, - Commands::Reversible(reversible_cmd) => - reversible::handle_reversible_command(reversible_cmd, node_url, execution_mode).await, - Commands::HighSecurity(hs_cmd) => - high_security::handle_high_security_command(hs_cmd, node_url, execution_mode).await, - Commands::Recovery(recovery_cmd) => - recovery::handle_recovery_command(recovery_cmd, node_url, execution_mode).await, - Commands::Scheduler(scheduler_cmd) => - scheduler::handle_scheduler_command(scheduler_cmd, node_url, execution_mode).await, - Commands::Storage(storage_cmd) => - storage::handle_storage_command(storage_cmd, node_url, execution_mode).await, - Commands::TechCollective(tech_collective_cmd) => + .await + }, + Commands::Batch(batch_cmd) => { + batch::handle_batch_command(batch_cmd, node_url, execution_mode).await + }, + Commands::Reversible(reversible_cmd) => { + reversible::handle_reversible_command(reversible_cmd, node_url, execution_mode).await + }, + Commands::HighSecurity(hs_cmd) => { + high_security::handle_high_security_command(hs_cmd, node_url, execution_mode).await + }, + Commands::Recovery(recovery_cmd) => { + recovery::handle_recovery_command(recovery_cmd, node_url, execution_mode).await + }, + Commands::Scheduler(scheduler_cmd) => { + scheduler::handle_scheduler_command(scheduler_cmd, node_url, execution_mode).await + }, + Commands::Storage(storage_cmd) => { + storage::handle_storage_command(storage_cmd, node_url, execution_mode).await + }, + Commands::TechCollective(tech_collective_cmd) => { tech_collective::handle_tech_collective_command( tech_collective_cmd, node_url, execution_mode, ) - .await, - Commands::Preimage(preimage_cmd) => - preimage::handle_preimage_command(preimage_cmd, node_url, execution_mode).await, - Commands::TechReferenda(tech_referenda_cmd) => + .await + }, + Commands::Preimage(preimage_cmd) => { + preimage::handle_preimage_command(preimage_cmd, node_url, execution_mode).await + }, + Commands::TechReferenda(tech_referenda_cmd) => { tech_referenda::handle_tech_referenda_command( tech_referenda_cmd, node_url, execution_mode, ) - .await, - Commands::Referenda(referenda_cmd) => - referenda::handle_referenda_command(referenda_cmd, node_url, execution_mode).await, - Commands::Treasury(treasury_cmd) => - treasury::handle_treasury_command(treasury_cmd, node_url, execution_mode).await, - Commands::Runtime(runtime_cmd) => - runtime::handle_runtime_command(runtime_cmd, node_url, execution_mode).await, + .await + }, + Commands::Referenda(referenda_cmd) => { + referenda::handle_referenda_command(referenda_cmd, node_url, execution_mode).await + }, + Commands::Treasury(treasury_cmd) => { + treasury::handle_treasury_command(treasury_cmd, node_url, execution_mode).await + }, + Commands::Runtime(runtime_cmd) => { + runtime::handle_runtime_command(runtime_cmd, node_url, execution_mode).await + }, Commands::Call { pallet, call, @@ -305,7 +318,7 @@ pub async fn execute_command( tip, offline, call_data_only, - } => + } => { handle_generic_call_command( pallet, call, @@ -319,7 +332,8 @@ pub async fn execute_command( node_url, execution_mode, ) - .await, + .await + }, Commands::Balance { address } => { let quantus_client = crate::chain::client::QuantusClient::new(node_url).await?; @@ -339,11 +353,12 @@ pub async fn execute_command( Ok(()) }, }, - Commands::Events { block, block_hash, latest: _, finalized, pallet, raw, no_decode } => + Commands::Events { block, block_hash, latest: _, finalized, pallet, raw, no_decode } => { events::handle_events_command( block, block_hash, finalized, pallet, raw, !no_decode, node_url, ) - .await, + .await + }, Commands::System { runtime, metadata, rpc_methods } => { if runtime || metadata || rpc_methods { system::handle_system_extended_command( @@ -358,8 +373,9 @@ pub async fn execute_command( system::handle_system_command(node_url).await } }, - Commands::Metadata { no_docs, stats_only, pallet } => - metadata::handle_metadata_command(node_url, no_docs, stats_only, pallet).await, + Commands::Metadata { no_docs, stats_only, pallet } => { + metadata::handle_metadata_command(node_url, no_docs, stats_only, pallet).await + }, Commands::Version => { log_print!("CLI Version: Quantus CLI v{}", env!("CARGO_PKG_VERSION")); Ok(()) diff --git a/src/cli/referenda.rs b/src/cli/referenda.rs index 04f4416..9e2ead3 100644 --- a/src/cli/referenda.rs +++ b/src/cli/referenda.rs @@ -178,7 +178,7 @@ pub async fn handle_referenda_command( let quantus_client = crate::chain::client::QuantusClient::new(node_url).await?; match command { - ReferendaCommands::SubmitRemark { message, from, password, password_file, origin } => + ReferendaCommands::SubmitRemark { message, from, password, password_file, origin } => { submit_remark_proposal( &quantus_client, &message, @@ -188,8 +188,9 @@ pub async fn handle_referenda_command( &origin, execution_mode, ) - .await, - ReferendaCommands::Submit { preimage_hash, from, password, password_file, origin } => + .await + }, + ReferendaCommands::Submit { preimage_hash, from, password, password_file, origin } => { submit_proposal( &quantus_client, &preimage_hash, @@ -199,12 +200,14 @@ pub async fn handle_referenda_command( &origin, execution_mode, ) - .await, + .await + }, ReferendaCommands::List => list_proposals(&quantus_client).await, - ReferendaCommands::Get { index, decode } => - get_proposal_details(&quantus_client, index, decode).await, + ReferendaCommands::Get { index, decode } => { + get_proposal_details(&quantus_client, index, decode).await + }, ReferendaCommands::Status { index } => get_proposal_status(&quantus_client, index).await, - ReferendaCommands::PlaceDecisionDeposit { index, from, password, password_file } => + ReferendaCommands::PlaceDecisionDeposit { index, from, password, password_file } => { place_decision_deposit( &quantus_client, index, @@ -213,7 +216,8 @@ pub async fn handle_referenda_command( password_file, execution_mode, ) - .await, + .await + }, ReferendaCommands::Vote { index, aye, @@ -222,7 +226,7 @@ pub async fn handle_referenda_command( from, password, password_file, - } => + } => { vote_on_referendum( &quantus_client, index, @@ -234,8 +238,9 @@ pub async fn handle_referenda_command( password_file, execution_mode, ) - .await, - ReferendaCommands::RefundSubmissionDeposit { index, from, password, password_file } => + .await + }, + ReferendaCommands::RefundSubmissionDeposit { index, from, password, password_file } => { refund_submission_deposit( &quantus_client, index, @@ -244,8 +249,9 @@ pub async fn handle_referenda_command( password_file, execution_mode, ) - .await, - ReferendaCommands::RefundDecisionDeposit { index, from, password, password_file } => + .await + }, + ReferendaCommands::RefundDecisionDeposit { index, from, password, password_file } => { refund_decision_deposit( &quantus_client, index, @@ -254,7 +260,8 @@ pub async fn handle_referenda_command( password_file, execution_mode, ) - .await, + .await + }, ReferendaCommands::Config => get_config(&quantus_client).await, } } @@ -342,11 +349,12 @@ async fn submit_remark_proposal( quantus_subxt::api::runtime_types::frame_support::dispatch::RawOrigin::Root; quantus_subxt::api::runtime_types::quantus_runtime::OriginCaller::system(raw_origin) }, - _ => + _ => { return Err(QuantusError::Generic(format!( "Invalid origin type: {}. Must be 'signed', 'none', or 'root'", origin_type - ))), + ))) + }, }; let enactment = @@ -459,11 +467,12 @@ async fn submit_proposal( quantus_subxt::api::runtime_types::frame_support::dispatch::RawOrigin::Root; quantus_subxt::api::runtime_types::quantus_runtime::OriginCaller::system(raw_origin) }, - _ => + _ => { return Err(QuantusError::Generic(format!( "Invalid origin type: {}. Must be 'signed', 'none', or 'root'", origin_type - ))), + ))) + }, }; let enactment = @@ -724,8 +733,8 @@ async fn vote_on_referendum( let amount_value: u128 = (amount .parse::() .map_err(|_| QuantusError::Generic("Invalid amount format".to_string()))? - .max(0.0) * - 1_000_000_000_000_000_000.0) as u128; + .max(0.0) + * 1_000_000_000_000_000_000.0) as u128; // Validate conviction if conviction > 6 { diff --git a/src/cli/referenda_decode.rs b/src/cli/referenda_decode.rs index 7140fa7..7ee5aaf 100644 --- a/src/cli/referenda_decode.rs +++ b/src/cli/referenda_decode.rs @@ -22,8 +22,9 @@ pub async fn decode_preimage( let content = match preimage_result { Ok(Some(bounded_vec)) => bounded_vec.0, - Ok(None) => - return Err(QuantusError::Generic(format!("Preimage not found for hash {:?}", hash))), + Ok(None) => { + return Err(QuantusError::Generic(format!("Preimage not found for hash {:?}", hash))) + }, Err(e) => return Err(QuantusError::Generic(format!("Error fetching preimage: {:?}", e))), }; diff --git a/src/cli/reversible.rs b/src/cli/reversible.rs index 63d5ed0..52bd779 100644 --- a/src/cli/reversible.rs +++ b/src/cli/reversible.rs @@ -253,8 +253,9 @@ pub async fn handle_reversible_command( let quantus_client = crate::chain::client::QuantusClient::new(node_url).await?; match command { - ReversibleCommands::ListPending { address, from, password, password_file } => - list_pending_transactions(&quantus_client, address, from, password, password_file).await, + ReversibleCommands::ListPending { address, from, password, password_file } => { + list_pending_transactions(&quantus_client, address, from, password, password_file).await + }, ReversibleCommands::ScheduleTransfer { to, amount, from, password, password_file } => { // Parse and validate the amount let quantus_client = crate::chain::client::QuantusClient::new(node_url).await?; diff --git a/src/cli/scheduler.rs b/src/cli/scheduler.rs index e89a1cd..67ab6c2 100644 --- a/src/cli/scheduler.rs +++ b/src/cli/scheduler.rs @@ -166,7 +166,8 @@ pub async fn handle_scheduler_command( Ok(()) }, SchedulerCommands::Agenda { range } => list_agenda_range(&quantus_client, &range).await, - SchedulerCommands::ScheduleRemark { after, from } => - schedule_remark(&quantus_client, after, &from, execution_mode).await, + SchedulerCommands::ScheduleRemark { after, from } => { + schedule_remark(&quantus_client, after, &from, execution_mode).await + }, } } diff --git a/src/cli/storage.rs b/src/cli/storage.rs index 2ad0ce0..3567190 100644 --- a/src/cli/storage.rs +++ b/src/cli/storage.rs @@ -839,14 +839,18 @@ pub async fn handle_storage_command( .await } }, - StorageCommands::List { pallet, names_only } => - list_storage_items(&quantus_client, &pallet, names_only).await, - StorageCommands::ListPallets { with_counts } => - list_pallets_with_storage(&quantus_client, with_counts).await, - StorageCommands::Stats { pallet, detailed } => - show_storage_stats(&quantus_client, pallet, detailed).await, - StorageCommands::Iterate { pallet, name, limit, decode_as, block } => - iterate_storage_entries(&quantus_client, &pallet, &name, limit, decode_as, block).await, + StorageCommands::List { pallet, names_only } => { + list_storage_items(&quantus_client, &pallet, names_only).await + }, + StorageCommands::ListPallets { with_counts } => { + list_pallets_with_storage(&quantus_client, with_counts).await + }, + StorageCommands::Stats { pallet, detailed } => { + show_storage_stats(&quantus_client, pallet, detailed).await + }, + StorageCommands::Iterate { pallet, name, limit, decode_as, block } => { + iterate_storage_entries(&quantus_client, &pallet, &name, limit, decode_as, block).await + }, StorageCommands::Set { pallet, name, value, wallet, password, password_file, r#type } => { log_print!("✍️ Setting storage for {}::{}", pallet.bright_green(), name.bright_cyan()); @@ -890,10 +894,11 @@ pub async fn handle_storage_command( .map_err(|e| QuantusError::Generic(format!("Invalid hex value: {e}")))? } }, - Some(unsupported) => + Some(unsupported) => { return Err(QuantusError::Generic(format!( "Unsupported type for --type: {unsupported}" - ))), + ))) + }, }; log_verbose!("Encoded value bytes: 0x{}", hex::encode(&value_bytes).dimmed()); diff --git a/src/cli/tech_collective.rs b/src/cli/tech_collective.rs index 6234b6f..f917dd1 100644 --- a/src/cli/tech_collective.rs +++ b/src/cli/tech_collective.rs @@ -429,7 +429,7 @@ pub async fn handle_tech_collective_command( // Get actual member list match get_member_list(&quantus_client).await { - Ok(members) => + Ok(members) => { if members.is_empty() { log_print!("πŸ“­ No members in Tech Collective"); } else { @@ -443,7 +443,8 @@ pub async fn handle_tech_collective_command( member.to_quantus_ss58().bright_green() ); } - }, + } + }, Err(e) => { log_verbose!("⚠️ Failed to get member list: {:?}", e); // Fallback to member count diff --git a/src/cli/tech_referenda.rs b/src/cli/tech_referenda.rs index 6fc8860..4589c1b 100644 --- a/src/cli/tech_referenda.rs +++ b/src/cli/tech_referenda.rs @@ -192,7 +192,7 @@ pub async fn handle_tech_referenda_command( let quantus_client = crate::chain::client::QuantusClient::new(node_url).await?; match command { - TechReferendaCommands::Submit { preimage_hash, from, password, password_file } => + TechReferendaCommands::Submit { preimage_hash, from, password, password_file } => { submit_runtime_upgrade( &quantus_client, &preimage_hash, @@ -201,8 +201,9 @@ pub async fn handle_tech_referenda_command( password_file, execution_mode, ) - .await, - TechReferendaCommands::SubmitWithPreimage { wasm_file, from, password, password_file } => + .await + }, + TechReferendaCommands::SubmitWithPreimage { wasm_file, from, password, password_file } => { submit_runtime_upgrade_with_preimage( &quantus_client, &wasm_file, @@ -211,12 +212,14 @@ pub async fn handle_tech_referenda_command( password_file, execution_mode, ) - .await, + .await + }, TechReferendaCommands::List => list_proposals(&quantus_client).await, TechReferendaCommands::Get { index } => get_proposal_details(&quantus_client, index).await, - TechReferendaCommands::Status { index } => - get_proposal_status(&quantus_client, index).await, - TechReferendaCommands::PlaceDecisionDeposit { index, from, password, password_file } => + TechReferendaCommands::Status { index } => { + get_proposal_status(&quantus_client, index).await + }, + TechReferendaCommands::PlaceDecisionDeposit { index, from, password, password_file } => { place_decision_deposit( &quantus_client, index, @@ -225,17 +228,21 @@ pub async fn handle_tech_referenda_command( password_file, execution_mode, ) - .await, - TechReferendaCommands::Cancel { index, from, password, password_file } => + .await + }, + TechReferendaCommands::Cancel { index, from, password, password_file } => { cancel_proposal(&quantus_client, index, &from, password, password_file, execution_mode) - .await, - TechReferendaCommands::Kill { index, from, password, password_file } => + .await + }, + TechReferendaCommands::Kill { index, from, password, password_file } => { kill_proposal(&quantus_client, index, &from, password, password_file, execution_mode) - .await, - TechReferendaCommands::Nudge { index, from, password, password_file } => + .await + }, + TechReferendaCommands::Nudge { index, from, password, password_file } => { nudge_proposal(&quantus_client, index, &from, password, password_file, execution_mode) - .await, - TechReferendaCommands::RefundSubmissionDeposit { index, from, password, password_file } => + .await + }, + TechReferendaCommands::RefundSubmissionDeposit { index, from, password, password_file } => { refund_submission_deposit( &quantus_client, index, @@ -244,8 +251,9 @@ pub async fn handle_tech_referenda_command( password_file, execution_mode, ) - .await, - TechReferendaCommands::RefundDecisionDeposit { index, from, password, password_file } => + .await + }, + TechReferendaCommands::RefundDecisionDeposit { index, from, password, password_file } => { refund_decision_deposit( &quantus_client, index, @@ -254,7 +262,8 @@ pub async fn handle_tech_referenda_command( password_file, execution_mode, ) - .await, + .await + }, TechReferendaCommands::Config => get_config(&quantus_client).await, } } diff --git a/src/cli/treasury.rs b/src/cli/treasury.rs index e910bea..b82509a 100644 --- a/src/cli/treasury.rs +++ b/src/cli/treasury.rs @@ -132,7 +132,7 @@ pub async fn handle_treasury_command( from, password, password_file, - } => + } => { submit_spend_referendum( &quantus_client, &beneficiary, @@ -143,11 +143,13 @@ pub async fn handle_treasury_command( password_file, execution_mode, ) - .await, - TreasuryCommands::Payout { index, from, password, password_file } => + .await + }, + TreasuryCommands::Payout { index, from, password, password_file } => { payout_spend(&quantus_client, index, &from, password, password_file, execution_mode) - .await, - TreasuryCommands::CheckStatus { index, from, password, password_file } => + .await + }, + TreasuryCommands::CheckStatus { index, from, password, password_file } => { check_spend_status( &quantus_client, index, @@ -156,9 +158,10 @@ pub async fn handle_treasury_command( password_file, execution_mode, ) - .await, + .await + }, TreasuryCommands::ListSpends => list_spends(&quantus_client).await, - TreasuryCommands::SpendSudo { beneficiary, amount, from, password, password_file } => + TreasuryCommands::SpendSudo { beneficiary, amount, from, password, password_file } => { spend_sudo( &quantus_client, &beneficiary, @@ -168,7 +171,8 @@ pub async fn handle_treasury_command( password_file, execution_mode, ) - .await, + .await + }, } } diff --git a/src/cli/wallet.rs b/src/cli/wallet.rs index ee30a21..b1425d5 100644 --- a/src/cli/wallet.rs +++ b/src/cli/wallet.rs @@ -224,7 +224,7 @@ pub async fn handle_wallet_command( if all { // Show all wallets (same as list command but with different header) match wallet_manager.list_wallets() { - Ok(wallets) => + Ok(wallets) => { if wallets.is_empty() { log_print!("{}", "No wallets found.".dimmed()); } else { @@ -254,7 +254,8 @@ pub async fn handle_wallet_command( log_print!(); } } - }, + } + }, Err(e) => { log_error!("{}", format!("❌ Failed to view wallets: {e}").red()); return Err(e); @@ -445,7 +446,7 @@ pub async fn handle_wallet_command( let wallet_manager = WalletManager::new()?; match wallet_manager.list_wallets() { - Ok(wallets) => + Ok(wallets) => { if wallets.is_empty() { log_print!("{}", "No wallets found.".dimmed()); log_print!( @@ -481,7 +482,8 @@ pub async fn handle_wallet_command( "πŸ’‘ Use 'quantus wallet view --name ' to see full details" .dimmed() ); - }, + } + }, Err(e) => { log_error!("{}", format!("❌ Failed to list wallets: {e}").red()); return Err(e); diff --git a/src/main.rs b/src/main.rs index ff07b3c..2bf667a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -42,7 +42,7 @@ struct Cli { finalized_tx: bool, /// Wait for transaction validation/inclusion before returning - /// Default: false (fire and forget - return immediately with hash) + /// Default: false #[arg(long, global = true, default_value = "false")] wait_for_transaction: bool, } From 6a9711ce6505b1e8b6ab1d0091ccc2bed93f6375 Mon Sep 17 00:00:00 2001 From: Nikolaus Heger Date: Sun, 11 Jan 2026 23:26:20 +0800 Subject: [PATCH 04/10] fix proxy check address --- src/cli/recovery.rs | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/cli/recovery.rs b/src/cli/recovery.rs index 14dd05d..6b04467 100644 --- a/src/cli/recovery.rs +++ b/src/cli/recovery.rs @@ -318,7 +318,9 @@ pub async fn handle_recovery_command( quantus_client.client().storage().at(latest).fetch(&proxy_storage).await; let proxy_of = match proxy_result { Ok(Some(proxy)) => { - log_print!("🧩 Proxy mapping: rescuer proxies -> {}", format!("{}", proxy)); + let proxy_bytes: &[u8; 32] = proxy.as_ref(); + let proxy_sp = SpAccountId32::from(*proxy_bytes); + log_print!("🧩 Proxy mapping: rescuer proxies -> {}", proxy_sp.to_ss58check()); Some(proxy) }, Ok(None) => { @@ -326,7 +328,8 @@ pub async fn handle_recovery_command( "❌ No proxy mapping found for rescuer - recovery not set up properly" ); return Err(crate::error::QuantusError::Generic( - "Rescuer has no proxy mapping. Recovery process may not be properly set up.".to_string() + "Rescuer has no proxy mapping. Recovery process may not be properly set up." + .to_string(), )); }, Err(e) => { @@ -339,7 +342,9 @@ pub async fn handle_recovery_command( // Validate that the proxy points to the correct lost account if let Some(proxy) = proxy_of { - let proxy_addr = format!("{proxy}"); + let proxy_bytes: &[u8; 32] = proxy.as_ref(); + let proxy_sp = SpAccountId32::from(*proxy_bytes); + let proxy_addr = proxy_sp.to_ss58check(); if proxy_addr != lost_resolved { log_error!( "❌ Proxy mismatch! Rescuer proxies {} but we're trying to recover {}", From 12ceff736625c9f0f995f98b005b5d11cf93d466 Mon Sep 17 00:00:00 2001 From: Nikolaus Heger Date: Sun, 11 Jan 2026 23:28:39 +0800 Subject: [PATCH 05/10] fix high security walkthrough script --- scripts/high_security_example.sh | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/scripts/high_security_example.sh b/scripts/high_security_example.sh index 5101878..9478328 100644 --- a/scripts/high_security_example.sh +++ b/scripts/high_security_example.sh @@ -21,31 +21,33 @@ quantus high-security set --from crystal_alice --interceptor crystal_bob --delay quantus send --from crystal_alice --to crystal_bob --amount 9999 # fail case 3 also send a reversible with a different delay more or less - should fail -quantus reversible schedule-transfer-with-delay --from crystal_alice --to crystal_bob --amount 555 --delay-seconds 90 +quantus reversible schedule-transfer-with-delay --from crystal_alice --to crystal_bob --amount 5556 --delay 90 # Check balances of Alice and Charlie quantus balance --address crystal_alice quantus balance --address crystal_charlie # Alice sends a reversible transfer to bob over 500000 coins of quantus over 1 hour delay -quantus reversible schedule-transfer-with-delay --from crystal_alice --to crystal_bob --amount 500000 --delay 3600 +quantus reversible schedule-transfer --from crystal_alice --to crystal_bob --amount 500000 -# Alice should be able to cancel the reversible transfer -# quantus reversible cancel --tx-id --from crystal_alice +quantus reversible list-pending --from crystal_alice -# Charlie intercepts the transfer and sends it to himself -quantus reversible schedule-transfer-with-delay --from crystal_charlie --to crystal_charlie --amount 555 --delay 3600 +# Interceptor account charlie reverses transaction +quantus reversible cancel --tx-id 0xb8ee1f940e13fbc171481d1b06967760bf1d39f06dbcdb595c02c420aec6a45e --from crystal_charlie # Check balances of Alice, Bob, and Charlie quantus balance --address crystal_alice quantus balance --address crystal_bob quantus balance --address crystal_charlie +# activate the recovery first vouch then claim. +ququantus recovery initiate --rescuer crystal_charlie --lost crystal_alice +quantus recovery active --rescuer crystal_charlie --lost crystal_alice +quantus recovery vouch --rescuer crystal_charlie --lost crystal_alice --friend crystal_charlie +quantus recovery claim --rescuer crystal_charlie --lost crystal_alice +quantus recovery proxy-of --rescuer crystal_charlie + # Charlie pulls all money from Alice's account -# this is simply done by charlie making a transfer on behalf of alice which sends all money to charlie -# We need to use the proxy pallet for this -# because Charlie is a guardian for alice, charlie is also a recoverer through the recovery pallet. -# so we can use the recovery pallet to send all money to charlie quantus recovery recover-all --rescuer crystal_charlie --lost crystal_alice --dest crystal_charlie # Check balances of Alice, Bob, and Charlie From 1f6c572fc49ee8a2a304f913ed9f19f8f166ce62 Mon Sep 17 00:00:00 2001 From: Nikolaus Heger Date: Sun, 11 Jan 2026 23:29:00 +0800 Subject: [PATCH 06/10] remove hard coded urls --- src/chain/client.rs | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/src/chain/client.rs b/src/chain/client.rs index efc728d..5d85f68 100644 --- a/src/chain/client.rs +++ b/src/chain/client.rs @@ -64,15 +64,6 @@ impl QuantusClient { ))); } - // Provide helpful hints for common URL issues - if node_url.starts_with("ws://") - && (node_url.contains("a.i.res.fm") || node_url.contains("a.t.res.fm")) - { - log_verbose!( - "πŸ’‘ Hint: Remote nodes typically require secure WebSocket connections (wss://)" - ); - } - // Create WS client with custom timeouts let ws_client = WsClientBuilder::default() // TODO: Make these configurable in a separate change @@ -85,11 +76,11 @@ impl QuantusClient { // Provide more helpful error messages for common issues let error_str = format!("{e:?}"); let error_msg = if error_str.contains("TimedOut") || error_str.contains("timed out") { - if node_url.starts_with("ws://") && (node_url.contains("a.i.res.fm") || node_url.contains("a.t.res.fm")) { + if node_url.starts_with("ws://") { format!( - "Connection timed out. This remote node requires secure WebSocket connections (wss://). Try using 'wss://{}' instead of 'ws://{}'", + "Connection timed out. Try using 'wss://{}' instead of '{}'", node_url.strip_prefix("ws://").unwrap_or(node_url), - node_url.strip_prefix("ws://").unwrap_or(node_url) + node_url ) } else { format!("Connection timed out. Please check if the node is running and accessible at: {node_url}") From 8888bbe0cac3c6dd7a1eb07a536841954d42c52c Mon Sep 17 00:00:00 2001 From: Nikolaus Heger Date: Sun, 11 Jan 2026 23:29:24 +0800 Subject: [PATCH 07/10] remove printout --- src/cli/common.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/cli/common.rs b/src/cli/common.rs index 1211920..471fe7e 100644 --- a/src/cli/common.rs +++ b/src/cli/common.rs @@ -150,12 +150,6 @@ where loop { attempt += 1; - - crate::log_print!( - "submit transaction with wait for transaction: {}", - execution_mode.wait_for_transaction - ); - // Get fresh nonce for each attempt, or increment if we have a previous nonce let nonce = if let Some(prev_nonce) = current_nonce { // After first failure, try with incremented nonce From ff178e9fce62e2ccc7a446fbb3629af9bbd66271 Mon Sep 17 00:00:00 2001 From: Nikolaus Heger Date: Sun, 11 Jan 2026 23:30:00 +0800 Subject: [PATCH 08/10] cargo format --- src/chain/quantus_subxt.rs | 4 +- src/cli/batch.rs | 10 ++--- src/cli/block.rs | 14 +++---- src/cli/common.rs | 15 ++++--- src/cli/generic_call.rs | 45 +++++++++------------ src/cli/mod.rs | 80 +++++++++++++++---------------------- src/cli/referenda.rs | 49 ++++++++++------------- src/cli/referenda_decode.rs | 5 +-- src/cli/reversible.rs | 5 +-- src/cli/scheduler.rs | 5 +-- src/cli/storage.rs | 25 +++++------- src/cli/tech_collective.rs | 5 +-- src/cli/tech_referenda.rs | 45 +++++++++------------ src/cli/treasury.rs | 20 ++++------ src/cli/wallet.rs | 10 ++--- 15 files changed, 136 insertions(+), 201 deletions(-) diff --git a/src/chain/quantus_subxt.rs b/src/chain/quantus_subxt.rs index d2c9f6d..a94a0d2 100644 --- a/src/chain/quantus_subxt.rs +++ b/src/chain/quantus_subxt.rs @@ -1995,8 +1995,8 @@ pub mod api { .only_these_pallets(&PALLETS) .only_these_runtime_apis(&RUNTIME_APIS) .hash(); - runtime_metadata_hash - == [ + runtime_metadata_hash == + [ 194u8, 46u8, 30u8, 103u8, 67u8, 25u8, 224u8, 42u8, 104u8, 224u8, 105u8, 213u8, 149u8, 58u8, 199u8, 151u8, 221u8, 215u8, 141u8, 247u8, 109u8, 85u8, 204u8, 202u8, 96u8, 104u8, 173u8, 94u8, 198u8, 124u8, 113u8, 174u8, diff --git a/src/cli/batch.rs b/src/cli/batch.rs index 0449979..b1b84c8 100644 --- a/src/cli/batch.rs +++ b/src/cli/batch.rs @@ -75,7 +75,7 @@ pub async fn handle_batch_command( count, to, amount, - } => { + } => handle_batch_send_command( from, node_url, @@ -88,11 +88,9 @@ pub async fn handle_batch_command( amount, execution_mode, ) - .await - }, - BatchCommands::Config { limits, info } => { - handle_batch_config_command(node_url, limits, info).await - }, + .await, + BatchCommands::Config { limits, info } => + handle_batch_config_command(node_url, limits, info).await, } } diff --git a/src/cli/block.rs b/src/cli/block.rs index b085592..a5c6b1c 100644 --- a/src/cli/block.rs +++ b/src/cli/block.rs @@ -79,7 +79,7 @@ pub async fn handle_block_command( extrinsics_details, events, all, - } => { + } => handle_block_analyze_command( number, hash, @@ -91,11 +91,9 @@ pub async fn handle_block_command( all, node_url, ) - .await - }, - BlockCommands::List { start, end, step } => { - handle_block_list_command(start, end, step, node_url).await - }, + .await, + BlockCommands::List { start, end, step } => + handle_block_list_command(start, end, step, node_url).await, } } @@ -140,9 +138,7 @@ async fn handle_block_analyze_command( })?; (block_num, hash) } else { - return Err(QuantusError::Generic( - "Must specify --number, --hash, or --latest".to_string(), - )); + return Err(QuantusError::Generic("Must specify --number, --hash, or --latest".to_string())); }; log_print!("πŸ“¦ Block #{} - {:#x}", block_number, block_hash); diff --git a/src/cli/common.rs b/src/cli/common.rs index 471fe7e..22e12ad 100644 --- a/src/cli/common.rs +++ b/src/cli/common.rs @@ -240,11 +240,11 @@ where let error_msg = format!("{e:?}"); // Check if it's a retryable error - let is_retryable = error_msg.contains("Priority is too low") - || error_msg.contains("Transaction is outdated") - || error_msg.contains("Transaction is temporarily banned") - || error_msg.contains("Transaction has a bad signature") - || error_msg.contains("Invalid Transaction"); + let is_retryable = error_msg.contains("Priority is too low") || + error_msg.contains("Transaction is outdated") || + error_msg.contains("Transaction is temporarily banned") || + error_msg.contains("Transaction has a bad signature") || + error_msg.contains("Invalid Transaction"); if is_retryable && attempt < 5 { log_verbose!( @@ -400,11 +400,10 @@ async fn wait_tx_inclusion( crate::log_verbose!(" Transaction status: {:?} (elapsed: {}s)", status, elapsed_secs); match status { - TxStatus::Validated => { + TxStatus::Validated => if let Some(ref pb) = spinner { pb.set_message(format!("Transaction validated βœ“ ({}s)", elapsed_secs)); - } - }, + }, TxStatus::InBestBlock(block_hash) => { crate::log_verbose!(" Transaction included in block: {:?}", block_hash); if finalized { diff --git a/src/cli/generic_call.rs b/src/cli/generic_call.rs index a33f1e6..fe2049a 100644 --- a/src/cli/generic_call.rs +++ b/src/cli/generic_call.rs @@ -53,7 +53,7 @@ pub async fn execute_generic_call( let tx_hash = match (pallet, call) { // Balances pallet calls - ("Balances", "transfer_allow_death") => { + ("Balances", "transfer_allow_death") => submit_balance_transfer( quantus_client, from_keypair, @@ -62,9 +62,8 @@ pub async fn execute_generic_call( tip_amount, execution_mode, ) - .await? - }, - ("Balances", "transfer_keep_alive") => { + .await?, + ("Balances", "transfer_keep_alive") => submit_balance_transfer( quantus_client, from_keypair, @@ -73,48 +72,40 @@ pub async fn execute_generic_call( tip_amount, execution_mode, ) - .await? - }, + .await?, // System pallet calls - ("System", "remark") => { + ("System", "remark") => submit_system_remark(quantus_client, from_keypair, &args, tip_amount, execution_mode) - .await? - }, + .await?, // Sudo pallet calls ("Sudo", "sudo") => submit_sudo_call(quantus_client, from_keypair, &args).await?, // TechCollective pallet calls - ("TechCollective", "add_member") => { + ("TechCollective", "add_member") => submit_tech_collective_add_member(quantus_client, from_keypair, &args, execution_mode) - .await? - }, - ("TechCollective", "remove_member") => { + .await?, + ("TechCollective", "remove_member") => submit_tech_collective_remove_member( quantus_client, from_keypair, &args, execution_mode, ) - .await? - }, - ("TechCollective", "vote") => { - submit_tech_collective_vote(quantus_client, from_keypair, &args, execution_mode).await? - }, + .await?, + ("TechCollective", "vote") => + submit_tech_collective_vote(quantus_client, from_keypair, &args, execution_mode).await?, // ReversibleTransfers pallet calls - ("ReversibleTransfers", "schedule_transfer") => { - submit_reversible_transfer(quantus_client, from_keypair, &args, execution_mode).await? - }, + ("ReversibleTransfers", "schedule_transfer") => + submit_reversible_transfer(quantus_client, from_keypair, &args, execution_mode).await?, // Scheduler pallet calls - ("Scheduler", "schedule") => { - submit_scheduler_schedule(quantus_client, from_keypair, &args).await? - }, - ("Scheduler", "cancel") => { - submit_scheduler_cancel(quantus_client, from_keypair, &args).await? - }, + ("Scheduler", "schedule") => + submit_scheduler_schedule(quantus_client, from_keypair, &args).await?, + ("Scheduler", "cancel") => + submit_scheduler_cancel(quantus_client, from_keypair, &args).await?, // Generic fallback for unknown calls (_, _) => { diff --git a/src/cli/mod.rs b/src/cli/mod.rs index 22af008..a5c768e 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -248,7 +248,7 @@ pub async fn execute_command( ) -> crate::error::Result<()> { match command { Commands::Wallet(wallet_cmd) => wallet::handle_wallet_command(wallet_cmd, node_url).await, - Commands::Send { from, to, amount, password, password_file, tip, nonce } => { + Commands::Send { from, to, amount, password, password_file, tip, nonce } => send::handle_send_command( from, to, @@ -260,54 +260,41 @@ pub async fn execute_command( nonce, execution_mode, ) - .await - }, - Commands::Batch(batch_cmd) => { - batch::handle_batch_command(batch_cmd, node_url, execution_mode).await - }, - Commands::Reversible(reversible_cmd) => { - reversible::handle_reversible_command(reversible_cmd, node_url, execution_mode).await - }, - Commands::HighSecurity(hs_cmd) => { - high_security::handle_high_security_command(hs_cmd, node_url, execution_mode).await - }, - Commands::Recovery(recovery_cmd) => { - recovery::handle_recovery_command(recovery_cmd, node_url, execution_mode).await - }, - Commands::Scheduler(scheduler_cmd) => { - scheduler::handle_scheduler_command(scheduler_cmd, node_url, execution_mode).await - }, - Commands::Storage(storage_cmd) => { - storage::handle_storage_command(storage_cmd, node_url, execution_mode).await - }, - Commands::TechCollective(tech_collective_cmd) => { + .await, + Commands::Batch(batch_cmd) => + batch::handle_batch_command(batch_cmd, node_url, execution_mode).await, + Commands::Reversible(reversible_cmd) => + reversible::handle_reversible_command(reversible_cmd, node_url, execution_mode).await, + Commands::HighSecurity(hs_cmd) => + high_security::handle_high_security_command(hs_cmd, node_url, execution_mode).await, + Commands::Recovery(recovery_cmd) => + recovery::handle_recovery_command(recovery_cmd, node_url, execution_mode).await, + Commands::Scheduler(scheduler_cmd) => + scheduler::handle_scheduler_command(scheduler_cmd, node_url, execution_mode).await, + Commands::Storage(storage_cmd) => + storage::handle_storage_command(storage_cmd, node_url, execution_mode).await, + Commands::TechCollective(tech_collective_cmd) => tech_collective::handle_tech_collective_command( tech_collective_cmd, node_url, execution_mode, ) - .await - }, - Commands::Preimage(preimage_cmd) => { - preimage::handle_preimage_command(preimage_cmd, node_url, execution_mode).await - }, - Commands::TechReferenda(tech_referenda_cmd) => { + .await, + Commands::Preimage(preimage_cmd) => + preimage::handle_preimage_command(preimage_cmd, node_url, execution_mode).await, + Commands::TechReferenda(tech_referenda_cmd) => tech_referenda::handle_tech_referenda_command( tech_referenda_cmd, node_url, execution_mode, ) - .await - }, - Commands::Referenda(referenda_cmd) => { - referenda::handle_referenda_command(referenda_cmd, node_url, execution_mode).await - }, - Commands::Treasury(treasury_cmd) => { - treasury::handle_treasury_command(treasury_cmd, node_url, execution_mode).await - }, - Commands::Runtime(runtime_cmd) => { - runtime::handle_runtime_command(runtime_cmd, node_url, execution_mode).await - }, + .await, + Commands::Referenda(referenda_cmd) => + referenda::handle_referenda_command(referenda_cmd, node_url, execution_mode).await, + Commands::Treasury(treasury_cmd) => + treasury::handle_treasury_command(treasury_cmd, node_url, execution_mode).await, + Commands::Runtime(runtime_cmd) => + runtime::handle_runtime_command(runtime_cmd, node_url, execution_mode).await, Commands::Call { pallet, call, @@ -318,7 +305,7 @@ pub async fn execute_command( tip, offline, call_data_only, - } => { + } => handle_generic_call_command( pallet, call, @@ -332,8 +319,7 @@ pub async fn execute_command( node_url, execution_mode, ) - .await - }, + .await, Commands::Balance { address } => { let quantus_client = crate::chain::client::QuantusClient::new(node_url).await?; @@ -353,12 +339,11 @@ pub async fn execute_command( Ok(()) }, }, - Commands::Events { block, block_hash, latest: _, finalized, pallet, raw, no_decode } => { + Commands::Events { block, block_hash, latest: _, finalized, pallet, raw, no_decode } => events::handle_events_command( block, block_hash, finalized, pallet, raw, !no_decode, node_url, ) - .await - }, + .await, Commands::System { runtime, metadata, rpc_methods } => { if runtime || metadata || rpc_methods { system::handle_system_extended_command( @@ -373,9 +358,8 @@ pub async fn execute_command( system::handle_system_command(node_url).await } }, - Commands::Metadata { no_docs, stats_only, pallet } => { - metadata::handle_metadata_command(node_url, no_docs, stats_only, pallet).await - }, + Commands::Metadata { no_docs, stats_only, pallet } => + metadata::handle_metadata_command(node_url, no_docs, stats_only, pallet).await, Commands::Version => { log_print!("CLI Version: Quantus CLI v{}", env!("CARGO_PKG_VERSION")); Ok(()) diff --git a/src/cli/referenda.rs b/src/cli/referenda.rs index 9e2ead3..04f4416 100644 --- a/src/cli/referenda.rs +++ b/src/cli/referenda.rs @@ -178,7 +178,7 @@ pub async fn handle_referenda_command( let quantus_client = crate::chain::client::QuantusClient::new(node_url).await?; match command { - ReferendaCommands::SubmitRemark { message, from, password, password_file, origin } => { + ReferendaCommands::SubmitRemark { message, from, password, password_file, origin } => submit_remark_proposal( &quantus_client, &message, @@ -188,9 +188,8 @@ pub async fn handle_referenda_command( &origin, execution_mode, ) - .await - }, - ReferendaCommands::Submit { preimage_hash, from, password, password_file, origin } => { + .await, + ReferendaCommands::Submit { preimage_hash, from, password, password_file, origin } => submit_proposal( &quantus_client, &preimage_hash, @@ -200,14 +199,12 @@ pub async fn handle_referenda_command( &origin, execution_mode, ) - .await - }, + .await, ReferendaCommands::List => list_proposals(&quantus_client).await, - ReferendaCommands::Get { index, decode } => { - get_proposal_details(&quantus_client, index, decode).await - }, + ReferendaCommands::Get { index, decode } => + get_proposal_details(&quantus_client, index, decode).await, ReferendaCommands::Status { index } => get_proposal_status(&quantus_client, index).await, - ReferendaCommands::PlaceDecisionDeposit { index, from, password, password_file } => { + ReferendaCommands::PlaceDecisionDeposit { index, from, password, password_file } => place_decision_deposit( &quantus_client, index, @@ -216,8 +213,7 @@ pub async fn handle_referenda_command( password_file, execution_mode, ) - .await - }, + .await, ReferendaCommands::Vote { index, aye, @@ -226,7 +222,7 @@ pub async fn handle_referenda_command( from, password, password_file, - } => { + } => vote_on_referendum( &quantus_client, index, @@ -238,9 +234,8 @@ pub async fn handle_referenda_command( password_file, execution_mode, ) - .await - }, - ReferendaCommands::RefundSubmissionDeposit { index, from, password, password_file } => { + .await, + ReferendaCommands::RefundSubmissionDeposit { index, from, password, password_file } => refund_submission_deposit( &quantus_client, index, @@ -249,9 +244,8 @@ pub async fn handle_referenda_command( password_file, execution_mode, ) - .await - }, - ReferendaCommands::RefundDecisionDeposit { index, from, password, password_file } => { + .await, + ReferendaCommands::RefundDecisionDeposit { index, from, password, password_file } => refund_decision_deposit( &quantus_client, index, @@ -260,8 +254,7 @@ pub async fn handle_referenda_command( password_file, execution_mode, ) - .await - }, + .await, ReferendaCommands::Config => get_config(&quantus_client).await, } } @@ -349,12 +342,11 @@ async fn submit_remark_proposal( quantus_subxt::api::runtime_types::frame_support::dispatch::RawOrigin::Root; quantus_subxt::api::runtime_types::quantus_runtime::OriginCaller::system(raw_origin) }, - _ => { + _ => return Err(QuantusError::Generic(format!( "Invalid origin type: {}. Must be 'signed', 'none', or 'root'", origin_type - ))) - }, + ))), }; let enactment = @@ -467,12 +459,11 @@ async fn submit_proposal( quantus_subxt::api::runtime_types::frame_support::dispatch::RawOrigin::Root; quantus_subxt::api::runtime_types::quantus_runtime::OriginCaller::system(raw_origin) }, - _ => { + _ => return Err(QuantusError::Generic(format!( "Invalid origin type: {}. Must be 'signed', 'none', or 'root'", origin_type - ))) - }, + ))), }; let enactment = @@ -733,8 +724,8 @@ async fn vote_on_referendum( let amount_value: u128 = (amount .parse::() .map_err(|_| QuantusError::Generic("Invalid amount format".to_string()))? - .max(0.0) - * 1_000_000_000_000_000_000.0) as u128; + .max(0.0) * + 1_000_000_000_000_000_000.0) as u128; // Validate conviction if conviction > 6 { diff --git a/src/cli/referenda_decode.rs b/src/cli/referenda_decode.rs index 7ee5aaf..7140fa7 100644 --- a/src/cli/referenda_decode.rs +++ b/src/cli/referenda_decode.rs @@ -22,9 +22,8 @@ pub async fn decode_preimage( let content = match preimage_result { Ok(Some(bounded_vec)) => bounded_vec.0, - Ok(None) => { - return Err(QuantusError::Generic(format!("Preimage not found for hash {:?}", hash))) - }, + Ok(None) => + return Err(QuantusError::Generic(format!("Preimage not found for hash {:?}", hash))), Err(e) => return Err(QuantusError::Generic(format!("Error fetching preimage: {:?}", e))), }; diff --git a/src/cli/reversible.rs b/src/cli/reversible.rs index 52bd779..63d5ed0 100644 --- a/src/cli/reversible.rs +++ b/src/cli/reversible.rs @@ -253,9 +253,8 @@ pub async fn handle_reversible_command( let quantus_client = crate::chain::client::QuantusClient::new(node_url).await?; match command { - ReversibleCommands::ListPending { address, from, password, password_file } => { - list_pending_transactions(&quantus_client, address, from, password, password_file).await - }, + ReversibleCommands::ListPending { address, from, password, password_file } => + list_pending_transactions(&quantus_client, address, from, password, password_file).await, ReversibleCommands::ScheduleTransfer { to, amount, from, password, password_file } => { // Parse and validate the amount let quantus_client = crate::chain::client::QuantusClient::new(node_url).await?; diff --git a/src/cli/scheduler.rs b/src/cli/scheduler.rs index 67ab6c2..e89a1cd 100644 --- a/src/cli/scheduler.rs +++ b/src/cli/scheduler.rs @@ -166,8 +166,7 @@ pub async fn handle_scheduler_command( Ok(()) }, SchedulerCommands::Agenda { range } => list_agenda_range(&quantus_client, &range).await, - SchedulerCommands::ScheduleRemark { after, from } => { - schedule_remark(&quantus_client, after, &from, execution_mode).await - }, + SchedulerCommands::ScheduleRemark { after, from } => + schedule_remark(&quantus_client, after, &from, execution_mode).await, } } diff --git a/src/cli/storage.rs b/src/cli/storage.rs index 3567190..2ad0ce0 100644 --- a/src/cli/storage.rs +++ b/src/cli/storage.rs @@ -839,18 +839,14 @@ pub async fn handle_storage_command( .await } }, - StorageCommands::List { pallet, names_only } => { - list_storage_items(&quantus_client, &pallet, names_only).await - }, - StorageCommands::ListPallets { with_counts } => { - list_pallets_with_storage(&quantus_client, with_counts).await - }, - StorageCommands::Stats { pallet, detailed } => { - show_storage_stats(&quantus_client, pallet, detailed).await - }, - StorageCommands::Iterate { pallet, name, limit, decode_as, block } => { - iterate_storage_entries(&quantus_client, &pallet, &name, limit, decode_as, block).await - }, + StorageCommands::List { pallet, names_only } => + list_storage_items(&quantus_client, &pallet, names_only).await, + StorageCommands::ListPallets { with_counts } => + list_pallets_with_storage(&quantus_client, with_counts).await, + StorageCommands::Stats { pallet, detailed } => + show_storage_stats(&quantus_client, pallet, detailed).await, + StorageCommands::Iterate { pallet, name, limit, decode_as, block } => + iterate_storage_entries(&quantus_client, &pallet, &name, limit, decode_as, block).await, StorageCommands::Set { pallet, name, value, wallet, password, password_file, r#type } => { log_print!("✍️ Setting storage for {}::{}", pallet.bright_green(), name.bright_cyan()); @@ -894,11 +890,10 @@ pub async fn handle_storage_command( .map_err(|e| QuantusError::Generic(format!("Invalid hex value: {e}")))? } }, - Some(unsupported) => { + Some(unsupported) => return Err(QuantusError::Generic(format!( "Unsupported type for --type: {unsupported}" - ))) - }, + ))), }; log_verbose!("Encoded value bytes: 0x{}", hex::encode(&value_bytes).dimmed()); diff --git a/src/cli/tech_collective.rs b/src/cli/tech_collective.rs index f917dd1..6234b6f 100644 --- a/src/cli/tech_collective.rs +++ b/src/cli/tech_collective.rs @@ -429,7 +429,7 @@ pub async fn handle_tech_collective_command( // Get actual member list match get_member_list(&quantus_client).await { - Ok(members) => { + Ok(members) => if members.is_empty() { log_print!("πŸ“­ No members in Tech Collective"); } else { @@ -443,8 +443,7 @@ pub async fn handle_tech_collective_command( member.to_quantus_ss58().bright_green() ); } - } - }, + }, Err(e) => { log_verbose!("⚠️ Failed to get member list: {:?}", e); // Fallback to member count diff --git a/src/cli/tech_referenda.rs b/src/cli/tech_referenda.rs index 4589c1b..6fc8860 100644 --- a/src/cli/tech_referenda.rs +++ b/src/cli/tech_referenda.rs @@ -192,7 +192,7 @@ pub async fn handle_tech_referenda_command( let quantus_client = crate::chain::client::QuantusClient::new(node_url).await?; match command { - TechReferendaCommands::Submit { preimage_hash, from, password, password_file } => { + TechReferendaCommands::Submit { preimage_hash, from, password, password_file } => submit_runtime_upgrade( &quantus_client, &preimage_hash, @@ -201,9 +201,8 @@ pub async fn handle_tech_referenda_command( password_file, execution_mode, ) - .await - }, - TechReferendaCommands::SubmitWithPreimage { wasm_file, from, password, password_file } => { + .await, + TechReferendaCommands::SubmitWithPreimage { wasm_file, from, password, password_file } => submit_runtime_upgrade_with_preimage( &quantus_client, &wasm_file, @@ -212,14 +211,12 @@ pub async fn handle_tech_referenda_command( password_file, execution_mode, ) - .await - }, + .await, TechReferendaCommands::List => list_proposals(&quantus_client).await, TechReferendaCommands::Get { index } => get_proposal_details(&quantus_client, index).await, - TechReferendaCommands::Status { index } => { - get_proposal_status(&quantus_client, index).await - }, - TechReferendaCommands::PlaceDecisionDeposit { index, from, password, password_file } => { + TechReferendaCommands::Status { index } => + get_proposal_status(&quantus_client, index).await, + TechReferendaCommands::PlaceDecisionDeposit { index, from, password, password_file } => place_decision_deposit( &quantus_client, index, @@ -228,21 +225,17 @@ pub async fn handle_tech_referenda_command( password_file, execution_mode, ) - .await - }, - TechReferendaCommands::Cancel { index, from, password, password_file } => { + .await, + TechReferendaCommands::Cancel { index, from, password, password_file } => cancel_proposal(&quantus_client, index, &from, password, password_file, execution_mode) - .await - }, - TechReferendaCommands::Kill { index, from, password, password_file } => { + .await, + TechReferendaCommands::Kill { index, from, password, password_file } => kill_proposal(&quantus_client, index, &from, password, password_file, execution_mode) - .await - }, - TechReferendaCommands::Nudge { index, from, password, password_file } => { + .await, + TechReferendaCommands::Nudge { index, from, password, password_file } => nudge_proposal(&quantus_client, index, &from, password, password_file, execution_mode) - .await - }, - TechReferendaCommands::RefundSubmissionDeposit { index, from, password, password_file } => { + .await, + TechReferendaCommands::RefundSubmissionDeposit { index, from, password, password_file } => refund_submission_deposit( &quantus_client, index, @@ -251,9 +244,8 @@ pub async fn handle_tech_referenda_command( password_file, execution_mode, ) - .await - }, - TechReferendaCommands::RefundDecisionDeposit { index, from, password, password_file } => { + .await, + TechReferendaCommands::RefundDecisionDeposit { index, from, password, password_file } => refund_decision_deposit( &quantus_client, index, @@ -262,8 +254,7 @@ pub async fn handle_tech_referenda_command( password_file, execution_mode, ) - .await - }, + .await, TechReferendaCommands::Config => get_config(&quantus_client).await, } } diff --git a/src/cli/treasury.rs b/src/cli/treasury.rs index b82509a..e910bea 100644 --- a/src/cli/treasury.rs +++ b/src/cli/treasury.rs @@ -132,7 +132,7 @@ pub async fn handle_treasury_command( from, password, password_file, - } => { + } => submit_spend_referendum( &quantus_client, &beneficiary, @@ -143,13 +143,11 @@ pub async fn handle_treasury_command( password_file, execution_mode, ) - .await - }, - TreasuryCommands::Payout { index, from, password, password_file } => { + .await, + TreasuryCommands::Payout { index, from, password, password_file } => payout_spend(&quantus_client, index, &from, password, password_file, execution_mode) - .await - }, - TreasuryCommands::CheckStatus { index, from, password, password_file } => { + .await, + TreasuryCommands::CheckStatus { index, from, password, password_file } => check_spend_status( &quantus_client, index, @@ -158,10 +156,9 @@ pub async fn handle_treasury_command( password_file, execution_mode, ) - .await - }, + .await, TreasuryCommands::ListSpends => list_spends(&quantus_client).await, - TreasuryCommands::SpendSudo { beneficiary, amount, from, password, password_file } => { + TreasuryCommands::SpendSudo { beneficiary, amount, from, password, password_file } => spend_sudo( &quantus_client, &beneficiary, @@ -171,8 +168,7 @@ pub async fn handle_treasury_command( password_file, execution_mode, ) - .await - }, + .await, } } diff --git a/src/cli/wallet.rs b/src/cli/wallet.rs index b1425d5..ee30a21 100644 --- a/src/cli/wallet.rs +++ b/src/cli/wallet.rs @@ -224,7 +224,7 @@ pub async fn handle_wallet_command( if all { // Show all wallets (same as list command but with different header) match wallet_manager.list_wallets() { - Ok(wallets) => { + Ok(wallets) => if wallets.is_empty() { log_print!("{}", "No wallets found.".dimmed()); } else { @@ -254,8 +254,7 @@ pub async fn handle_wallet_command( log_print!(); } } - } - }, + }, Err(e) => { log_error!("{}", format!("❌ Failed to view wallets: {e}").red()); return Err(e); @@ -446,7 +445,7 @@ pub async fn handle_wallet_command( let wallet_manager = WalletManager::new()?; match wallet_manager.list_wallets() { - Ok(wallets) => { + Ok(wallets) => if wallets.is_empty() { log_print!("{}", "No wallets found.".dimmed()); log_print!( @@ -482,8 +481,7 @@ pub async fn handle_wallet_command( "πŸ’‘ Use 'quantus wallet view --name ' to see full details" .dimmed() ); - } - }, + }, Err(e) => { log_error!("{}", format!("❌ Failed to list wallets: {e}").red()); return Err(e); From 220e42f2f94d939c183b0a25ba48c1d81ce96c03 Mon Sep 17 00:00:00 2001 From: Nikolaus Heger Date: Mon, 12 Jan 2026 11:25:31 +0800 Subject: [PATCH 09/10] clippy fix --- src/cli/common.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/cli/common.rs b/src/cli/common.rs index 22e12ad..8bb6c33 100644 --- a/src/cli/common.rs +++ b/src/cli/common.rs @@ -8,16 +8,12 @@ use subxt::{ }; #[derive(Debug, Clone, Copy)] +#[derive(Default)] pub struct ExecutionMode { pub finalized: bool, pub wait_for_transaction: bool, } -impl Default for ExecutionMode { - fn default() -> Self { - Self { finalized: false, wait_for_transaction: false } - } -} /// Resolve address - if it's a wallet name, return the wallet's address /// If it's already an SS58 address, return it as is From b4989d5e72e84bf84a1145b5f424cd0c8f0d086f Mon Sep 17 00:00:00 2001 From: Nikolaus Heger Date: Mon, 12 Jan 2026 11:37:00 +0800 Subject: [PATCH 10/10] fmt --- src/cli/common.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/cli/common.rs b/src/cli/common.rs index 8bb6c33..74fd89f 100644 --- a/src/cli/common.rs +++ b/src/cli/common.rs @@ -7,14 +7,12 @@ use subxt::{ OnlineClient, }; -#[derive(Debug, Clone, Copy)] -#[derive(Default)] +#[derive(Debug, Clone, Copy, Default)] pub struct ExecutionMode { pub finalized: bool, pub wait_for_transaction: bool, } - /// Resolve address - if it's a wallet name, return the wallet's address /// If it's already an SS58 address, return it as is pub fn resolve_address(address_or_wallet_name: &str) -> Result {