diff --git a/crates/pop-cli/src/commands/call/parachain.rs b/crates/pop-cli/src/commands/call/parachain.rs index 10eeb9d2..5b776a80 100644 --- a/crates/pop-cli/src/commands/call/parachain.rs +++ b/crates/pop-cli/src/commands/call/parachain.rs @@ -4,8 +4,8 @@ use crate::cli::{self, traits::*}; use anyhow::{anyhow, Result}; use clap::Args; use pop_parachains::{ - construct_extrinsic, encode_call_data, find_extrinsic_by_name, find_pallet_by_name, - parse_chain_metadata, set_up_api, sign_and_submit_extrinsic, + construct_extrinsic, construct_sudo_extrinsic, encode_call_data, find_extrinsic_by_name, + find_pallet_by_name, parse_chain_metadata, set_up_api, sign_and_submit_extrinsic, sign_and_submit_extrinsic_with_call_data, supported_actions, Action, DynamicPayload, OnlineClient, Pallet, Param, SubstrateConfig, }; @@ -34,6 +34,9 @@ pub struct CallParachainCommand { /// - with a password "//Alice///SECRET_PASSWORD" #[clap(name = "suri", long, short, default_value = DEFAULT_URI)] suri: String, + /// Authenticates the sudo key and dispatches a function call with `Root` origin. + #[arg(name = "sudo", long, short = 'S')] + sudo: bool, /// SCALE encoded bytes representing the call data of the transaction. #[arg(name = "call", short = 'c', long, conflicts_with_all = ["pallet", "extrinsic", "args"])] call_data: Option, @@ -94,6 +97,9 @@ impl CallParachainCommand { full_message.push_str(&format!(" --args {}", args.join(" "))); } full_message.push_str(&format!(" --url {} --suri {}", self.url, self.suri)); + if self.sudo { + full_message.push_str(" --sudo"); + } full_message } @@ -187,6 +193,13 @@ impl CallParachainCommand { } self.args = contract_args; } + // Prompt the user to confirm if they want to execute the call with sudo privileges. + if !self.sudo { + self.sudo = cli + .confirm("Would you like to execute this operation with sudo privileges?") + .initial_value(false) + .interact()?; + } cli.info(self.display())?; Ok(()) @@ -216,6 +229,8 @@ impl CallParachainCommand { return Err(anyhow!("Error: {}", e)); }, }; + // If sudo is enabled, wrap the call in a sudo call. + let tx = if self.sudo { construct_sudo_extrinsic(tx).await? } else { tx }; cli.info(format!("Encoded call data: {}", encode_call_data(api, &tx)?))?; Ok(tx) } @@ -324,6 +339,7 @@ impl CallParachainCommand { self.pallet = None; self.extrinsic = None; self.args.clear(); + self.sudo = false; } } diff --git a/crates/pop-parachains/src/call/mod.rs b/crates/pop-parachains/src/call/mod.rs index 90545aa9..6e9fd405 100644 --- a/crates/pop-parachains/src/call/mod.rs +++ b/crates/pop-parachains/src/call/mod.rs @@ -24,6 +24,14 @@ pub async fn construct_extrinsic( Ok(subxt::dynamic::tx(pallet_name, extrinsic_name, parsed_args)) } +/// Constructs a Sudo extrinsic. +/// +/// # Arguments +/// * `tx`: transaction that should be executed with sudo privileges.. +pub async fn construct_sudo_extrinsic(tx: DynamicPayload) -> Result { + Ok(subxt::dynamic::tx("Sudo", "sudo", [tx.into_value()].to_vec())) +} + pub async fn sign_and_submit_extrinsic( api: OnlineClient, tx: DynamicPayload, diff --git a/crates/pop-parachains/src/lib.rs b/crates/pop-parachains/src/lib.rs index 6847c24d..30a90abb 100644 --- a/crates/pop-parachains/src/lib.rs +++ b/crates/pop-parachains/src/lib.rs @@ -16,7 +16,7 @@ pub use build::{ generate_plain_chain_spec, generate_raw_chain_spec, is_supported, ChainSpec, }; pub use call::{ - construct_extrinsic, encode_call_data, + construct_extrinsic, construct_sudo_extrinsic, encode_call_data, metadata::{ action::{supported_actions, Action}, find_extrinsic_by_name, find_pallet_by_name,