From bde1629f86985c36449d2c47e52663e68327b512 Mon Sep 17 00:00:00 2001
From: Serban Iorga <serban@parity.io>
Date: Wed, 14 Dec 2022 12:29:09 +0200
Subject: [PATCH] Remove SOURCE_PARACHAIN_PARA_ID (#1716)

* Remove SOURCE_PARACHAIN_PARA_ID

Remove SubstrateParachainsPipeline::SOURCE_PARACHAIN_PARA_ID

* Avoid duplicate ChainBase and ParachainBase implementations

* Replace ChainShadow with UnderlyingChainProvider
---
 bridges/bin/runtime-common/src/messages.rs    |  9 +---
 bridges/primitives/runtime/src/chain.rs       | 39 +++++++++++++++
 bridges/primitives/runtime/src/lib.rs         |  3 +-
 .../src/chains/rialto_parachains_to_millau.rs |  2 -
 .../rococo_parachains_to_bridge_hub_wococo.rs |  2 -
 .../chains/westend_parachains_to_millau.rs    |  2 -
 .../wococo_parachains_to_bridge_hub_rococo.rs |  2 -
 .../relays/bin-substrate/src/cli/bridge.rs    |  9 +++-
 .../src/cli/relay_headers_and_messages/mod.rs |  1 +
 .../parachain_to_parachain.rs                 | 21 ++++++---
 .../relay_to_parachain.rs                     | 13 +++--
 .../bin-substrate/src/cli/relay_parachains.rs | 10 +++-
 .../client-bridge-hub-rococo/src/lib.rs       | 26 ++--------
 .../client-bridge-hub-wococo/src/lib.rs       | 26 ++--------
 bridges/relays/client-kusama/src/lib.rs       | 23 ++-------
 bridges/relays/client-millau/src/lib.rs       | 26 ++--------
 bridges/relays/client-polkadot/src/lib.rs     | 23 ++-------
 .../relays/client-rialto-parachain/src/lib.rs | 25 ++--------
 bridges/relays/client-rialto/src/lib.rs       | 25 ++--------
 bridges/relays/client-rococo/src/lib.rs       | 25 ++--------
 bridges/relays/client-substrate/src/chain.rs  |  8 +++-
 bridges/relays/client-substrate/src/lib.rs    |  7 +--
 bridges/relays/client-westend/src/lib.rs      | 47 +++----------------
 bridges/relays/client-wococo/src/lib.rs       | 25 ++--------
 .../src/on_demand/parachains.rs               | 10 ++--
 .../lib-substrate-relay/src/parachains/mod.rs |  9 ++--
 .../src/parachains/source.rs                  |  8 ++--
 27 files changed, 154 insertions(+), 272 deletions(-)

diff --git a/bridges/bin/runtime-common/src/messages.rs b/bridges/bin/runtime-common/src/messages.rs
index a0a75692ba0..ca48a6015f1 100644
--- a/bridges/bin/runtime-common/src/messages.rs
+++ b/bridges/bin/runtime-common/src/messages.rs
@@ -27,6 +27,7 @@ use bp_messages::{
 	InboundLaneData, LaneId, Message, MessageKey, MessageNonce, MessagePayload, OutboundLaneData,
 };
 use bp_runtime::{messages::MessageDispatchResult, Chain, ChainId, Size, StorageProofChecker};
+pub use bp_runtime::{UnderlyingChainOf, UnderlyingChainProvider};
 use codec::{Decode, DecodeLimit, Encode};
 use frame_support::{traits::Get, weights::Weight, RuntimeDebug};
 use hash_db::Hasher;
@@ -54,12 +55,6 @@ pub trait MessageBridge {
 	type BridgedHeaderChain: HeaderChain<UnderlyingChainOf<Self::BridgedChain>>;
 }
 
-/// A trait that provides the type of the underlying chain.
-pub trait UnderlyingChainProvider {
-	/// Underlying chain type.
-	type Chain: Chain;
-}
-
 /// This chain that has `pallet-bridge-messages` module.
 pub trait ThisChainWithMessages: UnderlyingChainProvider {
 	/// Call origin on the chain.
@@ -87,8 +82,6 @@ pub trait BridgedChainWithMessages: UnderlyingChainProvider {
 pub type ThisChain<B> = <B as MessageBridge>::ThisChain;
 /// Bridged chain in context of message bridge.
 pub type BridgedChain<B> = <B as MessageBridge>::BridgedChain;
-/// Underlying chain type.
-pub type UnderlyingChainOf<C> = <C as UnderlyingChainProvider>::Chain;
 /// Hash used on the chain.
 pub type HashOf<C> = bp_runtime::HashOf<<C as UnderlyingChainProvider>::Chain>;
 /// Hasher used on the chain.
diff --git a/bridges/primitives/runtime/src/chain.rs b/bridges/primitives/runtime/src/chain.rs
index 78e63be405b..f5771e9fdd5 100644
--- a/bridges/primitives/runtime/src/chain.rs
+++ b/bridges/primitives/runtime/src/chain.rs
@@ -192,12 +192,51 @@ pub trait Chain: Send + Sync + 'static {
 	fn max_extrinsic_weight() -> Weight;
 }
 
+/// A trait that provides the type of the underlying chain.
+pub trait UnderlyingChainProvider {
+	/// Underlying chain type.
+	type Chain: Chain;
+}
+
+impl<T> Chain for T
+where
+	T: Send + Sync + 'static + UnderlyingChainProvider,
+{
+	type BlockNumber = <T::Chain as Chain>::BlockNumber;
+	type Hash = <T::Chain as Chain>::Hash;
+	type Hasher = <T::Chain as Chain>::Hasher;
+	type Header = <T::Chain as Chain>::Header;
+	type AccountId = <T::Chain as Chain>::AccountId;
+	type Balance = <T::Chain as Chain>::Balance;
+	type Index = <T::Chain as Chain>::Index;
+	type Signature = <T::Chain as Chain>::Signature;
+
+	fn max_extrinsic_size() -> u32 {
+		<T::Chain as Chain>::max_extrinsic_size()
+	}
+
+	fn max_extrinsic_weight() -> Weight {
+		<T::Chain as Chain>::max_extrinsic_weight()
+	}
+}
+
 /// Minimal parachain representation that may be used from no_std environment.
 pub trait Parachain: Chain {
 	/// Parachain identifier.
 	const PARACHAIN_ID: u32;
 }
 
+impl<T> Parachain for T
+where
+	T: Chain + UnderlyingChainProvider,
+	<T as UnderlyingChainProvider>::Chain: Parachain,
+{
+	const PARACHAIN_ID: u32 = <<T as UnderlyingChainProvider>::Chain as Parachain>::PARACHAIN_ID;
+}
+
+/// Underlying chain type.
+pub type UnderlyingChainOf<C> = <C as UnderlyingChainProvider>::Chain;
+
 /// Block number used by the chain.
 pub type BlockNumberOf<C> = <C as Chain>::BlockNumber;
 
diff --git a/bridges/primitives/runtime/src/lib.rs b/bridges/primitives/runtime/src/lib.rs
index 5db54b87f7f..340088a85b1 100644
--- a/bridges/primitives/runtime/src/lib.rs
+++ b/bridges/primitives/runtime/src/lib.rs
@@ -32,7 +32,8 @@ use sp_std::{convert::TryFrom, fmt::Debug, vec, vec::Vec};
 
 pub use chain::{
 	AccountIdOf, AccountPublicOf, BalanceOf, BlockNumberOf, Chain, EncodedOrDecodedCall, HashOf,
-	HasherOf, HeaderOf, IndexOf, Parachain, SignatureOf, TransactionEraOf,
+	HasherOf, HeaderOf, IndexOf, Parachain, SignatureOf, TransactionEraOf, UnderlyingChainOf,
+	UnderlyingChainProvider,
 };
 pub use frame_support::storage::storage_prefix as storage_value_final_key;
 use num_traits::{CheckedSub, One};
diff --git a/bridges/relays/bin-substrate/src/chains/rialto_parachains_to_millau.rs b/bridges/relays/bin-substrate/src/chains/rialto_parachains_to_millau.rs
index d1cf853ac77..b3471ad1a38 100644
--- a/bridges/relays/bin-substrate/src/chains/rialto_parachains_to_millau.rs
+++ b/bridges/relays/bin-substrate/src/chains/rialto_parachains_to_millau.rs
@@ -40,8 +40,6 @@ impl SubstrateParachainsPipeline for RialtoParachainsToMillau {
 	type TargetChain = Millau;
 
 	type SubmitParachainHeadsCallBuilder = RialtoParachainsToMillauSubmitParachainHeadsCallBuilder;
-
-	const SOURCE_PARACHAIN_PARA_ID: u32 = bp_rialto_parachain::RIALTO_PARACHAIN_ID;
 }
 
 /// `submit_parachain_heads` call builder for Rialto-to-Millau parachains sync pipeline.
diff --git a/bridges/relays/bin-substrate/src/chains/rococo_parachains_to_bridge_hub_wococo.rs b/bridges/relays/bin-substrate/src/chains/rococo_parachains_to_bridge_hub_wococo.rs
index 23e87194c91..b028253d8a4 100644
--- a/bridges/relays/bin-substrate/src/chains/rococo_parachains_to_bridge_hub_wococo.rs
+++ b/bridges/relays/bin-substrate/src/chains/rococo_parachains_to_bridge_hub_wococo.rs
@@ -39,8 +39,6 @@ impl SubstrateParachainsPipeline for BridgeHubRococoToBridgeHubWococo {
 	type TargetChain = relay_bridge_hub_wococo_client::BridgeHubWococo;
 
 	type SubmitParachainHeadsCallBuilder = BridgeHubRococoToBridgeHubWococoCallBuilder;
-
-	const SOURCE_PARACHAIN_PARA_ID: u32 = bp_bridge_hub_rococo::BRIDGE_HUB_ROCOCO_PARACHAIN_ID;
 }
 
 pub struct BridgeHubRococoToBridgeHubWococoCallBuilder;
diff --git a/bridges/relays/bin-substrate/src/chains/westend_parachains_to_millau.rs b/bridges/relays/bin-substrate/src/chains/westend_parachains_to_millau.rs
index 73409e65569..f025f48dcb6 100644
--- a/bridges/relays/bin-substrate/src/chains/westend_parachains_to_millau.rs
+++ b/bridges/relays/bin-substrate/src/chains/westend_parachains_to_millau.rs
@@ -39,8 +39,6 @@ impl SubstrateParachainsPipeline for WestendParachainsToMillau {
 	type TargetChain = Millau;
 
 	type SubmitParachainHeadsCallBuilder = WestendParachainsToMillauSubmitParachainHeadsCallBuilder;
-
-	const SOURCE_PARACHAIN_PARA_ID: u32 = bp_westend::WESTMINT_PARACHAIN_ID;
 }
 
 /// `submit_parachain_heads` call builder for Rialto-to-Millau parachains sync pipeline.
diff --git a/bridges/relays/bin-substrate/src/chains/wococo_parachains_to_bridge_hub_rococo.rs b/bridges/relays/bin-substrate/src/chains/wococo_parachains_to_bridge_hub_rococo.rs
index caaeab56655..f821af1a0cf 100644
--- a/bridges/relays/bin-substrate/src/chains/wococo_parachains_to_bridge_hub_rococo.rs
+++ b/bridges/relays/bin-substrate/src/chains/wococo_parachains_to_bridge_hub_rococo.rs
@@ -39,8 +39,6 @@ impl SubstrateParachainsPipeline for BridgeHubWococoToBridgeHubRococo {
 	type TargetChain = relay_bridge_hub_rococo_client::BridgeHubRococo;
 
 	type SubmitParachainHeadsCallBuilder = BridgeHubWococoToBridgeHubRococoCallBuilder;
-
-	const SOURCE_PARACHAIN_PARA_ID: u32 = bp_bridge_hub_wococo::BRIDGE_HUB_WOCOCO_PARACHAIN_ID;
 }
 
 pub struct BridgeHubWococoToBridgeHubRococoCallBuilder;
diff --git a/bridges/relays/bin-substrate/src/cli/bridge.rs b/bridges/relays/bin-substrate/src/cli/bridge.rs
index c1923f89a84..0f0c11f3909 100644
--- a/bridges/relays/bin-substrate/src/cli/bridge.rs
+++ b/bridges/relays/bin-substrate/src/cli/bridge.rs
@@ -17,7 +17,9 @@
 use crate::cli::CliChain;
 use pallet_bridge_parachains::{RelayBlockHash, RelayBlockHasher, RelayBlockNumber};
 use parachains_relay::ParachainsPipeline;
-use relay_substrate_client::{AccountKeyPairOf, Chain, ChainWithTransactions, RelayChain};
+use relay_substrate_client::{
+	AccountKeyPairOf, Chain, ChainWithTransactions, Parachain, RelayChain,
+};
 use strum::{EnumString, EnumVariantNames};
 use substrate_relay_helper::{
 	finality::SubstrateFinalitySyncPipeline, messages_lane::SubstrateMessageLane,
@@ -76,7 +78,10 @@ pub trait RelayToRelayHeadersCliBridge: CliBridgeBase {
 
 /// Bridge representation that can be used from the CLI for relaying headers
 /// from a parachain to a relay chain.
-pub trait ParachainToRelayHeadersCliBridge: CliBridgeBase {
+pub trait ParachainToRelayHeadersCliBridge: CliBridgeBase
+where
+	Self::Source: Parachain,
+{
 	// The `CliBridgeBase` type represents the parachain in this situation.
 	// We need to add an extra type for the relay chain.
 	type SourceRelay: Chain<BlockNumber = RelayBlockNumber, Hash = RelayBlockHash, Hasher = RelayBlockHasher>
diff --git a/bridges/relays/bin-substrate/src/cli/relay_headers_and_messages/mod.rs b/bridges/relays/bin-substrate/src/cli/relay_headers_and_messages/mod.rs
index f84174563e1..11cae48d1d9 100644
--- a/bridges/relays/bin-substrate/src/cli/relay_headers_and_messages/mod.rs
+++ b/bridges/relays/bin-substrate/src/cli/relay_headers_and_messages/mod.rs
@@ -62,6 +62,7 @@ use bp_messages::LaneId;
 use bp_runtime::{BalanceOf, BlockNumberOf};
 use relay_substrate_client::{
 	AccountIdOf, AccountKeyPairOf, Chain, ChainWithBalances, ChainWithTransactions, Client,
+	Parachain,
 };
 use relay_utils::metrics::MetricsParams;
 use sp_core::Pair;
diff --git a/bridges/relays/bin-substrate/src/cli/relay_headers_and_messages/parachain_to_parachain.rs b/bridges/relays/bin-substrate/src/cli/relay_headers_and_messages/parachain_to_parachain.rs
index 4ac3a08aeff..eedebe93c33 100644
--- a/bridges/relays/bin-substrate/src/cli/relay_headers_and_messages/parachain_to_parachain.rs
+++ b/bridges/relays/bin-substrate/src/cli/relay_headers_and_messages/parachain_to_parachain.rs
@@ -25,7 +25,9 @@ use crate::cli::{
 use bp_polkadot_core::parachains::ParaHash;
 use bp_runtime::BlockNumberOf;
 use pallet_bridge_parachains::{RelayBlockHash, RelayBlockHasher, RelayBlockNumber};
-use relay_substrate_client::{AccountIdOf, AccountKeyPairOf, Chain, ChainWithTransactions, Client};
+use relay_substrate_client::{
+	AccountIdOf, AccountKeyPairOf, Chain, ChainWithTransactions, Client, Parachain,
+};
 use sp_core::Pair;
 use substrate_relay_helper::{
 	finality::SubstrateFinalitySyncPipeline,
@@ -42,7 +44,10 @@ use substrate_relay_helper::{
 pub struct ParachainToParachainBridge<
 	L2R: MessagesCliBridge + ParachainToRelayHeadersCliBridge,
 	R2L: MessagesCliBridge + ParachainToRelayHeadersCliBridge,
-> {
+> where
+	<L2R as CliBridgeBase>::Source: Parachain,
+	<R2L as CliBridgeBase>::Source: Parachain,
+{
 	/// Parameters that are shared by all bridge types.
 	pub common:
 		Full2WayBridgeCommonParams<<R2L as CliBridgeBase>::Target, <L2R as CliBridgeBase>::Target>,
@@ -118,9 +123,9 @@ macro_rules! declare_parachain_to_parachain_bridge_schema {
 
 			impl [<$left_parachain $right_parachain HeadersAndMessages>] {
 				async fn into_bridge<
-					Left: ChainWithTransactions + CliChain<KeyPair = AccountKeyPairOf<Left>>,
+					Left: ChainWithTransactions + CliChain<KeyPair = AccountKeyPairOf<Left>> + Parachain,
 					LeftRelay: CliChain,
-					Right: ChainWithTransactions + CliChain<KeyPair = AccountKeyPairOf<Right>>,
+					Right: ChainWithTransactions + CliChain<KeyPair = AccountKeyPairOf<Right>> + Parachain,
 					RightRelay: CliChain,
 					L2R: CliBridgeBase<Source = Left, Target = Right>
 						+ MessagesCliBridge
@@ -172,10 +177,14 @@ macro_rules! declare_parachain_to_parachain_bridge_schema {
 
 #[async_trait]
 impl<
-		Left: Chain<Hash = ParaHash> + ChainWithTransactions + CliChain<KeyPair = AccountKeyPairOf<Left>>,
+		Left: Chain<Hash = ParaHash>
+			+ ChainWithTransactions
+			+ CliChain<KeyPair = AccountKeyPairOf<Left>>
+			+ Parachain,
 		Right: Chain<Hash = ParaHash>
 			+ ChainWithTransactions
-			+ CliChain<KeyPair = AccountKeyPairOf<Right>>,
+			+ CliChain<KeyPair = AccountKeyPairOf<Right>>
+			+ Parachain,
 		LeftRelay: Chain<BlockNumber = RelayBlockNumber, Hash = RelayBlockHash, Hasher = RelayBlockHasher>
 			+ CliChain,
 		RightRelay: Chain<BlockNumber = RelayBlockNumber, Hash = RelayBlockHash, Hasher = RelayBlockHasher>
diff --git a/bridges/relays/bin-substrate/src/cli/relay_headers_and_messages/relay_to_parachain.rs b/bridges/relays/bin-substrate/src/cli/relay_headers_and_messages/relay_to_parachain.rs
index 4070783df09..22324c1d6ff 100644
--- a/bridges/relays/bin-substrate/src/cli/relay_headers_and_messages/relay_to_parachain.rs
+++ b/bridges/relays/bin-substrate/src/cli/relay_headers_and_messages/relay_to_parachain.rs
@@ -28,7 +28,9 @@ use crate::cli::{
 use bp_polkadot_core::parachains::ParaHash;
 use bp_runtime::BlockNumberOf;
 use pallet_bridge_parachains::{RelayBlockHash, RelayBlockHasher, RelayBlockNumber};
-use relay_substrate_client::{AccountIdOf, AccountKeyPairOf, Chain, ChainWithTransactions, Client};
+use relay_substrate_client::{
+	AccountIdOf, AccountKeyPairOf, Chain, ChainWithTransactions, Client, Parachain,
+};
 use sp_core::Pair;
 use substrate_relay_helper::{
 	finality::SubstrateFinalitySyncPipeline,
@@ -45,7 +47,9 @@ use substrate_relay_helper::{
 pub struct RelayToParachainBridge<
 	L2R: MessagesCliBridge + RelayToRelayHeadersCliBridge,
 	R2L: MessagesCliBridge + ParachainToRelayHeadersCliBridge,
-> {
+> where
+	<R2L as CliBridgeBase>::Source: Parachain,
+{
 	/// Parameters that are shared by all bridge types.
 	pub common:
 		Full2WayBridgeCommonParams<<R2L as CliBridgeBase>::Target, <L2R as CliBridgeBase>::Target>,
@@ -112,7 +116,7 @@ macro_rules! declare_relay_to_parachain_bridge_schema {
 			impl [<$left_chain $right_parachain HeadersAndMessages>] {
 				async fn into_bridge<
 					Left: ChainWithTransactions + CliChain<KeyPair = AccountKeyPairOf<Left>>,
-					Right: ChainWithTransactions + CliChain<KeyPair = AccountKeyPairOf<Right>>,
+					Right: ChainWithTransactions + CliChain<KeyPair = AccountKeyPairOf<Right>> + Parachain,
 					RightRelay: CliChain,
 					L2R: CliBridgeBase<Source = Left, Target = Right> + MessagesCliBridge + RelayToRelayHeadersCliBridge,
 					R2L: CliBridgeBase<Source = Right, Target = Left>
@@ -165,7 +169,8 @@ impl<
 		Left: ChainWithTransactions + CliChain<KeyPair = AccountKeyPairOf<Left>>,
 		Right: Chain<Hash = ParaHash>
 			+ ChainWithTransactions
-			+ CliChain<KeyPair = AccountKeyPairOf<Right>>,
+			+ CliChain<KeyPair = AccountKeyPairOf<Right>>
+			+ Parachain,
 		RightRelay: Chain<BlockNumber = RelayBlockNumber, Hash = RelayBlockHash, Hasher = RelayBlockHasher>
 			+ CliChain,
 		L2R: CliBridgeBase<Source = Left, Target = Right>
diff --git a/bridges/relays/bin-substrate/src/cli/relay_parachains.rs b/bridges/relays/bin-substrate/src/cli/relay_parachains.rs
index 286cecc914b..1a0bba3fd1f 100644
--- a/bridges/relays/bin-substrate/src/cli/relay_parachains.rs
+++ b/bridges/relays/bin-substrate/src/cli/relay_parachains.rs
@@ -26,6 +26,7 @@ use bp_polkadot_core::parachains::ParaId;
 use parachains_relay::parachains_loop::{
 	AvailableHeader, ParachainSyncParams, SourceClient, TargetClient,
 };
+use relay_substrate_client::{Parachain, ParachainBase};
 use relay_utils::metrics::{GlobalMetrics, StandaloneMetric};
 use std::sync::Arc;
 use structopt::StructOpt;
@@ -38,7 +39,11 @@ use substrate_relay_helper::{
 	TransactionParams,
 };
 
-use crate::cli::{bridge::ParachainToRelayHeadersCliBridge, chain_schema::*, PrometheusParams};
+use crate::cli::{
+	bridge::{CliBridgeBase, ParachainToRelayHeadersCliBridge},
+	chain_schema::*,
+	PrometheusParams,
+};
 
 /// Start parachain heads relayer process.
 #[derive(StructOpt)]
@@ -74,6 +79,7 @@ where
 		SourceClient<ParachainsPipelineAdapter<Self::ParachainFinality>>,
 	ParachainsTarget<Self::ParachainFinality>:
 		TargetClient<ParachainsPipelineAdapter<Self::ParachainFinality>>,
+	<Self as CliBridgeBase>::Source: Parachain,
 {
 	async fn relay_headers(data: RelayParachains) -> anyhow::Result<()> {
 		let source_client = data.source.into_client::<Self::SourceRelay>().await?;
@@ -100,7 +106,7 @@ where
 			target_client,
 			ParachainSyncParams {
 				parachains: vec![
-					ParaId(<Self::ParachainFinality as SubstrateParachainsPipeline>::SOURCE_PARACHAIN_PARA_ID)
+					ParaId(<Self::ParachainFinality as SubstrateParachainsPipeline>::SourceParachain::PARACHAIN_ID)
 				],
 				stall_timeout: std::time::Duration::from_secs(60),
 				strategy: parachains_relay::parachains_loop::ParachainSyncStrategy::Any,
diff --git a/bridges/relays/client-bridge-hub-rococo/src/lib.rs b/bridges/relays/client-bridge-hub-rococo/src/lib.rs
index 3863d1c2932..7e9047e32ce 100644
--- a/bridges/relays/client-bridge-hub-rococo/src/lib.rs
+++ b/bridges/relays/client-bridge-hub-rococo/src/lib.rs
@@ -16,11 +16,11 @@
 
 //! Types used to connect to the BridgeHub-Rococo-Substrate parachain.
 
-use bp_messages::{MessageNonce, Weight};
+use bp_messages::MessageNonce;
 use codec::Encode;
 use relay_substrate_client::{
-	Chain, ChainBase, ChainWithBalances, ChainWithMessages, ChainWithTransactions,
-	Error as SubstrateError, SignParam, UnsignedTransaction,
+	Chain, ChainWithBalances, ChainWithMessages, ChainWithTransactions, Error as SubstrateError,
+	SignParam, UnderlyingChainProvider, UnsignedTransaction,
 };
 use sp_core::{storage::StorageKey, Pair};
 use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount};
@@ -34,24 +34,8 @@ pub use runtime_wrapper as runtime;
 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
 pub struct BridgeHubRococo;
 
-impl ChainBase for BridgeHubRococo {
-	type BlockNumber = bp_bridge_hub_rococo::BlockNumber;
-	type Hash = bp_bridge_hub_rococo::Hash;
-	type Hasher = bp_bridge_hub_rococo::Hashing;
-	type Header = bp_bridge_hub_rococo::Header;
-
-	type AccountId = bp_bridge_hub_rococo::AccountId;
-	type Balance = bp_bridge_hub_rococo::Balance;
-	type Index = bp_bridge_hub_rococo::Nonce;
-	type Signature = bp_bridge_hub_rococo::Signature;
-
-	fn max_extrinsic_size() -> u32 {
-		bp_bridge_hub_rococo::BridgeHubRococo::max_extrinsic_size()
-	}
-
-	fn max_extrinsic_weight() -> Weight {
-		bp_bridge_hub_rococo::BridgeHubRococo::max_extrinsic_weight()
-	}
+impl UnderlyingChainProvider for BridgeHubRococo {
+	type Chain = bp_bridge_hub_rococo::BridgeHubRococo;
 }
 
 impl Chain for BridgeHubRococo {
diff --git a/bridges/relays/client-bridge-hub-wococo/src/lib.rs b/bridges/relays/client-bridge-hub-wococo/src/lib.rs
index ceb1095b342..516f5d9fb80 100644
--- a/bridges/relays/client-bridge-hub-wococo/src/lib.rs
+++ b/bridges/relays/client-bridge-hub-wococo/src/lib.rs
@@ -16,11 +16,11 @@
 
 //! Types used to connect to the BridgeHub-Wococo-Substrate parachain.
 
-use bp_messages::{MessageNonce, Weight};
+use bp_messages::MessageNonce;
 use codec::Encode;
 use relay_substrate_client::{
-	Chain, ChainBase, ChainWithBalances, ChainWithMessages, ChainWithTransactions,
-	Error as SubstrateError, SignParam, UnsignedTransaction,
+	Chain, ChainWithBalances, ChainWithMessages, ChainWithTransactions, Error as SubstrateError,
+	SignParam, UnderlyingChainProvider, UnsignedTransaction,
 };
 use sp_core::{storage::StorageKey, Pair};
 use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount};
@@ -34,24 +34,8 @@ pub use runtime_wrapper as runtime;
 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
 pub struct BridgeHubWococo;
 
-impl ChainBase for BridgeHubWococo {
-	type BlockNumber = bp_bridge_hub_wococo::BlockNumber;
-	type Hash = bp_bridge_hub_wococo::Hash;
-	type Hasher = bp_bridge_hub_wococo::Hashing;
-	type Header = bp_bridge_hub_wococo::Header;
-
-	type AccountId = bp_bridge_hub_wococo::AccountId;
-	type Balance = bp_bridge_hub_wococo::Balance;
-	type Index = bp_bridge_hub_wococo::Nonce;
-	type Signature = bp_bridge_hub_wococo::Signature;
-
-	fn max_extrinsic_size() -> u32 {
-		bp_bridge_hub_wococo::BridgeHubWococo::max_extrinsic_size()
-	}
-
-	fn max_extrinsic_weight() -> Weight {
-		bp_bridge_hub_wococo::BridgeHubWococo::max_extrinsic_weight()
-	}
+impl UnderlyingChainProvider for BridgeHubWococo {
+	type Chain = bp_bridge_hub_wococo::BridgeHubWococo;
 }
 
 impl Chain for BridgeHubWococo {
diff --git a/bridges/relays/client-kusama/src/lib.rs b/bridges/relays/client-kusama/src/lib.rs
index 25d7bb76e59..cd6e23a4607 100644
--- a/bridges/relays/client-kusama/src/lib.rs
+++ b/bridges/relays/client-kusama/src/lib.rs
@@ -17,8 +17,7 @@
 //! Types used to connect to the Kusama chain.
 
 use bp_kusama::AccountInfoStorageMapKeyProvider;
-use frame_support::weights::Weight;
-use relay_substrate_client::{Chain, ChainBase, ChainWithBalances, ChainWithGrandpa};
+use relay_substrate_client::{Chain, ChainWithBalances, ChainWithGrandpa, UnderlyingChainProvider};
 use sp_core::storage::StorageKey;
 use std::time::Duration;
 
@@ -29,24 +28,8 @@ pub type HeaderId = relay_utils::HeaderId<bp_kusama::Hash, bp_kusama::BlockNumbe
 #[derive(Debug, Clone, Copy)]
 pub struct Kusama;
 
-impl ChainBase for Kusama {
-	type BlockNumber = bp_kusama::BlockNumber;
-	type Hash = bp_kusama::Hash;
-	type Hasher = bp_kusama::Hasher;
-	type Header = bp_kusama::Header;
-
-	type AccountId = bp_kusama::AccountId;
-	type Balance = bp_kusama::Balance;
-	type Index = bp_kusama::Nonce;
-	type Signature = bp_kusama::Signature;
-
-	fn max_extrinsic_size() -> u32 {
-		bp_kusama::Kusama::max_extrinsic_size()
-	}
-
-	fn max_extrinsic_weight() -> Weight {
-		bp_kusama::Kusama::max_extrinsic_weight()
-	}
+impl UnderlyingChainProvider for Kusama {
+	type Chain = bp_kusama::Kusama;
 }
 
 impl Chain for Kusama {
diff --git a/bridges/relays/client-millau/src/lib.rs b/bridges/relays/client-millau/src/lib.rs
index 1fe480fdf2d..815cd68f39f 100644
--- a/bridges/relays/client-millau/src/lib.rs
+++ b/bridges/relays/client-millau/src/lib.rs
@@ -18,10 +18,10 @@
 
 use bp_messages::MessageNonce;
 use codec::{Compact, Decode, Encode};
-use frame_support::weights::Weight;
 use relay_substrate_client::{
-	BalanceOf, Chain, ChainBase, ChainWithBalances, ChainWithGrandpa, ChainWithMessages,
-	ChainWithTransactions, Error as SubstrateError, IndexOf, SignParam, UnsignedTransaction,
+	BalanceOf, Chain, ChainWithBalances, ChainWithGrandpa, ChainWithMessages,
+	ChainWithTransactions, Error as SubstrateError, IndexOf, SignParam, UnderlyingChainProvider,
+	UnsignedTransaction,
 };
 use sp_core::{storage::StorageKey, Pair};
 use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount};
@@ -34,24 +34,8 @@ pub type HeaderId = relay_utils::HeaderId<millau_runtime::Hash, millau_runtime::
 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
 pub struct Millau;
 
-impl ChainBase for Millau {
-	type BlockNumber = millau_runtime::BlockNumber;
-	type Hash = millau_runtime::Hash;
-	type Hasher = millau_runtime::Hashing;
-	type Header = millau_runtime::Header;
-
-	type AccountId = millau_runtime::AccountId;
-	type Balance = millau_runtime::Balance;
-	type Index = millau_runtime::Index;
-	type Signature = millau_runtime::Signature;
-
-	fn max_extrinsic_size() -> u32 {
-		bp_millau::Millau::max_extrinsic_size()
-	}
-
-	fn max_extrinsic_weight() -> Weight {
-		bp_millau::Millau::max_extrinsic_weight()
-	}
+impl UnderlyingChainProvider for Millau {
+	type Chain = bp_millau::Millau;
 }
 
 impl ChainWithGrandpa for Millau {
diff --git a/bridges/relays/client-polkadot/src/lib.rs b/bridges/relays/client-polkadot/src/lib.rs
index 8bba686cfe9..ac67d55ab54 100644
--- a/bridges/relays/client-polkadot/src/lib.rs
+++ b/bridges/relays/client-polkadot/src/lib.rs
@@ -17,8 +17,7 @@
 //! Types used to connect to the Polkadot chain.
 
 use bp_polkadot::AccountInfoStorageMapKeyProvider;
-use frame_support::weights::Weight;
-use relay_substrate_client::{Chain, ChainBase, ChainWithBalances, ChainWithGrandpa};
+use relay_substrate_client::{Chain, ChainWithBalances, ChainWithGrandpa, UnderlyingChainProvider};
 use sp_core::storage::StorageKey;
 use std::time::Duration;
 
@@ -29,24 +28,8 @@ pub type HeaderId = relay_utils::HeaderId<bp_polkadot::Hash, bp_polkadot::BlockN
 #[derive(Debug, Clone, Copy)]
 pub struct Polkadot;
 
-impl ChainBase for Polkadot {
-	type BlockNumber = bp_polkadot::BlockNumber;
-	type Hash = bp_polkadot::Hash;
-	type Hasher = bp_polkadot::Hasher;
-	type Header = bp_polkadot::Header;
-
-	type AccountId = bp_polkadot::AccountId;
-	type Balance = bp_polkadot::Balance;
-	type Index = bp_polkadot::Nonce;
-	type Signature = bp_polkadot::Signature;
-
-	fn max_extrinsic_size() -> u32 {
-		bp_polkadot::Polkadot::max_extrinsic_size()
-	}
-
-	fn max_extrinsic_weight() -> Weight {
-		bp_polkadot::Polkadot::max_extrinsic_weight()
-	}
+impl UnderlyingChainProvider for Polkadot {
+	type Chain = bp_polkadot::Polkadot;
 }
 
 impl Chain for Polkadot {
diff --git a/bridges/relays/client-rialto-parachain/src/lib.rs b/bridges/relays/client-rialto-parachain/src/lib.rs
index cfb8d808dfd..16abd6e8808 100644
--- a/bridges/relays/client-rialto-parachain/src/lib.rs
+++ b/bridges/relays/client-rialto-parachain/src/lib.rs
@@ -18,10 +18,9 @@
 
 use bp_messages::MessageNonce;
 use codec::Encode;
-use frame_support::weights::Weight;
 use relay_substrate_client::{
-	Chain, ChainBase, ChainWithBalances, ChainWithMessages, ChainWithTransactions,
-	Error as SubstrateError, SignParam, UnsignedTransaction,
+	Chain, ChainWithBalances, ChainWithMessages, ChainWithTransactions, Error as SubstrateError,
+	SignParam, UnderlyingChainProvider, UnsignedTransaction,
 };
 use sp_core::{storage::StorageKey, Pair};
 use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount};
@@ -35,24 +34,8 @@ pub type HeaderId =
 #[derive(Debug, Clone, Copy)]
 pub struct RialtoParachain;
 
-impl ChainBase for RialtoParachain {
-	type BlockNumber = rialto_parachain_runtime::BlockNumber;
-	type Hash = rialto_parachain_runtime::Hash;
-	type Hasher = rialto_parachain_runtime::Hashing;
-	type Header = rialto_parachain_runtime::Header;
-
-	type AccountId = rialto_parachain_runtime::AccountId;
-	type Balance = rialto_parachain_runtime::Balance;
-	type Index = rialto_parachain_runtime::Index;
-	type Signature = rialto_parachain_runtime::Signature;
-
-	fn max_extrinsic_size() -> u32 {
-		bp_rialto_parachain::RialtoParachain::max_extrinsic_size()
-	}
-
-	fn max_extrinsic_weight() -> Weight {
-		bp_rialto_parachain::RialtoParachain::max_extrinsic_weight()
-	}
+impl UnderlyingChainProvider for RialtoParachain {
+	type Chain = bp_rialto_parachain::RialtoParachain;
 }
 
 impl Chain for RialtoParachain {
diff --git a/bridges/relays/client-rialto/src/lib.rs b/bridges/relays/client-rialto/src/lib.rs
index 6ea500ea00a..4c3a9d1e18e 100644
--- a/bridges/relays/client-rialto/src/lib.rs
+++ b/bridges/relays/client-rialto/src/lib.rs
@@ -18,11 +18,10 @@
 
 use bp_messages::MessageNonce;
 use codec::{Compact, Decode, Encode};
-use frame_support::weights::Weight;
 use relay_substrate_client::{
-	BalanceOf, Chain, ChainBase, ChainWithBalances, ChainWithGrandpa, ChainWithMessages,
+	BalanceOf, Chain, ChainWithBalances, ChainWithGrandpa, ChainWithMessages,
 	ChainWithTransactions, Error as SubstrateError, IndexOf, RelayChain, SignParam,
-	UnsignedTransaction,
+	UnderlyingChainProvider, UnsignedTransaction,
 };
 use sp_core::{storage::StorageKey, Pair};
 use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount};
@@ -35,24 +34,8 @@ pub type HeaderId = relay_utils::HeaderId<rialto_runtime::Hash, rialto_runtime::
 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
 pub struct Rialto;
 
-impl ChainBase for Rialto {
-	type BlockNumber = rialto_runtime::BlockNumber;
-	type Hash = rialto_runtime::Hash;
-	type Hasher = rialto_runtime::Hashing;
-	type Header = rialto_runtime::Header;
-
-	type AccountId = rialto_runtime::AccountId;
-	type Balance = rialto_runtime::Balance;
-	type Index = rialto_runtime::Index;
-	type Signature = rialto_runtime::Signature;
-
-	fn max_extrinsic_size() -> u32 {
-		bp_rialto::Rialto::max_extrinsic_size()
-	}
-
-	fn max_extrinsic_weight() -> Weight {
-		bp_rialto::Rialto::max_extrinsic_weight()
-	}
+impl UnderlyingChainProvider for Rialto {
+	type Chain = bp_rialto::Rialto;
 }
 
 impl Chain for Rialto {
diff --git a/bridges/relays/client-rococo/src/lib.rs b/bridges/relays/client-rococo/src/lib.rs
index 38a95042ff3..0123fe1d772 100644
--- a/bridges/relays/client-rococo/src/lib.rs
+++ b/bridges/relays/client-rococo/src/lib.rs
@@ -16,8 +16,9 @@
 
 //! Types used to connect to the Rococo-Substrate chain.
 
-use frame_support::weights::Weight;
-use relay_substrate_client::{Chain, ChainBase, ChainWithBalances, ChainWithGrandpa, RelayChain};
+use relay_substrate_client::{
+	Chain, ChainWithBalances, ChainWithGrandpa, RelayChain, UnderlyingChainProvider,
+};
 use sp_core::storage::StorageKey;
 use std::time::Duration;
 
@@ -31,24 +32,8 @@ pub type SyncHeader = relay_substrate_client::SyncHeader<bp_rococo::Header>;
 #[derive(Debug, Clone, Copy)]
 pub struct Rococo;
 
-impl ChainBase for Rococo {
-	type BlockNumber = bp_rococo::BlockNumber;
-	type Hash = bp_rococo::Hash;
-	type Hasher = bp_rococo::Hashing;
-	type Header = bp_rococo::Header;
-
-	type AccountId = bp_rococo::AccountId;
-	type Balance = bp_rococo::Balance;
-	type Index = bp_rococo::Nonce;
-	type Signature = bp_rococo::Signature;
-
-	fn max_extrinsic_size() -> u32 {
-		bp_rococo::Rococo::max_extrinsic_size()
-	}
-
-	fn max_extrinsic_weight() -> Weight {
-		bp_rococo::Rococo::max_extrinsic_weight()
-	}
+impl UnderlyingChainProvider for Rococo {
+	type Chain = bp_rococo::Rococo;
 }
 
 impl Chain for Rococo {
diff --git a/bridges/relays/client-substrate/src/chain.rs b/bridges/relays/client-substrate/src/chain.rs
index 27a95a3106d..10e3a4749e0 100644
--- a/bridges/relays/client-substrate/src/chain.rs
+++ b/bridges/relays/client-substrate/src/chain.rs
@@ -16,7 +16,8 @@
 
 use bp_messages::MessageNonce;
 use bp_runtime::{
-	Chain as ChainBase, EncodedOrDecodedCall, HashOf, TransactionEra, TransactionEraOf,
+	Chain as ChainBase, EncodedOrDecodedCall, HashOf, Parachain as ParachainBase, TransactionEra,
+	TransactionEraOf, UnderlyingChainProvider,
 };
 use codec::{Codec, Encode};
 use jsonrpsee::core::{DeserializeOwned, Serialize};
@@ -72,6 +73,11 @@ pub trait RelayChain: Chain {
 	const PARACHAINS_FINALITY_PALLET_NAME: &'static str;
 }
 
+/// Substrate-based parachain from minimal relay-client point of view.
+pub trait Parachain: Chain + ParachainBase {}
+
+impl<T> Parachain for T where T: UnderlyingChainProvider + Chain + ParachainBase {}
+
 /// Substrate-based chain that is using direct GRANDPA finality from minimal relay-client point of
 /// view.
 ///
diff --git a/bridges/relays/client-substrate/src/lib.rs b/bridges/relays/client-substrate/src/lib.rs
index 7170d58e2c0..c9926855fd5 100644
--- a/bridges/relays/client-substrate/src/lib.rs
+++ b/bridges/relays/client-substrate/src/lib.rs
@@ -34,8 +34,8 @@ use std::time::Duration;
 pub use crate::{
 	chain::{
 		AccountKeyPairOf, BlockWithJustification, CallOf, Chain, ChainWithBalances,
-		ChainWithGrandpa, ChainWithMessages, ChainWithTransactions, RelayChain, SignParam,
-		TransactionStatusOf, UnsignedTransaction,
+		ChainWithGrandpa, ChainWithMessages, ChainWithTransactions, Parachain, RelayChain,
+		SignParam, TransactionStatusOf, UnsignedTransaction,
 	},
 	client::{ChainRuntimeVersion, Client, OpaqueGrandpaAuthoritiesSet, Subscription},
 	error::{Error, Result},
@@ -45,7 +45,8 @@ pub use crate::{
 };
 pub use bp_runtime::{
 	AccountIdOf, AccountPublicOf, BalanceOf, BlockNumberOf, Chain as ChainBase, HashOf, HeaderIdOf,
-	HeaderOf, IndexOf, SignatureOf, TransactionEra, TransactionEraOf,
+	HeaderOf, IndexOf, Parachain as ParachainBase, SignatureOf, TransactionEra, TransactionEraOf,
+	UnderlyingChainProvider,
 };
 
 /// Substrate-over-websocket connection params.
diff --git a/bridges/relays/client-westend/src/lib.rs b/bridges/relays/client-westend/src/lib.rs
index 9132a38710a..6467f431335 100644
--- a/bridges/relays/client-westend/src/lib.rs
+++ b/bridges/relays/client-westend/src/lib.rs
@@ -16,8 +16,9 @@
 
 //! Types used to connect to the Westend chain.
 
-use frame_support::weights::Weight;
-use relay_substrate_client::{Chain, ChainBase, ChainWithBalances, ChainWithGrandpa, RelayChain};
+use relay_substrate_client::{
+	Chain, ChainWithBalances, ChainWithGrandpa, RelayChain, UnderlyingChainProvider,
+};
 use sp_core::storage::StorageKey;
 use std::time::Duration;
 
@@ -31,24 +32,8 @@ pub type SyncHeader = relay_substrate_client::SyncHeader<bp_westend::Header>;
 #[derive(Debug, Clone, Copy)]
 pub struct Westend;
 
-impl ChainBase for Westend {
-	type BlockNumber = bp_westend::BlockNumber;
-	type Hash = bp_westend::Hash;
-	type Hasher = bp_westend::Hasher;
-	type Header = bp_westend::Header;
-
-	type AccountId = bp_westend::AccountId;
-	type Balance = bp_westend::Balance;
-	type Index = bp_westend::Nonce;
-	type Signature = bp_westend::Signature;
-
-	fn max_extrinsic_size() -> u32 {
-		bp_westend::Westend::max_extrinsic_size()
-	}
-
-	fn max_extrinsic_weight() -> Weight {
-		bp_westend::Westend::max_extrinsic_weight()
-	}
+impl UnderlyingChainProvider for Westend {
+	type Chain = bp_westend::Westend;
 }
 
 impl Chain for Westend {
@@ -83,26 +68,8 @@ impl ChainWithBalances for Westend {
 #[derive(Debug, Clone, Copy)]
 pub struct Westmint;
 
-// Westmint seems to use the same configuration as all Polkadot-like chains, so we'll use Westend
-// primitives here.
-impl ChainBase for Westmint {
-	type BlockNumber = bp_westend::BlockNumber;
-	type Hash = bp_westend::Hash;
-	type Hasher = bp_westend::Hasher;
-	type Header = bp_westend::Header;
-
-	type AccountId = bp_westend::AccountId;
-	type Balance = bp_westend::Balance;
-	type Index = bp_westend::Nonce;
-	type Signature = bp_westend::Signature;
-
-	fn max_extrinsic_size() -> u32 {
-		bp_westend::Westend::max_extrinsic_size()
-	}
-
-	fn max_extrinsic_weight() -> Weight {
-		bp_westend::Westend::max_extrinsic_weight()
-	}
+impl UnderlyingChainProvider for Westmint {
+	type Chain = bp_westend::Westmint;
 }
 
 // Westmint seems to use the same configuration as all Polkadot-like chains, so we'll use Westend
diff --git a/bridges/relays/client-wococo/src/lib.rs b/bridges/relays/client-wococo/src/lib.rs
index 6fc3714f667..63bd9b8f896 100644
--- a/bridges/relays/client-wococo/src/lib.rs
+++ b/bridges/relays/client-wococo/src/lib.rs
@@ -16,8 +16,9 @@
 
 //! Types used to connect to the Wococo-Substrate chain.
 
-use frame_support::weights::Weight;
-use relay_substrate_client::{Chain, ChainBase, ChainWithBalances, ChainWithGrandpa, RelayChain};
+use relay_substrate_client::{
+	Chain, ChainWithBalances, ChainWithGrandpa, RelayChain, UnderlyingChainProvider,
+};
 use sp_core::storage::StorageKey;
 use std::time::Duration;
 
@@ -31,24 +32,8 @@ pub type SyncHeader = relay_substrate_client::SyncHeader<bp_wococo::Header>;
 #[derive(Debug, Clone, Copy)]
 pub struct Wococo;
 
-impl ChainBase for Wococo {
-	type BlockNumber = bp_wococo::BlockNumber;
-	type Hash = bp_wococo::Hash;
-	type Hasher = bp_wococo::Hashing;
-	type Header = bp_wococo::Header;
-
-	type AccountId = bp_wococo::AccountId;
-	type Balance = bp_wococo::Balance;
-	type Index = bp_wococo::Nonce;
-	type Signature = bp_wococo::Signature;
-
-	fn max_extrinsic_size() -> u32 {
-		bp_wococo::Wococo::max_extrinsic_size()
-	}
-
-	fn max_extrinsic_weight() -> Weight {
-		bp_wococo::Wococo::max_extrinsic_weight()
-	}
+impl UnderlyingChainProvider for Wococo {
+	type Chain = bp_wococo::Wococo;
 }
 
 impl Chain for Wococo {
diff --git a/bridges/relays/lib-substrate-relay/src/on_demand/parachains.rs b/bridges/relays/lib-substrate-relay/src/on_demand/parachains.rs
index 35ef8244ae6..991a84352e7 100644
--- a/bridges/relays/lib-substrate-relay/src/on_demand/parachains.rs
+++ b/bridges/relays/lib-substrate-relay/src/on_demand/parachains.rs
@@ -39,6 +39,7 @@ use pallet_bridge_parachains::{RelayBlockHash, RelayBlockHasher, RelayBlockNumbe
 use parachains_relay::parachains_loop::{AvailableHeader, ParachainSyncParams, TargetClient};
 use relay_substrate_client::{
 	AccountIdOf, AccountKeyPairOf, BlockNumberOf, Chain, Client, Error as SubstrateError, HashOf,
+	ParachainBase,
 };
 use relay_utils::{
 	metrics::MetricsParams, relay_loop::Client as RelayClient, FailedClient, HeaderId,
@@ -278,7 +279,7 @@ async fn background_task<P: SubstrateParachainsPipeline>(
 					parachains_source.clone(),
 					parachains_target.clone(),
 					ParachainSyncParams {
-						parachains: vec![P::SOURCE_PARACHAIN_PARA_ID.into()],
+						parachains: vec![P::SourceParachain::PARACHAIN_ID.into()],
 						stall_timeout: std::time::Duration::from_secs(60),
 						strategy: parachains_relay::parachains_loop::ParachainSyncStrategy::Any,
 					},
@@ -386,7 +387,10 @@ where
 		source.client().best_finalized_header().await.map_err(map_source_err)?;
 	let best_finalized_relay_block_id = best_finalized_relay_header.id();
 	let para_header_at_source = source
-		.on_chain_para_head_id(best_finalized_relay_block_id, P::SOURCE_PARACHAIN_PARA_ID.into())
+		.on_chain_para_head_id(
+			best_finalized_relay_block_id,
+			P::SourceParachain::PARACHAIN_ID.into(),
+		)
 		.await
 		.map_err(map_source_err)?;
 
@@ -401,7 +405,7 @@ where
 		.map_err(map_target_err)?;
 
 	let para_header_at_relay_header_at_target = source
-		.on_chain_para_head_id(relay_header_at_target, P::SOURCE_PARACHAIN_PARA_ID.into())
+		.on_chain_para_head_id(relay_header_at_target, P::SourceParachain::PARACHAIN_ID.into())
 		.await
 		.map_err(map_source_err)?;
 
diff --git a/bridges/relays/lib-substrate-relay/src/parachains/mod.rs b/bridges/relays/lib-substrate-relay/src/parachains/mod.rs
index 1d744a30e4e..9852e512f7e 100644
--- a/bridges/relays/lib-substrate-relay/src/parachains/mod.rs
+++ b/bridges/relays/lib-substrate-relay/src/parachains/mod.rs
@@ -24,7 +24,9 @@ use pallet_bridge_parachains::{
 	RelayBlockHasher, RelayBlockNumber,
 };
 use parachains_relay::ParachainsPipeline;
-use relay_substrate_client::{CallOf, Chain, ChainWithTransactions, HeaderIdOf, RelayChain};
+use relay_substrate_client::{
+	CallOf, Chain, ChainWithTransactions, HeaderIdOf, Parachain, RelayChain,
+};
 use std::{fmt::Debug, marker::PhantomData};
 
 pub mod source;
@@ -37,7 +39,7 @@ pub mod target;
 #[async_trait]
 pub trait SubstrateParachainsPipeline: 'static + Clone + Debug + Send + Sync {
 	/// Headers of this parachain are submitted to the `Self::TargetChain`.
-	type SourceParachain: Chain;
+	type SourceParachain: Parachain;
 	/// Relay chain that is storing headers of `Self::SourceParachain`.
 	type SourceRelayChain: RelayChain;
 	/// Target chain where `Self::SourceParachain` headers are submitted.
@@ -45,9 +47,6 @@ pub trait SubstrateParachainsPipeline: 'static + Clone + Debug + Send + Sync {
 
 	/// How submit parachains heads call is built?
 	type SubmitParachainHeadsCallBuilder: SubmitParachainHeadsCallBuilder<Self>;
-
-	/// Id of the `Self::SourceParachain`, used for registration in `Self::SourceRelayChain`.
-	const SOURCE_PARACHAIN_PARA_ID: u32;
 }
 
 /// Adapter that allows all `SubstrateParachainsPipeline` to act as `ParachainsPipeline`.
diff --git a/bridges/relays/lib-substrate-relay/src/parachains/source.rs b/bridges/relays/lib-substrate-relay/src/parachains/source.rs
index b61b893e5bc..afacd18e292 100644
--- a/bridges/relays/lib-substrate-relay/src/parachains/source.rs
+++ b/bridges/relays/lib-substrate-relay/src/parachains/source.rs
@@ -29,7 +29,7 @@ use parachains_relay::{
 	parachains_loop_metrics::ParachainsLoopMetrics,
 };
 use relay_substrate_client::{
-	Chain, Client, Error as SubstrateError, HeaderIdOf, HeaderOf, RelayChain,
+	Chain, Client, Error as SubstrateError, HeaderIdOf, HeaderOf, ParachainBase, RelayChain,
 };
 use relay_utils::relay_loop::Client as RelayClient;
 
@@ -107,11 +107,11 @@ where
 		para_id: ParaId,
 	) -> Result<AvailableHeader<ParaHash>, Self::Error> {
 		// we don't need to support many parachains now
-		if para_id.0 != P::SOURCE_PARACHAIN_PARA_ID {
+		if para_id.0 != P::SourceParachain::PARACHAIN_ID {
 			return Err(SubstrateError::Custom(format!(
 				"Parachain id {} is not matching expected {}",
 				para_id.0,
-				P::SOURCE_PARACHAIN_PARA_ID,
+				P::SourceParachain::PARACHAIN_ID,
 			)))
 		}
 
@@ -144,7 +144,7 @@ where
 		at_block: HeaderIdOf<P::SourceRelayChain>,
 		parachains: &[ParaId],
 	) -> Result<(ParaHeadsProof, Vec<ParaHash>), Self::Error> {
-		let parachain = ParaId(P::SOURCE_PARACHAIN_PARA_ID);
+		let parachain = ParaId(P::SourceParachain::PARACHAIN_ID);
 		if parachains != [parachain] {
 			return Err(SubstrateError::Custom(format!(
 				"Trying to prove unexpected parachains {parachains:?}. Expected {parachain:?}",
-- 
GitLab