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( uri: &str, password: Option, network_override: Option, output: OutputType, ) where Pair: sp_core::Pair, Pair::Public: Into, { 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::(seed), "publicKey": format_public_key::(public_key.clone()), "ss58PublicKey": public_key.to_ss58check_with_version(network_override), "accountId": format_account_id::(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::(seed), format_public_key::(public_key.clone()), format_account_id::(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::(seed) } else { "n/a".into() }, "publicKey": format_public_key::(public_key.clone()), "ss58PublicKey": public_key.to_ss58check_with_version(network_override), "accountId": format_account_id::(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::(seed) } else { "n/a".into() }, format_public_key::(public_key.clone()), format_account_id::(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::(public_key.clone()), "accountId": format_account_id::(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::(public_key.clone()), format_account_id::(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( public_str: &str, network_override: Option, output: OutputType, ) -> Result<(), sc_cli::Error> where Pair: sp_core::Pair, Pair::Public: Into, { 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::(public_key.clone()), "accountId": format_account_id::(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::(public_key.clone()), format_account_id::(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) -> 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(seed: SeedFor

) -> String { format!("0x{}", HexDisplay::from(&seed.as_ref())) } fn format_public_key(public_key: PublicFor

) -> String { format!("0x{}", HexDisplay::from(&public_key.as_ref())) } fn format_account_id(public_key: PublicFor

) -> String where PublicFor

: Into, { format!("0x{}", HexDisplay::from(&public_key.into().into_account().as_ref())) }