Skip to content

Commit

Permalink
chore: merge
Browse files Browse the repository at this point in the history
  • Loading branch information
peterwht committed Dec 16, 2024
2 parents 0ac034d + 074e2f9 commit 6271bb0
Show file tree
Hide file tree
Showing 19 changed files with 682 additions and 461 deletions.
462 changes: 231 additions & 231 deletions Cargo.lock

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ contract-extrinsics = { git = "https://github.com/use-ink/cargo-contract", branc
#contract-transcode = "5.0.0"
contract-transcode = { git = "https://github.com/use-ink/cargo-contract", branch = "peter/chore-make-types-pub" }
heck = "0.5.0"
hex = { version = "0.4.3", default-features = false }

# parachains
askama = "0.12"
Expand Down
4 changes: 2 additions & 2 deletions crates/pop-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ url.workspace = true
clap.workspace = true
cliclack.workspace = true
console.workspace = true
sp-core.workspace = true
strum.workspace = true
strum_macros.workspace = true

# contracts
pop-contracts = { path = "../pop-contracts", version = "0.5.0", optional = true }
sp-core = { workspace = true, optional = true }
sp-weights = { workspace = true, optional = true }

# parachains
Expand Down Expand Up @@ -61,6 +61,6 @@ sp-weights.workspace = true

[features]
default = ["contract", "parachain", "telemetry"]
contract = ["dep:pop-contracts", "dep:sp-core", "dep:sp-weights", "dep:dirs"]
contract = ["dep:pop-contracts", "dep:sp-weights", "dep:dirs"]
parachain = ["dep:pop-parachains", "dep:dirs"]
telemetry = ["dep:pop-telemetry"]
1 change: 0 additions & 1 deletion crates/pop-cli/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,6 @@ impl traits::Confirm for Confirm {

/// A input prompt using cliclack.
struct Input(cliclack::Input);

impl traits::Input for Input {
/// Sets the default value for the input.
fn default_input(mut self, value: &str) -> Self {
Expand Down
129 changes: 113 additions & 16 deletions crates/pop-cli/src/commands/call/chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@

use std::path::Path;

use crate::cli::{self, traits::*};
use crate::{
cli::{self, traits::*},
common::wallet::wait_for_signature,
};
use anyhow::{anyhow, Result};
use clap::Args;
use pop_parachains::{
construct_extrinsic, construct_sudo_extrinsic, decode_call_data, encode_call_data,
find_dispatchable_by_name, find_pallet_by_name, parse_chain_metadata, set_up_client,
sign_and_submit_extrinsic, supported_actions, Action, CallData, DynamicPayload, Function,
OnlineClient, Pallet, Param, SubstrateConfig,
sign_and_submit_extrinsic, submit_signed_extrinsic, supported_actions, Action, CallData,
DynamicPayload, Function, OnlineClient, Pallet, Param, Payload, SubstrateConfig,
};
use url::Url;

Expand Down Expand Up @@ -40,6 +43,9 @@ pub struct CallChainCommand {
/// - with a password "//Alice///SECRET_PASSWORD"
#[arg(short, long)]
suri: Option<String>,
/// Use your browser wallet to sign the extrinsic.
#[arg(name = "use-wallet", short('w'), long, default_value = "false", conflicts_with = "suri")]
use_wallet: bool,
/// SCALE encoded bytes representing the call data of the extrinsic.
#[arg(name = "call", short, long, conflicts_with_all = ["pallet", "function", "args"])]
call_data: Option<String>,
Expand Down Expand Up @@ -95,7 +101,14 @@ impl CallChainCommand {
};

// Sign and submit the extrinsic.
if let Err(e) = call.submit_extrinsic(&chain.client, &chain.url, xt, &mut cli).await {
let result = if self.use_wallet {
let call_data = xt.encode_call_data(&chain.client.metadata())?;
submit_extrinsic_with_wallet(&chain.client, &chain.url, call_data, &mut cli).await
} else {
call.submit_extrinsic(&chain.client, &chain.url, xt, &mut cli).await
};

if let Err(e) = result {
display_message(&e.to_string(), false, &mut cli)?;
break;
}
Expand Down Expand Up @@ -197,11 +210,25 @@ impl CallChainCommand {
// sudo.
self.configure_sudo(chain, cli)?;

// Resolve who is signing the extrinsic.
// Resolve who is signing the extrinsic. If a `suri` was provided via the command line,
// skip the prompt.
let suri = match self.suri.as_ref() {
Some(suri) => suri.clone(),
None =>
cli.input("Signer of the extrinsic:").default_input(DEFAULT_URI).interact()?,
None => {
if !self.use_wallet {
if cli.confirm("Do you want to use your browser wallet to sign the transaction? (Selecting 'No' will prompt you to manually enter the secret key URI for signing, e.g., '//Alice')")
.initial_value(true)
.interact()? {
self.use_wallet = true;
DEFAULT_URI.to_string() // Default value because the user is using the browser wallet.
}
else {
cli.input("Signer of the extrinsic:").default_input(DEFAULT_URI).interact()?
}
} else {
DEFAULT_URI.to_string() // Default value because the user is using the browser wallet.
}
},
};

return Ok(Call {
Expand All @@ -210,6 +237,7 @@ impl CallChainCommand {
suri,
skip_confirm: self.skip_confirm,
sudo: self.sudo,
use_wallet: self.use_wallet,
});
}
}
Expand All @@ -222,11 +250,36 @@ impl CallChainCommand {
call_data: &str,
cli: &mut impl Cli,
) -> Result<()> {
// Resolve who is signing the extrinsic.
// Resolve who is signing the extrinsic. If a `suri` was provided via the command line,
// skip the prompt.
let mut use_wallet = self.use_wallet;
let suri = match self.suri.as_ref() {
Some(suri) => suri,
None => &cli.input("Signer of the extrinsic:").default_input(DEFAULT_URI).interact()?,
Some(suri) => suri.clone(),
None =>
if !self.use_wallet {
if cli.confirm("Do you want to use your browser wallet to sign the transaction? (Selecting 'No' will prompt you to manually enter the secret key URI for signing, e.g., '//Alice')")
.initial_value(true)
.interact()? {
use_wallet = true;
DEFAULT_URI.to_string()
}
else {
cli.input("Signer of the extrinsic:").default_input(DEFAULT_URI).interact()?
}
} else {
DEFAULT_URI.to_string()
},
};
// Perform signing steps with wallet integration and return early.
if use_wallet {
let call_data_bytes =
decode_call_data(call_data).map_err(|err| anyhow!("{}", format!("{err:?}")))?;
submit_extrinsic_with_wallet(client, &url, call_data_bytes, cli)

Check warning on line 277 in crates/pop-cli/src/commands/call/chain.rs

View workflow job for this annotation

GitHub Actions / clippy

this expression creates a reference which is immediately dereferenced by the compiler

warning: this expression creates a reference which is immediately dereferenced by the compiler --> crates/pop-cli/src/commands/call/chain.rs:277:41 | 277 | submit_extrinsic_with_wallet(client, &url, call_data_bytes, cli) | ^^^^ help: change this to: `url` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow = note: `#[warn(clippy::needless_borrow)]` on by default
.await
.map_err(|err| anyhow!("{}", format!("{err:?}")))?;
display_message("Call complete.", true, cli)?;
return Ok(());
}
cli.info(format!("Encoded call data: {}", call_data))?;
if !self.skip_confirm &&
!cli.confirm("Do you want to submit the extrinsic?")
Expand All @@ -244,7 +297,7 @@ impl CallChainCommand {
spinner.start("Signing and submitting the extrinsic and then waiting for finalization, please be patient...");
let call_data_bytes =
decode_call_data(call_data).map_err(|err| anyhow!("{}", format!("{err:?}")))?;
let result = sign_and_submit_extrinsic(client, url, CallData::new(call_data_bytes), suri)
let result = sign_and_submit_extrinsic(client, url, CallData::new(call_data_bytes), &suri)
.await
.map_err(|err| anyhow!("{}", format!("{err:?}")))?;

Expand Down Expand Up @@ -283,6 +336,7 @@ impl CallChainCommand {
self.function = None;
self.args.clear();
self.sudo = false;
self.use_wallet = false;
}

// Function to check if all required fields are specified.
Expand Down Expand Up @@ -334,6 +388,8 @@ struct Call {
/// - for a dev account "//Alice"
/// - with a password "//Alice///SECRET_PASSWORD"
suri: String,
/// Whether to use your browser wallet to sign the extrinsic.
use_wallet: bool,
/// Whether to automatically sign and submit the extrinsic without prompting for confirmation.
skip_confirm: bool,
/// Whether to dispatch the function call with `Root` origin.
Expand Down Expand Up @@ -411,14 +467,45 @@ impl Call {
.collect();
full_message.push_str(&format!(" --args {}", args.join(" ")));
}
full_message.push_str(&format!(" --url {} --suri {}", chain.url, self.suri));
full_message.push_str(&format!(" --url {}", chain.url));
if self.use_wallet {
full_message.push_str(" --use-wallet");
} else {
full_message.push_str(&format!(" --suri {}", self.suri));
}
if self.sudo {
full_message.push_str(" --sudo");
}
full_message
}
}

// Sign and submit an extrinsic using wallet integration.
async fn submit_extrinsic_with_wallet(
client: &OnlineClient<SubstrateConfig>,
url: &Url,
call_data: Vec<u8>,
cli: &mut impl Cli,
) -> Result<()> {
let maybe_payload = wait_for_signature(call_data, url.to_string()).await?;
if let Some(payload) = maybe_payload {
cli.success("Signed payload received.")?;
let spinner = cliclack::spinner();
spinner.start(
"Submitting the extrinsic and then waiting for finalization, please be patient...",
);

let result = submit_signed_extrinsic(client.clone(), payload)
.await
.map_err(|err| anyhow!("{}", format!("{err:?}")))?;

spinner.stop(format!("Extrinsic submitted with hash: {:?}", result));
} else {
display_message("No signed payload received.", false, cli)?;
}
Ok(())
}

// Displays a message to the user, with formatting based on the success status.
fn display_message(message: &str, success: bool, cli: &mut impl Cli) -> Result<()> {
if success {
Expand Down Expand Up @@ -642,7 +729,7 @@ mod tests {
)
.expect_input("The value for `remark` might be too large to enter. You may enter the path to a file instead.", "0x11".into())
.expect_confirm("Would you like to dispatch this function call with `Root` origin?", true)
.expect_input("Signer of the extrinsic:", "//Bob".into());
.expect_confirm("Do you want to use your browser wallet to sign the transaction? (Selecting 'No' will prompt you to manually enter the secret key URI for signing, e.g., '//Alice')", true);

let chain = call_config.configure_chain(&mut cli).await?;
assert_eq!(chain.url, Url::parse(POP_NETWORK_TESTNET_URL)?);
Expand All @@ -651,9 +738,10 @@ mod tests {
assert_eq!(call_chain.function.pallet, "System");
assert_eq!(call_chain.function.name, "remark");
assert_eq!(call_chain.args, ["0x11".to_string()].to_vec());
assert_eq!(call_chain.suri, "//Bob");
assert_eq!(call_chain.suri, "//Alice"); // Default value
assert!(call_chain.use_wallet);
assert!(call_chain.sudo);
assert_eq!(call_chain.display(&chain), "pop call chain --pallet System --function remark --args \"0x11\" --url wss://rpc1.paseo.popnetwork.xyz/ --suri //Bob --sudo");
assert_eq!(call_chain.display(&chain), "pop call chain --pallet System --function remark --args \"0x11\" --url wss://rpc1.paseo.popnetwork.xyz/ --use-wallet --sudo");
cli.verify()
}

Expand Down Expand Up @@ -714,6 +802,7 @@ mod tests {
},
args: vec!["0x11".to_string()].to_vec(),
suri: DEFAULT_URI.to_string(),
use_wallet: false,
skip_confirm: false,
sudo: false,
};
Expand Down Expand Up @@ -753,6 +842,7 @@ mod tests {
function: find_dispatchable_by_name(&pallets, "System", "remark")?.clone(),
args: vec!["0x11".to_string()].to_vec(),
suri: DEFAULT_URI.to_string(),
use_wallet: false,
skip_confirm: false,
sudo: false,
};
Expand All @@ -776,11 +866,13 @@ mod tests {
args: vec![].to_vec(),
url: Some(Url::parse(POP_NETWORK_TESTNET_URL)?),
suri: None,
use_wallet: false,
skip_confirm: false,
call_data: Some("0x00000411".to_string()),
sudo: false,
};
let mut cli = MockCli::new()
.expect_confirm("Do you want to use your browser wallet to sign the transaction? (Selecting 'No' will prompt you to manually enter the secret key URI for signing, e.g., '//Alice')", false)
.expect_input("Signer of the extrinsic:", "//Bob".into())
.expect_confirm("Do you want to submit the extrinsic?", false)
.expect_outro_cancel("Extrinsic with call data 0x00000411 was not submitted.");
Expand All @@ -803,8 +895,9 @@ mod tests {
pallet: None,
function: None,
args: vec![].to_vec(),
url: Some(Url::parse("wss://polkadot-rpc.publicnode.com")?),
url: Some(Url::parse(POLKADOT_NETWORK_URL)?),
suri: Some("//Alice".to_string()),
use_wallet: false,
skip_confirm: false,
call_data: Some("0x00000411".to_string()),
sudo: true,
Expand Down Expand Up @@ -836,6 +929,7 @@ mod tests {
function: Some("remark".to_string()),
args: vec!["0x11".to_string()].to_vec(),
url: Some(Url::parse(POP_NETWORK_TESTNET_URL)?),
use_wallet: true,
suri: Some(DEFAULT_URI.to_string()),
skip_confirm: false,
call_data: None,
Expand All @@ -846,6 +940,7 @@ mod tests {
assert_eq!(call_config.function, None);
assert_eq!(call_config.args.len(), 0);
assert!(!call_config.sudo);
assert!(!call_config.use_wallet);
Ok(())
}

Expand All @@ -857,6 +952,7 @@ mod tests {
args: vec!["0x11".to_string()].to_vec(),
url: Some(Url::parse(POP_NETWORK_TESTNET_URL)?),
suri: Some(DEFAULT_URI.to_string()),
use_wallet: false,
skip_confirm: false,
call_data: None,
sudo: false,
Expand All @@ -875,6 +971,7 @@ mod tests {
args: vec!["2000".to_string(), "0x1".to_string(), "0x12".to_string()].to_vec(),
url: Some(Url::parse(POP_NETWORK_TESTNET_URL)?),
suri: Some(DEFAULT_URI.to_string()),
use_wallet: false,
call_data: None,
skip_confirm: false,
sudo: false,
Expand Down
Loading

0 comments on commit 6271bb0

Please sign in to comment.