From a979340e49f9468b9853d632ec1d642f5fbf92e8 Mon Sep 17 00:00:00 2001
From: Svyatoslav Nikolsky <svyatonik@gmail.com>
Date: Wed, 2 Nov 2022 14:36:48 +0300
Subject: [PATCH] refactor transaction sign scheme (#1621)

---
 .../src/chains/millau_headers_to_rialto.rs    |  1 -
 .../millau_headers_to_rialto_parachain.rs     |  1 -
 .../src/chains/millau_messages_to_rialto.rs   |  3 -
 .../millau_messages_to_rialto_parachain.rs    |  3 -
 .../relays/bin-substrate/src/chains/mod.rs    |  2 +-
 .../src/chains/rialto_headers_to_millau.rs    |  1 -
 .../src/chains/rialto_messages_to_millau.rs   |  3 -
 .../rialto_parachain_messages_to_millau.rs    |  3 -
 .../src/chains/rialto_parachains_to_millau.rs |  1 -
 .../src/chains/westend_headers_to_millau.rs   |  1 -
 .../chains/westend_parachains_to_millau.rs    |  1 -
 .../relays/bin-substrate/src/cli/bridge.rs    | 11 +--
 .../src/cli/relay_headers_and_messages/mod.rs | 31 ++++----
 .../relay_to_parachain.rs                     | 14 ++--
 .../relay_to_relay.rs                         | 10 +--
 .../bin-substrate/src/cli/relay_messages.rs   |  5 +-
 .../src/cli/resubmit_transactions.rs          | 76 +++++++++----------
 .../bin-substrate/src/cli/send_message.rs     |  6 +-
 bridges/relays/client-millau/src/lib.rs       | 17 ++---
 .../relays/client-rialto-parachain/src/lib.rs | 11 ++-
 bridges/relays/client-rialto/src/lib.rs       | 17 ++---
 bridges/relays/client-substrate/src/chain.rs  | 16 ++--
 bridges/relays/client-substrate/src/client.rs | 28 ++++---
 bridges/relays/client-substrate/src/lib.rs    |  2 +-
 .../src/conversion_rate_update.rs             | 24 +++---
 .../src/finality/guards.rs                    |  8 +-
 .../src/finality/initialize.rs                |  6 +-
 .../lib-substrate-relay/src/finality/mod.rs   | 15 ++--
 .../src/finality/target.rs                    | 11 ++-
 .../lib-substrate-relay/src/messages_lane.rs  | 25 ++----
 .../src/messages_source.rs                    | 27 +++----
 .../src/messages_target.rs                    | 27 +++----
 .../src/on_demand/headers.rs                  | 19 ++---
 .../src/on_demand/parachains.rs               | 12 +--
 .../lib-substrate-relay/src/parachains/mod.rs |  6 +-
 .../src/parachains/target.rs                  | 13 ++--
 36 files changed, 188 insertions(+), 269 deletions(-)

diff --git a/bridges/relays/bin-substrate/src/chains/millau_headers_to_rialto.rs b/bridges/relays/bin-substrate/src/chains/millau_headers_to_rialto.rs
index 0aa49bdada9..e0dbabd86b4 100644
--- a/bridges/relays/bin-substrate/src/chains/millau_headers_to_rialto.rs
+++ b/bridges/relays/bin-substrate/src/chains/millau_headers_to_rialto.rs
@@ -36,7 +36,6 @@ impl SubstrateFinalitySyncPipeline for MillauFinalityToRialto {
 		rialto_runtime::Runtime,
 		rialto_runtime::MillauGrandpaInstance,
 	>;
-	type TransactionSignScheme = relay_rialto_client::Rialto;
 }
 
 //// `Millau` to `Rialto` bridge definition.
diff --git a/bridges/relays/bin-substrate/src/chains/millau_headers_to_rialto_parachain.rs b/bridges/relays/bin-substrate/src/chains/millau_headers_to_rialto_parachain.rs
index 4eaf3f6f750..cdb3999db6e 100644
--- a/bridges/relays/bin-substrate/src/chains/millau_headers_to_rialto_parachain.rs
+++ b/bridges/relays/bin-substrate/src/chains/millau_headers_to_rialto_parachain.rs
@@ -54,7 +54,6 @@ impl SubstrateFinalitySyncPipeline for MillauFinalityToRialtoParachain {
 		rialto_parachain_runtime::Runtime,
 		rialto_parachain_runtime::MillauGrandpaInstance,
 	>;
-	type TransactionSignScheme = relay_rialto_parachain_client::RialtoParachain;
 }
 
 //// `Millau` to `RialtoParachain`  bridge definition.
diff --git a/bridges/relays/bin-substrate/src/chains/millau_messages_to_rialto.rs b/bridges/relays/bin-substrate/src/chains/millau_messages_to_rialto.rs
index f20669e6c7a..332721e217f 100644
--- a/bridges/relays/bin-substrate/src/chains/millau_messages_to_rialto.rs
+++ b/bridges/relays/bin-substrate/src/chains/millau_messages_to_rialto.rs
@@ -49,9 +49,6 @@ impl SubstrateMessageLane for MillauMessagesToRialto {
 	type SourceChain = Millau;
 	type TargetChain = Rialto;
 
-	type SourceTransactionSignScheme = Millau;
-	type TargetTransactionSignScheme = Rialto;
-
 	type ReceiveMessagesProofCallBuilder = DirectReceiveMessagesProofCallBuilder<
 		Self,
 		rialto_runtime::Runtime,
diff --git a/bridges/relays/bin-substrate/src/chains/millau_messages_to_rialto_parachain.rs b/bridges/relays/bin-substrate/src/chains/millau_messages_to_rialto_parachain.rs
index d5b42798dd4..04b2b1e46e6 100644
--- a/bridges/relays/bin-substrate/src/chains/millau_messages_to_rialto_parachain.rs
+++ b/bridges/relays/bin-substrate/src/chains/millau_messages_to_rialto_parachain.rs
@@ -54,9 +54,6 @@ impl SubstrateMessageLane for MillauMessagesToRialtoParachain {
 	type SourceChain = Millau;
 	type TargetChain = RialtoParachain;
 
-	type SourceTransactionSignScheme = Millau;
-	type TargetTransactionSignScheme = RialtoParachain;
-
 	type ReceiveMessagesProofCallBuilder = DirectReceiveMessagesProofCallBuilder<
 		Self,
 		rialto_parachain_runtime::Runtime,
diff --git a/bridges/relays/bin-substrate/src/chains/mod.rs b/bridges/relays/bin-substrate/src/chains/mod.rs
index 772f2552f5b..13aca0651ae 100644
--- a/bridges/relays/bin-substrate/src/chains/mod.rs
+++ b/bridges/relays/bin-substrate/src/chains/mod.rs
@@ -40,7 +40,7 @@ mod tests {
 	use codec::Encode;
 	use relay_millau_client::Millau;
 	use relay_rialto_client::Rialto;
-	use relay_substrate_client::{SignParam, TransactionSignScheme, UnsignedTransaction};
+	use relay_substrate_client::{ChainWithTransactions, SignParam, UnsignedTransaction};
 
 	#[test]
 	fn maximal_rialto_to_millau_message_size_is_computed_correctly() {
diff --git a/bridges/relays/bin-substrate/src/chains/rialto_headers_to_millau.rs b/bridges/relays/bin-substrate/src/chains/rialto_headers_to_millau.rs
index 65c5cba1ae3..b1ab4a8537b 100644
--- a/bridges/relays/bin-substrate/src/chains/rialto_headers_to_millau.rs
+++ b/bridges/relays/bin-substrate/src/chains/rialto_headers_to_millau.rs
@@ -36,7 +36,6 @@ impl SubstrateFinalitySyncPipeline for RialtoFinalityToMillau {
 		millau_runtime::Runtime,
 		millau_runtime::RialtoGrandpaInstance,
 	>;
-	type TransactionSignScheme = relay_millau_client::Millau;
 }
 
 //// `Rialto` to `Millau` bridge definition.
diff --git a/bridges/relays/bin-substrate/src/chains/rialto_messages_to_millau.rs b/bridges/relays/bin-substrate/src/chains/rialto_messages_to_millau.rs
index d34f4714644..e922659ab9a 100644
--- a/bridges/relays/bin-substrate/src/chains/rialto_messages_to_millau.rs
+++ b/bridges/relays/bin-substrate/src/chains/rialto_messages_to_millau.rs
@@ -49,9 +49,6 @@ impl SubstrateMessageLane for RialtoMessagesToMillau {
 	type SourceChain = Rialto;
 	type TargetChain = Millau;
 
-	type SourceTransactionSignScheme = Rialto;
-	type TargetTransactionSignScheme = Millau;
-
 	type ReceiveMessagesProofCallBuilder = DirectReceiveMessagesProofCallBuilder<
 		Self,
 		millau_runtime::Runtime,
diff --git a/bridges/relays/bin-substrate/src/chains/rialto_parachain_messages_to_millau.rs b/bridges/relays/bin-substrate/src/chains/rialto_parachain_messages_to_millau.rs
index b8ff0af10f8..ef13920cf85 100644
--- a/bridges/relays/bin-substrate/src/chains/rialto_parachain_messages_to_millau.rs
+++ b/bridges/relays/bin-substrate/src/chains/rialto_parachain_messages_to_millau.rs
@@ -54,9 +54,6 @@ impl SubstrateMessageLane for RialtoParachainMessagesToMillau {
 	type SourceChain = RialtoParachain;
 	type TargetChain = Millau;
 
-	type SourceTransactionSignScheme = RialtoParachain;
-	type TargetTransactionSignScheme = Millau;
-
 	type ReceiveMessagesProofCallBuilder = DirectReceiveMessagesProofCallBuilder<
 		Self,
 		millau_runtime::Runtime,
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 800d5a3e79b..911d4399389 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,7 +40,6 @@ impl SubstrateParachainsPipeline for RialtoParachainsToMillau {
 	type TargetChain = Millau;
 
 	type SubmitParachainHeadsCallBuilder = RialtoParachainsToMillauSubmitParachainHeadsCallBuilder;
-	type TransactionSignScheme = Millau;
 
 	const SOURCE_PARACHAIN_PARA_ID: u32 = bp_rialto_parachain::RIALTO_PARACHAIN_ID;
 }
diff --git a/bridges/relays/bin-substrate/src/chains/westend_headers_to_millau.rs b/bridges/relays/bin-substrate/src/chains/westend_headers_to_millau.rs
index 83394645897..2a253756c2b 100644
--- a/bridges/relays/bin-substrate/src/chains/westend_headers_to_millau.rs
+++ b/bridges/relays/bin-substrate/src/chains/westend_headers_to_millau.rs
@@ -36,7 +36,6 @@ impl SubstrateFinalitySyncPipeline for WestendFinalityToMillau {
 		millau_runtime::Runtime,
 		millau_runtime::WestendGrandpaInstance,
 	>;
-	type TransactionSignScheme = relay_millau_client::Millau;
 }
 
 //// `Westend` to `Millau` bridge definition.
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 586d391d247..73409e65569 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,7 +39,6 @@ impl SubstrateParachainsPipeline for WestendParachainsToMillau {
 	type TargetChain = Millau;
 
 	type SubmitParachainHeadsCallBuilder = WestendParachainsToMillauSubmitParachainHeadsCallBuilder;
-	type TransactionSignScheme = Millau;
 
 	const SOURCE_PARACHAIN_PARA_ID: u32 = bp_westend::WESTMINT_PARACHAIN_ID;
 }
diff --git a/bridges/relays/bin-substrate/src/cli/bridge.rs b/bridges/relays/bin-substrate/src/cli/bridge.rs
index 503e523c028..ffe4cc51e55 100644
--- a/bridges/relays/bin-substrate/src/cli/bridge.rs
+++ b/bridges/relays/bin-substrate/src/cli/bridge.rs
@@ -18,7 +18,7 @@ use crate::cli::CliChain;
 use messages_relay::relay_strategy::MixStrategy;
 use pallet_bridge_parachains::{RelayBlockHash, RelayBlockHasher, RelayBlockNumber};
 use parachains_relay::ParachainsPipeline;
-use relay_substrate_client::{AccountKeyPairOf, Chain, RelayChain, TransactionSignScheme};
+use relay_substrate_client::{AccountKeyPairOf, Chain, ChainWithTransactions, RelayChain};
 use strum::{EnumString, EnumVariantNames};
 use substrate_relay_helper::{
 	finality::SubstrateFinalitySyncPipeline, messages_lane::SubstrateMessageLane,
@@ -58,9 +58,7 @@ pub trait CliBridgeBase: Sized {
 	/// The source chain.
 	type Source: Chain + CliChain;
 	/// The target chain.
-	type Target: Chain
-		+ TransactionSignScheme<Chain = Self::Target>
-		+ CliChain<KeyPair = AccountKeyPairOf<Self::Target>>;
+	type Target: ChainWithTransactions + CliChain<KeyPair = AccountKeyPairOf<Self::Target>>;
 }
 
 /// Bridge representation that can be used from the CLI for relaying headers
@@ -70,7 +68,6 @@ pub trait RelayToRelayHeadersCliBridge: CliBridgeBase {
 	type Finality: SubstrateFinalitySyncPipeline<
 		SourceChain = Self::Source,
 		TargetChain = Self::Target,
-		TransactionSignScheme = Self::Target,
 	>;
 }
 
@@ -87,13 +84,11 @@ pub trait ParachainToRelayHeadersCliBridge: CliBridgeBase {
 			SourceRelayChain = Self::SourceRelay,
 			SourceParachain = Self::Source,
 			TargetChain = Self::Target,
-			TransactionSignScheme = Self::Target,
 		> + ParachainsPipeline<SourceChain = Self::SourceRelay, TargetChain = Self::Target>;
 	/// Finality proofs synchronization pipeline (source relay chain -> target).
 	type RelayFinality: SubstrateFinalitySyncPipeline<
 		SourceChain = Self::SourceRelay,
 		TargetChain = Self::Target,
-		TransactionSignScheme = Self::Target,
 	>;
 }
 
@@ -106,8 +101,6 @@ pub trait MessagesCliBridge: CliBridgeBase {
 	type MessagesLane: SubstrateMessageLane<
 		SourceChain = Self::Source,
 		TargetChain = Self::Target,
-		SourceTransactionSignScheme = Self::Source,
-		TargetTransactionSignScheme = Self::Target,
 		RelayStrategy = MixStrategy,
 	>;
 }
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 98a0469ae4d..1feba9d6284 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
@@ -59,7 +59,7 @@ use bp_messages::LaneId;
 use bp_runtime::{BalanceOf, BlockNumberOf};
 use messages_relay::relay_strategy::MixStrategy;
 use relay_substrate_client::{
-	AccountIdOf, AccountKeyPairOf, Chain, ChainWithBalances, Client, TransactionSignScheme,
+	AccountIdOf, AccountKeyPairOf, Chain, ChainWithBalances, ChainWithTransactions, Client,
 };
 use relay_utils::metrics::MetricsParams;
 use sp_core::Pair;
@@ -93,8 +93,8 @@ pub struct HeadersAndMessagesSharedParams {
 }
 
 pub struct Full2WayBridgeCommonParams<
-	Left: TransactionSignScheme + CliChain,
-	Right: TransactionSignScheme + CliChain,
+	Left: ChainWithTransactions + CliChain,
+	Right: ChainWithTransactions + CliChain,
 > {
 	pub shared: HeadersAndMessagesSharedParams,
 	pub left: BridgeEndCommonParams<Left>,
@@ -105,7 +105,7 @@ pub struct Full2WayBridgeCommonParams<
 	pub right_to_left_metrics: StandaloneMessagesMetrics<Right, Left>,
 }
 
-impl<Left: TransactionSignScheme + CliChain, Right: TransactionSignScheme + CliChain>
+impl<Left: ChainWithTransactions + CliChain, Right: ChainWithTransactions + CliChain>
 	Full2WayBridgeCommonParams<Left, Right>
 {
 	pub fn new<L2R: MessagesCliBridge<Source = Left, Target = Right>>(
@@ -132,7 +132,7 @@ impl<Left: TransactionSignScheme + CliChain, Right: TransactionSignScheme + CliC
 	}
 }
 
-pub struct BridgeEndCommonParams<Chain: TransactionSignScheme + CliChain> {
+pub struct BridgeEndCommonParams<Chain: ChainWithTransactions + CliChain> {
 	pub client: Client<Chain>,
 	pub sign: AccountKeyPairOf<Chain>,
 	pub transactions_mortality: Option<u32>,
@@ -142,8 +142,8 @@ pub struct BridgeEndCommonParams<Chain: TransactionSignScheme + CliChain> {
 
 struct FullBridge<
 	'a,
-	Source: TransactionSignScheme + CliChain,
-	Target: TransactionSignScheme + CliChain,
+	Source: ChainWithTransactions + CliChain,
+	Target: ChainWithTransactions + CliChain,
 	Bridge: MessagesCliBridge<Source = Source, Target = Target>,
 > {
 	shared: &'a HeadersAndMessagesSharedParams,
@@ -156,8 +156,8 @@ struct FullBridge<
 
 impl<
 		'a,
-		Source: TransactionSignScheme<Chain = Source> + CliChain,
-		Target: TransactionSignScheme<Chain = Target> + CliChain,
+		Source: ChainWithTransactions + CliChain,
+		Target: ChainWithTransactions + CliChain,
 		Bridge: MessagesCliBridge<Source = Source, Target = Target>,
 	> FullBridge<'a, Source, Target, Bridge>
 where
@@ -186,7 +186,6 @@ where
 			};
 			substrate_relay_helper::conversion_rate_update::run_conversion_rate_update_loop::<
 				Bridge::MessagesLane,
-				Source,
 			>(
 				self.source.client.clone(),
 				TransactionParams {
@@ -266,11 +265,9 @@ trait Full2WayBridgeBase: Sized + Send + Sync {
 	/// The CLI params for the bridge.
 	type Params;
 	/// The left relay chain.
-	type Left: TransactionSignScheme<Chain = Self::Left>
-		+ CliChain<KeyPair = AccountKeyPairOf<Self::Left>>;
+	type Left: ChainWithTransactions + CliChain<KeyPair = AccountKeyPairOf<Self::Left>>;
 	/// The right destination chain (it can be a relay or a parachain).
-	type Right: TransactionSignScheme<Chain = Self::Right>
-		+ CliChain<KeyPair = AccountKeyPairOf<Self::Right>>;
+	type Right: ChainWithTransactions + CliChain<KeyPair = AccountKeyPairOf<Self::Right>>;
 
 	fn common(&self) -> &Full2WayBridgeCommonParams<Self::Left, Self::Right>;
 
@@ -295,14 +292,12 @@ where
 	type Base: Full2WayBridgeBase<Left = Self::Left, Right = Self::Right>;
 
 	/// The left relay chain.
-	type Left: Chain
+	type Left: ChainWithTransactions
 		+ ChainWithBalances
-		+ TransactionSignScheme<Chain = Self::Left>
 		+ CliChain<KeyPair = AccountKeyPairOf<Self::Left>>;
 	/// The right relay chain.
-	type Right: Chain
+	type Right: ChainWithTransactions
 		+ ChainWithBalances
-		+ TransactionSignScheme<Chain = Self::Right>
 		+ CliChain<KeyPair = AccountKeyPairOf<Self::Right>>;
 
 	// Left to Right bridge
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 4123dae5a70..0990a2d2175 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,7 @@ 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, Client, TransactionSignScheme};
+use relay_substrate_client::{AccountIdOf, AccountKeyPairOf, Chain, ChainWithTransactions, Client};
 use sp_core::Pair;
 use substrate_relay_helper::{
 	finality::SubstrateFinalitySyncPipeline,
@@ -95,9 +95,9 @@ macro_rules! declare_relay_to_parachain_bridge_schema {
 
 			impl [<$left_chain $right_parachain HeadersAndMessages>] {
 				async fn into_bridge<
-					Left: TransactionSignScheme + CliChain<KeyPair = AccountKeyPairOf<Left>>,
-					Right: TransactionSignScheme + CliChain<KeyPair = AccountKeyPairOf<Right>>,
-					RightRelay: TransactionSignScheme + CliChain,
+					Left: ChainWithTransactions + CliChain<KeyPair = AccountKeyPairOf<Left>>,
+					Right: ChainWithTransactions + CliChain<KeyPair = AccountKeyPairOf<Right>>,
+					RightRelay: ChainWithTransactions + CliChain,
 					L2R: CliBridgeBase<Source = Left, Target = Right> + MessagesCliBridge + RelayToRelayHeadersCliBridge,
 					R2L: CliBridgeBase<Source = Right, Target = Left>
 						+ MessagesCliBridge
@@ -146,12 +146,12 @@ macro_rules! declare_relay_to_parachain_bridge_schema {
 
 #[async_trait]
 impl<
-		Left: Chain + TransactionSignScheme<Chain = Left> + CliChain<KeyPair = AccountKeyPairOf<Left>>,
+		Left: ChainWithTransactions + CliChain<KeyPair = AccountKeyPairOf<Left>>,
 		Right: Chain<Hash = ParaHash>
-			+ TransactionSignScheme<Chain = Right>
+			+ ChainWithTransactions
 			+ CliChain<KeyPair = AccountKeyPairOf<Right>>,
 		RightRelay: Chain<BlockNumber = RelayBlockNumber, Hash = RelayBlockHash, Hasher = RelayBlockHasher>
-			+ TransactionSignScheme
+			+ ChainWithTransactions
 			+ CliChain,
 		L2R: CliBridgeBase<Source = Left, Target = Right>
 			+ MessagesCliBridge
diff --git a/bridges/relays/bin-substrate/src/cli/relay_headers_and_messages/relay_to_relay.rs b/bridges/relays/bin-substrate/src/cli/relay_headers_and_messages/relay_to_relay.rs
index 2e092ad406b..fb33fab8b78 100644
--- a/bridges/relays/bin-substrate/src/cli/relay_headers_and_messages/relay_to_relay.rs
+++ b/bridges/relays/bin-substrate/src/cli/relay_headers_and_messages/relay_to_relay.rs
@@ -23,7 +23,7 @@ use crate::cli::{
 	CliChain,
 };
 use bp_runtime::BlockNumberOf;
-use relay_substrate_client::{AccountIdOf, AccountKeyPairOf, Chain, TransactionSignScheme};
+use relay_substrate_client::{AccountIdOf, AccountKeyPairOf, ChainWithTransactions};
 use sp_core::Pair;
 use substrate_relay_helper::{
 	finality::SubstrateFinalitySyncPipeline,
@@ -77,8 +77,8 @@ macro_rules! declare_relay_to_relay_bridge_schema {
 
 			impl [<$left_chain $right_chain HeadersAndMessages>] {
 				async fn into_bridge<
-					Left: TransactionSignScheme + CliChain<KeyPair = AccountKeyPairOf<Left>>,
-					Right: TransactionSignScheme + CliChain<KeyPair = AccountKeyPairOf<Right>>,
+					Left: ChainWithTransactions + CliChain<KeyPair = AccountKeyPairOf<Left>>,
+					Right: ChainWithTransactions + CliChain<KeyPair = AccountKeyPairOf<Right>>,
 					L2R: CliBridgeBase<Source = Left, Target = Right> + MessagesCliBridge + RelayToRelayHeadersCliBridge,
 					R2L: CliBridgeBase<Source = Right, Target = Left> + MessagesCliBridge + RelayToRelayHeadersCliBridge,
 				>(
@@ -117,8 +117,8 @@ macro_rules! declare_relay_to_relay_bridge_schema {
 
 #[async_trait]
 impl<
-		Left: Chain + TransactionSignScheme<Chain = Left> + CliChain<KeyPair = AccountKeyPairOf<Left>>,
-		Right: Chain + TransactionSignScheme<Chain = Right> + CliChain<KeyPair = AccountKeyPairOf<Right>>,
+		Left: ChainWithTransactions + CliChain<KeyPair = AccountKeyPairOf<Left>>,
+		Right: ChainWithTransactions + CliChain<KeyPair = AccountKeyPairOf<Right>>,
 		L2R: CliBridgeBase<Source = Left, Target = Right>
 			+ MessagesCliBridge
 			+ RelayToRelayHeadersCliBridge,
diff --git a/bridges/relays/bin-substrate/src/cli/relay_messages.rs b/bridges/relays/bin-substrate/src/cli/relay_messages.rs
index a68ce030543..d03a1f97c3d 100644
--- a/bridges/relays/bin-substrate/src/cli/relay_messages.rs
+++ b/bridges/relays/bin-substrate/src/cli/relay_messages.rs
@@ -26,7 +26,7 @@ use crate::chains::{
 	rialto_parachains_to_millau::RialtoParachainToMillauCliBridge,
 };
 use messages_relay::relay_strategy::MixStrategy;
-use relay_substrate_client::{AccountIdOf, AccountKeyPairOf, BalanceOf, TransactionSignScheme};
+use relay_substrate_client::{AccountIdOf, AccountKeyPairOf, BalanceOf, ChainWithTransactions};
 use substrate_relay_helper::{messages_lane::MessagesRelayParams, TransactionParams};
 
 use crate::cli::{bridge::*, chain_schema::*, CliChain, HexLaneId, PrometheusParams};
@@ -77,8 +77,7 @@ pub struct RelayMessages {
 #[async_trait]
 trait MessagesRelayer: MessagesCliBridge
 where
-	Self::Source: TransactionSignScheme<Chain = Self::Source>
-		+ CliChain<KeyPair = AccountKeyPairOf<Self::Source>>,
+	Self::Source: ChainWithTransactions + CliChain<KeyPair = AccountKeyPairOf<Self::Source>>,
 	AccountIdOf<Self::Source>: From<<AccountKeyPairOf<Self::Source> as Pair>::Public>,
 	AccountIdOf<Self::Target>: From<<AccountKeyPairOf<Self::Target> as Pair>::Public>,
 	BalanceOf<Self::Source>: TryFrom<BalanceOf<Self::Target>>,
diff --git a/bridges/relays/bin-substrate/src/cli/resubmit_transactions.rs b/bridges/relays/bin-substrate/src/cli/resubmit_transactions.rs
index 4481d3fb712..c69f9c8ae4e 100644
--- a/bridges/relays/bin-substrate/src/cli/resubmit_transactions.rs
+++ b/bridges/relays/bin-substrate/src/cli/resubmit_transactions.rs
@@ -20,8 +20,8 @@ use bp_runtime::HeaderIdProvider;
 use codec::{Decode, Encode};
 use num_traits::{One, Zero};
 use relay_substrate_client::{
-	BlockWithJustification, Chain, Client, Error as SubstrateError, HeaderIdOf, HeaderOf,
-	SignParam, TransactionSignScheme,
+	AccountKeyPairOf, BlockWithJustification, Chain, ChainWithTransactions, Client,
+	Error as SubstrateError, HeaderIdOf, HeaderOf, SignParam,
 };
 use relay_utils::FailedClient;
 use sp_core::Bytes;
@@ -111,7 +111,7 @@ impl ResubmitTransactions {
 
 			relay_utils::relay_loop((), client)
 				.run(relay_loop_name, move |_, client, _| {
-					run_until_connection_lost::<Target, TargetSign>(
+					run_until_connection_lost(
 						client,
 						transaction_params.clone(),
 						Context {
@@ -140,16 +140,16 @@ impl ResubmitTransactions {
 
 impl PrioritySelectionStrategy {
 	/// Select target priority.
-	async fn select_target_priority<C: Chain, S: TransactionSignScheme<Chain = C>>(
+	async fn select_target_priority<C: ChainWithTransactions>(
 		&self,
 		client: &Client<C>,
 		context: &Context<C>,
 	) -> Result<Option<TransactionPriority>, SubstrateError> {
 		match *self {
 			PrioritySelectionStrategy::MakeItBestTransaction =>
-				read_previous_block_best_priority::<C, S>(client, context).await,
+				read_previous_block_best_priority(client, context).await,
 			PrioritySelectionStrategy::MakeItBetterThanQueuedTransaction =>
-				select_priority_from_queue::<C, S>(client, context).await,
+				select_priority_from_queue(client, context).await,
 		}
 	}
 }
@@ -202,16 +202,15 @@ impl<C: Chain> Context<C> {
 }
 
 /// Run resubmit transactions loop.
-async fn run_until_connection_lost<C: Chain, S: TransactionSignScheme<Chain = C>>(
+async fn run_until_connection_lost<C: ChainWithTransactions>(
 	client: Client<C>,
-	transaction_params: TransactionParams<S::AccountKeyPair>,
+	transaction_params: TransactionParams<AccountKeyPairOf<C>>,
 	mut context: Context<C>,
 ) -> Result<(), FailedClient> {
 	loop {
 		async_std::task::sleep(C::AVERAGE_BLOCK_INTERVAL).await;
 
-		let result =
-			run_loop_iteration::<C, S>(client.clone(), transaction_params.clone(), context).await;
+		let result = run_loop_iteration(client.clone(), transaction_params.clone(), context).await;
 		context = match result {
 			Ok(context) => context,
 			Err(error) => {
@@ -228,9 +227,9 @@ async fn run_until_connection_lost<C: Chain, S: TransactionSignScheme<Chain = C>
 }
 
 /// Run single loop iteration.
-async fn run_loop_iteration<C: Chain, S: TransactionSignScheme<Chain = C>>(
+async fn run_loop_iteration<C: ChainWithTransactions>(
 	client: Client<C>,
-	transaction_params: TransactionParams<S::AccountKeyPair>,
+	transaction_params: TransactionParams<AccountKeyPairOf<C>>,
 	mut context: Context<C>,
 ) -> Result<Context<C>, SubstrateError> {
 	// correct best header is required for all other actions
@@ -238,7 +237,7 @@ async fn run_loop_iteration<C: Chain, S: TransactionSignScheme<Chain = C>>(
 
 	// check if there's queued transaction, signed by given author
 	let original_transaction =
-		match lookup_signer_transaction::<C, S>(&client, &transaction_params.signer).await? {
+		match lookup_signer_transaction(&client, &transaction_params.signer).await? {
 			Some(original_transaction) => original_transaction,
 			None => {
 				log::trace!(target: "bridge", "No {} transactions from required signer in the txpool", C::NAME);
@@ -262,17 +261,16 @@ async fn run_loop_iteration<C: Chain, S: TransactionSignScheme<Chain = C>>(
 	}
 
 	// select priority for updated transaction
-	let target_priority =
-		match context.strategy.select_target_priority::<C, S>(&client, &context).await? {
-			Some(target_priority) => target_priority,
-			None => {
-				log::trace!(target: "bridge", "Failed to select target priority");
-				return Ok(context)
-			},
-		};
+	let target_priority = match context.strategy.select_target_priority(&client, &context).await? {
+		Some(target_priority) => target_priority,
+		None => {
+			log::trace!(target: "bridge", "Failed to select target priority");
+			return Ok(context)
+		},
+	};
 
 	// update transaction tip
-	let (is_updated, updated_transaction) = update_transaction_tip::<C, S>(
+	let (is_updated, updated_transaction) = update_transaction_tip(
 		&client,
 		&transaction_params,
 		context.best_header.id(),
@@ -304,15 +302,15 @@ async fn run_loop_iteration<C: Chain, S: TransactionSignScheme<Chain = C>>(
 }
 
 /// Search transaction pool for transaction, signed by given key pair.
-async fn lookup_signer_transaction<C: Chain, S: TransactionSignScheme<Chain = C>>(
+async fn lookup_signer_transaction<C: ChainWithTransactions>(
 	client: &Client<C>,
-	key_pair: &S::AccountKeyPair,
-) -> Result<Option<S::SignedTransaction>, SubstrateError> {
+	key_pair: &AccountKeyPairOf<C>,
+) -> Result<Option<C::SignedTransaction>, SubstrateError> {
 	let pending_transactions = client.pending_extrinsics().await?;
 	for pending_transaction in pending_transactions {
-		let pending_transaction = S::SignedTransaction::decode(&mut &pending_transaction.0[..])
+		let pending_transaction = C::SignedTransaction::decode(&mut &pending_transaction.0[..])
 			.map_err(SubstrateError::ResponseParseFailed)?;
-		if !S::is_signed_by(key_pair, &pending_transaction) {
+		if !C::is_signed_by(key_pair, &pending_transaction) {
 			continue
 		}
 
@@ -323,7 +321,7 @@ async fn lookup_signer_transaction<C: Chain, S: TransactionSignScheme<Chain = C>
 }
 
 /// Read priority of best signed transaction of previous block.
-async fn read_previous_block_best_priority<C: Chain, S: TransactionSignScheme<Chain = C>>(
+async fn read_previous_block_best_priority<C: ChainWithTransactions>(
 	client: &Client<C>,
 	context: &Context<C>,
 ) -> Result<Option<TransactionPriority>, SubstrateError> {
@@ -331,8 +329,8 @@ async fn read_previous_block_best_priority<C: Chain, S: TransactionSignScheme<Ch
 	let best_transaction = best_block
 		.extrinsics()
 		.iter()
-		.filter_map(|xt| S::SignedTransaction::decode(&mut &xt[..]).ok())
-		.find(|xt| S::is_signed(xt));
+		.filter_map(|xt| C::SignedTransaction::decode(&mut &xt[..]).ok())
+		.find(|xt| C::is_signed(xt));
 	match best_transaction {
 		Some(best_transaction) => Ok(Some(
 			client
@@ -345,7 +343,7 @@ async fn read_previous_block_best_priority<C: Chain, S: TransactionSignScheme<Ch
 }
 
 /// Select priority of some queued transaction.
-async fn select_priority_from_queue<C: Chain, S: TransactionSignScheme<Chain = C>>(
+async fn select_priority_from_queue<C: ChainWithTransactions>(
 	client: &Client<C>,
 	context: &Context<C>,
 ) -> Result<Option<TransactionPriority>, SubstrateError> {
@@ -356,7 +354,7 @@ async fn select_priority_from_queue<C: Chain, S: TransactionSignScheme<Chain = C
 		None => return Ok(None),
 	};
 
-	let selected_transaction = S::SignedTransaction::decode(&mut &selected_transaction[..])
+	let selected_transaction = C::SignedTransaction::decode(&mut &selected_transaction[..])
 		.map_err(SubstrateError::ResponseParseFailed)?;
 	let target_priority = client
 		.validate_transaction(context.best_header.hash(), selected_transaction)
@@ -389,18 +387,18 @@ fn select_transaction_from_queue<C: Chain>(
 }
 
 /// Try to find appropriate tip for transaction so that its priority is larger than given.
-async fn update_transaction_tip<C: Chain, S: TransactionSignScheme<Chain = C>>(
+async fn update_transaction_tip<C: ChainWithTransactions>(
 	client: &Client<C>,
-	transaction_params: &TransactionParams<S::AccountKeyPair>,
+	transaction_params: &TransactionParams<AccountKeyPairOf<C>>,
 	at_block: HeaderIdOf<C>,
-	tx: S::SignedTransaction,
+	tx: C::SignedTransaction,
 	tip_step: C::Balance,
 	tip_limit: C::Balance,
 	target_priority: TransactionPriority,
-) -> Result<(bool, S::SignedTransaction), SubstrateError> {
+) -> Result<(bool, C::SignedTransaction), SubstrateError> {
 	let stx = format!("{tx:?}");
 	let mut current_priority = client.validate_transaction(at_block.1, tx.clone()).await??.priority;
-	let mut unsigned_tx = S::parse_transaction(tx).ok_or_else(|| {
+	let mut unsigned_tx = C::parse_transaction(tx).ok_or_else(|| {
 		SubstrateError::Custom(format!("Failed to parse {} transaction {stx}", C::NAME,))
 	})?;
 	let old_tip = unsigned_tx.tip;
@@ -425,7 +423,7 @@ async fn update_transaction_tip<C: Chain, S: TransactionSignScheme<Chain = C>>(
 		current_priority = client
 			.validate_transaction(
 				at_block.1,
-				S::sign_transaction(
+				C::sign_transaction(
 					SignParam {
 						spec_version,
 						transaction_version,
@@ -449,7 +447,7 @@ async fn update_transaction_tip<C: Chain, S: TransactionSignScheme<Chain = C>>(
 
 	Ok((
 		old_tip != unsigned_tx.tip,
-		S::sign_transaction(
+		C::sign_transaction(
 			SignParam {
 				spec_version,
 				transaction_version,
diff --git a/bridges/relays/bin-substrate/src/cli/send_message.rs b/bridges/relays/bin-substrate/src/cli/send_message.rs
index 79d1efee638..2b314b921fa 100644
--- a/bridges/relays/bin-substrate/src/cli/send_message.rs
+++ b/bridges/relays/bin-substrate/src/cli/send_message.rs
@@ -32,7 +32,7 @@ use crate::{
 use async_trait::async_trait;
 use codec::{Decode, Encode};
 use relay_substrate_client::{
-	AccountIdOf, AccountKeyPairOf, Chain, ChainBase, SignParam, TransactionSignScheme,
+	AccountIdOf, AccountKeyPairOf, Chain, ChainBase, ChainWithTransactions, SignParam,
 	UnsignedTransaction,
 };
 use sp_core::{Bytes, Pair};
@@ -96,12 +96,12 @@ pub struct SendMessage {
 trait MessageSender: MessagesCliBridge
 where
 	Self::Source: ChainBase<Index = u32>
-		+ TransactionSignScheme<Chain = Self::Source>
+		+ ChainWithTransactions
 		+ CliChain<KeyPair = AccountKeyPairOf<Self::Source>>
 		+ CliEncodeMessage,
 	<Self::Source as ChainBase>::Balance: Display + From<u64> + Into<u128>,
 	<Self::Source as Chain>::Call: Sync,
-	<Self::Source as TransactionSignScheme>::SignedTransaction: Sync,
+	<Self::Source as ChainWithTransactions>::SignedTransaction: Sync,
 	AccountIdOf<Self::Source>: From<<AccountKeyPairOf<Self::Source> as Pair>::Public>,
 	AccountId32: From<<AccountKeyPairOf<Self::Source> as Pair>::Public>,
 {
diff --git a/bridges/relays/client-millau/src/lib.rs b/bridges/relays/client-millau/src/lib.rs
index 8adb108c85b..77f09a89f15 100644
--- a/bridges/relays/client-millau/src/lib.rs
+++ b/bridges/relays/client-millau/src/lib.rs
@@ -21,7 +21,7 @@ use codec::{Compact, Decode, Encode};
 use frame_support::weights::Weight;
 use relay_substrate_client::{
 	BalanceOf, Chain, ChainBase, ChainWithBalances, ChainWithGrandpa, ChainWithMessages,
-	Error as SubstrateError, IndexOf, SignParam, TransactionSignScheme, UnsignedTransaction,
+	ChainWithTransactions, Error as SubstrateError, IndexOf, SignParam, UnsignedTransaction,
 };
 use sp_core::{storage::StorageKey, Pair};
 use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount};
@@ -97,14 +97,13 @@ impl ChainWithBalances for Millau {
 	}
 }
 
-impl TransactionSignScheme for Millau {
-	type Chain = Millau;
+impl ChainWithTransactions for Millau {
 	type AccountKeyPair = sp_core::sr25519::Pair;
 	type SignedTransaction = millau_runtime::UncheckedExtrinsic;
 
 	fn sign_transaction(
 		param: SignParam<Self>,
-		unsigned: UnsignedTransaction<Self::Chain>,
+		unsigned: UnsignedTransaction<Self>,
 	) -> Result<Self::SignedTransaction, SubstrateError> {
 		let raw_payload = SignedPayload::from_raw(
 			unsigned.call.clone(),
@@ -156,18 +155,14 @@ impl TransactionSignScheme for Millau {
 			.unwrap_or(false)
 	}
 
-	fn parse_transaction(tx: Self::SignedTransaction) -> Option<UnsignedTransaction<Self::Chain>> {
+	fn parse_transaction(tx: Self::SignedTransaction) -> Option<UnsignedTransaction<Self>> {
 		let extra = &tx.signature.as_ref()?.2;
 		Some(
 			UnsignedTransaction::new(
 				tx.function.into(),
-				Compact::<IndexOf<Self::Chain>>::decode(&mut &extra.5.encode()[..]).ok()?.into(),
+				Compact::<IndexOf<Self>>::decode(&mut &extra.5.encode()[..]).ok()?.into(),
 			)
-			.tip(
-				Compact::<BalanceOf<Self::Chain>>::decode(&mut &extra.7.encode()[..])
-					.ok()?
-					.into(),
-			),
+			.tip(Compact::<BalanceOf<Self>>::decode(&mut &extra.7.encode()[..]).ok()?.into()),
 		)
 	}
 }
diff --git a/bridges/relays/client-rialto-parachain/src/lib.rs b/bridges/relays/client-rialto-parachain/src/lib.rs
index 7e1415720ba..fe7c2c81616 100644
--- a/bridges/relays/client-rialto-parachain/src/lib.rs
+++ b/bridges/relays/client-rialto-parachain/src/lib.rs
@@ -20,8 +20,8 @@ use bp_messages::MessageNonce;
 use codec::Encode;
 use frame_support::weights::Weight;
 use relay_substrate_client::{
-	Chain, ChainBase, ChainWithBalances, ChainWithMessages, Error as SubstrateError, SignParam,
-	TransactionSignScheme, UnsignedTransaction,
+	Chain, ChainBase, ChainWithBalances, ChainWithMessages, ChainWithTransactions,
+	Error as SubstrateError, SignParam, UnsignedTransaction,
 };
 use sp_core::{storage::StorageKey, Pair};
 use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount};
@@ -96,14 +96,13 @@ impl ChainWithMessages for RialtoParachain {
 	type WeightInfo = ();
 }
 
-impl TransactionSignScheme for RialtoParachain {
-	type Chain = RialtoParachain;
+impl ChainWithTransactions for RialtoParachain {
 	type AccountKeyPair = sp_core::sr25519::Pair;
 	type SignedTransaction = rialto_parachain_runtime::UncheckedExtrinsic;
 
 	fn sign_transaction(
 		param: SignParam<Self>,
-		unsigned: UnsignedTransaction<Self::Chain>,
+		unsigned: UnsignedTransaction<Self>,
 	) -> Result<Self::SignedTransaction, SubstrateError> {
 		let raw_payload = SignedPayload::from_raw(
 			unsigned.call,
@@ -157,7 +156,7 @@ impl TransactionSignScheme for RialtoParachain {
 			.unwrap_or(false)
 	}
 
-	fn parse_transaction(_tx: Self::SignedTransaction) -> Option<UnsignedTransaction<Self::Chain>> {
+	fn parse_transaction(_tx: Self::SignedTransaction) -> Option<UnsignedTransaction<Self>> {
 		unimplemented!("TODO")
 	}
 }
diff --git a/bridges/relays/client-rialto/src/lib.rs b/bridges/relays/client-rialto/src/lib.rs
index fbb1f85ec1b..45166559b36 100644
--- a/bridges/relays/client-rialto/src/lib.rs
+++ b/bridges/relays/client-rialto/src/lib.rs
@@ -21,7 +21,7 @@ use codec::{Compact, Decode, Encode};
 use frame_support::weights::Weight;
 use relay_substrate_client::{
 	BalanceOf, Chain, ChainBase, ChainWithBalances, ChainWithGrandpa, ChainWithMessages,
-	Error as SubstrateError, IndexOf, RelayChain, SignParam, TransactionSignScheme,
+	ChainWithTransactions, Error as SubstrateError, IndexOf, RelayChain, SignParam,
 	UnsignedTransaction,
 };
 use sp_core::{storage::StorageKey, Pair};
@@ -104,14 +104,13 @@ impl ChainWithBalances for Rialto {
 	}
 }
 
-impl TransactionSignScheme for Rialto {
-	type Chain = Rialto;
+impl ChainWithTransactions for Rialto {
 	type AccountKeyPair = sp_core::sr25519::Pair;
 	type SignedTransaction = rialto_runtime::UncheckedExtrinsic;
 
 	fn sign_transaction(
 		param: SignParam<Self>,
-		unsigned: UnsignedTransaction<Self::Chain>,
+		unsigned: UnsignedTransaction<Self>,
 	) -> Result<Self::SignedTransaction, SubstrateError> {
 		let raw_payload = SignedPayload::from_raw(
 			unsigned.call.clone(),
@@ -159,18 +158,14 @@ impl TransactionSignScheme for Rialto {
 			.unwrap_or(false)
 	}
 
-	fn parse_transaction(tx: Self::SignedTransaction) -> Option<UnsignedTransaction<Self::Chain>> {
+	fn parse_transaction(tx: Self::SignedTransaction) -> Option<UnsignedTransaction<Self>> {
 		let extra = &tx.signature.as_ref()?.2;
 		Some(
 			UnsignedTransaction::new(
 				tx.function.into(),
-				Compact::<IndexOf<Self::Chain>>::decode(&mut &extra.5.encode()[..]).ok()?.into(),
+				Compact::<IndexOf<Self>>::decode(&mut &extra.5.encode()[..]).ok()?.into(),
 			)
-			.tip(
-				Compact::<BalanceOf<Self::Chain>>::decode(&mut &extra.7.encode()[..])
-					.ok()?
-					.into(),
-			),
+			.tip(Compact::<BalanceOf<Self>>::decode(&mut &extra.7.encode()[..]).ok()?.into()),
 		)
 	}
 }
diff --git a/bridges/relays/client-substrate/src/chain.rs b/bridges/relays/client-substrate/src/chain.rs
index 97e3b0f0fc2..5763d4a6135 100644
--- a/bridges/relays/client-substrate/src/chain.rs
+++ b/bridges/relays/client-substrate/src/chain.rs
@@ -185,12 +185,10 @@ impl<C: Chain> UnsignedTransaction<C> {
 }
 
 /// Account key pair used by transactions signing scheme.
-pub type AccountKeyPairOf<S> = <S as TransactionSignScheme>::AccountKeyPair;
+pub type AccountKeyPairOf<S> = <S as ChainWithTransactions>::AccountKeyPair;
 
 /// Substrate-based chain transactions signing scheme.
-pub trait TransactionSignScheme: 'static {
-	/// Chain that this scheme is to be used.
-	type Chain: Chain;
+pub trait ChainWithTransactions: Chain {
 	/// Type of key pairs used to sign transactions.
 	type AccountKeyPair: Pair;
 	/// Signed transaction.
@@ -199,7 +197,7 @@ pub trait TransactionSignScheme: 'static {
 	/// Create transaction for given runtime call, signed by given account.
 	fn sign_transaction(
 		param: SignParam<Self>,
-		unsigned: UnsignedTransaction<Self::Chain>,
+		unsigned: UnsignedTransaction<Self>,
 	) -> Result<Self::SignedTransaction, crate::Error>
 	where
 		Self: Sized;
@@ -213,19 +211,19 @@ pub trait TransactionSignScheme: 'static {
 	/// Parse signed transaction into its unsigned part.
 	///
 	/// Returns `None` if signed transaction has unsupported format.
-	fn parse_transaction(tx: Self::SignedTransaction) -> Option<UnsignedTransaction<Self::Chain>>;
+	fn parse_transaction(tx: Self::SignedTransaction) -> Option<UnsignedTransaction<Self>>;
 }
 
 /// Sign transaction parameters
-pub struct SignParam<T: TransactionSignScheme> {
+pub struct SignParam<C: ChainWithTransactions> {
 	/// Version of the runtime specification.
 	pub spec_version: u32,
 	/// Transaction version
 	pub transaction_version: u32,
 	/// Hash of the genesis block.
-	pub genesis_hash: <T::Chain as ChainBase>::Hash,
+	pub genesis_hash: HashOf<C>,
 	/// Signer account
-	pub signer: T::AccountKeyPair,
+	pub signer: AccountKeyPairOf<C>,
 }
 
 impl<Block: BlockT> BlockWithJustification<Block::Header> for SignedBlock<Block> {
diff --git a/bridges/relays/client-substrate/src/client.rs b/bridges/relays/client-substrate/src/client.rs
index a713b3ba121..4f783291ee3 100644
--- a/bridges/relays/client-substrate/src/client.rs
+++ b/bridges/relays/client-substrate/src/client.rs
@@ -17,14 +17,14 @@
 //! Substrate node client.
 
 use crate::{
-	chain::{Chain, ChainWithBalances},
+	chain::{Chain, ChainWithBalances, ChainWithTransactions},
 	rpc::{
 		SubstrateAuthorClient, SubstrateChainClient, SubstrateFinalityClient,
 		SubstrateFrameSystemClient, SubstrateStateClient, SubstrateSystemClient,
 		SubstrateTransactionPaymentClient,
 	},
 	transaction_stall_timeout, ConnectionParams, Error, HashOf, HeaderIdOf, Result, SignParam,
-	TransactionSignScheme, TransactionTracker, UnsignedTransaction,
+	TransactionTracker, UnsignedTransaction,
 };
 
 use async_std::sync::{Arc, Mutex};
@@ -421,14 +421,17 @@ impl<C: Chain> Client<C> {
 	/// if all client instances are clones of the same initial `Client`.
 	///
 	/// Note: The given transaction needs to be SCALE encoded beforehand.
-	pub async fn submit_signed_extrinsic<S: TransactionSignScheme<Chain = C> + 'static>(
+	pub async fn submit_signed_extrinsic(
 		&self,
 		extrinsic_signer: C::AccountId,
-		signing_data: SignParam<S>,
+		signing_data: SignParam<C>,
 		prepare_extrinsic: impl FnOnce(HeaderIdOf<C>, C::Index) -> Result<UnsignedTransaction<C>>
 			+ Send
 			+ 'static,
-	) -> Result<C::Hash> {
+	) -> Result<C::Hash>
+	where
+		C: ChainWithTransactions,
+	{
 		let _guard = self.submit_signed_extrinsic_lock.lock().await;
 		let transaction_nonce = self.next_account_index(extrinsic_signer).await?;
 		let best_header = self.best_header().await?;
@@ -442,7 +445,7 @@ impl<C: Chain> Client<C> {
 
 		self.jsonrpsee_execute(move |client| async move {
 			let extrinsic = prepare_extrinsic(best_header_id, transaction_nonce)?;
-			let signed_extrinsic = S::sign_transaction(signing_data, extrinsic)?.encode();
+			let signed_extrinsic = C::sign_transaction(signing_data, extrinsic)?.encode();
 			let tx_hash =
 				SubstrateAuthorClient::<C>::submit_extrinsic(&*client, Bytes(signed_extrinsic))
 					.await
@@ -458,16 +461,17 @@ impl<C: Chain> Client<C> {
 
 	/// Does exactly the same as `submit_signed_extrinsic`, but keeps watching for extrinsic status
 	/// after submission.
-	pub async fn submit_and_watch_signed_extrinsic<
-		S: TransactionSignScheme<Chain = C> + 'static,
-	>(
+	pub async fn submit_and_watch_signed_extrinsic(
 		&self,
 		extrinsic_signer: C::AccountId,
-		signing_data: SignParam<S>,
+		signing_data: SignParam<C>,
 		prepare_extrinsic: impl FnOnce(HeaderIdOf<C>, C::Index) -> Result<UnsignedTransaction<C>>
 			+ Send
 			+ 'static,
-	) -> Result<TransactionTracker<C, Self>> {
+	) -> Result<TransactionTracker<C, Self>>
+	where
+		C: ChainWithTransactions,
+	{
 		let self_clone = self.clone();
 		let _guard = self.submit_signed_extrinsic_lock.lock().await;
 		let transaction_nonce = self.next_account_index(extrinsic_signer).await?;
@@ -482,7 +486,7 @@ impl<C: Chain> Client<C> {
 					C::AVERAGE_BLOCK_INTERVAL,
 					STALL_TIMEOUT,
 				);
-				let signed_extrinsic = S::sign_transaction(signing_data, extrinsic)?.encode();
+				let signed_extrinsic = C::sign_transaction(signing_data, extrinsic)?.encode();
 				let tx_hash = C::Hasher::hash(&signed_extrinsic);
 				let subscription = SubstrateAuthorClient::<C>::submit_and_watch_extrinsic(
 					&*client,
diff --git a/bridges/relays/client-substrate/src/lib.rs b/bridges/relays/client-substrate/src/lib.rs
index 9e6c73d83ca..99ff0fbe394 100644
--- a/bridges/relays/client-substrate/src/lib.rs
+++ b/bridges/relays/client-substrate/src/lib.rs
@@ -34,7 +34,7 @@ use std::time::Duration;
 pub use crate::{
 	chain::{
 		AccountKeyPairOf, BlockWithJustification, CallOf, Chain, ChainWithBalances,
-		ChainWithGrandpa, ChainWithMessages, RelayChain, SignParam, TransactionSignScheme,
+		ChainWithGrandpa, ChainWithMessages, ChainWithTransactions, RelayChain, SignParam,
 		TransactionStatusOf, UnsignedTransaction, WeightToFeeOf,
 	},
 	client::{ChainRuntimeVersion, Client, OpaqueGrandpaAuthoritiesSet, Subscription},
diff --git a/bridges/relays/lib-substrate-relay/src/conversion_rate_update.rs b/bridges/relays/lib-substrate-relay/src/conversion_rate_update.rs
index ed13f4e5b35..3bd9a5a6a19 100644
--- a/bridges/relays/lib-substrate-relay/src/conversion_rate_update.rs
+++ b/bridges/relays/lib-substrate-relay/src/conversion_rate_update.rs
@@ -19,8 +19,8 @@
 use crate::{messages_lane::SubstrateMessageLane, TransactionParams};
 
 use relay_substrate_client::{
-	transaction_stall_timeout, AccountIdOf, AccountKeyPairOf, CallOf, Chain, Client, SignParam,
-	TransactionEra, TransactionSignScheme, UnsignedTransaction,
+	transaction_stall_timeout, AccountIdOf, AccountKeyPairOf, CallOf, Chain, ChainWithTransactions,
+	Client, SignParam, TransactionEra, UnsignedTransaction,
 };
 use relay_utils::metrics::F64SharedRef;
 use sp_core::Pair;
@@ -119,17 +119,17 @@ macro_rules! generate_mocked_update_conversion_rate_call_builder {
 ///
 /// The loop is maintaining the Left -> Right conversion rate, used as `RightTokens = LeftTokens *
 /// Rate`.
-pub fn run_conversion_rate_update_loop<Lane, Sign>(
+pub fn run_conversion_rate_update_loop<Lane>(
 	client: Client<Lane::SourceChain>,
-	transaction_params: TransactionParams<AccountKeyPairOf<Sign>>,
+	transaction_params: TransactionParams<AccountKeyPairOf<Lane::SourceChain>>,
 	left_to_right_stored_conversion_rate: F64SharedRef,
 	left_to_base_conversion_rate: F64SharedRef,
 	right_to_base_conversion_rate: F64SharedRef,
 	max_difference_ratio: f64,
 ) where
 	Lane: SubstrateMessageLane,
-	Sign: TransactionSignScheme<Chain = Lane::SourceChain>,
-	AccountIdOf<Lane::SourceChain>: From<<AccountKeyPairOf<Sign> as Pair>::Public>,
+	Lane::SourceChain: ChainWithTransactions,
+	AccountIdOf<Lane::SourceChain>: From<<AccountKeyPairOf<Lane::SourceChain> as Pair>::Public>,
 {
 	let stall_timeout = transaction_stall_timeout(
 		transaction_params.mortality,
@@ -169,7 +169,7 @@ pub fn run_conversion_rate_update_loop<Lane, Sign>(
 					new_conversion_rate,
 				);
 
-				let result = update_target_to_source_conversion_rate::<Lane, Sign>(
+				let result = update_target_to_source_conversion_rate::<Lane>(
 					client.clone(),
 					transaction_params.clone(),
 					new_conversion_rate,
@@ -253,15 +253,15 @@ async fn maybe_select_new_conversion_rate(
 }
 
 /// Update Target -> Source tokens conversion rate, stored in the Source runtime storage.
-pub async fn update_target_to_source_conversion_rate<Lane, Sign>(
+pub async fn update_target_to_source_conversion_rate<Lane>(
 	client: Client<Lane::SourceChain>,
-	transaction_params: TransactionParams<AccountKeyPairOf<Sign>>,
+	transaction_params: TransactionParams<AccountKeyPairOf<Lane::SourceChain>>,
 	updated_rate: f64,
 ) -> anyhow::Result<()>
 where
 	Lane: SubstrateMessageLane,
-	Sign: TransactionSignScheme<Chain = Lane::SourceChain>,
-	AccountIdOf<Lane::SourceChain>: From<<AccountKeyPairOf<Sign> as Pair>::Public>,
+	Lane::SourceChain: ChainWithTransactions,
+	AccountIdOf<Lane::SourceChain>: From<<AccountKeyPairOf<Lane::SourceChain> as Pair>::Public>,
 {
 	let genesis_hash = *client.genesis_hash();
 	let signer_id = transaction_params.signer.public().into();
@@ -273,7 +273,7 @@ where
 	client
 		.submit_signed_extrinsic(
 			signer_id,
-			SignParam::<Sign> {
+			SignParam::<Lane::SourceChain> {
 				spec_version,
 				transaction_version,
 				genesis_hash,
diff --git a/bridges/relays/lib-substrate-relay/src/finality/guards.rs b/bridges/relays/lib-substrate-relay/src/finality/guards.rs
index a3e69afe1b1..1451b549cc0 100644
--- a/bridges/relays/lib-substrate-relay/src/finality/guards.rs
+++ b/bridges/relays/lib-substrate-relay/src/finality/guards.rs
@@ -19,19 +19,19 @@
 use crate::TransactionParams;
 
 use relay_substrate_client::{
-	AccountIdOf, AccountKeyPairOf, ChainWithBalances, TransactionSignScheme,
+	AccountIdOf, AccountKeyPairOf, ChainWithBalances, ChainWithTransactions,
 };
 use sp_core::Pair;
 
 /// Start finality relay guards.
-pub async fn start<C: ChainWithBalances, S: TransactionSignScheme<Chain = C>>(
+pub async fn start<C: ChainWithBalances + ChainWithTransactions>(
 	target_client: &relay_substrate_client::Client<C>,
-	transaction_params: &TransactionParams<S::AccountKeyPair>,
+	transaction_params: &TransactionParams<AccountKeyPairOf<C>>,
 	enable_version_guard: bool,
 	maximal_balance_decrease_per_day: C::Balance,
 ) -> relay_substrate_client::Result<()>
 where
-	AccountIdOf<C>: From<<AccountKeyPairOf<S> as Pair>::Public>,
+	AccountIdOf<C>: From<<AccountKeyPairOf<C> as Pair>::Public>,
 {
 	if enable_version_guard {
 		relay_substrate_client::guard::abort_on_spec_version_change(
diff --git a/bridges/relays/lib-substrate-relay/src/finality/initialize.rs b/bridges/relays/lib-substrate-relay/src/finality/initialize.rs
index e25743180ee..6ff185800cc 100644
--- a/bridges/relays/lib-substrate-relay/src/finality/initialize.rs
+++ b/bridges/relays/lib-substrate-relay/src/finality/initialize.rs
@@ -24,7 +24,7 @@
 use crate::{error::Error, finality::engine::Engine};
 
 use relay_substrate_client::{
-	Chain, Client, Error as SubstrateError, SignParam, TransactionSignScheme, UnsignedTransaction,
+	Chain, ChainWithTransactions, Client, Error as SubstrateError, SignParam, UnsignedTransaction,
 };
 use sp_runtime::traits::Header as HeaderT;
 
@@ -32,7 +32,7 @@ use sp_runtime::traits::Header as HeaderT;
 pub async fn initialize<
 	E: Engine<SourceChain>,
 	SourceChain: Chain,
-	TargetChain: Chain + TransactionSignScheme<Chain = TargetChain>,
+	TargetChain: ChainWithTransactions,
 	F,
 >(
 	source_client: Client<SourceChain>,
@@ -80,7 +80,7 @@ pub async fn initialize<
 async fn do_initialize<
 	E: Engine<SourceChain>,
 	SourceChain: Chain,
-	TargetChain: Chain + TransactionSignScheme<Chain = TargetChain>,
+	TargetChain: ChainWithTransactions,
 	F,
 >(
 	source_client: Client<SourceChain>,
diff --git a/bridges/relays/lib-substrate-relay/src/finality/mod.rs b/bridges/relays/lib-substrate-relay/src/finality/mod.rs
index aefcd217225..5d7b52cd1de 100644
--- a/bridges/relays/lib-substrate-relay/src/finality/mod.rs
+++ b/bridges/relays/lib-substrate-relay/src/finality/mod.rs
@@ -31,8 +31,8 @@ use bp_header_chain::justification::GrandpaJustification;
 use finality_relay::FinalitySyncPipeline;
 use pallet_bridge_grandpa::{Call as BridgeGrandpaCall, Config as BridgeGrandpaConfig};
 use relay_substrate_client::{
-	transaction_stall_timeout, AccountIdOf, AccountKeyPairOf, BlockNumberOf, CallOf, Chain, Client,
-	HashOf, HeaderOf, SyncHeader, TransactionSignScheme,
+	transaction_stall_timeout, AccountIdOf, AccountKeyPairOf, BlockNumberOf, CallOf, Chain,
+	ChainWithTransactions, Client, HashOf, HeaderOf, SyncHeader,
 };
 use relay_utils::metrics::MetricsParams;
 use sp_core::Pair;
@@ -56,19 +56,17 @@ pub trait SubstrateFinalitySyncPipeline: 'static + Clone + Debug + Send + Sync {
 	/// Headers of this chain are submitted to the `TargetChain`.
 	type SourceChain: Chain;
 	/// Headers of the `SourceChain` are submitted to this chain.
-	type TargetChain: Chain;
+	type TargetChain: ChainWithTransactions;
 
 	/// Finality engine.
 	type FinalityEngine: Engine<Self::SourceChain>;
 	/// How submit finality proof call is built?
 	type SubmitFinalityProofCallBuilder: SubmitFinalityProofCallBuilder<Self>;
-	/// Scheme used to sign target chain transactions.
-	type TransactionSignScheme: TransactionSignScheme;
 
 	/// Add relay guards if required.
 	async fn start_relay_guards(
 		_target_client: &Client<Self::TargetChain>,
-		_transaction_params: &TransactionParams<AccountKeyPairOf<Self::TransactionSignScheme>>,
+		_transaction_params: &TransactionParams<AccountKeyPairOf<Self::TargetChain>>,
 		_enable_version_guard: bool,
 	) -> relay_substrate_client::Result<()> {
 		Ok(())
@@ -169,12 +167,11 @@ pub async fn run<P: SubstrateFinalitySyncPipeline>(
 	source_client: Client<P::SourceChain>,
 	target_client: Client<P::TargetChain>,
 	only_mandatory_headers: bool,
-	transaction_params: TransactionParams<AccountKeyPairOf<P::TransactionSignScheme>>,
+	transaction_params: TransactionParams<AccountKeyPairOf<P::TargetChain>>,
 	metrics_params: MetricsParams,
 ) -> anyhow::Result<()>
 where
-	AccountIdOf<P::TargetChain>: From<<AccountKeyPairOf<P::TransactionSignScheme> as Pair>::Public>,
-	P::TransactionSignScheme: TransactionSignScheme<Chain = P::TargetChain>,
+	AccountIdOf<P::TargetChain>: From<<AccountKeyPairOf<P::TargetChain> as Pair>::Public>,
 {
 	log::info!(
 		target: "bridge",
diff --git a/bridges/relays/lib-substrate-relay/src/finality/target.rs b/bridges/relays/lib-substrate-relay/src/finality/target.rs
index 132c3325343..09d9ad15f54 100644
--- a/bridges/relays/lib-substrate-relay/src/finality/target.rs
+++ b/bridges/relays/lib-substrate-relay/src/finality/target.rs
@@ -28,7 +28,7 @@ use async_trait::async_trait;
 use finality_relay::TargetClient;
 use relay_substrate_client::{
 	AccountIdOf, AccountKeyPairOf, Chain, Client, Error, HeaderIdOf, HeaderOf, SignParam,
-	SyncHeader, TransactionEra, TransactionSignScheme, TransactionTracker, UnsignedTransaction,
+	SyncHeader, TransactionEra, TransactionTracker, UnsignedTransaction,
 };
 use relay_utils::relay_loop::Client as RelayClient;
 use sp_core::Pair;
@@ -36,14 +36,14 @@ use sp_core::Pair;
 /// Substrate client as Substrate finality target.
 pub struct SubstrateFinalityTarget<P: SubstrateFinalitySyncPipeline> {
 	client: Client<P::TargetChain>,
-	transaction_params: TransactionParams<AccountKeyPairOf<P::TransactionSignScheme>>,
+	transaction_params: TransactionParams<AccountKeyPairOf<P::TargetChain>>,
 }
 
 impl<P: SubstrateFinalitySyncPipeline> SubstrateFinalityTarget<P> {
 	/// Create new Substrate headers target.
 	pub fn new(
 		client: Client<P::TargetChain>,
-		transaction_params: TransactionParams<AccountKeyPairOf<P::TransactionSignScheme>>,
+		transaction_params: TransactionParams<AccountKeyPairOf<P::TargetChain>>,
 	) -> Self {
 		SubstrateFinalityTarget { client, transaction_params }
 	}
@@ -86,8 +86,7 @@ impl<P: SubstrateFinalitySyncPipeline> RelayClient for SubstrateFinalityTarget<P
 impl<P: SubstrateFinalitySyncPipeline> TargetClient<FinalitySyncPipelineAdapter<P>>
 	for SubstrateFinalityTarget<P>
 where
-	AccountIdOf<P::TargetChain>: From<<AccountKeyPairOf<P::TransactionSignScheme> as Pair>::Public>,
-	P::TransactionSignScheme: TransactionSignScheme<Chain = P::TargetChain>,
+	AccountIdOf<P::TargetChain>: From<<AccountKeyPairOf<P::TargetChain> as Pair>::Public>,
 {
 	type TransactionTracker = TransactionTracker<P::TargetChain, Client<P::TargetChain>>;
 
@@ -120,7 +119,7 @@ where
 		self.client
 			.submit_and_watch_signed_extrinsic(
 				self.transaction_params.signer.public().into(),
-				SignParam::<P::TransactionSignScheme> {
+				SignParam::<P::TargetChain> {
 					spec_version,
 					transaction_version,
 					genesis_hash,
diff --git a/bridges/relays/lib-substrate-relay/src/messages_lane.rs b/bridges/relays/lib-substrate-relay/src/messages_lane.rs
index 72da8f20220..09d02f7448e 100644
--- a/bridges/relays/lib-substrate-relay/src/messages_lane.rs
+++ b/bridges/relays/lib-substrate-relay/src/messages_lane.rs
@@ -37,7 +37,7 @@ use messages_relay::{message_lane::MessageLane, relay_strategy::RelayStrategy};
 use pallet_bridge_messages::{Call as BridgeMessagesCall, Config as BridgeMessagesConfig};
 use relay_substrate_client::{
 	transaction_stall_timeout, AccountKeyPairOf, BalanceOf, BlockNumberOf, CallOf, Chain,
-	ChainWithMessages, Client, HashOf, TransactionSignScheme,
+	ChainWithMessages, ChainWithTransactions, Client, HashOf,
 };
 use relay_utils::{metrics::MetricsParams, STALL_TIMEOUT};
 use sp_core::Pair;
@@ -77,14 +77,9 @@ pub trait SubstrateMessageLane: 'static + Clone + Debug + Send + Sync {
 	const AT_TARGET_TRANSACTION_PAYMENT_PALLET_NAME: Option<&'static str>;
 
 	/// Messages of this chain are relayed to the `TargetChain`.
-	type SourceChain: ChainWithMessages;
+	type SourceChain: ChainWithMessages + ChainWithTransactions;
 	/// Messages from the `SourceChain` are dispatched on this chain.
-	type TargetChain: ChainWithMessages;
-
-	/// Scheme used to sign source chain transactions.
-	type SourceTransactionSignScheme: TransactionSignScheme;
-	/// Scheme used to sign target chain transactions.
-	type TargetTransactionSignScheme: TransactionSignScheme;
+	type TargetChain: ChainWithMessages + ChainWithTransactions;
 
 	/// How receive messages proof call is built?
 	type ReceiveMessagesProofCallBuilder: ReceiveMessagesProofCallBuilder<Self>;
@@ -128,13 +123,11 @@ pub struct MessagesRelayParams<P: SubstrateMessageLane> {
 	/// Messages source client.
 	pub source_client: Client<P::SourceChain>,
 	/// Source transaction params.
-	pub source_transaction_params:
-		TransactionParams<AccountKeyPairOf<P::SourceTransactionSignScheme>>,
+	pub source_transaction_params: TransactionParams<AccountKeyPairOf<P::SourceChain>>,
 	/// Messages target client.
 	pub target_client: Client<P::TargetChain>,
 	/// Target transaction params.
-	pub target_transaction_params:
-		TransactionParams<AccountKeyPairOf<P::TargetTransactionSignScheme>>,
+	pub target_transaction_params: TransactionParams<AccountKeyPairOf<P::TargetChain>>,
 	/// Optional on-demand source to target headers relay.
 	pub source_to_target_headers_relay:
 		Option<Arc<dyn OnDemandRelay<BlockNumberOf<P::SourceChain>>>>,
@@ -154,13 +147,9 @@ pub struct MessagesRelayParams<P: SubstrateMessageLane> {
 /// Run Substrate-to-Substrate messages sync loop.
 pub async fn run<P: SubstrateMessageLane>(params: MessagesRelayParams<P>) -> anyhow::Result<()>
 where
-	AccountIdOf<P::SourceChain>:
-		From<<AccountKeyPairOf<P::SourceTransactionSignScheme> as Pair>::Public>,
-	AccountIdOf<P::TargetChain>:
-		From<<AccountKeyPairOf<P::TargetTransactionSignScheme> as Pair>::Public>,
+	AccountIdOf<P::SourceChain>: From<<AccountKeyPairOf<P::SourceChain> as Pair>::Public>,
+	AccountIdOf<P::TargetChain>: From<<AccountKeyPairOf<P::TargetChain> as Pair>::Public>,
 	BalanceOf<P::SourceChain>: TryFrom<BalanceOf<P::TargetChain>>,
-	P::SourceTransactionSignScheme: TransactionSignScheme<Chain = P::SourceChain>,
-	P::TargetTransactionSignScheme: TransactionSignScheme<Chain = P::TargetChain>,
 {
 	let source_client = params.source_client;
 	let target_client = params.target_client;
diff --git a/bridges/relays/lib-substrate-relay/src/messages_source.rs b/bridges/relays/lib-substrate-relay/src/messages_source.rs
index c4e0f15f859..632c36a51bb 100644
--- a/bridges/relays/lib-substrate-relay/src/messages_source.rs
+++ b/bridges/relays/lib-substrate-relay/src/messages_source.rs
@@ -49,9 +49,9 @@ use messages_relay::{
 };
 use num_traits::{Bounded, Zero};
 use relay_substrate_client::{
-	AccountIdOf, AccountKeyPairOf, BalanceOf, BlockNumberOf, Chain, ChainWithMessages, Client,
-	Error as SubstrateError, HashOf, HeaderIdOf, IndexOf, SignParam, TransactionEra,
-	TransactionSignScheme, TransactionTracker, UnsignedTransaction,
+	AccountIdOf, AccountKeyPairOf, BalanceOf, BlockNumberOf, Chain, ChainWithMessages,
+	ChainWithTransactions, Client, Error as SubstrateError, HashOf, HeaderIdOf, IndexOf, SignParam,
+	TransactionEra, TransactionTracker, UnsignedTransaction,
 };
 use relay_utils::{relay_loop::Client as RelayClient, HeaderId};
 use sp_core::{Bytes, Pair};
@@ -69,7 +69,7 @@ pub struct SubstrateMessagesSource<P: SubstrateMessageLane> {
 	source_client: Client<P::SourceChain>,
 	target_client: Client<P::TargetChain>,
 	lane_id: LaneId,
-	transaction_params: TransactionParams<AccountKeyPairOf<P::SourceTransactionSignScheme>>,
+	transaction_params: TransactionParams<AccountKeyPairOf<P::SourceChain>>,
 	target_to_source_headers_relay: Option<Arc<dyn OnDemandRelay<BlockNumberOf<P::TargetChain>>>>,
 }
 
@@ -79,7 +79,7 @@ impl<P: SubstrateMessageLane> SubstrateMessagesSource<P> {
 		source_client: Client<P::SourceChain>,
 		target_client: Client<P::TargetChain>,
 		lane_id: LaneId,
-		transaction_params: TransactionParams<AccountKeyPairOf<P::SourceTransactionSignScheme>>,
+		transaction_params: TransactionParams<AccountKeyPairOf<P::SourceChain>>,
 		target_to_source_headers_relay: Option<
 			Arc<dyn OnDemandRelay<BlockNumberOf<P::TargetChain>>>,
 		>,
@@ -140,9 +140,7 @@ impl<P: SubstrateMessageLane> RelayClient for SubstrateMessagesSource<P> {
 #[async_trait]
 impl<P: SubstrateMessageLane> SourceClient<MessageLaneAdapter<P>> for SubstrateMessagesSource<P>
 where
-	AccountIdOf<P::SourceChain>:
-		From<<AccountKeyPairOf<P::SourceTransactionSignScheme> as Pair>::Public>,
-	P::SourceTransactionSignScheme: TransactionSignScheme<Chain = P::SourceChain>,
+	AccountIdOf<P::SourceChain>: From<<AccountKeyPairOf<P::SourceChain> as Pair>::Public>,
 {
 	type TransactionTracker = TransactionTracker<P::SourceChain, Client<P::SourceChain>>;
 
@@ -348,7 +346,7 @@ where
 		self.source_client
 			.submit_and_watch_signed_extrinsic(
 				self.transaction_params.signer.public().into(),
-				SignParam::<P::SourceTransactionSignScheme> {
+				SignParam::<P::SourceChain> {
 					spec_version,
 					transaction_version,
 					genesis_hash,
@@ -381,8 +379,8 @@ where
 			Err(_) => return BalanceOf::<P::SourceChain>::max_value(),
 		};
 		async {
-			let dummy_tx = P::SourceTransactionSignScheme::sign_transaction(
-				SignParam::<P::SourceTransactionSignScheme> {
+			let dummy_tx = P::SourceChain::sign_transaction(
+				SignParam::<P::SourceChain> {
 					spec_version: runtime_version.spec_version,
 					transaction_version: runtime_version.transaction_version,
 					genesis_hash: *self.source_client.genesis_hash(),
@@ -429,15 +427,12 @@ where
 
 /// Make messages delivery proof transaction from given proof.
 fn make_messages_delivery_proof_transaction<P: SubstrateMessageLane>(
-	source_transaction_params: &TransactionParams<AccountKeyPairOf<P::SourceTransactionSignScheme>>,
+	source_transaction_params: &TransactionParams<AccountKeyPairOf<P::SourceChain>>,
 	source_best_block_id: HeaderIdOf<P::SourceChain>,
 	transaction_nonce: IndexOf<P::SourceChain>,
 	proof: SubstrateMessagesDeliveryProof<P::TargetChain>,
 	trace_call: bool,
-) -> Result<UnsignedTransaction<P::SourceChain>, SubstrateError>
-where
-	P::SourceTransactionSignScheme: TransactionSignScheme<Chain = P::SourceChain>,
-{
+) -> Result<UnsignedTransaction<P::SourceChain>, SubstrateError> {
 	let call =
 		P::ReceiveMessagesDeliveryProofCallBuilder::build_receive_messages_delivery_proof_call(
 			proof, trace_call,
diff --git a/bridges/relays/lib-substrate-relay/src/messages_target.rs b/bridges/relays/lib-substrate-relay/src/messages_target.rs
index 46c3b6141cc..955f35942cf 100644
--- a/bridges/relays/lib-substrate-relay/src/messages_target.rs
+++ b/bridges/relays/lib-substrate-relay/src/messages_target.rs
@@ -43,9 +43,9 @@ use messages_relay::{
 };
 use num_traits::{Bounded, Zero};
 use relay_substrate_client::{
-	AccountIdOf, AccountKeyPairOf, BalanceOf, BlockNumberOf, Chain, ChainWithMessages, Client,
-	Error as SubstrateError, HashOf, HeaderIdOf, IndexOf, SignParam, TransactionEra,
-	TransactionSignScheme, TransactionTracker, UnsignedTransaction, WeightToFeeOf,
+	AccountIdOf, AccountKeyPairOf, BalanceOf, BlockNumberOf, Chain, ChainWithMessages,
+	ChainWithTransactions, Client, Error as SubstrateError, HashOf, HeaderIdOf, IndexOf, SignParam,
+	TransactionEra, TransactionTracker, UnsignedTransaction, WeightToFeeOf,
 };
 use relay_utils::{relay_loop::Client as RelayClient, HeaderId};
 use sp_core::{Bytes, Pair};
@@ -62,7 +62,7 @@ pub struct SubstrateMessagesTarget<P: SubstrateMessageLane> {
 	source_client: Client<P::SourceChain>,
 	lane_id: LaneId,
 	relayer_id_at_source: AccountIdOf<P::SourceChain>,
-	transaction_params: TransactionParams<AccountKeyPairOf<P::TargetTransactionSignScheme>>,
+	transaction_params: TransactionParams<AccountKeyPairOf<P::TargetChain>>,
 	metric_values: StandaloneMessagesMetrics<P::SourceChain, P::TargetChain>,
 	source_to_target_headers_relay: Option<Arc<dyn OnDemandRelay<BlockNumberOf<P::SourceChain>>>>,
 }
@@ -74,7 +74,7 @@ impl<P: SubstrateMessageLane> SubstrateMessagesTarget<P> {
 		source_client: Client<P::SourceChain>,
 		lane_id: LaneId,
 		relayer_id_at_source: AccountIdOf<P::SourceChain>,
-		transaction_params: TransactionParams<AccountKeyPairOf<P::TargetTransactionSignScheme>>,
+		transaction_params: TransactionParams<AccountKeyPairOf<P::TargetChain>>,
 		metric_values: StandaloneMessagesMetrics<P::SourceChain, P::TargetChain>,
 		source_to_target_headers_relay: Option<
 			Arc<dyn OnDemandRelay<BlockNumberOf<P::SourceChain>>>,
@@ -140,9 +140,7 @@ impl<P: SubstrateMessageLane> RelayClient for SubstrateMessagesTarget<P> {
 #[async_trait]
 impl<P: SubstrateMessageLane> TargetClient<MessageLaneAdapter<P>> for SubstrateMessagesTarget<P>
 where
-	AccountIdOf<P::TargetChain>:
-		From<<AccountKeyPairOf<P::TargetTransactionSignScheme> as Pair>::Public>,
-	P::TargetTransactionSignScheme: TransactionSignScheme<Chain = P::TargetChain>,
+	AccountIdOf<P::TargetChain>: From<<AccountKeyPairOf<P::TargetChain> as Pair>::Public>,
 	BalanceOf<P::SourceChain>: TryFrom<BalanceOf<P::TargetChain>>,
 {
 	type TransactionTracker = TransactionTracker<P::TargetChain, Client<P::TargetChain>>;
@@ -258,7 +256,7 @@ where
 			.target_client
 			.submit_and_watch_signed_extrinsic(
 				self.transaction_params.signer.public().into(),
-				SignParam::<P::TargetTransactionSignScheme> {
+				SignParam::<P::TargetChain> {
 					spec_version,
 					transaction_version,
 					genesis_hash,
@@ -305,7 +303,7 @@ where
 		let (spec_version, transaction_version) =
 			self.target_client.simple_runtime_version().await?;
 		// Prepare 'dummy' delivery transaction - we only care about its length and dispatch weight.
-		let delivery_tx = P::TargetTransactionSignScheme::sign_transaction(
+		let delivery_tx = P::TargetChain::sign_transaction(
 			SignParam {
 				spec_version,
 				transaction_version,
@@ -352,7 +350,7 @@ where
 			let (spec_version, transaction_version) =
 				self.target_client.simple_runtime_version().await?;
 			let larger_dispatch_weight = total_dispatch_weight.saturating_add(WEIGHT_DIFFERENCE);
-			let dummy_tx = P::TargetTransactionSignScheme::sign_transaction(
+			let dummy_tx = P::TargetChain::sign_transaction(
 				SignParam {
 					spec_version,
 					transaction_version,
@@ -425,17 +423,14 @@ where
 
 /// Make messages delivery transaction from given proof.
 fn make_messages_delivery_transaction<P: SubstrateMessageLane>(
-	target_transaction_params: &TransactionParams<AccountKeyPairOf<P::TargetTransactionSignScheme>>,
+	target_transaction_params: &TransactionParams<AccountKeyPairOf<P::TargetChain>>,
 	target_best_block_id: HeaderIdOf<P::TargetChain>,
 	transaction_nonce: IndexOf<P::TargetChain>,
 	relayer_id_at_source: AccountIdOf<P::SourceChain>,
 	nonces: RangeInclusive<MessageNonce>,
 	proof: SubstrateMessagesProof<P::SourceChain>,
 	trace_call: bool,
-) -> Result<UnsignedTransaction<P::TargetChain>, SubstrateError>
-where
-	P::TargetTransactionSignScheme: TransactionSignScheme<Chain = P::TargetChain>,
-{
+) -> Result<UnsignedTransaction<P::TargetChain>, SubstrateError> {
 	let messages_count = nonces.end() - nonces.start() + 1;
 	let dispatch_weight = proof.0;
 	let call = P::ReceiveMessagesProofCallBuilder::build_receive_messages_proof_call(
diff --git a/bridges/relays/lib-substrate-relay/src/on_demand/headers.rs b/bridges/relays/lib-substrate-relay/src/on_demand/headers.rs
index 3a54e6bb00c..c0603cda8cd 100644
--- a/bridges/relays/lib-substrate-relay/src/on_demand/headers.rs
+++ b/bridges/relays/lib-substrate-relay/src/on_demand/headers.rs
@@ -24,9 +24,7 @@ use num_traits::{One, Zero};
 use sp_runtime::traits::Header;
 
 use finality_relay::{FinalitySyncParams, TargetClient as FinalityTargetClient};
-use relay_substrate_client::{
-	AccountIdOf, AccountKeyPairOf, BlockNumberOf, Chain, Client, TransactionSignScheme,
-};
+use relay_substrate_client::{AccountIdOf, AccountKeyPairOf, BlockNumberOf, Chain, Client};
 use relay_utils::{
 	metrics::MetricsParams, relay_loop::Client as RelayClient, FailedClient, MaybeConnectionError,
 	STALL_TIMEOUT,
@@ -61,13 +59,12 @@ impl<SourceChain: Chain> OnDemandHeadersRelay<SourceChain> {
 	pub fn new<P: SubstrateFinalitySyncPipeline<SourceChain = SourceChain>>(
 		source_client: Client<P::SourceChain>,
 		target_client: Client<P::TargetChain>,
-		target_transaction_params: TransactionParams<AccountKeyPairOf<P::TransactionSignScheme>>,
+		target_transaction_params: TransactionParams<AccountKeyPairOf<P::TargetChain>>,
 		only_mandatory_headers: bool,
 	) -> Self
 	where
 		AccountIdOf<P::TargetChain>:
-			From<<AccountKeyPairOf<P::TransactionSignScheme> as sp_core::Pair>::Public>,
-		P::TransactionSignScheme: TransactionSignScheme<Chain = P::TargetChain>,
+			From<<AccountKeyPairOf<P::TargetChain> as sp_core::Pair>::Public>,
 	{
 		let required_header_number = Arc::new(Mutex::new(Zero::zero()));
 		let this = OnDemandHeadersRelay {
@@ -113,13 +110,11 @@ impl<SourceChain: Chain> OnDemandRelay<BlockNumberOf<SourceChain>>
 async fn background_task<P: SubstrateFinalitySyncPipeline>(
 	source_client: Client<P::SourceChain>,
 	target_client: Client<P::TargetChain>,
-	target_transaction_params: TransactionParams<AccountKeyPairOf<P::TransactionSignScheme>>,
+	target_transaction_params: TransactionParams<AccountKeyPairOf<P::TargetChain>>,
 	only_mandatory_headers: bool,
 	required_header_number: RequiredHeaderNumberRef<P::SourceChain>,
 ) where
-	AccountIdOf<P::TargetChain>:
-		From<<AccountKeyPairOf<P::TransactionSignScheme> as sp_core::Pair>::Public>,
-	P::TransactionSignScheme: TransactionSignScheme<Chain = P::TargetChain>,
+	AccountIdOf<P::TargetChain>: From<<AccountKeyPairOf<P::TargetChain> as sp_core::Pair>::Public>,
 {
 	let relay_task_name = on_demand_headers_relay_name::<P::SourceChain, P::TargetChain>();
 	let target_transactions_mortality = target_transaction_params.mortality;
@@ -389,9 +384,7 @@ async fn best_finalized_source_header_at_target<P: SubstrateFinalitySyncPipeline
 	relay_task_name: &str,
 ) -> Result<BlockNumberOf<P::SourceChain>, <SubstrateFinalityTarget<P> as RelayClient>::Error>
 where
-	AccountIdOf<P::TargetChain>:
-		From<<AccountKeyPairOf<P::TransactionSignScheme> as sp_core::Pair>::Public>,
-	P::TransactionSignScheme: TransactionSignScheme<Chain = P::TargetChain>,
+	AccountIdOf<P::TargetChain>: From<<AccountKeyPairOf<P::TargetChain> as sp_core::Pair>::Public>,
 {
 	finality_target
 		.best_finalized_source_block_id()
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 577312e16c1..35ef8244ae6 100644
--- a/bridges/relays/lib-substrate-relay/src/on_demand/parachains.rs
+++ b/bridges/relays/lib-substrate-relay/src/on_demand/parachains.rs
@@ -39,7 +39,6 @@ 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,
-	TransactionSignScheme,
 };
 use relay_utils::{
 	metrics::MetricsParams, relay_loop::Client as RelayClient, FailedClient, HeaderId,
@@ -68,7 +67,7 @@ impl<SourceParachain: Chain> OnDemandParachainsRelay<SourceParachain> {
 	pub fn new<P: SubstrateParachainsPipeline<SourceParachain = SourceParachain>>(
 		source_relay_client: Client<P::SourceRelayChain>,
 		target_client: Client<P::TargetChain>,
-		target_transaction_params: TransactionParams<AccountKeyPairOf<P::TransactionSignScheme>>,
+		target_transaction_params: TransactionParams<AccountKeyPairOf<P::TargetChain>>,
 		on_demand_source_relay_to_target_headers: Arc<
 			dyn OnDemandRelay<BlockNumberOf<P::SourceRelayChain>>,
 		>,
@@ -78,8 +77,7 @@ impl<SourceParachain: Chain> OnDemandParachainsRelay<SourceParachain> {
 		P::SourceRelayChain:
 			Chain<BlockNumber = RelayBlockNumber, Hash = RelayBlockHash, Hasher = RelayBlockHasher>,
 		AccountIdOf<P::TargetChain>:
-			From<<AccountKeyPairOf<P::TransactionSignScheme> as sp_core::Pair>::Public>,
-		P::TransactionSignScheme: TransactionSignScheme<Chain = P::TargetChain>,
+			From<<AccountKeyPairOf<P::TargetChain> as sp_core::Pair>::Public>,
 	{
 		let (required_header_number_sender, required_header_number_receiver) = unbounded();
 		let this = OnDemandParachainsRelay {
@@ -125,7 +123,7 @@ where
 async fn background_task<P: SubstrateParachainsPipeline>(
 	source_relay_client: Client<P::SourceRelayChain>,
 	target_client: Client<P::TargetChain>,
-	target_transaction_params: TransactionParams<AccountKeyPairOf<P::TransactionSignScheme>>,
+	target_transaction_params: TransactionParams<AccountKeyPairOf<P::TargetChain>>,
 	on_demand_source_relay_to_target_headers: Arc<
 		dyn OnDemandRelay<BlockNumberOf<P::SourceRelayChain>>,
 	>,
@@ -134,9 +132,7 @@ async fn background_task<P: SubstrateParachainsPipeline>(
 	P::SourceParachain: Chain<Hash = ParaHash>,
 	P::SourceRelayChain:
 		Chain<BlockNumber = RelayBlockNumber, Hash = RelayBlockHash, Hasher = RelayBlockHasher>,
-	AccountIdOf<P::TargetChain>:
-		From<<AccountKeyPairOf<P::TransactionSignScheme> as sp_core::Pair>::Public>,
-	P::TransactionSignScheme: TransactionSignScheme<Chain = P::TargetChain>,
+	AccountIdOf<P::TargetChain>: From<<AccountKeyPairOf<P::TargetChain> as sp_core::Pair>::Public>,
 {
 	let relay_task_name = on_demand_parachains_relay_name::<P::SourceParachain, P::TargetChain>();
 	let target_transactions_mortality = target_transaction_params.mortality;
diff --git a/bridges/relays/lib-substrate-relay/src/parachains/mod.rs b/bridges/relays/lib-substrate-relay/src/parachains/mod.rs
index f201476aa16..1d744a30e4e 100644
--- a/bridges/relays/lib-substrate-relay/src/parachains/mod.rs
+++ b/bridges/relays/lib-substrate-relay/src/parachains/mod.rs
@@ -24,7 +24,7 @@ use pallet_bridge_parachains::{
 	RelayBlockHasher, RelayBlockNumber,
 };
 use parachains_relay::ParachainsPipeline;
-use relay_substrate_client::{CallOf, Chain, HeaderIdOf, RelayChain, TransactionSignScheme};
+use relay_substrate_client::{CallOf, Chain, ChainWithTransactions, HeaderIdOf, RelayChain};
 use std::{fmt::Debug, marker::PhantomData};
 
 pub mod source;
@@ -41,12 +41,10 @@ pub trait SubstrateParachainsPipeline: 'static + Clone + Debug + Send + Sync {
 	/// Relay chain that is storing headers of `Self::SourceParachain`.
 	type SourceRelayChain: RelayChain;
 	/// Target chain where `Self::SourceParachain` headers are submitted.
-	type TargetChain: Chain;
+	type TargetChain: ChainWithTransactions;
 
 	/// How submit parachains heads call is built?
 	type SubmitParachainHeadsCallBuilder: SubmitParachainHeadsCallBuilder<Self>;
-	/// Scheme used to sign target chain transactions.
-	type TransactionSignScheme: TransactionSignScheme;
 
 	/// Id of the `Self::SourceParachain`, used for registration in `Self::SourceRelayChain`.
 	const SOURCE_PARACHAIN_PARA_ID: u32;
diff --git a/bridges/relays/lib-substrate-relay/src/parachains/target.rs b/bridges/relays/lib-substrate-relay/src/parachains/target.rs
index 8d0d361984f..c4022f12f5e 100644
--- a/bridges/relays/lib-substrate-relay/src/parachains/target.rs
+++ b/bridges/relays/lib-substrate-relay/src/parachains/target.rs
@@ -33,8 +33,8 @@ use parachains_relay::{
 };
 use relay_substrate_client::{
 	AccountIdOf, AccountKeyPairOf, BlockNumberOf, Chain, Client, Error as SubstrateError, HashOf,
-	HeaderIdOf, HeaderOf, RelayChain, SignParam, TransactionEra, TransactionSignScheme,
-	TransactionTracker, UnsignedTransaction,
+	HeaderIdOf, HeaderOf, RelayChain, SignParam, TransactionEra, TransactionTracker,
+	UnsignedTransaction,
 };
 use relay_utils::{relay_loop::Client as RelayClient, HeaderId};
 use sp_core::{Bytes, Pair};
@@ -43,14 +43,14 @@ use sp_runtime::traits::Header as HeaderT;
 /// Substrate client as parachain heads source.
 pub struct ParachainsTarget<P: SubstrateParachainsPipeline> {
 	client: Client<P::TargetChain>,
-	transaction_params: TransactionParams<AccountKeyPairOf<P::TransactionSignScheme>>,
+	transaction_params: TransactionParams<AccountKeyPairOf<P::TargetChain>>,
 }
 
 impl<P: SubstrateParachainsPipeline> ParachainsTarget<P> {
 	/// Creates new parachains target client.
 	pub fn new(
 		client: Client<P::TargetChain>,
-		transaction_params: TransactionParams<AccountKeyPairOf<P::TransactionSignScheme>>,
+		transaction_params: TransactionParams<AccountKeyPairOf<P::TargetChain>>,
 	) -> Self {
 		ParachainsTarget { client, transaction_params }
 	}
@@ -83,8 +83,7 @@ impl<P: SubstrateParachainsPipeline> RelayClient for ParachainsTarget<P> {
 impl<P> TargetClient<ParachainsPipelineAdapter<P>> for ParachainsTarget<P>
 where
 	P: SubstrateParachainsPipeline,
-	P::TransactionSignScheme: TransactionSignScheme<Chain = P::TargetChain>,
-	AccountIdOf<P::TargetChain>: From<<AccountKeyPairOf<P::TransactionSignScheme> as Pair>::Public>,
+	AccountIdOf<P::TargetChain>: From<<AccountKeyPairOf<P::TargetChain> as Pair>::Public>,
 {
 	type TransactionTracker = TransactionTracker<P::TargetChain, Client<P::TargetChain>>;
 
@@ -186,7 +185,7 @@ where
 		self.client
 			.submit_and_watch_signed_extrinsic(
 				self.transaction_params.signer.public().into(),
-				SignParam::<P::TransactionSignScheme> {
+				SignParam::<P::TargetChain> {
 					spec_version,
 					transaction_version,
 					genesis_hash,
-- 
GitLab