diff --git a/crates/pop-cli/src/commands/call/parachain.rs b/crates/pop-cli/src/commands/call/parachain.rs index d4bdecbf..db0e7c41 100644 --- a/crates/pop-cli/src/commands/call/parachain.rs +++ b/crates/pop-cli/src/commands/call/parachain.rs @@ -18,7 +18,7 @@ const DEFAULT_URI: &str = "//Alice"; 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)] +#[derive(Args, Clone, Default)] pub struct CallParachainCommand { /// The pallet containing the extrinsic to execute. #[arg(short, long, value_parser = parse_pallet_name)] @@ -564,41 +564,31 @@ mod tests { use tempfile::tempdir; use url::Url; + const BOB_SURI: &str = "//Bob"; + const POP_NETWORK_TESTNET_URL: &str = "wss://rpc1.paseo.popnetwork.xyz"; + const POLKADOT_NETWORK_URL: &str = "wss://polkadot-rpc.publicnode.com"; + #[tokio::test] async fn configure_chain_works() -> Result<()> { - let call_config = CallParachainCommand { - pallet: None, - extrinsic: None, - args: vec![].to_vec(), - url: None, - suri: Some(DEFAULT_URI.to_string()), - skip_confirm: false, - call_data: None, - }; + let call_config = + CallParachainCommand { suri: Some(DEFAULT_URI.to_string()), ..Default::default() }; let mut cli = MockCli::new().expect_intro("Call a parachain").expect_input( "Which chain would you like to interact with?", - "wss://rpc1.paseo.popnetwork.xyz".into(), + POP_NETWORK_TESTNET_URL.into(), ); let chain = call_config.configure_chain(&mut cli).await?; - assert_eq!(chain.url, Url::parse("wss://rpc1.paseo.popnetwork.xyz")?); + assert_eq!(chain.url, Url::parse(POP_NETWORK_TESTNET_URL)?); cli.verify() } #[tokio::test] async fn guide_user_to_call_parachain_works() -> Result<()> { - let mut call_config = CallParachainCommand { - pallet: Some("System".to_string()), - extrinsic: None, - args: vec![].to_vec(), - url: None, - suri: None, - skip_confirm: false, - call_data: None, - }; + let mut call_config = + CallParachainCommand { pallet: Some("System".to_string()), ..Default::default() }; let mut cli = MockCli::new() .expect_intro("Call a parachain") - .expect_input("Which chain would you like to interact with?", "wss://rpc1.paseo.popnetwork.xyz".into()) + .expect_input("Which chain would you like to interact with?", POP_NETWORK_TESTNET_URL.into()) .expect_select( "Select the extrinsic to call:", Some(true), @@ -622,38 +612,30 @@ mod tests { 0, // "remark" extrinsic ) .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()); + .expect_input("Signer of the extrinsic:", BOB_SURI.into()); let chain = call_config.configure_chain(&mut cli).await?; - assert_eq!(chain.url, Url::parse("wss://rpc1.paseo.popnetwork.xyz")?); + assert_eq!(chain.url, Url::parse(POP_NETWORK_TESTNET_URL)?); let call_parachain = call_config.configure_call(&chain, &mut cli).await?; assert_eq!(call_parachain.pallet.name, "System"); assert_eq!(call_parachain.extrinsic.name, "remark"); assert_eq!(call_parachain.args, ["0x11".to_string()].to_vec()); - assert_eq!(call_parachain.suri, "//Bob"); - assert_eq!(call_parachain.display(&chain), "pop call parachain --pallet System --extrinsic remark --args \"0x11\" --url wss://rpc1.paseo.popnetwork.xyz/ --suri //Bob"); + assert_eq!(call_parachain.suri, BOB_SURI); + assert_eq!(call_parachain.display(&chain), format!("pop call parachain --pallet System --extrinsic remark --args \"0x11\" --url {}/ --suri {}", POP_NETWORK_TESTNET_URL, BOB_SURI)); cli.verify() } #[tokio::test] async fn guide_user_to_configure_predefined_action_works() -> Result<()> { - let mut call_config = CallParachainCommand { - pallet: None, - extrinsic: None, - args: vec![].to_vec(), - url: None, - suri: None, - skip_confirm: false, - call_data: None, - }; + let mut call_config = CallParachainCommand::default(); let mut cli = MockCli::new().expect_intro("Call a parachain").expect_input( "Which chain would you like to interact with?", - "wss://polkadot-rpc.publicnode.com".into(), + POLKADOT_NETWORK_URL.into(), ); let chain = call_config.configure_chain(&mut cli).await?; - assert_eq!(chain.url, Url::parse("wss://polkadot-rpc.publicnode.com")?); + assert_eq!(chain.url, Url::parse(POLKADOT_NETWORK_URL)?); cli.verify()?; let mut cli = MockCli::new() @@ -678,33 +660,24 @@ mod tests { ) .expect_input("Enter the value for the parameter: max_amount", "10000".into()) .expect_input("Enter the value for the parameter: para_id", "2000".into()) - .expect_input("Signer of the extrinsic:", "//Bob".into()); + .expect_input("Signer of the extrinsic:", BOB_SURI.into()); let call_parachain = call_config.configure_call(&chain, &mut cli).await?; assert_eq!(call_parachain.pallet.name, "OnDemand"); assert_eq!(call_parachain.extrinsic.name, "place_order_allow_death"); assert_eq!(call_parachain.args, ["10000".to_string(), "2000".to_string()].to_vec()); - assert_eq!(call_parachain.suri, "//Bob"); - assert_eq!(call_parachain.display(&chain), "pop call parachain --pallet OnDemand --extrinsic place_order_allow_death --args \"10000\" \"2000\" --url wss://polkadot-rpc.publicnode.com/ --suri //Bob"); + assert_eq!(call_parachain.suri, BOB_SURI); + assert_eq!(call_parachain.display(&chain), format!("pop call parachain --pallet OnDemand --extrinsic place_order_allow_death --args \"10000\" \"2000\" --url {}/ --suri {}", POLKADOT_NETWORK_URL, BOB_SURI)); cli.verify() } #[tokio::test] async fn prepare_extrinsic_works() -> Result<()> { - let client = set_up_client("wss://rpc1.paseo.popnetwork.xyz").await?; + let client = set_up_client(POP_NETWORK_TESTNET_URL).await?; let mut call_config = CallParachain { - pallet: Pallet { - name: "WrongName".to_string(), - docs: "".to_string(), - extrinsics: vec![], - }, - extrinsic: Extrinsic { - name: "WrongName".to_string(), - docs: "".to_string(), - is_supported: false, - params: vec![], - }, + pallet: Pallet { name: "WrongName".to_string(), ..Default::default() }, + extrinsic: Extrinsic { name: "WrongName".to_string(), ..Default::default() }, args: vec!["0x11".to_string()].to_vec(), suri: DEFAULT_URI.to_string(), skip_confirm: false, @@ -732,7 +705,7 @@ mod tests { #[tokio::test] async fn user_cancel_submit_extrinsic_works() -> Result<()> { - let client = set_up_client("wss://rpc1.paseo.popnetwork.xyz").await?; + let client = set_up_client(POP_NETWORK_TESTNET_URL).await?; let pallets = parse_chain_metadata(&client).await?; let mut call_config = CallParachain { pallet: find_pallet_by_name(&pallets, "System").await?, @@ -779,7 +752,7 @@ mod tests { pallet: Some("System".to_string()), extrinsic: Some("remark".to_string()), args: vec!["0x11".to_string()].to_vec(), - url: Some(Url::parse("wss://rpc1.paseo.popnetwork.xyz")?), + url: Some(Url::parse(POP_NETWORK_TESTNET_URL)?), suri: Some(DEFAULT_URI.to_string()), skip_confirm: false, call_data: None, @@ -797,7 +770,7 @@ mod tests { pallet: Some("System".to_string()), extrinsic: Some("remark".to_string()), args: vec!["0x11".to_string()].to_vec(), - url: Some(Url::parse("wss://rpc1.paseo.popnetwork.xyz")?), + url: Some(Url::parse(POP_NETWORK_TESTNET_URL)?), suri: Some(DEFAULT_URI.to_string()), skip_confirm: false, call_data: None, @@ -814,7 +787,7 @@ mod tests { 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")?), + url: Some(Url::parse(POP_NETWORK_TESTNET_URL)?), suri: Some(DEFAULT_URI.to_string()), skip_confirm: false, call_data: None, @@ -857,7 +830,7 @@ mod tests { #[tokio::test] async fn prompt_predefined_actions_works() -> Result<()> { - let client = set_up_client("wss://rpc1.paseo.popnetwork.xyz").await?; + let client = set_up_client(POP_NETWORK_TESTNET_URL).await?; let pallets = parse_chain_metadata(&client).await?; let mut cli = MockCli::new().expect_select( "What would you like to do?", @@ -885,7 +858,7 @@ mod tests { #[tokio::test] async fn prompt_for_param_works() -> Result<()> { - let client = set_up_client("wss://rpc1.paseo.popnetwork.xyz").await?; + let client = set_up_client(POP_NETWORK_TESTNET_URL).await?; let pallets = parse_chain_metadata(&client).await?; // Using NFT mint extrinsic to test the majority of subfunctions let extrinsic = find_extrinsic_by_name(&pallets, "Nfts", "mint").await?; diff --git a/crates/pop-common/src/metadata.rs b/crates/pop-common/src/metadata.rs index e8a407c9..48f46da2 100644 --- a/crates/pop-common/src/metadata.rs +++ b/crates/pop-common/src/metadata.rs @@ -162,10 +162,11 @@ mod tests { use anyhow::Result; use subxt::{OnlineClient, SubstrateConfig}; + const POP_NETWORK_TESTNET_URL: &str = "wss://rpc1.paseo.popnetwork.xyz"; + #[tokio::test] async fn format_type_works() -> Result<()> { - let client = - OnlineClient::::from_url("wss://rpc1.paseo.popnetwork.xyz").await?; + let client = OnlineClient::::from_url(POP_NETWORK_TESTNET_URL).await?; let metadata = client.metadata(); let registry = metadata.types(); diff --git a/crates/pop-parachains/src/call/metadata/action.rs b/crates/pop-parachains/src/call/metadata/action.rs index d687ec35..608c3c22 100644 --- a/crates/pop-parachains/src/call/metadata/action.rs +++ b/crates/pop-parachains/src/call/metadata/action.rs @@ -126,6 +126,9 @@ mod tests { use anyhow::Result; use std::collections::HashMap; + const POP_NETWORK_TESTNET_URL: &str = "wss://rpc1.paseo.popnetwork.xyz"; + const POLKADOT_NETWORK_URL: &str = "wss://polkadot-rpc.publicnode.com"; + #[test] fn action_descriptions_are_correct() { let descriptions = HashMap::from([ @@ -184,7 +187,7 @@ mod tests { async fn supported_actions_works() -> Result<()> { // Test Pop Parachain. let mut client: subxt::OnlineClient = - set_up_client("wss://rpc1.paseo.popnetwork.xyz").await?; + set_up_client(POP_NETWORK_TESTNET_URL).await?; let mut actions = supported_actions(&parse_chain_metadata(&client).await?).await; assert_eq!(actions.len(), 5); assert_eq!(actions[0], Action::Transfer); @@ -194,7 +197,7 @@ mod tests { assert_eq!(actions[4], Action::MintNFT); // Test Polkadot Relay Chain. - client = set_up_client("wss://polkadot-rpc.publicnode.com").await?; + client = set_up_client(POLKADOT_NETWORK_URL).await?; actions = supported_actions(&parse_chain_metadata(&client).await?).await; assert_eq!(actions.len(), 4); assert_eq!(actions[0], Action::Transfer); diff --git a/crates/pop-parachains/src/call/metadata/mod.rs b/crates/pop-parachains/src/call/metadata/mod.rs index d3a057d4..26e8d927 100644 --- a/crates/pop-parachains/src/call/metadata/mod.rs +++ b/crates/pop-parachains/src/call/metadata/mod.rs @@ -10,7 +10,7 @@ pub mod action; pub mod params; /// Represents a pallet in the blockchain, including its extrinsics. -#[derive(Clone, PartialEq, Eq)] +#[derive(Clone, Debug, Default, Eq, PartialEq)] pub struct Pallet { /// The name of the pallet. pub name: String, @@ -27,7 +27,7 @@ impl Display for Pallet { } /// Represents an extrinsic. -#[derive(Clone, PartialEq, Eq, Debug)] +#[derive(Clone, Debug, Default, Eq, PartialEq)] pub struct Extrinsic { /// The name of the extrinsic. pub name: String, @@ -180,9 +180,11 @@ mod tests { use anyhow::Result; use subxt::ext::scale_bits; + const POP_NETWORK_TESTNET_URL: &str = "wss://rpc1.paseo.popnetwork.xyz"; + #[tokio::test] async fn parse_chain_metadata_works() -> Result<()> { - let client = set_up_client("wss://rpc1.paseo.popnetwork.xyz").await?; + let client = set_up_client(POP_NETWORK_TESTNET_URL).await?; let pallets = parse_chain_metadata(&client).await?; // Test the first pallet is parsed correctly let first_pallet = pallets.first().unwrap(); @@ -208,7 +210,7 @@ mod tests { #[tokio::test] async fn find_pallet_by_name_works() -> Result<()> { - let client = set_up_client("wss://rpc1.paseo.popnetwork.xyz").await?; + let client = set_up_client(POP_NETWORK_TESTNET_URL).await?; let pallets = parse_chain_metadata(&client).await?; assert!(matches!( find_pallet_by_name(&pallets, "WrongName").await, @@ -221,7 +223,7 @@ mod tests { #[tokio::test] async fn find_extrinsic_by_name_works() -> Result<()> { - let client = set_up_client("wss://rpc1.paseo.popnetwork.xyz").await?; + let client = set_up_client(POP_NETWORK_TESTNET_URL).await?; let pallets = parse_chain_metadata(&client).await?; assert!(matches!( find_extrinsic_by_name(&pallets, "WrongName", "wrong_extrinsic").await, diff --git a/crates/pop-parachains/src/call/metadata/params.rs b/crates/pop-parachains/src/call/metadata/params.rs index 077d27dd..232e4d6b 100644 --- a/crates/pop-parachains/src/call/metadata/params.rs +++ b/crates/pop-parachains/src/call/metadata/params.rs @@ -66,9 +66,7 @@ fn type_to_param(name: String, registry: &PortableRegistry, type_id: u32) -> Res type_name: sub_param.type_name, sub_params: sub_param.sub_params, is_optional: true, - is_tuple: false, - is_variant: false, - is_sequence: false, + ..Default::default() }) } else { Err(Error::MetadataParsingError(name)) @@ -77,15 +75,8 @@ 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::Compact(_) => Ok(Param { - name, - type_name, - sub_params: Vec::new(), - is_optional: false, - is_tuple: false, - is_variant: false, - is_sequence: false, - }), + TypeDef::Primitive(_) | TypeDef::Array(_) | TypeDef::Compact(_) => + Ok(Param { name, type_name, ..Default::default() }), TypeDef::Composite(composite) => { let sub_params = composite .fields @@ -100,15 +91,7 @@ fn type_to_param(name: String, registry: &PortableRegistry, type_id: u32) -> Res }) .collect::, Error>>()?; - Ok(Param { - name, - type_name, - sub_params, - is_optional: false, - is_tuple: false, - is_variant: false, - is_sequence: false, - }) + Ok(Param { name, type_name, sub_params, ..Default::default() }) }, TypeDef::Variant(variant) => { let variant_params = variant @@ -131,10 +114,8 @@ fn type_to_param(name: String, registry: &PortableRegistry, type_id: u32) -> Res name: variant_param.name.clone(), type_name: "".to_string(), sub_params: variant_sub_params, - is_optional: false, - is_tuple: false, is_variant: true, - is_sequence: false, + ..Default::default() }) }) .collect::, Error>>()?; @@ -143,21 +124,12 @@ fn type_to_param(name: String, registry: &PortableRegistry, type_id: u32) -> Res name, type_name, sub_params: variant_params, - is_optional: false, - is_tuple: false, is_variant: true, - is_sequence: false, + ..Default::default() }) }, - TypeDef::Sequence(_) => Ok(Param { - name, - type_name, - sub_params: Vec::new(), - is_optional: false, - is_tuple: false, - is_variant: false, - is_sequence: true, - }), + TypeDef::Sequence(_) => + Ok(Param { name, type_name, is_sequence: true, ..Default::default() }), TypeDef::Tuple(tuple) => { let sub_params = tuple .fields @@ -172,15 +144,7 @@ fn type_to_param(name: String, registry: &PortableRegistry, type_id: u32) -> Res }) .collect::, Error>>()?; - Ok(Param { - name, - type_name, - sub_params, - is_optional: false, - is_tuple: true, - is_variant: false, - is_sequence: false, - }) + Ok(Param { name, type_name, sub_params, is_tuple: true, ..Default::default() }) }, _ => Err(Error::MetadataParsingError(name)), } @@ -193,9 +157,11 @@ mod tests { use crate::set_up_client; use anyhow::Result; + const POP_NETWORK_TESTNET_URL: &str = "wss://rpc1.paseo.popnetwork.xyz"; + #[tokio::test] async fn field_to_param_works() -> Result<()> { - let client = set_up_client("wss://rpc1.paseo.popnetwork.xyz").await?; + let client = set_up_client(POP_NETWORK_TESTNET_URL).await?; let metadata = client.metadata(); // Test a supported extrinsic let extrinsic = metadata diff --git a/crates/pop-parachains/src/call/mod.rs b/crates/pop-parachains/src/call/mod.rs index 53ed0ff9..136d0d2d 100644 --- a/crates/pop-parachains/src/call/mod.rs +++ b/crates/pop-parachains/src/call/mod.rs @@ -125,23 +125,25 @@ pub async fn sign_and_submit_extrinsic_with_call_data( #[cfg(test)] mod tests { use super::*; - use crate::{find_extrinsic_by_name, parse_chain_metadata, set_up_client}; use anyhow::Result; + const ALICE_SURI: &str = "//Alice"; + const POP_NETWORK_TESTNET_URL: &str = "wss://rpc1.paseo.popnetwork.xyz"; + #[tokio::test] async fn set_up_client_works() -> Result<()> { assert!(matches!( set_up_client("wss://wronguri.xyz").await, Err(Error::ConnectionFailure(_)) )); - set_up_client("wss://rpc1.paseo.popnetwork.xyz").await?; + set_up_client(POP_NETWORK_TESTNET_URL).await?; Ok(()) } #[tokio::test] async fn construct_extrinsic_works() -> Result<()> { - let client = set_up_client("wss://rpc1.paseo.popnetwork.xyz").await?; + let client = set_up_client(POP_NETWORK_TESTNET_URL).await?; let pallets = parse_chain_metadata(&client).await?; let transfer_allow_death = find_extrinsic_by_name(&pallets, "Balances", "transfer_allow_death").await?; @@ -151,7 +153,7 @@ mod tests { construct_extrinsic( "Balances", &transfer_allow_death, - vec!["Bob".to_string(), "100".to_string()], + vec![ALICE_SURI.to_string(), "100".to_string()], ) .await, Err(Error::ParamProcessingError) @@ -173,7 +175,7 @@ mod tests { #[tokio::test] async fn encode_call_data_works() -> Result<()> { - let client = set_up_client("wss://rpc1.paseo.popnetwork.xyz").await?; + let client = set_up_client(POP_NETWORK_TESTNET_URL).await?; let pallets = parse_chain_metadata(&client).await?; let remark = find_extrinsic_by_name(&pallets, "System", "remark").await?; let extrinsic = construct_extrinsic("System", &remark, vec!["0x11".to_string()]).await?; @@ -199,16 +201,16 @@ mod tests { #[tokio::test] async fn sign_and_submit_wrong_extrinsic_fails() -> Result<()> { - let client = set_up_client("wss://rpc1.paseo.popnetwork.xyz").await?; + let client = set_up_client(POP_NETWORK_TESTNET_URL).await?; let extrinsic = Extrinsic { name: "wrong_extrinsic".to_string(), docs: "documentation".to_string(), - params: vec![], is_supported: true, + ..Default::default() }; let tx = construct_extrinsic("WrongPallet", &extrinsic, vec!["0x11".to_string()]).await?; assert!(matches!( - sign_and_submit_extrinsic(client, tx, "//Alice").await, + sign_and_submit_extrinsic(client, tx, ALICE_SURI).await, Err(Error::ExtrinsicSubmissionError(message)) if message.contains("PalletNameNotFound(\"WrongPallet\"))") )); Ok(())