1234567891011121314151617use std::collections::BTreeMap;1819#[cfg(all(not(feature = "unique-runtime"), not(feature = "quartz-runtime")))]20pub use opal_runtime as default_runtime;21#[cfg(all(not(feature = "unique-runtime"), feature = "quartz-runtime"))]22pub use quartz_runtime as default_runtime;23use sc_chain_spec::{ChainSpecExtension, ChainSpecGroup};24use sc_service::ChainType;25use serde::{Deserialize, Serialize};26use serde_json::map::Map;27use sp_core::{sr25519, Pair, Public};28use sp_runtime::traits::{IdentifyAccount, Verify};29#[cfg(feature = "unique-runtime")]30pub use unique_runtime as default_runtime;31use up_common::types::opaque::*;323334#[cfg(feature = "unique-runtime")]35pub type UniqueChainSpec =36 sc_service::GenericChainSpec<unique_runtime::RuntimeGenesisConfig, Extensions>;373839#[cfg(feature = "quartz-runtime")]40pub type QuartzChainSpec =41 sc_service::GenericChainSpec<quartz_runtime::RuntimeGenesisConfig, Extensions>;424344pub type OpalChainSpec =45 sc_service::GenericChainSpec<opal_runtime::RuntimeGenesisConfig, Extensions>;4647#[cfg(feature = "unique-runtime")]48pub type DefaultChainSpec = UniqueChainSpec;4950#[cfg(all(not(feature = "unique-runtime"), feature = "quartz-runtime"))]51pub type DefaultChainSpec = QuartzChainSpec;5253#[cfg(all(not(feature = "unique-runtime"), not(feature = "quartz-runtime")))]54pub type DefaultChainSpec = OpalChainSpec;5556#[cfg(not(feature = "unique-runtime"))]5758const PARA_ID: u32 = 2095;5960#[cfg(feature = "unique-runtime")]6162const PARA_ID: u32 = 2037;6364pub trait RuntimeIdentification {65 fn runtime_id(&self) -> RuntimeId;66}6768impl RuntimeIdentification for Box<dyn sc_service::ChainSpec> {69 fn runtime_id(&self) -> RuntimeId {70 #[cfg(feature = "unique-runtime")]71 if self.id().starts_with("unique") || self.id().starts_with("unq") {72 return RuntimeId::Unique;73 }7475 #[cfg(feature = "quartz-runtime")]76 if self.id().starts_with("quartz")77 || self.id().starts_with("qtz")78 || self.id().starts_with("sapphire")79 {80 return RuntimeId::Quartz;81 }8283 if self.id().starts_with("opal") || self.id() == "dev" || self.id() == "local_testnet" {84 return RuntimeId::Opal;85 }8687 RuntimeId::Unknown(self.id().into())88 }89}9091pub enum ServiceId {92 Prod,93 Dev,94}9596pub trait ServiceIdentification {97 fn service_id(&self) -> ServiceId;98}99100impl ServiceIdentification for Box<dyn sc_service::ChainSpec> {101 fn service_id(&self) -> ServiceId {102 if self.id().ends_with("dev") {103 ServiceId::Dev104 } else {105 ServiceId::Prod106 }107 }108}109110111pub fn get_from_seed<TPublic: Public>(seed: &str) -> <TPublic::Pair as Pair>::Public {112 TPublic::Pair::from_string(&format!("//{seed}"), None)113 .expect("static values are valid; qed")114 .public()115}116117118#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ChainSpecGroup, ChainSpecExtension)]119#[serde(deny_unknown_fields)]120pub struct Extensions {121 122 pub relay_chain: String,123 124 pub para_id: u32,125}126127impl Extensions {128 129 pub fn try_get(chain_spec: &dyn sc_service::ChainSpec) -> Option<&Self> {130 sc_chain_spec::get_extension(chain_spec.extensions())131 }132}133134type AccountPublic = <Signature as Verify>::Signer;135136137pub fn get_account_id_from_seed<TPublic: Public>(seed: &str) -> AccountId138where139 AccountPublic: From<<TPublic::Pair as Pair>::Public>,140{141 AccountPublic::from(get_from_seed::<TPublic>(seed)).into_account()142}143144#[cfg(not(feature = "unique-runtime"))]145macro_rules! testnet_genesis {146 (147 $runtime:path,148 $root_key:expr,149 $initial_invulnerables:expr,150 $endowed_accounts:expr,151 $id:expr152 ) => {{153 use $runtime::*;154155 RuntimeGenesisConfig {156 system: SystemConfig {157 code: WASM_BINARY158 .expect("WASM binary was not build, please build it!")159 .to_vec(),160 ..Default::default()161 },162 balances: BalancesConfig {163 balances: $endowed_accounts164 .iter()165 .cloned()166 167 .map(|k| (k, 1 << 100))168 .collect(),169 },170 sudo: SudoConfig {171 key: Some($root_key),172 },173174 vesting: VestingConfig { vesting: vec![] },175 parachain_info: ParachainInfoConfig {176 parachain_id: $id.into(),177 ..Default::default()178 },179 collator_selection: CollatorSelectionConfig {180 invulnerables: $initial_invulnerables181 .iter()182 .cloned()183 .map(|(acc, _)| acc)184 .collect(),185 },186 session: SessionConfig {187 keys: $initial_invulnerables188 .into_iter()189 .map(|(acc, aura)| {190 (191 acc.clone(), 192 acc, 193 SessionKeys { aura }, 194 )195 })196 .collect(),197 },198 evm: EVMConfig {199 accounts: BTreeMap::new(),200 ..Default::default()201 },202 ..Default::default()203 }204 }};205}206207#[cfg(feature = "unique-runtime")]208macro_rules! testnet_genesis {209 (210 $runtime:path,211 $root_key:expr,212 $initial_invulnerables:expr,213 $endowed_accounts:expr,214 $id:expr215 ) => {{216 use $runtime::*;217218 RuntimeGenesisConfig {219 system: SystemConfig {220 code: WASM_BINARY221 .expect("WASM binary was not build, please build it!")222 .to_vec(),223 ..Default::default()224 },225 balances: BalancesConfig {226 balances: $endowed_accounts227 .iter()228 .cloned()229 230 .map(|k| (k, 1 << 100))231 .collect(),232 },233 sudo: SudoConfig {234 key: Some($root_key),235 },236 vesting: VestingConfig { vesting: vec![] },237 parachain_info: ParachainInfoConfig {238 parachain_id: $id.into(),239 ..Default::default()240 },241 aura: AuraConfig {242 authorities: $initial_invulnerables243 .into_iter()244 .map(|(_, aura)| aura)245 .collect(),246 },247 evm: EVMConfig {248 accounts: BTreeMap::new(),249 ..Default::default()250 },251 ..Default::default()252 }253 }};254}255256pub fn development_config() -> DefaultChainSpec {257 let mut properties = Map::new();258 properties.insert("tokenSymbol".into(), default_runtime::TOKEN_SYMBOL.into());259 properties.insert("tokenDecimals".into(), default_runtime::DECIMALS.into());260 properties.insert(261 "ss58Format".into(),262 default_runtime::SS58Prefix::get().into(),263 );264265 DefaultChainSpec::from_genesis(266 267 format!(268 "{}{}",269 default_runtime::VERSION.spec_name.to_uppercase(),270 if cfg!(feature = "unique-runtime") {271 ""272 } else {273 " by UNIQUE"274 }275 )276 .as_str(),277 278 format!("{}_dev", default_runtime::VERSION.spec_name).as_str(),279 ChainType::Local,280 move || {281 testnet_genesis!(282 default_runtime,283 284 get_account_id_from_seed::<sr25519::Public>("Alice"),285 [286 (287 get_account_id_from_seed::<sr25519::Public>("Alice"),288 get_from_seed::<AuraId>("Alice"),289 ),290 (291 get_account_id_from_seed::<sr25519::Public>("Bob"),292 get_from_seed::<AuraId>("Bob"),293 ),294 ],295 296 vec![297 get_account_id_from_seed::<sr25519::Public>("Alice"),298 get_account_id_from_seed::<sr25519::Public>("Bob"),299 get_account_id_from_seed::<sr25519::Public>("Charlie"),300 get_account_id_from_seed::<sr25519::Public>("Dave"),301 get_account_id_from_seed::<sr25519::Public>("Eve"),302 get_account_id_from_seed::<sr25519::Public>("Ferdie"),303 get_account_id_from_seed::<sr25519::Public>("Alice//stash"),304 get_account_id_from_seed::<sr25519::Public>("Bob//stash"),305 get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),306 get_account_id_from_seed::<sr25519::Public>("Dave//stash"),307 get_account_id_from_seed::<sr25519::Public>("Eve//stash"),308 get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),309 ],310 PARA_ID311 )312 },313 314 vec![],315 316 None,317 318 None,319 None,320 321 Some(properties),322 323 Extensions {324 relay_chain: "rococo-dev".into(),325 para_id: PARA_ID,326 },327 )328}329330pub fn local_testnet_config() -> DefaultChainSpec {331 let mut properties = Map::new();332 properties.insert("tokenSymbol".into(), default_runtime::TOKEN_SYMBOL.into());333 properties.insert("tokenDecimals".into(), default_runtime::DECIMALS.into());334 properties.insert(335 "ss58Format".into(),336 default_runtime::SS58Prefix::get().into(),337 );338339 DefaultChainSpec::from_genesis(340 341 format!(342 "{}{}",343 default_runtime::VERSION.impl_name.to_uppercase(),344 if cfg!(feature = "unique-runtime") {345 ""346 } else {347 " by UNIQUE"348 }349 )350 .as_str(),351 352 format!("{}_local", default_runtime::VERSION.spec_name).as_str(),353 ChainType::Local,354 move || {355 testnet_genesis!(356 default_runtime,357 358 get_account_id_from_seed::<sr25519::Public>("Alice"),359 [360 (361 get_account_id_from_seed::<sr25519::Public>("Alice"),362 get_from_seed::<AuraId>("Alice"),363 ),364 (365 get_account_id_from_seed::<sr25519::Public>("Bob"),366 get_from_seed::<AuraId>("Bob"),367 ),368 ],369 370 vec![371 get_account_id_from_seed::<sr25519::Public>("Alice"),372 get_account_id_from_seed::<sr25519::Public>("Bob"),373 get_account_id_from_seed::<sr25519::Public>("Charlie"),374 get_account_id_from_seed::<sr25519::Public>("Dave"),375 get_account_id_from_seed::<sr25519::Public>("Eve"),376 get_account_id_from_seed::<sr25519::Public>("Ferdie"),377 get_account_id_from_seed::<sr25519::Public>("Alice//stash"),378 get_account_id_from_seed::<sr25519::Public>("Bob//stash"),379 get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),380 get_account_id_from_seed::<sr25519::Public>("Dave//stash"),381 get_account_id_from_seed::<sr25519::Public>("Eve//stash"),382 get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),383 ],384 PARA_ID385 )386 },387 388 vec![],389 390 None,391 392 None,393 None,394 395 Some(properties),396 397 Extensions {398 relay_chain: "westend-local".into(),399 para_id: PARA_ID,400 },401 )402}