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 tokens: TokensConfig { balances: vec![] },234 sudo: SudoConfig {235 key: Some($root_key),236 },237 vesting: VestingConfig { vesting: vec![] },238 parachain_info: ParachainInfoConfig {239 parachain_id: $id.into(),240 ..Default::default()241 },242 aura: AuraConfig {243 authorities: $initial_invulnerables244 .into_iter()245 .map(|(_, aura)| aura)246 .collect(),247 },248 evm: EVMConfig {249 accounts: BTreeMap::new(),250 ..Default::default()251 },252 ..Default::default()253 }254 }};255}256257pub fn development_config() -> DefaultChainSpec {258 let mut properties = Map::new();259 properties.insert("tokenSymbol".into(), default_runtime::TOKEN_SYMBOL.into());260 properties.insert("tokenDecimals".into(), default_runtime::DECIMALS.into());261 properties.insert(262 "ss58Format".into(),263 default_runtime::SS58Prefix::get().into(),264 );265266 DefaultChainSpec::from_genesis(267 268 format!(269 "{}{}",270 default_runtime::VERSION.spec_name.to_uppercase(),271 if cfg!(feature = "unique-runtime") {272 ""273 } else {274 " by UNIQUE"275 }276 )277 .as_str(),278 279 format!("{}_dev", default_runtime::VERSION.spec_name).as_str(),280 ChainType::Local,281 move || {282 testnet_genesis!(283 default_runtime,284 285 get_account_id_from_seed::<sr25519::Public>("Alice"),286 [287 (288 get_account_id_from_seed::<sr25519::Public>("Alice"),289 get_from_seed::<AuraId>("Alice"),290 ),291 (292 get_account_id_from_seed::<sr25519::Public>("Bob"),293 get_from_seed::<AuraId>("Bob"),294 ),295 ],296 297 vec![298 get_account_id_from_seed::<sr25519::Public>("Alice"),299 get_account_id_from_seed::<sr25519::Public>("Bob"),300 get_account_id_from_seed::<sr25519::Public>("Charlie"),301 get_account_id_from_seed::<sr25519::Public>("Dave"),302 get_account_id_from_seed::<sr25519::Public>("Eve"),303 get_account_id_from_seed::<sr25519::Public>("Ferdie"),304 get_account_id_from_seed::<sr25519::Public>("Alice//stash"),305 get_account_id_from_seed::<sr25519::Public>("Bob//stash"),306 get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),307 get_account_id_from_seed::<sr25519::Public>("Dave//stash"),308 get_account_id_from_seed::<sr25519::Public>("Eve//stash"),309 get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),310 ],311 PARA_ID312 )313 },314 315 vec![],316 317 None,318 319 None,320 None,321 322 Some(properties),323 324 Extensions {325 relay_chain: "rococo-dev".into(),326 para_id: PARA_ID,327 },328 )329}330331pub fn local_testnet_config() -> DefaultChainSpec {332 let mut properties = Map::new();333 properties.insert("tokenSymbol".into(), default_runtime::TOKEN_SYMBOL.into());334 properties.insert("tokenDecimals".into(), default_runtime::DECIMALS.into());335 properties.insert(336 "ss58Format".into(),337 default_runtime::SS58Prefix::get().into(),338 );339340 DefaultChainSpec::from_genesis(341 342 format!(343 "{}{}",344 default_runtime::VERSION.impl_name.to_uppercase(),345 if cfg!(feature = "unique-runtime") {346 ""347 } else {348 " by UNIQUE"349 }350 )351 .as_str(),352 353 format!("{}_local", default_runtime::VERSION.spec_name).as_str(),354 ChainType::Local,355 move || {356 testnet_genesis!(357 default_runtime,358 359 get_account_id_from_seed::<sr25519::Public>("Alice"),360 [361 (362 get_account_id_from_seed::<sr25519::Public>("Alice"),363 get_from_seed::<AuraId>("Alice"),364 ),365 (366 get_account_id_from_seed::<sr25519::Public>("Bob"),367 get_from_seed::<AuraId>("Bob"),368 ),369 ],370 371 vec![372 get_account_id_from_seed::<sr25519::Public>("Alice"),373 get_account_id_from_seed::<sr25519::Public>("Bob"),374 get_account_id_from_seed::<sr25519::Public>("Charlie"),375 get_account_id_from_seed::<sr25519::Public>("Dave"),376 get_account_id_from_seed::<sr25519::Public>("Eve"),377 get_account_id_from_seed::<sr25519::Public>("Ferdie"),378 get_account_id_from_seed::<sr25519::Public>("Alice//stash"),379 get_account_id_from_seed::<sr25519::Public>("Bob//stash"),380 get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),381 get_account_id_from_seed::<sr25519::Public>("Dave//stash"),382 get_account_id_from_seed::<sr25519::Public>("Eve//stash"),383 get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),384 ],385 PARA_ID386 )387 },388 389 vec![],390 391 None,392 393 None,394 None,395 396 Some(properties),397 398 Extensions {399 relay_chain: "westend-local".into(),400 para_id: PARA_ID,401 },402 )403}