MrBoec/client/cli/src/commands/utils.rs

221 lines
7.0 KiB
Rust
Raw Normal View History

use serde_json::json;
use sc_cli::{
OutputType,
utils::{PublicFor, SeedFor},
};
use sp_runtime::{traits::IdentifyAccount, MultiSigner};
use sp_core::{
crypto::{
unwrap_or_default_ss58_version,
Ss58Codec, ExposeSecret, Ss58AddressFormat, SecretString,
},
hexdisplay::HexDisplay,
};
pub fn print_from_uri<Pair>(
uri: &str,
password: Option<SecretString>,
network_override: Option<Ss58AddressFormat>,
output: OutputType,
) where
Pair: sp_core::Pair,
Pair::Public: Into<MultiSigner>,
{
let password = password.as_ref().map(|s| s.expose_secret().as_str());
let network_id = unwrap_or_default_ss58_name(network_override);
if let Ok((pair, seed)) = Pair::from_phrase(uri, password) {
let public_key = pair.public();
let network_override = unwrap_or_default_ss58_version(network_override);
match output {
OutputType::Json => {
let json = json!({
"secretPhrase": uri,
"networkId": network_id,
"secretSeed": format_seed::<Pair>(seed),
"publicKey": format_public_key::<Pair>(public_key.clone()),
"ss58PublicKey": public_key.to_ss58check_with_version(network_override),
"accountId": format_account_id::<Pair>(public_key),
"ss58Address": pair.public().into().into_account().to_ss58check_with_version(network_override),
});
println!(
"{}",
serde_json::to_string_pretty(&json).expect("Json pretty print failed")
);
},
OutputType::Text => {
println!(
"Secret phrase: {}\n \
Network ID: {}\n \
Secret seed: {}\n \
Public key (hex): {}\n \
Account ID: {}\n \
Public key (SS58): {}\n \
SS58 Address: {}",
uri,
network_id,
format_seed::<Pair>(seed),
format_public_key::<Pair>(public_key.clone()),
format_account_id::<Pair>(public_key.clone()),
public_key.to_ss58check_with_version(network_override),
pair.public().into().into_account().to_ss58check_with_version(network_override),
);
},
}
} else if let Ok((pair, seed)) = Pair::from_string_with_seed(uri, password) {
let public_key = pair.public();
let network_override = unwrap_or_default_ss58_version(network_override);
match output {
OutputType::Json => {
let json = json!({
"secretKeyUri": uri,
"networkId": network_id,
"secretSeed": if let Some(seed) = seed { format_seed::<Pair>(seed) } else { "n/a".into() },
"publicKey": format_public_key::<Pair>(public_key.clone()),
"ss58PublicKey": public_key.to_ss58check_with_version(network_override),
"accountId": format_account_id::<Pair>(public_key),
"ss58Address": pair.public().into().into_account().to_ss58check_with_version(network_override),
});
println!(
"{}",
serde_json::to_string_pretty(&json).expect("Json pretty print failed")
);
},
OutputType::Text => {
println!(
"Secret Key URI `{}` is account:\n \
Network ID: {}\n \
Secret seed: {}\n \
Public key (hex): {}\n \
Account ID: {}\n \
Public key (SS58): {}\n \
SS58 Address: {}",
uri,
network_id,
if let Some(seed) = seed { format_seed::<Pair>(seed) } else { "n/a".into() },
format_public_key::<Pair>(public_key.clone()),
format_account_id::<Pair>(public_key.clone()),
public_key.to_ss58check_with_version(network_override),
pair.public().into().into_account().to_ss58check_with_version(network_override),
);
},
}
} else if let Ok((public_key, network)) = Pair::Public::from_string_with_version(uri) {
let network_override = network_override.unwrap_or(network);
match output {
OutputType::Json => {
let json = json!({
"publicKeyUri": uri,
"networkId": String::from(network_override),
"publicKey": format_public_key::<Pair>(public_key.clone()),
"accountId": format_account_id::<Pair>(public_key.clone()),
"ss58PublicKey": public_key.to_ss58check_with_version(network_override),
"ss58Address": public_key.to_ss58check_with_version(network_override),
});
println!(
"{}",
serde_json::to_string_pretty(&json).expect("Json pretty print failed")
);
},
OutputType::Text => {
println!(
"Public Key URI `{}` is account:\n \
Network ID/Version: {}\n \
Public key (hex): {}\n \
Account ID: {}\n \
Public key (SS58): {}\n \
SS58 Address: {}",
uri,
String::from(network_override),
format_public_key::<Pair>(public_key.clone()),
format_account_id::<Pair>(public_key.clone()),
public_key.to_ss58check_with_version(network_override),
public_key.to_ss58check_with_version(network_override),
);
},
}
} else {
println!("Invalid phrase/URI given");
}
}
/// Try to parse given `public` as hex encoded public key and print relevant information.
pub fn print_from_public<Pair>(
public_str: &str,
network_override: Option<Ss58AddressFormat>,
output: OutputType,
) -> Result<(), sc_cli::Error>
where
Pair: sp_core::Pair,
Pair::Public: Into<MultiSigner>,
{
let public = array_bytes::hex2bytes(public_str)?;
let public_key = Pair::Public::try_from(&public)
.map_err(|_| "Failed to construct public key from given hex")?;
let network_override = unwrap_or_default_ss58_version(network_override);
match output {
OutputType::Json => {
let json = json!({
"networkId": String::from(network_override),
"publicKey": format_public_key::<Pair>(public_key.clone()),
"accountId": format_account_id::<Pair>(public_key.clone()),
"ss58PublicKey": public_key.to_ss58check_with_version(network_override),
"ss58Address": public_key.to_ss58check_with_version(network_override),
});
println!("{}", serde_json::to_string_pretty(&json).expect("Json pretty print failed"));
},
OutputType::Text => {
println!(
"Network ID/Version: {}\n \
Public key (hex): {}\n \
Account ID: {}\n \
Public key (SS58): {}\n \
SS58 Address: {}",
String::from(network_override),
format_public_key::<Pair>(public_key.clone()),
format_account_id::<Pair>(public_key.clone()),
public_key.to_ss58check_with_version(network_override),
public_key.to_ss58check_with_version(network_override),
);
},
}
Ok(())
}
pub fn unwrap_or_default_ss58_name(x: Option<Ss58AddressFormat>) -> String {
if let Some(x) = x {
let name = match x.prefix() {
1995 => String::from("Ghost"),
1996 => String::from("Casper"),
_ => String::from("Unwknown"),
};
format!("{} ({})", name, x.prefix())
} else {
String::from("Unknown (unknown)")
}
}
pub fn format_seed<P: sp_core::Pair>(seed: SeedFor<P>) -> String {
format!("0x{}", HexDisplay::from(&seed.as_ref()))
}
fn format_public_key<P: sp_core::Pair>(public_key: PublicFor<P>) -> String {
format!("0x{}", HexDisplay::from(&public_key.as_ref()))
}
fn format_account_id<P: sp_core::Pair>(public_key: PublicFor<P>) -> String
where
PublicFor<P>: Into<MultiSigner>,
{
format!("0x{}", HexDisplay::from(&public_key.into().into_account().as_ref()))
}