From 32230f44093967a9013230098204927620436c0e Mon Sep 17 00:00:00 2001 From: AlexD10S Date: Thu, 5 Dec 2024 20:58:13 +0100 Subject: [PATCH 01/10] feat: parse files when the argument values are very big --- crates/pop-cli/src/commands/call/parachain.rs | 78 +++++++++++++++---- .../pop-parachains/src/call/metadata/mod.rs | 1 + .../src/call/metadata/params.rs | 22 +++++- 3 files changed, 81 insertions(+), 20 deletions(-) diff --git a/crates/pop-cli/src/commands/call/parachain.rs b/crates/pop-cli/src/commands/call/parachain.rs index 38b72f30..dc12e958 100644 --- a/crates/pop-cli/src/commands/call/parachain.rs +++ b/crates/pop-cli/src/commands/call/parachain.rs @@ -12,6 +12,7 @@ use url::Url; const DEFAULT_URL: &str = "ws://localhost:9944/"; const DEFAULT_URI: &str = "//Alice"; +const ENCODED_CALL_DATA_MAX_LEN: usize = 1000; // Maximum length of encoded call data to display. /// Command to execute extrinsics with configurable pallets, arguments, and signing options. #[derive(Args, Clone)] @@ -74,8 +75,9 @@ impl CallParachainCommand { break; } - if !prompt_to_repeat_call || - !cli.confirm("Do you want to perform another call?") + if !prompt_to_repeat_call + || !cli + .confirm("Do you want to perform another call?") .initial_value(false) .interact()? { @@ -138,8 +140,9 @@ impl CallParachainCommand { // Resolve extrinsic. let extrinsic = match self.extrinsic { - Some(ref extrinsic_name) => - find_extrinsic_by_name(&chain.pallets, &pallet.name, extrinsic_name).await?, + Some(ref extrinsic_name) => { + find_extrinsic_by_name(&chain.pallets, &pallet.name, extrinsic_name).await? + }, None => { let mut prompt_extrinsic = cli.select("Select the extrinsic to call:"); for extrinsic in &pallet.extrinsics { @@ -176,8 +179,9 @@ impl CallParachainCommand { // Resolve who is signing the extrinsic. let suri = match self.suri.as_ref() { Some(suri) => suri.clone(), - None => - cli.input("Signer of the extrinsic:").default_input(DEFAULT_URI).interact()?, + None => { + cli.input("Signer of the extrinsic:").default_input(DEFAULT_URI).interact()? + }, }; return Ok(CallParachain { @@ -199,11 +203,11 @@ impl CallParachainCommand { // Function to check if all required fields are specified. fn requires_user_input(&self) -> bool { - self.pallet.is_none() || - self.extrinsic.is_none() || - self.args.is_empty() || - self.url.is_none() || - self.suri.is_none() + self.pallet.is_none() + || self.extrinsic.is_none() + || self.args.is_empty() + || self.url.is_none() + || self.suri.is_none() } } @@ -256,7 +260,11 @@ impl CallParachain { return Err(anyhow!("Error: {}", e)); }, }; - cli.info(format!("Encoded call data: {}", encode_call_data(client, &tx)?))?; + let encoded_data = encode_call_data(client, &tx)?; + // If the encoded call data is too long, don't display it all. + if encoded_data.len() < ENCODED_CALL_DATA_MAX_LEN { + cli.info(format!("Encoded call data: {}", encode_call_data(client, &tx)?))?; + } Ok(tx) } @@ -267,8 +275,9 @@ impl CallParachain { tx: DynamicPayload, cli: &mut impl Cli, ) -> Result<()> { - if !self.skip_confirm && - !cli.confirm("Do you want to submit the extrinsic?") + if !self.skip_confirm + && !cli + .confirm("Do you want to submit the extrinsic?") .initial_value(true) .interact()? { @@ -293,7 +302,18 @@ impl CallParachain { full_message.push_str(&format!(" --pallet {}", self.pallet)); full_message.push_str(&format!(" --extrinsic {}", self.extrinsic)); if !self.args.is_empty() { - let args: Vec<_> = self.args.iter().map(|a| format!("\"{a}\"")).collect(); + let args: Vec<_> = self + .args + .iter() + .map(|a| { + // If the argument is too long, don't show it all, truncate it. + if a.len() > ENCODED_CALL_DATA_MAX_LEN { + format!("\"{}...{}\"", &a[..20], &a[a.len() - 20..]) + } else { + format!("\"{a}\"") + } + }) + .collect(); full_message.push_str(&format!(" --args {}", args.join(" "))); } full_message.push_str(&format!(" --url {} --suri {}", chain.url, self.suri)); @@ -349,7 +369,9 @@ fn prompt_for_param(cli: &mut impl Cli, param: &Param) -> Result { // Resolves the value of a parameter based on its type. fn get_param_value(cli: &mut impl Cli, param: &Param) -> Result { - if param.sub_params.is_empty() { + if param.is_sequence { + prompt_for_sequence_param(cli, param) + } else if param.sub_params.is_empty() { prompt_for_primitive_param(cli, param) } else if param.is_variant { prompt_for_variant_param(cli, param) @@ -360,6 +382,30 @@ fn get_param_value(cli: &mut impl Cli, param: &Param) -> Result { } } +// Prompt for the value when it is a sequence. +fn prompt_for_sequence_param(cli: &mut impl Cli, param: &Param) -> Result { + if cli + .confirm(format!( + "The value for `{}` might be too large to enter. Provide a file instead?", + param.name + )) + .initial_value(true) + .interact()? + { + let file_path = cli + .input(format!("Enter the file path for the parameter `{}`:", param.name)) + .placeholder("e.g., /path/to/your/file.json") + .interact()?; + + let content = std::fs::read_to_string(&file_path) + .map_err(|err| anyhow!("Failed to read file {}", err.to_string()))?; + + return Ok(content); + } else { + prompt_for_primitive_param(cli, param) + } +} + // Prompt for the value when it is a primitive. fn prompt_for_primitive_param(cli: &mut impl Cli, param: &Param) -> Result { Ok(cli diff --git a/crates/pop-parachains/src/call/metadata/mod.rs b/crates/pop-parachains/src/call/metadata/mod.rs index 360e6719..5e6f80cf 100644 --- a/crates/pop-parachains/src/call/metadata/mod.rs +++ b/crates/pop-parachains/src/call/metadata/mod.rs @@ -191,6 +191,7 @@ mod tests { assert!(!first_extrinsic.params.first().unwrap().is_optional); assert!(!first_extrinsic.params.first().unwrap().is_tuple); assert!(!first_extrinsic.params.first().unwrap().is_variant); + assert!(first_extrinsic.params.first().unwrap().is_sequence); Ok(()) } diff --git a/crates/pop-parachains/src/call/metadata/params.rs b/crates/pop-parachains/src/call/metadata/params.rs index da369a4f..b2bb0972 100644 --- a/crates/pop-parachains/src/call/metadata/params.rs +++ b/crates/pop-parachains/src/call/metadata/params.rs @@ -20,6 +20,8 @@ pub struct Param { pub is_tuple: bool, /// Indicates if the parameter is a Variant. pub is_variant: bool, + /// Indicates if the parameter is a Sequence. + pub is_sequence: bool, } /// Transforms a metadata field into its `Param` representation. @@ -66,6 +68,7 @@ fn type_to_param(name: String, registry: &PortableRegistry, type_id: u32) -> Res is_optional: true, is_tuple: false, is_variant: false, + is_sequence: false, }) } else { Err(Error::MetadataParsingError(name)) @@ -74,16 +77,14 @@ fn type_to_param(name: String, registry: &PortableRegistry, type_id: u32) -> Res // Determine the formatted type name. let type_name = format_type(type_info, registry); match &type_info.type_def { - TypeDef::Primitive(_) | - TypeDef::Array(_) | - TypeDef::Sequence(_) | - TypeDef::Compact(_) => Ok(Param { + TypeDef::Primitive(_) | TypeDef::Array(_) | TypeDef::Compact(_) => Ok(Param { name, type_name, sub_params: Vec::new(), is_optional: false, is_tuple: false, is_variant: false, + is_sequence: false, }), TypeDef::Composite(composite) => { let sub_params = composite @@ -106,6 +107,7 @@ fn type_to_param(name: String, registry: &PortableRegistry, type_id: u32) -> Res is_optional: false, is_tuple: false, is_variant: false, + is_sequence: false, }) }, TypeDef::Variant(variant) => { @@ -132,6 +134,7 @@ fn type_to_param(name: String, registry: &PortableRegistry, type_id: u32) -> Res is_optional: false, is_tuple: false, is_variant: true, + is_sequence: false, }) }) .collect::, Error>>()?; @@ -143,8 +146,18 @@ fn type_to_param(name: String, registry: &PortableRegistry, type_id: u32) -> Res is_optional: false, is_tuple: false, is_variant: true, + is_sequence: false, }) }, + TypeDef::Sequence(_) => Ok(Param { + name, + type_name, + sub_params: Vec::new(), + is_optional: false, + is_tuple: false, + is_variant: false, + is_sequence: true, + }), TypeDef::Tuple(tuple) => { let sub_params = tuple .fields @@ -166,6 +179,7 @@ fn type_to_param(name: String, registry: &PortableRegistry, type_id: u32) -> Res is_optional: false, is_tuple: true, is_variant: false, + is_sequence: false, }) }, _ => Err(Error::MetadataParsingError(name)), From 466534a5b47026b55174e5d6b39f05eb36854e25 Mon Sep 17 00:00:00 2001 From: AlexD10S Date: Fri, 6 Dec 2024 16:19:36 +0100 Subject: [PATCH 02/10] test: unit test --- crates/pop-cli/src/commands/call/parachain.rs | 31 +++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) diff --git a/crates/pop-cli/src/commands/call/parachain.rs b/crates/pop-cli/src/commands/call/parachain.rs index dc12e958..a3a537ad 100644 --- a/crates/pop-cli/src/commands/call/parachain.rs +++ b/crates/pop-cli/src/commands/call/parachain.rs @@ -12,7 +12,7 @@ use url::Url; const DEFAULT_URL: &str = "ws://localhost:9944/"; const DEFAULT_URI: &str = "//Alice"; -const ENCODED_CALL_DATA_MAX_LEN: usize = 1000; // Maximum length of encoded call data to display. +const ENCODED_CALL_DATA_MAX_LEN: usize = 500; // Maximum length of encoded call data to display. /// Command to execute extrinsics with configurable pallets, arguments, and signing options. #[derive(Args, Clone)] @@ -400,7 +400,7 @@ fn prompt_for_sequence_param(cli: &mut impl Cli, param: &Param) -> Result Result { mod tests { use super::*; use crate::cli::MockCli; + use tempfile::tempdir; use url::Url; #[tokio::test] @@ -834,6 +835,32 @@ mod tests { assert_eq!(params[0], "(0, 0)".to_string()); // task: test tuples assert_eq!(params[1], "0".to_string()); // retries: test primitive assert_eq!(params[2], "0".to_string()); // period: test primitive + cli.verify()?; + + // Using System remark extrinsic to test the sequence params + let extrinsic = find_extrinsic_by_name(&pallets, "System", "remark").await?; + // Temporal file for testing the input. + let temp_dir = tempdir()?; + let file = temp_dir.path().join("file.json"); + std::fs::write(&file, "testing")?; + + let mut cli = MockCli::new() + .expect_confirm( + "The value for `remark` might be too large to enter. Provide a file instead?", + true, + ) + .expect_input( + "Enter the file path for the parameter `remark`:", + file.display().to_string(), + ); + + // Test all the extrinsic params + let mut params: Vec = Vec::new(); + for param in extrinsic.params { + params.push(prompt_for_param(&client, &mut cli, ¶m)?); + } + assert_eq!(params.len(), 1); + assert_eq!(params[0], "testing".to_string()); // remark: test sequence from file cli.verify() } From d30a234842f07defefec3ee0d603a0dc7369bbcc Mon Sep 17 00:00:00 2001 From: AlexD10S Date: Fri, 6 Dec 2024 16:23:06 +0100 Subject: [PATCH 03/10] chore: fmt --- crates/pop-cli/src/commands/call/parachain.rs | 30 ++++++++----------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/crates/pop-cli/src/commands/call/parachain.rs b/crates/pop-cli/src/commands/call/parachain.rs index a3a537ad..5cfcd423 100644 --- a/crates/pop-cli/src/commands/call/parachain.rs +++ b/crates/pop-cli/src/commands/call/parachain.rs @@ -75,9 +75,8 @@ impl CallParachainCommand { break; } - if !prompt_to_repeat_call - || !cli - .confirm("Do you want to perform another call?") + if !prompt_to_repeat_call || + !cli.confirm("Do you want to perform another call?") .initial_value(false) .interact()? { @@ -140,9 +139,8 @@ impl CallParachainCommand { // Resolve extrinsic. let extrinsic = match self.extrinsic { - Some(ref extrinsic_name) => { - find_extrinsic_by_name(&chain.pallets, &pallet.name, extrinsic_name).await? - }, + Some(ref extrinsic_name) => + find_extrinsic_by_name(&chain.pallets, &pallet.name, extrinsic_name).await?, None => { let mut prompt_extrinsic = cli.select("Select the extrinsic to call:"); for extrinsic in &pallet.extrinsics { @@ -179,9 +177,8 @@ impl CallParachainCommand { // Resolve who is signing the extrinsic. let suri = match self.suri.as_ref() { Some(suri) => suri.clone(), - None => { - cli.input("Signer of the extrinsic:").default_input(DEFAULT_URI).interact()? - }, + None => + cli.input("Signer of the extrinsic:").default_input(DEFAULT_URI).interact()?, }; return Ok(CallParachain { @@ -203,11 +200,11 @@ impl CallParachainCommand { // Function to check if all required fields are specified. fn requires_user_input(&self) -> bool { - self.pallet.is_none() - || self.extrinsic.is_none() - || self.args.is_empty() - || self.url.is_none() - || self.suri.is_none() + self.pallet.is_none() || + self.extrinsic.is_none() || + self.args.is_empty() || + self.url.is_none() || + self.suri.is_none() } } @@ -275,9 +272,8 @@ impl CallParachain { tx: DynamicPayload, cli: &mut impl Cli, ) -> Result<()> { - if !self.skip_confirm - && !cli - .confirm("Do you want to submit the extrinsic?") + if !self.skip_confirm && + !cli.confirm("Do you want to submit the extrinsic?") .initial_value(true) .interact()? { From be1d1b6f88c31a18b9b5bde758fffa18c55e8449 Mon Sep 17 00:00:00 2001 From: AlexD10S Date: Fri, 6 Dec 2024 17:12:35 +0100 Subject: [PATCH 04/10] feat: file logic using the command line --- crates/pop-cli/src/commands/call/parachain.rs | 55 ++++++++++++++++++- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/crates/pop-cli/src/commands/call/parachain.rs b/crates/pop-cli/src/commands/call/parachain.rs index 5cfcd423..9cbc7621 100644 --- a/crates/pop-cli/src/commands/call/parachain.rs +++ b/crates/pop-cli/src/commands/call/parachain.rs @@ -171,7 +171,7 @@ impl CallParachainCommand { } args } else { - self.args.clone() + self.expand_file_arguments()? }; // Resolve who is signing the extrinsic. @@ -206,6 +206,21 @@ impl CallParachainCommand { self.url.is_none() || self.suri.is_none() } + + /// Replaces file arguments with their contents, leaving other arguments unchanged. + fn expand_file_arguments(&self) -> Result> { + self.args + .iter() + .map(|arg| { + if std::fs::metadata(arg).map(|m| m.is_file()).unwrap_or(false) { + std::fs::read_to_string(arg) + .map_err(|err| anyhow!("Failed to read file {}", err.to_string())) + } else { + Ok(arg.clone()) + } + }) + .collect() + } } /// Represents a chain, including its URL, client connection, and available pallets. @@ -715,6 +730,42 @@ mod tests { Ok(()) } + #[test] + fn expand_file_arguments_works() -> Result<()> { + let mut call_config = CallParachainCommand { + pallet: Some("Registrar".to_string()), + extrinsic: Some("register".to_string()), + args: vec!["2000".to_string(), "0x1".to_string(), "0x12".to_string()].to_vec(), + url: Some(Url::parse("wss://rpc1.paseo.popnetwork.xyz")?), + suri: Some(DEFAULT_URI.to_string()), + skip_confirm: false, + }; + assert_eq!( + call_config.expand_file_arguments()?, + vec!["2000".to_string(), "0x1".to_string(), "0x12".to_string()] + ); + // Temporal file for testing when the input is a file. + let temp_dir = tempdir()?; + let genesis_file = temp_dir.path().join("genesis_file.json"); + std::fs::write(&genesis_file, "genesis_file_content")?; + let wasm_file = temp_dir.path().join("wasm_file.json"); + std::fs::write(&wasm_file, "wasm_file_content")?; + call_config.args = vec![ + "2000".to_string(), + genesis_file.display().to_string(), + wasm_file.display().to_string(), + ]; + assert_eq!( + call_config.expand_file_arguments()?, + vec![ + "2000".to_string(), + "genesis_file_content".to_string(), + "wasm_file_content".to_string() + ] + ); + Ok(()) + } + #[test] fn display_message_works() -> Result<()> { let mut cli = MockCli::new().expect_outro(&"Call completed successfully!"); @@ -853,7 +904,7 @@ mod tests { // Test all the extrinsic params let mut params: Vec = Vec::new(); for param in extrinsic.params { - params.push(prompt_for_param(&client, &mut cli, ¶m)?); + params.push(prompt_for_param(&mut cli, ¶m)?); } assert_eq!(params.len(), 1); assert_eq!(params[0], "testing".to_string()); // remark: test sequence from file From 3f79680b2c97ac3a30192f80961052b254c042f5 Mon Sep 17 00:00:00 2001 From: AlexD10S Date: Sun, 8 Dec 2024 13:20:24 +0100 Subject: [PATCH 05/10] fix: sequence arguments --- crates/pop-cli/src/commands/call/parachain.rs | 2 +- .../pop-parachains/src/call/metadata/mod.rs | 74 +++++++++++++++---- crates/pop-parachains/src/call/mod.rs | 36 ++++++--- 3 files changed, 88 insertions(+), 24 deletions(-) diff --git a/crates/pop-cli/src/commands/call/parachain.rs b/crates/pop-cli/src/commands/call/parachain.rs index 9cbc7621..5dd4a740 100644 --- a/crates/pop-cli/src/commands/call/parachain.rs +++ b/crates/pop-cli/src/commands/call/parachain.rs @@ -262,7 +262,7 @@ impl CallParachain { ) -> Result { let tx = match construct_extrinsic( self.pallet.name.as_str(), - self.extrinsic.name.as_str(), + &self.extrinsic, self.args.clone(), ) .await diff --git a/crates/pop-parachains/src/call/metadata/mod.rs b/crates/pop-parachains/src/call/metadata/mod.rs index 5e6f80cf..50af4077 100644 --- a/crates/pop-parachains/src/call/metadata/mod.rs +++ b/crates/pop-parachains/src/call/metadata/mod.rs @@ -146,19 +146,31 @@ pub async fn find_extrinsic_by_name( /// Parses and processes raw string parameters for an extrinsic, mapping them to `Value` types. /// /// # Arguments +/// * `extrinsic`: The definition of the extrinsic, containing parameter metadata. /// * `raw_params`: A vector of raw string arguments for the extrinsic. -pub async fn parse_extrinsic_arguments(raw_params: Vec) -> Result, Error> { - let mut parsed_params: Vec = Vec::new(); - for raw_param in raw_params { - let parsed_value: Value = scale_value::stringify::from_str_custom() - .add_custom_parser(custom_parsers::parse_hex) - .add_custom_parser(custom_parsers::parse_ss58) - .parse(&raw_param) - .0 - .map_err(|_| Error::ParamProcessingError)?; - parsed_params.push(parsed_value); - } - Ok(parsed_params) +pub async fn parse_extrinsic_arguments( + extrinsic: &Extrinsic, + raw_params: Vec, +) -> Result, Error> { + extrinsic + .params + .iter() + .zip(raw_params) + .map(|(param, raw_param)| { + // Convert sequence parameters to hex if is_sequence + let processed_param = if param.is_sequence && !raw_param.starts_with("0x") { + format!("0x{}", hex::encode(raw_param)) + } else { + raw_param + }; + scale_value::stringify::from_str_custom() + .add_custom_parser(custom_parsers::parse_hex) + .add_custom_parser(custom_parsers::parse_ss58) + .parse(&processed_param) + .0 + .map_err(|_| Error::ParamProcessingError) + }) + .collect() } #[cfg(test)] @@ -229,6 +241,24 @@ mod tests { #[tokio::test] async fn parse_extrinsic_arguments_works() -> Result<()> { + /// Helper function to create a `Param` with default values. + fn create_param( + name: &str, + type_name: &str, + is_sequence: bool, + is_variant: bool, + is_tuple: bool, + ) -> Param { + Param { + name: name.to_string(), + type_name: type_name.to_string(), + sub_params: vec![], + is_optional: false, + is_sequence, + is_variant, + is_tuple, + } + } // Values for testing from: https://docs.rs/scale-value/0.18.0/scale_value/stringify/fn.from_str.html // and https://docs.rs/scale-value/0.18.0/scale_value/stringify/fn.from_str_custom.html let args = [ @@ -254,8 +284,26 @@ mod tests { .into_iter() .map(|b| Value::u128(b as u128)) .collect(); + // Define mock extrinsic with parameters for testing. + let extrinsic = Extrinsic { + name: "test_extrinsic".to_string(), + docs: "Test extrinsic documentation".to_string(), + params: vec![ + create_param("param_1", "u128", false, false, false), + create_param("param_2", "i128", false, false, false), + create_param("param_3", "bool", false, false, false), + create_param("param_4", "char", false, false, false), + create_param("param_5", "string", false, false, false), + create_param("param_6", "composite", false, false, false), + create_param("param_7", "variant", false, true, false), + create_param("param_8", "bit_sequence", false, false, false), + create_param("param_9", "tuple", false, false, true), + create_param("param_10", "composite", false, false, false), + ], + is_supported: true, + }; assert_eq!( - parse_extrinsic_arguments(args).await?, + parse_extrinsic_arguments(&extrinsic, args).await?, [ Value::u128(1), Value::i128(-1), diff --git a/crates/pop-parachains/src/call/mod.rs b/crates/pop-parachains/src/call/mod.rs index 5ca10cd0..9a9940c8 100644 --- a/crates/pop-parachains/src/call/mod.rs +++ b/crates/pop-parachains/src/call/mod.rs @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-3.0 -use crate::errors::Error; +use crate::{errors::Error, Extrinsic}; use pop_common::create_signer; use subxt::{ dynamic::Value, @@ -28,11 +28,11 @@ pub async fn set_up_client(url: &str) -> Result, E /// * `args` - A vector of string arguments to be passed to the extrinsic. pub async fn construct_extrinsic( pallet_name: &str, - extrinsic_name: &str, + extrinsic: &Extrinsic, args: Vec, ) -> Result { - let parsed_args: Vec = metadata::parse_extrinsic_arguments(args).await?; - Ok(subxt::dynamic::tx(pallet_name, extrinsic_name, parsed_args)) + let parsed_args: Vec = metadata::parse_extrinsic_arguments(&extrinsic, args).await?; + Ok(subxt::dynamic::tx(pallet_name, extrinsic.name.clone(), parsed_args)) } /// Signs and submits a given extrinsic. @@ -77,7 +77,7 @@ pub fn encode_call_data( mod tests { use super::*; - use crate::set_up_client; + use crate::{find_extrinsic_by_name, parse_chain_metadata, set_up_client}; use anyhow::Result; #[tokio::test] @@ -92,11 +92,16 @@ mod tests { #[tokio::test] async fn construct_extrinsic_works() -> Result<()> { + let client = set_up_client("wss://rpc1.paseo.popnetwork.xyz").await?; + let pallets = parse_chain_metadata(&client).await?; + let transfer_allow_death = + find_extrinsic_by_name(&pallets, "Balances", "transfer_allow_death").await?; + // Wrong parameters assert!(matches!( construct_extrinsic( "Balances", - "transfer_allow_death", + &transfer_allow_death, vec!["Bob".to_string(), "100".to_string()], ) .await, @@ -105,7 +110,7 @@ mod tests { // Valid parameters let extrinsic = construct_extrinsic( "Balances", - "transfer_allow_death", + &transfer_allow_death, vec![ "Id(5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty)".to_string(), "100".to_string(), @@ -120,16 +125,27 @@ mod tests { #[tokio::test] async fn encode_call_data_works() -> Result<()> { let client = set_up_client("wss://rpc1.paseo.popnetwork.xyz").await?; - let extrinsic = construct_extrinsic("System", "remark", vec!["0x11".to_string()]).await?; + let pallets = parse_chain_metadata(&client).await?; + let remark = find_extrinsic_by_name(&pallets, "Balances", "remark").await?; + let extrinsic = construct_extrinsic("System", &remark, vec!["0x11".to_string()]).await?; assert_eq!(encode_call_data(&client, &extrinsic)?, "0x00000411"); + let extrinsic = construct_extrinsic("System", &remark, vec!["123".to_string()]).await?; + assert_eq!(encode_call_data(&client, &extrinsic)?, "0x00000c313233"); + let extrinsic = construct_extrinsic("System", &remark, vec!["test".to_string()]).await?; + assert_eq!(encode_call_data(&client, &extrinsic)?, "0x00001074657374"); Ok(()) } #[tokio::test] async fn sign_and_submit_wrong_extrinsic_fails() -> Result<()> { let client = set_up_client("wss://rpc1.paseo.popnetwork.xyz").await?; - let tx = - construct_extrinsic("WrongPallet", "wrongExtrinsic", vec!["0x11".to_string()]).await?; + let extrinsic = Extrinsic { + name: "wrong_extrinsic".to_string(), + docs: "documentation".to_string(), + params: vec![], + is_supported: true, + }; + let tx = construct_extrinsic("WrongPallet", &extrinsic, vec!["0x11".to_string()]).await?; assert!(matches!( sign_and_submit_extrinsic(client, tx, "//Alice").await, Err(Error::ExtrinsicSubmissionError(message)) if message.contains("PalletNameNotFound(\"WrongPallet\"))") From 0551279c054cd419aa3e186fce2097e1fd521d8e Mon Sep 17 00:00:00 2001 From: AlexD10S Date: Sun, 8 Dec 2024 15:16:42 +0100 Subject: [PATCH 06/10] test: fix unit test --- crates/pop-parachains/src/call/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/pop-parachains/src/call/mod.rs b/crates/pop-parachains/src/call/mod.rs index 9a9940c8..86d453cb 100644 --- a/crates/pop-parachains/src/call/mod.rs +++ b/crates/pop-parachains/src/call/mod.rs @@ -126,7 +126,7 @@ mod tests { async fn encode_call_data_works() -> Result<()> { let client = set_up_client("wss://rpc1.paseo.popnetwork.xyz").await?; let pallets = parse_chain_metadata(&client).await?; - let remark = find_extrinsic_by_name(&pallets, "Balances", "remark").await?; + let remark = find_extrinsic_by_name(&pallets, "System", "remark").await?; let extrinsic = construct_extrinsic("System", &remark, vec!["0x11".to_string()]).await?; assert_eq!(encode_call_data(&client, &extrinsic)?, "0x00000411"); let extrinsic = construct_extrinsic("System", &remark, vec!["123".to_string()]).await?; From f39900e7f0791e61b0ad289333e01c54abe48bf2 Mon Sep 17 00:00:00 2001 From: AlexD10S Date: Mon, 9 Dec 2024 13:59:39 +0100 Subject: [PATCH 07/10] refactor: remove prompting the user if input is file or value --- crates/pop-cli/src/commands/call/parachain.rs | 71 +++++++++---------- 1 file changed, 34 insertions(+), 37 deletions(-) diff --git a/crates/pop-cli/src/commands/call/parachain.rs b/crates/pop-cli/src/commands/call/parachain.rs index 5dd4a740..69ab5d97 100644 --- a/crates/pop-cli/src/commands/call/parachain.rs +++ b/crates/pop-cli/src/commands/call/parachain.rs @@ -1,5 +1,7 @@ // SPDX-License-Identifier: GPL-3.0 +use std::path::Path; + use crate::cli::{self, traits::*}; use anyhow::{anyhow, Result}; use clap::Args; @@ -75,8 +77,9 @@ impl CallParachainCommand { break; } - if !prompt_to_repeat_call || - !cli.confirm("Do you want to perform another call?") + if !prompt_to_repeat_call + || !cli + .confirm("Do you want to perform another call?") .initial_value(false) .interact()? { @@ -139,8 +142,9 @@ impl CallParachainCommand { // Resolve extrinsic. let extrinsic = match self.extrinsic { - Some(ref extrinsic_name) => - find_extrinsic_by_name(&chain.pallets, &pallet.name, extrinsic_name).await?, + Some(ref extrinsic_name) => { + find_extrinsic_by_name(&chain.pallets, &pallet.name, extrinsic_name).await? + }, None => { let mut prompt_extrinsic = cli.select("Select the extrinsic to call:"); for extrinsic in &pallet.extrinsics { @@ -177,8 +181,9 @@ impl CallParachainCommand { // Resolve who is signing the extrinsic. let suri = match self.suri.as_ref() { Some(suri) => suri.clone(), - None => - cli.input("Signer of the extrinsic:").default_input(DEFAULT_URI).interact()?, + None => { + cli.input("Signer of the extrinsic:").default_input(DEFAULT_URI).interact()? + }, }; return Ok(CallParachain { @@ -200,11 +205,11 @@ impl CallParachainCommand { // Function to check if all required fields are specified. fn requires_user_input(&self) -> bool { - self.pallet.is_none() || - self.extrinsic.is_none() || - self.args.is_empty() || - self.url.is_none() || - self.suri.is_none() + self.pallet.is_none() + || self.extrinsic.is_none() + || self.args.is_empty() + || self.url.is_none() + || self.suri.is_none() } /// Replaces file arguments with their contents, leaving other arguments unchanged. @@ -287,8 +292,9 @@ impl CallParachain { tx: DynamicPayload, cli: &mut impl Cli, ) -> Result<()> { - if !self.skip_confirm && - !cli.confirm("Do you want to submit the extrinsic?") + if !self.skip_confirm + && !cli + .confirm("Do you want to submit the extrinsic?") .initial_value(true) .interact()? { @@ -395,26 +401,21 @@ fn get_param_value(cli: &mut impl Cli, param: &Param) -> Result { // Prompt for the value when it is a sequence. fn prompt_for_sequence_param(cli: &mut impl Cli, param: &Param) -> Result { - if cli - .confirm(format!( - "The value for `{}` might be too large to enter. Provide a file instead?", - param.name + let input_value = cli + .input(format!( + "The value for `{}` might be too large to enter. You may enter the path to a file instead.", + param.name + )) + .placeholder(&format!( + "Enter a value of type {} or provide a file path (e.g., /path/to/your/file.json)", + param.type_name )) - .initial_value(true) - .interact()? - { - let file_path = cli - .input(format!("Enter the file path for the parameter `{}`:", param.name)) - .placeholder("e.g., /path/to/your/file.json") - .interact()?; - - let content = std::fs::read_to_string(&file_path) - .map_err(|err| anyhow!("Failed to read file {}", err.to_string()))?; - - Ok(content) - } else { - prompt_for_primitive_param(cli, param) + .interact()?; + if Path::new(&input_value).is_file() { + return std::fs::read_to_string(&input_value) + .map_err(|err| anyhow!("Failed to read file {}", err.to_string())); } + Ok(input_value) } // Prompt for the value when it is a primitive. @@ -569,7 +570,7 @@ mod tests { ), 0, // "remark" extrinsic ) - .expect_input("Enter the value for the parameter: remark", "0x11".into()) + .expect_input("The value for `remark` might be too large to enter. You may enter the path to a file instead.", "0x11".into()) .expect_input("Signer of the extrinsic:", "//Bob".into()); let chain = call_config.configure_chain(&mut cli).await?; @@ -892,12 +893,8 @@ mod tests { std::fs::write(&file, "testing")?; let mut cli = MockCli::new() - .expect_confirm( - "The value for `remark` might be too large to enter. Provide a file instead?", - true, - ) .expect_input( - "Enter the file path for the parameter `remark`:", + "The value for `remark` might be too large to enter. You may enter the path to a file instead.", file.display().to_string(), ); From f2a0f76f1a4847b5eb294efc2c82c296e05eb697 Mon Sep 17 00:00:00 2001 From: AlexD10S Date: Mon, 9 Dec 2024 14:29:30 +0100 Subject: [PATCH 08/10] refactor: parse_extrinsic_arguments --- crates/pop-cli/src/commands/call/parachain.rs | 30 +++++----- .../pop-parachains/src/call/metadata/mod.rs | 58 ++++++------------- .../src/call/metadata/params.rs | 2 +- crates/pop-parachains/src/call/mod.rs | 3 +- 4 files changed, 33 insertions(+), 60 deletions(-) diff --git a/crates/pop-cli/src/commands/call/parachain.rs b/crates/pop-cli/src/commands/call/parachain.rs index 69ab5d97..0a054f78 100644 --- a/crates/pop-cli/src/commands/call/parachain.rs +++ b/crates/pop-cli/src/commands/call/parachain.rs @@ -77,9 +77,8 @@ impl CallParachainCommand { break; } - if !prompt_to_repeat_call - || !cli - .confirm("Do you want to perform another call?") + if !prompt_to_repeat_call || + !cli.confirm("Do you want to perform another call?") .initial_value(false) .interact()? { @@ -142,9 +141,8 @@ impl CallParachainCommand { // Resolve extrinsic. let extrinsic = match self.extrinsic { - Some(ref extrinsic_name) => { - find_extrinsic_by_name(&chain.pallets, &pallet.name, extrinsic_name).await? - }, + Some(ref extrinsic_name) => + find_extrinsic_by_name(&chain.pallets, &pallet.name, extrinsic_name).await?, None => { let mut prompt_extrinsic = cli.select("Select the extrinsic to call:"); for extrinsic in &pallet.extrinsics { @@ -181,9 +179,8 @@ impl CallParachainCommand { // Resolve who is signing the extrinsic. let suri = match self.suri.as_ref() { Some(suri) => suri.clone(), - None => { - cli.input("Signer of the extrinsic:").default_input(DEFAULT_URI).interact()? - }, + None => + cli.input("Signer of the extrinsic:").default_input(DEFAULT_URI).interact()?, }; return Ok(CallParachain { @@ -205,11 +202,11 @@ impl CallParachainCommand { // Function to check if all required fields are specified. fn requires_user_input(&self) -> bool { - self.pallet.is_none() - || self.extrinsic.is_none() - || self.args.is_empty() - || self.url.is_none() - || self.suri.is_none() + self.pallet.is_none() || + self.extrinsic.is_none() || + self.args.is_empty() || + self.url.is_none() || + self.suri.is_none() } /// Replaces file arguments with their contents, leaving other arguments unchanged. @@ -292,9 +289,8 @@ impl CallParachain { tx: DynamicPayload, cli: &mut impl Cli, ) -> Result<()> { - if !self.skip_confirm - && !cli - .confirm("Do you want to submit the extrinsic?") + if !self.skip_confirm && + !cli.confirm("Do you want to submit the extrinsic?") .initial_value(true) .interact()? { diff --git a/crates/pop-parachains/src/call/metadata/mod.rs b/crates/pop-parachains/src/call/metadata/mod.rs index 50af4077..dfd709b9 100644 --- a/crates/pop-parachains/src/call/metadata/mod.rs +++ b/crates/pop-parachains/src/call/metadata/mod.rs @@ -146,14 +146,13 @@ pub async fn find_extrinsic_by_name( /// Parses and processes raw string parameters for an extrinsic, mapping them to `Value` types. /// /// # Arguments -/// * `extrinsic`: The definition of the extrinsic, containing parameter metadata. +/// * `params`: The metadata definition for each parameter of the extrinsic. /// * `raw_params`: A vector of raw string arguments for the extrinsic. pub async fn parse_extrinsic_arguments( - extrinsic: &Extrinsic, + params: &[Param], raw_params: Vec, ) -> Result, Error> { - extrinsic - .params + params .iter() .zip(raw_params) .map(|(param, raw_param)| { @@ -241,24 +240,6 @@ mod tests { #[tokio::test] async fn parse_extrinsic_arguments_works() -> Result<()> { - /// Helper function to create a `Param` with default values. - fn create_param( - name: &str, - type_name: &str, - is_sequence: bool, - is_variant: bool, - is_tuple: bool, - ) -> Param { - Param { - name: name.to_string(), - type_name: type_name.to_string(), - sub_params: vec![], - is_optional: false, - is_sequence, - is_variant, - is_tuple, - } - } // Values for testing from: https://docs.rs/scale-value/0.18.0/scale_value/stringify/fn.from_str.html // and https://docs.rs/scale-value/0.18.0/scale_value/stringify/fn.from_str_custom.html let args = [ @@ -284,26 +265,21 @@ mod tests { .into_iter() .map(|b| Value::u128(b as u128)) .collect(); - // Define mock extrinsic with parameters for testing. - let extrinsic = Extrinsic { - name: "test_extrinsic".to_string(), - docs: "Test extrinsic documentation".to_string(), - params: vec![ - create_param("param_1", "u128", false, false, false), - create_param("param_2", "i128", false, false, false), - create_param("param_3", "bool", false, false, false), - create_param("param_4", "char", false, false, false), - create_param("param_5", "string", false, false, false), - create_param("param_6", "composite", false, false, false), - create_param("param_7", "variant", false, true, false), - create_param("param_8", "bit_sequence", false, false, false), - create_param("param_9", "tuple", false, false, true), - create_param("param_10", "composite", false, false, false), - ], - is_supported: true, - }; + // Define mock extrinsic parameters for testing. + let params = vec![ + Param { type_name: "u128".to_string(), ..Default::default() }, + Param { type_name: "i128".to_string(), ..Default::default() }, + Param { type_name: "bool".to_string(), ..Default::default() }, + Param { type_name: "char".to_string(), ..Default::default() }, + Param { type_name: "string".to_string(), ..Default::default() }, + Param { type_name: "compostie".to_string(), ..Default::default() }, + Param { type_name: "variant".to_string(), is_variant: true, ..Default::default() }, + Param { type_name: "bit_sequence".to_string(), ..Default::default() }, + Param { type_name: "tuple".to_string(), is_tuple: true, ..Default::default() }, + Param { type_name: "composite".to_string(), ..Default::default() }, + ]; assert_eq!( - parse_extrinsic_arguments(&extrinsic, args).await?, + parse_extrinsic_arguments(¶ms, args).await?, [ Value::u128(1), Value::i128(-1), diff --git a/crates/pop-parachains/src/call/metadata/params.rs b/crates/pop-parachains/src/call/metadata/params.rs index b2bb0972..6fc4f5ec 100644 --- a/crates/pop-parachains/src/call/metadata/params.rs +++ b/crates/pop-parachains/src/call/metadata/params.rs @@ -6,7 +6,7 @@ use scale_info::{form::PortableForm, Field, PortableRegistry, TypeDef}; use subxt::{Metadata, OnlineClient, SubstrateConfig}; /// Describes a parameter of an extrinsic. -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Default, Debug, Clone, PartialEq, Eq)] pub struct Param { /// The name of the parameter. pub name: String, diff --git a/crates/pop-parachains/src/call/mod.rs b/crates/pop-parachains/src/call/mod.rs index 86d453cb..e2a3ee64 100644 --- a/crates/pop-parachains/src/call/mod.rs +++ b/crates/pop-parachains/src/call/mod.rs @@ -31,7 +31,8 @@ pub async fn construct_extrinsic( extrinsic: &Extrinsic, args: Vec, ) -> Result { - let parsed_args: Vec = metadata::parse_extrinsic_arguments(&extrinsic, args).await?; + let parsed_args: Vec = + metadata::parse_extrinsic_arguments(&extrinsic.params, args).await?; Ok(subxt::dynamic::tx(pallet_name, extrinsic.name.clone(), parsed_args)) } From 423eb3b26e659aa6cc8da622aa677bdc29ad03c8 Mon Sep 17 00:00:00 2001 From: AlexD10S Date: Mon, 9 Dec 2024 14:48:37 +0100 Subject: [PATCH 09/10] fix: CI deny --- Cargo.lock | 265 ++++++++++++++++++++++++++++++++++++++++++++++++++--- Cargo.toml | 2 +- deny.toml | 1 + 3 files changed, 255 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4d6d8bd7..6ff7331d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2917,6 +2917,124 @@ dependencies = [ "cc", ] +[[package]] +name = "icu_collections" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.89", +] + [[package]] name = "ident_case" version = "1.0.1" @@ -2925,12 +3043,23 @@ checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" [[package]] name = "idna" -version = "0.5.0" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +dependencies = [ + "icu_normalizer", + "icu_properties", ] [[package]] @@ -3839,6 +3968,12 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +[[package]] +name = "litemap" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" + [[package]] name = "lock_api" version = "0.4.12" @@ -7021,6 +7156,17 @@ dependencies = [ "futures-core", ] +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.89", +] + [[package]] name = "system-configuration" version = "0.5.1" @@ -7196,6 +7342,16 @@ dependencies = [ "time-core", ] +[[package]] +name = "tinystr" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +dependencies = [ + "displaydoc", + "zerovec", +] + [[package]] name = "tinyvec" version = "1.8.0" @@ -7629,12 +7785,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "unicode-bidi" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" - [[package]] name = "unicode-ident" version = "1.0.13" @@ -7698,9 +7848,9 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.2" +version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" dependencies = [ "form_urlencoded", "idna", @@ -7714,6 +7864,18 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + [[package]] name = "utf8parse" version = "0.2.2" @@ -8482,6 +8644,18 @@ version = "0.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904" +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + [[package]] name = "wyz" version = "0.5.1" @@ -8526,6 +8700,30 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff4524214bc4629eba08d78ceb1d6507070cc0bcbbed23af74e19e6e924a24cf" +[[package]] +name = "yoke" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.89", + "synstructure", +] + [[package]] name = "zerocopy" version = "0.7.35" @@ -8547,6 +8745,27 @@ dependencies = [ "syn 2.0.89", ] +[[package]] +name = "zerofrom" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.89", + "synstructure", +] + [[package]] name = "zeroize" version = "1.8.1" @@ -8567,6 +8786,28 @@ dependencies = [ "syn 2.0.89", ] +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.89", +] + [[package]] name = "zip" version = "2.2.0" diff --git a/Cargo.toml b/Cargo.toml index e33ae6d5..30c181ca 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,7 +41,7 @@ toml = "0.5.0" # networking reqwest = { version = "0.12", features = ["json"] } tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] } -url = "2.5" +url = "2.5.4" # contracts subxt-signer = { version = "0.37.0", features = ["subxt", "sr25519"] } diff --git a/deny.toml b/deny.toml index 5c295de5..53c6d37e 100644 --- a/deny.toml +++ b/deny.toml @@ -20,6 +20,7 @@ allow = [ "GPL-3.0", "MIT", "MPL-2.0", + "Unicode-3.0", "Unicode-DFS-2016", "Unlicense" ] From 896ec4a519661a400b846e744f72c84efa22df89 Mon Sep 17 00:00:00 2001 From: AlexD10S Date: Mon, 9 Dec 2024 15:20:07 +0100 Subject: [PATCH 10/10] refactor: reorder Param derive macros --- crates/pop-parachains/src/call/metadata/params.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/pop-parachains/src/call/metadata/params.rs b/crates/pop-parachains/src/call/metadata/params.rs index 6fc4f5ec..b2b0f807 100644 --- a/crates/pop-parachains/src/call/metadata/params.rs +++ b/crates/pop-parachains/src/call/metadata/params.rs @@ -6,7 +6,7 @@ use scale_info::{form::PortableForm, Field, PortableRegistry, TypeDef}; use subxt::{Metadata, OnlineClient, SubstrateConfig}; /// Describes a parameter of an extrinsic. -#[derive(Default, Debug, Clone, PartialEq, Eq)] +#[derive(Clone, Debug, Default, Eq, PartialEq)] pub struct Param { /// The name of the parameter. pub name: String,