1234567891011121314151617use sc_chain_spec::{ChainSpecExtension, ChainSpecGroup};18use sc_service::ChainType;19use sp_core::{sr25519, Pair, Public};20use sp_runtime::traits::{IdentifyAccount, Verify};21use std::collections::BTreeMap;2223use serde::{Deserialize, Serialize};24use serde_json::map::Map;2526use up_common::types::opaque::*;2728#[cfg(feature = "unique-runtime")]29pub use unique_runtime as default_runtime;3031#[cfg(all(not(feature = "unique-runtime"), feature = "quartz-runtime"))]32pub use quartz_runtime as default_runtime;3334#[cfg(all(not(feature = "unique-runtime"), not(feature = "quartz-runtime")))]35pub use opal_runtime as default_runtime;363738#[cfg(feature = "unique-runtime")]39pub type UniqueChainSpec = sc_service::GenericChainSpec<unique_runtime::GenesisConfig, Extensions>;404142#[cfg(feature = "quartz-runtime")]43pub type QuartzChainSpec = sc_service::GenericChainSpec<quartz_runtime::GenesisConfig, Extensions>;444546pub type OpalChainSpec = sc_service::GenericChainSpec<opal_runtime::GenesisConfig, Extensions>;4748#[cfg(feature = "unique-runtime")]49pub type DefaultChainSpec = UniqueChainSpec;5051#[cfg(all(not(feature = "unique-runtime"), feature = "quartz-runtime"))]52pub type DefaultChainSpec = QuartzChainSpec;5354#[cfg(all(not(feature = "unique-runtime"), not(feature = "quartz-runtime")))]55pub type DefaultChainSpec = OpalChainSpec;5657#[cfg(not(feature = "unique-runtime"))]5859const PARA_ID: u32 = 2095;6061#[cfg(feature = "unique-runtime")]6263const PARA_ID: u32 = 2037;6465pub trait RuntimeIdentification {66 fn runtime_id(&self) -> RuntimeId;67}6869impl RuntimeIdentification for Box<dyn sc_service::ChainSpec> {70 fn runtime_id(&self) -> RuntimeId {71 #[cfg(feature = "unique-runtime")]72 if self.id().starts_with("unique") || self.id().starts_with("unq") {73 return RuntimeId::Unique;74 }7576 #[cfg(feature = "quartz-runtime")]77 if self.id().starts_with("quartz")78 || self.id().starts_with("qtz")79 || self.id().starts_with("sapphire")80 {81 return RuntimeId::Quartz;82 }8384 if self.id().starts_with("opal") || self.id() == "dev" || self.id() == "local_testnet" {85 return RuntimeId::Opal;86 }8788 RuntimeId::Unknown(self.id().into())89 }90}9192pub enum ServiceId {93 Prod,94 Dev,95}9697pub trait ServiceIdentification {98 fn service_id(&self) -> ServiceId;99}100101impl ServiceIdentification for Box<dyn sc_service::ChainSpec> {102 fn service_id(&self) -> ServiceId {103 if self.id().ends_with("dev") {104 ServiceId::Dev105 } else {106 ServiceId::Prod107 }108 }109}110111112pub fn get_from_seed<TPublic: Public>(seed: &str) -> <TPublic::Pair as Pair>::Public {113 TPublic::Pair::from_string(&format!("//{seed}"), None)114 .expect("static values are valid; qed")115 .public()116}117118119#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, ChainSpecGroup, ChainSpecExtension)]120#[serde(deny_unknown_fields)]121pub struct Extensions {122 123 pub relay_chain: String,124 125 pub para_id: u32,126}127128impl Extensions {129 130 pub fn try_get(chain_spec: &dyn sc_service::ChainSpec) -> Option<&Self> {131 sc_chain_spec::get_extension(chain_spec.extensions())132 }133}134135type AccountPublic = <Signature as Verify>::Signer;136137138pub fn get_account_id_from_seed<TPublic: Public>(seed: &str) -> AccountId139where140 AccountPublic: From<<TPublic::Pair as Pair>::Public>,141{142 AccountPublic::from(get_from_seed::<TPublic>(seed)).into_account()143}144145#[cfg(not(feature = "unique-runtime"))]146macro_rules! testnet_genesis {147 (148 $runtime:path,149 $root_key:expr,150 $initial_invulnerables:expr,151 $endowed_accounts:expr,152 $id:expr153 ) => {{154 use $runtime::*;155156 GenesisConfig {157 system: SystemConfig {158 code: WASM_BINARY159 .expect("WASM binary was not build, please build it!")160 .to_vec(),161 },162 balances: BalancesConfig {163 balances: $endowed_accounts164 .iter()165 .cloned()166 167 .map(|k| (k, 1 << 100))168 .collect(),169 },170 common: Default::default(),171 configuration: Default::default(),172 nonfungible: Default::default(),173 treasury: Default::default(),174 tokens: TokensConfig { balances: vec![] },175 sudo: SudoConfig {176 key: Some($root_key),177 },178 vesting: VestingConfig { vesting: vec![] },179 parachain_info: ParachainInfoConfig {180 parachain_id: $id.into(),181 },182 parachain_system: Default::default(),183 collator_selection: CollatorSelectionConfig {184 invulnerables: $initial_invulnerables185 .iter()186 .cloned()187 .map(|(acc, _)| acc)188 .collect(),189 },190 session: SessionConfig {191 keys: $initial_invulnerables192 .into_iter()193 .map(|(acc, aura)| {194 (195 acc.clone(), 196 acc, 197 SessionKeys { aura }, 198 )199 })200 .collect(),201 },202 aura: Default::default(),203 aura_ext: Default::default(),204 evm: EVMConfig {205 accounts: BTreeMap::new(),206 },207 ethereum: EthereumConfig {},208 polkadot_xcm: Default::default(),209 transaction_payment: Default::default(),210 }211 }};212}213214#[cfg(feature = "unique-runtime")]215macro_rules! testnet_genesis {216 (217 $runtime:path,218 $root_key:expr,219 $initial_invulnerables:expr,220 $endowed_accounts:expr,221 $id:expr222 ) => {{223 use $runtime::*;224225 GenesisConfig {226 system: SystemConfig {227 code: WASM_BINARY228 .expect("WASM binary was not build, please build it!")229 .to_vec(),230 },231 common: Default::default(),232 configuration: Default::default(),233 nonfungible: Default::default(),234 balances: BalancesConfig {235 balances: $endowed_accounts236 .iter()237 .cloned()238 239 .map(|k| (k, 1 << 100))240 .collect(),241 },242 treasury: Default::default(),243 tokens: TokensConfig { balances: vec![] },244 sudo: SudoConfig {245 key: Some($root_key),246 },247 vesting: VestingConfig { vesting: vec![] },248 parachain_info: ParachainInfoConfig {249 parachain_id: $id.into(),250 },251 parachain_system: Default::default(),252 aura: AuraConfig {253 authorities: $initial_invulnerables254 .into_iter()255 .map(|(_, aura)| aura)256 .collect(),257 },258 aura_ext: Default::default(),259 evm: EVMConfig {260 accounts: BTreeMap::new(),261 },262 ethereum: EthereumConfig {},263 polkadot_xcm: Default::default(),264 transaction_payment: Default::default(),265 }266 }};267}268269pub fn development_config() -> DefaultChainSpec {270 let mut properties = Map::new();271 properties.insert("tokenSymbol".into(), default_runtime::TOKEN_SYMBOL.into());272 properties.insert("tokenDecimals".into(), default_runtime::DECIMALS.into());273 properties.insert(274 "ss58Format".into(),275 default_runtime::SS58Prefix::get().into(),276 );277278 DefaultChainSpec::from_genesis(279 280 format!(281 "{}{}",282 default_runtime::RUNTIME_NAME.to_uppercase(),283 if cfg!(feature = "unique-runtime") {284 ""285 } else {286 " by UNIQUE"287 }288 )289 .as_str(),290 291 format!("{}_dev", default_runtime::RUNTIME_NAME).as_str(),292 ChainType::Local,293 move || {294 testnet_genesis!(295 default_runtime,296 297 get_account_id_from_seed::<sr25519::Public>("Alice"),298 vec![299 (300 get_account_id_from_seed::<sr25519::Public>("Alice"),301 get_from_seed::<AuraId>("Alice"),302 ),303 (304 get_account_id_from_seed::<sr25519::Public>("Bob"),305 get_from_seed::<AuraId>("Bob"),306 ),307 ],308 309 vec![310 get_account_id_from_seed::<sr25519::Public>("Alice"),311 get_account_id_from_seed::<sr25519::Public>("Bob"),312 get_account_id_from_seed::<sr25519::Public>("Charlie"),313 get_account_id_from_seed::<sr25519::Public>("Dave"),314 get_account_id_from_seed::<sr25519::Public>("Eve"),315 get_account_id_from_seed::<sr25519::Public>("Ferdie"),316 get_account_id_from_seed::<sr25519::Public>("Alice//stash"),317 get_account_id_from_seed::<sr25519::Public>("Bob//stash"),318 get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),319 get_account_id_from_seed::<sr25519::Public>("Dave//stash"),320 get_account_id_from_seed::<sr25519::Public>("Eve//stash"),321 get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),322 ],323 PARA_ID324 )325 },326 327 vec![],328 329 None,330 331 None,332 None,333 334 Some(properties),335 336 Extensions {337 relay_chain: "rococo-dev".into(),338 para_id: PARA_ID,339 },340 )341}342343pub fn local_testnet_config() -> DefaultChainSpec {344 let mut properties = Map::new();345 properties.insert("tokenSymbol".into(), default_runtime::TOKEN_SYMBOL.into());346 properties.insert("tokenDecimals".into(), default_runtime::DECIMALS.into());347 properties.insert(348 "ss58Format".into(),349 default_runtime::SS58Prefix::get().into(),350 );351352 DefaultChainSpec::from_genesis(353 354 format!(355 "{}{}",356 default_runtime::RUNTIME_NAME.to_uppercase(),357 if cfg!(feature = "unique-runtime") {358 ""359 } else {360 " by UNIQUE"361 }362 )363 .as_str(),364 365 format!("{}_local", default_runtime::RUNTIME_NAME).as_str(),366 ChainType::Local,367 move || {368 testnet_genesis!(369 default_runtime,370 371 get_account_id_from_seed::<sr25519::Public>("Alice"),372 vec![373 (374 get_account_id_from_seed::<sr25519::Public>("Alice"),375 get_from_seed::<AuraId>("Alice"),376 ),377 (378 get_account_id_from_seed::<sr25519::Public>("Bob"),379 get_from_seed::<AuraId>("Bob"),380 ),381 ],382 383 vec![384 get_account_id_from_seed::<sr25519::Public>("Alice"),385 get_account_id_from_seed::<sr25519::Public>("Bob"),386 get_account_id_from_seed::<sr25519::Public>("Charlie"),387 get_account_id_from_seed::<sr25519::Public>("Dave"),388 get_account_id_from_seed::<sr25519::Public>("Eve"),389 get_account_id_from_seed::<sr25519::Public>("Ferdie"),390 get_account_id_from_seed::<sr25519::Public>("Alice//stash"),391 get_account_id_from_seed::<sr25519::Public>("Bob//stash"),392 get_account_id_from_seed::<sr25519::Public>("Charlie//stash"),393 get_account_id_from_seed::<sr25519::Public>("Dave//stash"),394 get_account_id_from_seed::<sr25519::Public>("Eve//stash"),395 get_account_id_from_seed::<sr25519::Public>("Ferdie//stash"),396 ],397 PARA_ID398 )399 },400 401 vec![],402 403 None,404 405 None,406 None,407 408 Some(properties),409 410 Extensions {411 relay_chain: "westend-local".into(),412 para_id: PARA_ID,413 },414 )415}