Newer
Older
use crate::data::Data;
use crate::keys;
use crate::keys::KeyPair;
use crate::runtime_config::AccountId;
use crate::utils::GcliError;
use sp_core::{ed25519, Pair};
use std::str::FromStr;
/// define cesium subcommands
#[derive(Clone, Default, Debug, clap::Parser)]
pub enum Subcommand {
// Nothing
#[default]
#[clap(hide = true)]
Nothing,
/// Analyse a base58 pubkey and gives it in all its form
Pubkey { pubkey: String },
/// Prompt for cesium input
Prompt,
}
/// handle blockchain commands
pub async fn handle_command(_data: Data, command: Subcommand) -> Result<(), GcliError> {
match command {
Subcommand::Nothing => {}
Subcommand::Pubkey { pubkey } => {
let raw_pubkey = bs58::decode(pubkey).into_vec().unwrap();
let raw_pubkey: [u8; 32] = if raw_pubkey.len() > 32 {
return Err(GcliError::Input("invalid pubkey size".to_string()));
} else {
[vec![0; 32 - raw_pubkey.len()], raw_pubkey]
.concat()
.try_into()
.unwrap()
};
println!("Pubkey (hex): 0x{}", hex::encode(raw_pubkey));
let address: AccountId = sp_core::ed25519::Public::from_raw(raw_pubkey).into();
let pair = keys::prompt_secret_cesium();
Nicolas80
committed
println!(
"Pubkey: {}",
compute_g1v1_public_key_from_ed25519_pair(&pair)
Nicolas80
committed
);
let address: AccountId = pair.public().into();
Nicolas80
committed
/// Computes G1v1 public key from a KeyPair of type sp_core::ed25519::Pair - fails otherwise
pub fn compute_g1v1_public_key(key_pair: &KeyPair) -> Result<String, GcliError> {
match key_pair {
KeyPair::Sr25519(_) => Err(GcliError::Logic(
"key pair is not of type ed25519".to_string(),
)),
KeyPair::Ed25519(key_pair) => Ok(compute_g1v1_public_key_from_ed25519_pair(key_pair)),
Nicolas80
committed
}
}
/// Computes G1v1 public key from an ed25519 Pair
pub fn compute_g1v1_public_key_from_ed25519_pair(ed25519_key_pair: &ed25519::Pair) -> String {
compute_g1v1_public_key_from_ed25519_public(&ed25519_key_pair.public())
}
/// Computes G1v1 public key from an ed25519 Public
pub fn compute_g1v1_public_key_from_ed25519_public(ed25519_public: &ed25519::Public) -> String {
bs58::encode(ed25519_public).into_string()
}
/// Computes G1v1 public key from an ed25519 AccountId
pub fn compute_g1v1_public_key_from_ed25519_account_id(ed25519_account_id: &AccountId) -> String {
let ed25519_public: ed25519::Public = ed25519::Public::from(ed25519_account_id.0);
bs58::encode(ed25519_public).into_string()
}
/// Computes G1v1 public key from an ed25519 SS58 Address
#[allow(unused)]
pub fn compute_g1v1_public_key_from_ed25519_ss58_address(
ed25519_ss58_address: &str,
Nicolas80
committed
) -> Result<String, GcliError> {
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
Ok(compute_g1v1_public_key_from_ed25519_account_id(
&AccountId::from_str(ed25519_ss58_address).map_err(|e| GcliError::Input(e.to_string()))?,
))
}
// Unit tests
#[cfg(test)]
mod tests {
use super::*;
/// Test data:
/// cesium_id = "test_cesium_id"
/// cesium_pwd = "test_cesium_pwd"
///
/// G1v1 base58 public key: 86pW1doyJPVH3jeDPZNQa1UZFBo5zcdvHERcaeE758W7
///
/// ```
/// subkey inspect --scheme ed25519
/// URI:
/// Secret Key URI `0x2101d2bc68de9ad149c06293bfe489c8608de576c88927aa5439a81be17aae84` is account:
/// Network ID: substrate
/// Secret seed: 0x2101d2bc68de9ad149c06293bfe489c8608de576c88927aa5439a81be17aae84
/// Public key (hex): 0x697f6bd16ddebf142384e503fd3f3efc39fe5c7be7c693bd98d982403bb6eb74
/// Account ID: 0x697f6bd16ddebf142384e503fd3f3efc39fe5c7be7c693bd98d982403bb6eb74
/// Public key (SS58): 5ET2jhgJFoNQUpgfdSkdwftK8DKWdqZ1FKm5GKWdPfMWhPr4
/// SS58 Address: 5ET2jhgJFoNQUpgfdSkdwftK8DKWdqZ1FKm5GKWdPfMWhPr4
/// ```
#[test]
fn test_compute_g1v1_public_key() {
let expected_base58_public_key = "86pW1doyJPVH3jeDPZNQa1UZFBo5zcdvHERcaeE758W7";
let ss58_address = "5ET2jhgJFoNQUpgfdSkdwftK8DKWdqZ1FKm5GKWdPfMWhPr4";
assert_eq!(
expected_base58_public_key,
compute_g1v1_public_key_from_ed25519_ss58_address(ss58_address).unwrap()
);
let account_id = AccountId::from_str(ss58_address).unwrap();
assert_eq!(
expected_base58_public_key,
compute_g1v1_public_key_from_ed25519_account_id(&account_id)
);
let ed25519_public = ed25519::Public::from(account_id.0);
assert_eq!(
expected_base58_public_key,
compute_g1v1_public_key_from_ed25519_public(&ed25519_public)
);
let cesium_id = "test_cesium_id".to_string();
let cesium_pwd = "test_cesium_pwd".to_string();
let seed = keys::seed_from_cesium(&cesium_id, &cesium_pwd);
let ed25519_pair_from_seed = ed25519::Pair::from_seed(&seed);
assert_eq!(
expected_base58_public_key,
compute_g1v1_public_key_from_ed25519_pair(&ed25519_pair_from_seed)
);
}