use kestrel_runtime::{
opaque::SessionKeys, BalancesConfig, RuntimeGenesisConfig, SessionConfig, SudoConfig, SystemConfig, WASM_BINARY,
};
use runtime_common::{AccountId, AccountPublic};
use sc_service::{self, ChainType, Properties};
use serde_json::to_value;
use sp_consensus_aura::ed25519::AuthorityId as AuraId;
use sp_consensus_grandpa::AuthorityId as GrandpaId;
use sp_core::{ed25519, sr25519, Pair, Public};
use sp_runtime::traits::IdentifyAccount;
pub(crate) fn load_spec(id: &str) -> Result<Box<dyn sc_service::ChainSpec>, String> {
let chain_spec = match id {
"dev" => Ok::<_, String>(generate_dev_chain_spec()),
_ => return Err(format!("Unknown spec: {}", id)),
}?;
Ok(Box::new(chain_spec))
}
type ChainSpec = sc_service::GenericChainSpec<RuntimeGenesisConfig>;
fn generate_dev_chain_spec() -> ChainSpec {
let wasm_binary = WASM_BINARY.expect("Development WASM binary not available");
let properties = Properties::from_iter([
("tokenDecimals".into(), 15.into()),
("tokenSymbol".into(), "DILT".into()),
]);
let genesis_state = to_value(generate_genesis_state()).expect("Creating genesis state failed");
ChainSpec::builder(wasm_binary, None)
.with_name("Standalone Node (Dev)")
.with_id("standalone_node_development")
.with_chain_type(ChainType::Development)
.with_properties(properties)
.with_genesis_config(genesis_state)
.build()
}
fn generate_genesis_state() -> RuntimeGenesisConfig {
let endowed_accounts = vec![
get_account_id_from_secret::<ed25519::Public>(
"receive clutch item involve chaos clutch furnace arrest claw isolate okay together",
),
get_account_id_from_secret::<ed25519::Public>("//Alice"),
get_account_id_from_secret::<ed25519::Public>("//Bob"),
get_account_id_from_secret::<sr25519::Public>("//Alice"),
get_account_id_from_secret::<sr25519::Public>("//Bob"),
];
let initial_authorities = vec![get_authority_keys_from_secret("//Alice")];
let root_key = get_account_id_from_secret::<ed25519::Public>("//Alice");
RuntimeGenesisConfig {
system: SystemConfig { ..Default::default() },
balances: BalancesConfig {
balances: endowed_accounts.into_iter().map(|a| (a, 1u128 << 90)).collect(),
},
session: SessionConfig {
keys: initial_authorities
.into_iter()
.map(|(acc, aura, grandpa)| {
(
acc.clone(), acc, template_session_keys(aura, grandpa), )
})
.collect::<Vec<_>>(),
},
sudo: SudoConfig { key: Some(root_key) },
..Default::default()
}
}
fn template_session_keys(aura_keys: AuraId, grandpa_keys: GrandpaId) -> SessionKeys {
SessionKeys {
aura: aura_keys,
grandpa: grandpa_keys,
}
}
fn get_authority_keys_from_secret(seed: &str) -> (AccountId, AuraId, GrandpaId) {
(
get_account_id_from_secret::<ed25519::Public>(seed),
get_public_key_from_secret::<AuraId>(seed),
get_public_key_from_secret::<GrandpaId>(seed),
)
}
fn get_account_id_from_secret<TPublic: Public>(seed: &str) -> AccountId
where
AccountPublic: From<<TPublic::Pair as Pair>::Public>,
{
AccountPublic::from(get_public_key_from_secret::<TPublic>(seed)).into_account()
}
fn get_public_key_from_secret<TPublic: Public>(seed: &str) -> <TPublic::Pair as Pair>::Public {
TPublic::Pair::from_string(seed, None)
.unwrap_or_else(|_| panic!("Invalid string '{}'", seed))
.public()
}