moonbeam_service/chain_spec/
mod.rs1use bip32::ExtendedPrivateKey;
17use bip39::{Language, Mnemonic, Seed};
18use libsecp256k1::{PublicKey, PublicKeyFormat};
19use log::debug;
20use moonbeam_cli_opt::account_key::Secp256k1SecretKey;
21pub use moonbeam_core_primitives::AccountId;
22use sc_chain_spec::{ChainSpecExtension, ChainSpecGroup};
23use serde::{Deserialize, Serialize};
24use sha3::{Digest, Keccak256};
25use sp_core::{ecdsa, Pair, Public, H160, H256};
26
27#[cfg(feature = "moonbase-native")]
28pub mod moonbase;
29#[cfg(feature = "moonbeam-native")]
30pub mod moonbeam;
31#[cfg(feature = "moonriver-native")]
32pub mod moonriver;
33
34pub type RawChainSpec = sc_service::GenericChainSpec<Extensions>;
35
36#[derive(Default, Clone, Serialize, Deserialize, ChainSpecExtension, ChainSpecGroup)]
37#[serde(rename_all = "camelCase")]
38pub struct Extensions {
39 pub relay_chain: String,
41 pub para_id: u32,
43}
44
45impl Extensions {
46 pub fn try_get(chain_spec: &dyn sc_service::ChainSpec) -> Option<&Self> {
48 sc_chain_spec::get_extension(chain_spec.extensions())
49 }
50}
51
52pub fn derive_bip44_pairs_from_mnemonic<TPublic: Public>(
56 mnemonic: &str,
57 num_accounts: u32,
58) -> Vec<TPublic::Pair> {
59 let seed = Mnemonic::from_phrase(mnemonic, Language::English)
60 .map(|x| Seed::new(&x, ""))
61 .expect("Wrong mnemonic provided");
62
63 let mut childs = Vec::new();
64 for i in 0..num_accounts {
65 if let Some(child_pair) = format!("m/44'/60'/0'/0/{}", i)
66 .parse()
67 .ok()
68 .and_then(|derivation_path| {
69 ExtendedPrivateKey::<Secp256k1SecretKey>::derive_from_path(&seed, &derivation_path)
70 .ok()
71 })
72 .and_then(|extended| {
73 TPublic::Pair::from_seed_slice(&extended.private_key().0.serialize()).ok()
74 }) {
75 childs.push(child_pair);
76 } else {
77 log::error!("An error ocurred while deriving key {} from parent", i)
78 }
79 }
80 childs
81}
82
83pub fn get_account_id_from_pair(pair: ecdsa::Pair) -> Option<AccountId> {
85 let decompressed = PublicKey::parse_slice(&pair.public().0, Some(PublicKeyFormat::Compressed))
86 .ok()?
87 .serialize();
88
89 let mut m = [0u8; 64];
90 m.copy_from_slice(&decompressed[1..65]);
91
92 Some(H160::from(H256::from_slice(Keccak256::digest(&m).as_slice())).into())
93}
94
95pub fn generate_accounts(mnemonic: String, num_accounts: u32) -> Vec<AccountId> {
98 let childs = derive_bip44_pairs_from_mnemonic::<ecdsa::Public>(&mnemonic, num_accounts);
99 debug!("Account Generation");
100 childs
101 .iter()
102 .filter_map(|par| {
103 let account = get_account_id_from_pair(par.clone());
104 debug!(
105 "private_key {} --------> Account {:x?}",
106 sp_core::hexdisplay::HexDisplay::from(&par.clone().seed()),
107 account
108 );
109 account
110 })
111 .collect()
112}
113
114pub fn get_from_seed<TPublic: Public>(seed: &str) -> <TPublic::Pair as Pair>::Public {
116 TPublic::Pair::from_string(&format!("//{}", seed), None)
117 .expect("static values are valid; qed")
118 .public()
119}