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 tokens: TokensConfig { balances: vec![] },171 sudo: SudoConfig {172 key: Some($root_key),173 },174175 vesting: VestingConfig { vesting: vec![] },176 parachain_info: ParachainInfoConfig {177 parachain_id: $id.into(),178 ..Default::default()179 },180 collator_selection: CollatorSelectionConfig {181 invulnerables: $initial_invulnerables182 .iter()183 .cloned()184 .map(|(acc, _)| acc)185 .collect(),186 },187 session: SessionConfig {188 keys: $initial_invulnerables189 .into_iter()190 .map(|(acc, aura)| {191 (192 acc.clone(), 193 acc, 194 SessionKeys { aura }, 195 )196 })197 .collect(),198 },199 evm: EVMConfig {200 accounts: BTreeMap::new(),201 ..Default::default()202 },203 ..Default::default()204 }205 }};206}207208#[cfg(feature = "unique-runtime")]209macro_rules! testnet_genesis {210 (211 $runtime:path,212 $root_key:expr,213 $initial_invulnerables:expr,214 $endowed_accounts:expr,215 $id:expr216 ) => {{217 use $runtime::*;218219 RuntimeGenesisConfig {220 system: SystemConfig {221 code: WASM_BINARY222 .expect("WASM binary was not build, please build it!")223 .to_vec(),224 ..Default::default()225 },226 balances: BalancesConfig {227 balances: $endowed_accounts228 .iter()229 .cloned()230 231 .map(|k| (k, 1 << 100))232 .collect(),233 },234 tokens: TokensConfig { balances: vec![] },235 sudo: SudoConfig {236 key: Some($root_key),237 },238 vesting: VestingConfig { vesting: vec![] },239 parachain_info: ParachainInfoConfig {240 parachain_id: $id.into(),241 Default::default()242 },243 aura: AuraConfig {244 authorities: $initial_invulnerables245 .into_iter()246 .map(|(_, aura)| aura)247 .collect(),248 },249 evm: EVMConfig {250 accounts: BTreeMap::new(),251 ..Default::default()252 },253 ..Default::default()254 }255 }};256}257258pub fn development_config() -> DefaultChainSpec {259 let mut properties = Map::new();260 properties.insert("tokenSymbol".into(), default_runtime::TOKEN_SYMBOL.into());261 properties.insert("tokenDecimals".into(), default_runtime::DECIMALS.into());262 properties.insert(263 "ss58Format".into(),264 default_runtime::SS58Prefix::get().into(),265 );266267 DefaultChainSpec::from_genesis(268 269 format!(270 "{}{}",271 default_runtime::VERSION.spec_name.to_uppercase(),272 if cfg!(feature = "unique-runtime") {273 ""274 } else {275 " by UNIQUE"276 }277 )278 .as_str(),279 280 format!("{}_dev", default_runtime::VERSION.spec_name).as_str(),281 ChainType::Local,282 move || {283 testnet_genesis!(284 default_runtime,285 286 get_account_id_from_seed::<sr25519::Public>("Alice"),287 [288 (289 get_account_id_from_seed::<sr25519::Public>("Alice"),290 get_from_seed::<AuraId>("Alice"),291 ),292 (293 get_account_id_from_seed::<sr25519::Public>("Bob"),294 get_from_seed::<AuraId>("Bob"),295 ),296 ],297 298 vec![299 get_account_id_from_seed::<sr25519::Public>("Alice"),300 get_account_id_from_seed::<sr25519::Public>("Bob"),301 get_account_id_from_seed::<sr25519::Public>("Charlie"),302 get_account_id_from_seed::<sr25519::Public>("Dave"),303 get_account_id_from_seed::<sr25519::Public>("Eve"),304 get_account_id_from_seed::<sr25519::Public>("Ferdie"),305 get_account_id_from_seed::<sr25519::Public>("Alice//stash"),306 get_account_id_from_seed::<sr25519::Public>("Bob//stash"),307 get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),308 get_account_id_from_seed::<sr25519::Public>("Dave//stash"),309 get_account_id_from_seed::<sr25519::Public>("Eve//stash"),310 get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),311 ],312 PARA_ID313 )314 },315 316 vec![],317 318 None,319 320 None,321 None,322 323 Some(properties),324 325 Extensions {326 relay_chain: "rococo-dev".into(),327 para_id: PARA_ID,328 },329 )330}331332pub fn local_testnet_config() -> DefaultChainSpec {333 let mut properties = Map::new();334 properties.insert("tokenSymbol".into(), default_runtime::TOKEN_SYMBOL.into());335 properties.insert("tokenDecimals".into(), default_runtime::DECIMALS.into());336 properties.insert(337 "ss58Format".into(),338 default_runtime::SS58Prefix::get().into(),339 );340341 DefaultChainSpec::from_genesis(342 343 format!(344 "{}{}",345 default_runtime::VERSION.impl_name.to_uppercase(),346 if cfg!(feature = "unique-runtime") {347 ""348 } else {349 " by UNIQUE"350 }351 )352 .as_str(),353 354 format!("{}_local", default_runtime::VERSION.spec_name).as_str(),355 ChainType::Local,356 move || {357 testnet_genesis!(358 default_runtime,359 360 get_account_id_from_seed::<sr25519::Public>("Alice"),361 [362 (363 get_account_id_from_seed::<sr25519::Public>("Alice"),364 get_from_seed::<AuraId>("Alice"),365 ),366 (367 get_account_id_from_seed::<sr25519::Public>("Bob"),368 get_from_seed::<AuraId>("Bob"),369 ),370 ],371 372 vec![373 get_account_id_from_seed::<sr25519::Public>("Alice"),374 get_account_id_from_seed::<sr25519::Public>("Bob"),375 get_account_id_from_seed::<sr25519::Public>("Charlie"),376 get_account_id_from_seed::<sr25519::Public>("Dave"),377 get_account_id_from_seed::<sr25519::Public>("Eve"),378 get_account_id_from_seed::<sr25519::Public>("Ferdie"),379 get_account_id_from_seed::<sr25519::Public>("Alice//stash"),380 get_account_id_from_seed::<sr25519::Public>("Bob//stash"),381 get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),382 get_account_id_from_seed::<sr25519::Public>("Dave//stash"),383 get_account_id_from_seed::<sr25519::Public>("Eve//stash"),384 get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),385 ],386 PARA_ID387 )388 },389 390 vec![],391 392 None,393 394 None,395 None,396 397 Some(properties),398 399 Extensions {400 relay_chain: "westend-local".into(),401 para_id: PARA_ID,402 },403 )404}