diff --git a/Cargo.lock b/Cargo.lock
index 314afb5476f313c025bdd3bdcba3adddb9dc302c..77fd61a99f772c780d68a8aab754f254248bc4df 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -790,6 +790,7 @@ name = "asset-hub-rococo-emulated-chain"
 version = "0.0.0"
 dependencies = [
  "asset-hub-rococo-runtime",
+ "bp-bridge-hub-rococo",
  "cumulus-primitives-core",
  "emulated-integration-tests-common",
  "frame-support",
@@ -915,6 +916,7 @@ name = "asset-hub-westend-emulated-chain"
 version = "0.0.0"
 dependencies = [
  "asset-hub-westend-runtime",
+ "bp-bridge-hub-westend",
  "cumulus-primitives-core",
  "emulated-integration-tests-common",
  "frame-support",
@@ -1792,7 +1794,9 @@ dependencies = [
  "bp-bridge-hub-cumulus",
  "bp-messages",
  "bp-runtime",
+ "bp-xcm-bridge-hub",
  "frame-support",
+ "parity-scale-codec",
  "sp-api",
  "sp-runtime",
  "sp-std 14.0.0",
@@ -1805,7 +1809,9 @@ dependencies = [
  "bp-bridge-hub-cumulus",
  "bp-messages",
  "bp-runtime",
+ "bp-xcm-bridge-hub",
  "frame-support",
+ "parity-scale-codec",
  "sp-api",
  "sp-runtime",
  "sp-std 14.0.0",
@@ -2077,6 +2083,7 @@ dependencies = [
  "pallet-bridge-messages",
  "pallet-message-queue",
  "pallet-xcm",
+ "pallet-xcm-bridge-hub",
  "parachains-common",
  "parity-scale-codec",
  "rococo-system-emulated-network",
@@ -2261,11 +2268,13 @@ dependencies = [
  "pallet-bridge-messages",
  "pallet-message-queue",
  "pallet-xcm",
+ "pallet-xcm-bridge-hub",
  "parachains-common",
  "rococo-westend-system-emulated-network",
  "sp-runtime",
  "staging-xcm",
  "staging-xcm-executor",
+ "testnet-parachains-constants",
 ]
 
 [[package]]
@@ -5184,6 +5193,7 @@ version = "3.0.0"
 dependencies = [
  "asset-test-utils",
  "bp-messages",
+ "bp-xcm-bridge-hub",
  "bridge-runtime-common",
  "cumulus-pallet-parachain-system",
  "cumulus-pallet-xcmp-queue",
@@ -5194,6 +5204,7 @@ dependencies = [
  "pallet-bridge-messages",
  "pallet-message-queue",
  "pallet-xcm",
+ "pallet-xcm-bridge-hub",
  "parachains-common",
  "parity-scale-codec",
  "paste",
diff --git a/bridges/chains/chain-bridge-hub-rococo/Cargo.toml b/bridges/chains/chain-bridge-hub-rococo/Cargo.toml
index 5c918470322353c32556c3e5d381fb2ea713b2ab..88e978f26ed25911e359dfc71e9f4c67e7fbd5f7 100644
--- a/bridges/chains/chain-bridge-hub-rococo/Cargo.toml
+++ b/bridges/chains/chain-bridge-hub-rococo/Cargo.toml
@@ -11,14 +11,15 @@ repository.workspace = true
 workspace = true
 
 [dependencies]
-# Bridge Dependencies
+codec = { features = ["derive"], workspace = true }
 
+# Bridge Dependencies
 bp-bridge-hub-cumulus = { workspace = true }
 bp-runtime = { workspace = true }
 bp-messages = { workspace = true }
+bp-xcm-bridge-hub = { workspace = true }
 
 # Substrate Based Dependencies
-
 frame-support = { workspace = true }
 sp-api = { workspace = true }
 sp-runtime = { workspace = true }
@@ -30,6 +31,8 @@ std = [
 	"bp-bridge-hub-cumulus/std",
 	"bp-messages/std",
 	"bp-runtime/std",
+	"bp-xcm-bridge-hub/std",
+	"codec/std",
 	"frame-support/std",
 	"sp-api/std",
 	"sp-runtime/std",
diff --git a/bridges/chains/chain-bridge-hub-rococo/src/lib.rs b/bridges/chains/chain-bridge-hub-rococo/src/lib.rs
index 73af997b9950ef640040e44cbba0b93b6a7a56a3..fd039254dc9c7ee77fc07e69f9af53ea0049c7dc 100644
--- a/bridges/chains/chain-bridge-hub-rococo/src/lib.rs
+++ b/bridges/chains/chain-bridge-hub-rococo/src/lib.rs
@@ -25,6 +25,7 @@ use bp_messages::*;
 use bp_runtime::{
 	decl_bridge_finality_runtime_apis, decl_bridge_messages_runtime_apis, Chain, ChainId, Parachain,
 };
+use codec::{Decode, Encode};
 use frame_support::{
 	dispatch::DispatchClass,
 	sp_runtime::{MultiAddress, MultiSigner, RuntimeDebug, StateVersion},
@@ -114,3 +115,11 @@ frame_support::parameter_types! {
 	/// (initially was calculated by test `BridgeHubRococo::can_calculate_fee_for_standalone_message_confirmation_transaction` + `33%`)
 	pub const BridgeHubRococoBaseConfirmationFeeInRocs: u128 = 57_414_813;
 }
+
+/// Wrapper over `BridgeHubRococo`'s `RuntimeCall` that can be used without a runtime.
+#[derive(Decode, Encode)]
+pub enum RuntimeCall {
+	/// Points to the `pallet_xcm_bridge_hub` pallet instance for `BridgeHubWestend`.
+	#[codec(index = 52)]
+	XcmOverBridgeHubWestend(bp_xcm_bridge_hub::XcmBridgeHubCall),
+}
diff --git a/bridges/chains/chain-bridge-hub-westend/Cargo.toml b/bridges/chains/chain-bridge-hub-westend/Cargo.toml
index 0b429ab9a0bd9793a9129ed8483a608f71bfb44c..1e5a88687ee92d22623239406f033a95a8d20068 100644
--- a/bridges/chains/chain-bridge-hub-westend/Cargo.toml
+++ b/bridges/chains/chain-bridge-hub-westend/Cargo.toml
@@ -11,15 +11,15 @@ repository.workspace = true
 workspace = true
 
 [dependencies]
+codec = { features = ["derive"], workspace = true }
 
 # Bridge Dependencies
-
 bp-bridge-hub-cumulus = { workspace = true }
 bp-runtime = { workspace = true }
 bp-messages = { workspace = true }
+bp-xcm-bridge-hub = { workspace = true }
 
 # Substrate Based Dependencies
-
 frame-support = { workspace = true }
 sp-api = { workspace = true }
 sp-runtime = { workspace = true }
@@ -31,6 +31,8 @@ std = [
 	"bp-bridge-hub-cumulus/std",
 	"bp-messages/std",
 	"bp-runtime/std",
+	"bp-xcm-bridge-hub/std",
+	"codec/std",
 	"frame-support/std",
 	"sp-api/std",
 	"sp-runtime/std",
diff --git a/bridges/chains/chain-bridge-hub-westend/src/lib.rs b/bridges/chains/chain-bridge-hub-westend/src/lib.rs
index 17ff2c858a1d3eeae329cb972d95adc32952ede4..8834fbb6be00d6185160a5726f544eefca42af16 100644
--- a/bridges/chains/chain-bridge-hub-westend/src/lib.rs
+++ b/bridges/chains/chain-bridge-hub-westend/src/lib.rs
@@ -24,6 +24,7 @@ use bp_messages::*;
 use bp_runtime::{
 	decl_bridge_finality_runtime_apis, decl_bridge_messages_runtime_apis, Chain, ChainId, Parachain,
 };
+use codec::{Decode, Encode};
 use frame_support::dispatch::DispatchClass;
 use sp_runtime::{RuntimeDebug, StateVersion};
 
@@ -103,3 +104,11 @@ frame_support::parameter_types! {
 	/// (initially was calculated by test `BridgeHubWestend::can_calculate_fee_for_standalone_message_confirmation_transaction` + `33%`)
 	pub const BridgeHubWestendBaseConfirmationFeeInWnds: u128 = 17_224_486_452;
 }
+
+/// Wrapper over `BridgeHubWestend`'s `RuntimeCall` that can be used without a runtime.
+#[derive(Decode, Encode)]
+pub enum RuntimeCall {
+	/// Points to the `pallet_xcm_bridge_hub` pallet instance for `BridgeHubRococo`.
+	#[codec(index = 45)]
+	XcmOverBridgeHubRococo(bp_xcm_bridge_hub::XcmBridgeHubCall),
+}
diff --git a/bridges/modules/xcm-bridge-hub/src/lib.rs b/bridges/modules/xcm-bridge-hub/src/lib.rs
index 0421c64b3d479d543dc0bd3591bea6be1606f985..3f3c45580866871e64898b5ba515a62f87c0c6d4 100644
--- a/bridges/modules/xcm-bridge-hub/src/lib.rs
+++ b/bridges/modules/xcm-bridge-hub/src/lib.rs
@@ -1437,4 +1437,43 @@ mod tests {
 			cleanup(bridge_id_mismatch, lane_id);
 		});
 	}
+
+	#[test]
+	fn ensure_encoding_compatibility() {
+		use codec::Encode;
+
+		let bridge_destination_universal_location = BridgedUniversalDestination::get();
+		let may_prune_messages = 13;
+
+		assert_eq!(
+			bp_xcm_bridge_hub::XcmBridgeHubCall::open_bridge {
+				bridge_destination_universal_location: Box::new(
+					bridge_destination_universal_location.clone().into()
+				)
+			}
+			.encode(),
+			Call::<TestRuntime, ()>::open_bridge {
+				bridge_destination_universal_location: Box::new(
+					bridge_destination_universal_location.clone().into()
+				)
+			}
+			.encode()
+		);
+		assert_eq!(
+			bp_xcm_bridge_hub::XcmBridgeHubCall::close_bridge {
+				bridge_destination_universal_location: Box::new(
+					bridge_destination_universal_location.clone().into()
+				),
+				may_prune_messages,
+			}
+			.encode(),
+			Call::<TestRuntime, ()>::close_bridge {
+				bridge_destination_universal_location: Box::new(
+					bridge_destination_universal_location.clone().into()
+				),
+				may_prune_messages,
+			}
+			.encode()
+		);
+	}
 }
diff --git a/bridges/primitives/xcm-bridge-hub/src/call_info.rs b/bridges/primitives/xcm-bridge-hub/src/call_info.rs
new file mode 100644
index 0000000000000000000000000000000000000000..fd4fc67822fe0c390deae6481e5f4cb84f9b0708
--- /dev/null
+++ b/bridges/primitives/xcm-bridge-hub/src/call_info.rs
@@ -0,0 +1,43 @@
+// Copyright (C) Parity Technologies (UK) Ltd.
+// This file is part of Parity Bridges Common.
+
+// Parity Bridges Common is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+
+// Parity Bridges Common is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with Parity Bridges Common.  If not, see <http://www.gnu.org/licenses/>.
+
+//! Defines structures related to calls of the `pallet-xcm-bridge-hub` pallet.
+
+use bp_messages::MessageNonce;
+use codec::{Decode, Encode};
+use scale_info::TypeInfo;
+use sp_std::boxed::Box;
+use xcm::prelude::VersionedInteriorLocation;
+
+/// A minimized version of `pallet_xcm_bridge_hub::Call` that can be used without a runtime.
+#[derive(Encode, Decode, Debug, PartialEq, Eq, Clone, TypeInfo)]
+#[allow(non_camel_case_types)]
+pub enum XcmBridgeHubCall {
+	/// `pallet_xcm_bridge_hub::Call::open_bridge`
+	#[codec(index = 0)]
+	open_bridge {
+		/// Universal `InteriorLocation` from the bridged consensus.
+		bridge_destination_universal_location: Box<VersionedInteriorLocation>,
+	},
+	/// `pallet_xcm_bridge_hub::Call::close_bridge`
+	#[codec(index = 1)]
+	close_bridge {
+		/// Universal `InteriorLocation` from the bridged consensus.
+		bridge_destination_universal_location: Box<VersionedInteriorLocation>,
+		/// The number of messages that we may prune in a single call.
+		may_prune_messages: MessageNonce,
+	},
+}
diff --git a/bridges/primitives/xcm-bridge-hub/src/lib.rs b/bridges/primitives/xcm-bridge-hub/src/lib.rs
index b2d5a51b95e37e0b951e6b77840464314f2cfc0d..44a90a57d4fbc6c423973ab89d6756b5832da1ff 100644
--- a/bridges/primitives/xcm-bridge-hub/src/lib.rs
+++ b/bridges/primitives/xcm-bridge-hub/src/lib.rs
@@ -21,6 +21,7 @@
 
 use bp_messages::LaneId;
 use bp_runtime::{AccountIdOf, BalanceOf, Chain};
+pub use call_info::XcmBridgeHubCall;
 use codec::{Decode, Encode, MaxEncodedLen};
 use frame_support::{
 	ensure, sp_runtime::RuntimeDebug, CloneNoBound, PalletError, PartialEqNoBound,
@@ -36,6 +37,8 @@ use xcm::{
 	VersionedLocation,
 };
 
+mod call_info;
+
 /// Encoded XCM blob. We expect the bridge messages pallet to use this blob type for both inbound
 /// and outbound payloads.
 pub type XcmAsPlainPayload = sp_std::vec::Vec<u8>;
diff --git a/cumulus/parachains/integration-tests/emulated/chains/parachains/assets/asset-hub-rococo/Cargo.toml b/cumulus/parachains/integration-tests/emulated/chains/parachains/assets/asset-hub-rococo/Cargo.toml
index 7bd91ae6774c61f93b12a91af298e64777980ac1..7584c5c64003805671ec58299edf944ca885b5c4 100644
--- a/cumulus/parachains/integration-tests/emulated/chains/parachains/assets/asset-hub-rococo/Cargo.toml
+++ b/cumulus/parachains/integration-tests/emulated/chains/parachains/assets/asset-hub-rococo/Cargo.toml
@@ -26,3 +26,6 @@ testnet-parachains-constants = { features = ["rococo"], workspace = true, defaul
 
 # Polkadot
 xcm = { workspace = true }
+
+# Bridges
+bp-bridge-hub-rococo = { workspace = true }
\ No newline at end of file
diff --git a/cumulus/parachains/integration-tests/emulated/chains/parachains/assets/asset-hub-rococo/src/lib.rs b/cumulus/parachains/integration-tests/emulated/chains/parachains/assets/asset-hub-rococo/src/lib.rs
index 80d2376c6811d7e8f407330dd3c2b02a5260159b..1c0a75c13758b824ee88d84d7f2202a278ce1b67 100644
--- a/cumulus/parachains/integration-tests/emulated/chains/parachains/assets/asset-hub-rococo/src/lib.rs
+++ b/cumulus/parachains/integration-tests/emulated/chains/parachains/assets/asset-hub-rococo/src/lib.rs
@@ -24,8 +24,8 @@ use frame_support::traits::OnInitialize;
 use emulated_integration_tests_common::{
 	impl_accounts_helpers_for_parachain, impl_assert_events_helpers_for_parachain,
 	impl_assets_helpers_for_parachain, impl_assets_helpers_for_system_parachain,
-	impl_foreign_assets_helpers_for_parachain, impl_xcm_helpers_for_parachain, impls::Parachain,
-	xcm_emulator::decl_test_parachains,
+	impl_bridge_helpers_for_chain, impl_foreign_assets_helpers_for_parachain,
+	impl_xcm_helpers_for_parachain, impls::Parachain, xcm_emulator::decl_test_parachains,
 };
 use rococo_emulated_chain::Rococo;
 
@@ -61,3 +61,9 @@ impl_assets_helpers_for_system_parachain!(AssetHubRococo, Rococo);
 impl_assets_helpers_for_parachain!(AssetHubRococo);
 impl_foreign_assets_helpers_for_parachain!(AssetHubRococo, xcm::v3::Location);
 impl_xcm_helpers_for_parachain!(AssetHubRococo);
+impl_bridge_helpers_for_chain!(
+	AssetHubRococo,
+	ParaPallet,
+	PolkadotXcm,
+	bp_bridge_hub_rococo::RuntimeCall::XcmOverBridgeHubWestend
+);
diff --git a/cumulus/parachains/integration-tests/emulated/chains/parachains/assets/asset-hub-westend/Cargo.toml b/cumulus/parachains/integration-tests/emulated/chains/parachains/assets/asset-hub-westend/Cargo.toml
index 86d4ce3e7ac829e959aa3169adbd22a257cc26a5..0d5b06ed47005b216f03804c6cb1ea41e4f5f42f 100644
--- a/cumulus/parachains/integration-tests/emulated/chains/parachains/assets/asset-hub-westend/Cargo.toml
+++ b/cumulus/parachains/integration-tests/emulated/chains/parachains/assets/asset-hub-westend/Cargo.toml
@@ -26,3 +26,6 @@ testnet-parachains-constants = { features = ["westend"], workspace = true, defau
 
 # Polkadot
 xcm = { workspace = true }
+
+# Bridges
+bp-bridge-hub-westend = { workspace = true }
\ No newline at end of file
diff --git a/cumulus/parachains/integration-tests/emulated/chains/parachains/assets/asset-hub-westend/src/lib.rs b/cumulus/parachains/integration-tests/emulated/chains/parachains/assets/asset-hub-westend/src/lib.rs
index 608690218d2f4c439511e508e261fe3e74d37465..e484d908df291395fb8d322bcfb82ff846b3e7d3 100644
--- a/cumulus/parachains/integration-tests/emulated/chains/parachains/assets/asset-hub-westend/src/lib.rs
+++ b/cumulus/parachains/integration-tests/emulated/chains/parachains/assets/asset-hub-westend/src/lib.rs
@@ -24,8 +24,8 @@ use frame_support::traits::OnInitialize;
 use emulated_integration_tests_common::{
 	impl_accounts_helpers_for_parachain, impl_assert_events_helpers_for_parachain,
 	impl_assets_helpers_for_parachain, impl_assets_helpers_for_system_parachain,
-	impl_foreign_assets_helpers_for_parachain, impl_xcm_helpers_for_parachain, impls::Parachain,
-	xcm_emulator::decl_test_parachains,
+	impl_bridge_helpers_for_chain, impl_foreign_assets_helpers_for_parachain,
+	impl_xcm_helpers_for_parachain, impls::Parachain, xcm_emulator::decl_test_parachains,
 };
 use westend_emulated_chain::Westend;
 
@@ -61,3 +61,9 @@ impl_assets_helpers_for_system_parachain!(AssetHubWestend, Westend);
 impl_assets_helpers_for_parachain!(AssetHubWestend);
 impl_foreign_assets_helpers_for_parachain!(AssetHubWestend, xcm::v3::Location);
 impl_xcm_helpers_for_parachain!(AssetHubWestend);
+impl_bridge_helpers_for_chain!(
+	AssetHubWestend,
+	ParaPallet,
+	PolkadotXcm,
+	bp_bridge_hub_westend::RuntimeCall::XcmOverBridgeHubRococo
+);
diff --git a/cumulus/parachains/integration-tests/emulated/common/Cargo.toml b/cumulus/parachains/integration-tests/emulated/common/Cargo.toml
index 7152f1dbc272bd8eef49e2343b2c5cbbeb9f1ba4..981ee5c88b4e28e57b4ff9c8361ca64432305471 100644
--- a/cumulus/parachains/integration-tests/emulated/common/Cargo.toml
+++ b/cumulus/parachains/integration-tests/emulated/common/Cargo.toml
@@ -42,5 +42,7 @@ asset-test-utils = { workspace = true, default-features = true }
 
 # Bridges
 bp-messages = { workspace = true, default-features = true }
+bp-xcm-bridge-hub = { workspace = true, default-features = true }
 pallet-bridge-messages = { workspace = true, default-features = true }
+pallet-xcm-bridge-hub = { workspace = true, default-features = true }
 bridge-runtime-common = { workspace = true, default-features = true }
diff --git a/cumulus/parachains/integration-tests/emulated/common/src/impls.rs b/cumulus/parachains/integration-tests/emulated/common/src/impls.rs
index 8f2789eb2f3a0e45d5c98263a16a118bd63cb425..559a16379bb410150cbf569bfa60a4e99be45cb2 100644
--- a/cumulus/parachains/integration-tests/emulated/common/src/impls.rs
+++ b/cumulus/parachains/integration-tests/emulated/common/src/impls.rs
@@ -17,7 +17,8 @@ pub use codec::{Decode, Encode};
 pub use paste;
 
 pub use crate::{
-	xcm_helpers::xcm_transact_unpaid_execution, PROOF_SIZE_THRESHOLD, REF_TIME_THRESHOLD,
+	xcm_helpers::{xcm_transact_paid_execution, xcm_transact_unpaid_execution},
+	PROOF_SIZE_THRESHOLD, REF_TIME_THRESHOLD,
 };
 
 // Substrate
@@ -30,7 +31,6 @@ pub use frame_support::{
 pub use pallet_assets;
 pub use pallet_message_queue;
 pub use pallet_xcm;
-use sp_core::Get;
 
 // Polkadot
 pub use polkadot_runtime_parachains::{
@@ -38,7 +38,9 @@ pub use polkadot_runtime_parachains::{
 	inclusion::{AggregateMessageOrigin, UmpQueueId},
 };
 pub use xcm::{
-	prelude::{Location, OriginKind, Outcome, VersionedXcm, XcmError, XcmVersion},
+	prelude::{
+		Asset, InteriorLocation, Location, OriginKind, Outcome, VersionedXcm, XcmError, XcmVersion,
+	},
 	DoubleEncoded,
 };
 
@@ -51,7 +53,7 @@ pub use cumulus_primitives_core::{
 };
 pub use parachains_common::{AccountId, Balance};
 pub use xcm_emulator::{
-	assert_expected_events, bx, helpers::weight_within_threshold, BridgeMessage,
+	assert_expected_events, bx, helpers::weight_within_threshold, BridgeLaneId, BridgeMessage,
 	BridgeMessageDispatchError, BridgeMessageHandler, Chain, Network, Parachain, RelayChain,
 	TestExt,
 };
@@ -61,60 +63,60 @@ use bp_messages::{
 	target_chain::{DispatchMessage, DispatchMessageData, MessageDispatch},
 	LaneId, MessageKey, OutboundLaneData,
 };
-use bridge_runtime_common::messages_xcm_extension::XcmBlobMessageDispatchResult;
-use pallet_bridge_messages::{Config, OutboundLanes, Pallet};
+pub use bp_xcm_bridge_hub::XcmBridgeHubCall;
+use pallet_bridge_messages::{Config as BridgeMessagesConfig, OutboundLanes, Pallet};
 pub use pallet_bridge_messages::{
 	Instance1 as BridgeMessagesInstance1, Instance2 as BridgeMessagesInstance2,
 	Instance3 as BridgeMessagesInstance3,
 };
+use pallet_xcm_bridge_hub::XcmBlobMessageDispatchResult;
 
 pub struct BridgeHubMessageHandler<S, SI, T, TI> {
 	_marker: std::marker::PhantomData<(S, SI, T, TI)>,
 }
 
 struct LaneIdWrapper(LaneId);
-
-impl From<LaneIdWrapper> for u32 {
-	fn from(lane_id: LaneIdWrapper) -> u32 {
-		u32::from_be_bytes(lane_id.0 .0)
+impl From<LaneIdWrapper> for BridgeLaneId {
+	fn from(lane_id: LaneIdWrapper) -> BridgeLaneId {
+		lane_id.0.encode()
 	}
 }
-
-impl From<u32> for LaneIdWrapper {
-	fn from(id: u32) -> LaneIdWrapper {
-		LaneIdWrapper(LaneId(id.to_be_bytes()))
+impl From<BridgeLaneId> for LaneIdWrapper {
+	fn from(id: BridgeLaneId) -> LaneIdWrapper {
+		LaneIdWrapper(LaneId::decode(&mut &id[..]).expect("decodable"))
 	}
 }
 
 impl<S, SI, T, TI> BridgeMessageHandler for BridgeHubMessageHandler<S, SI, T, TI>
 where
-	S: Config<SI>,
+	S: BridgeMessagesConfig<SI>,
 	SI: 'static,
-	T: Config<TI>,
+	T: BridgeMessagesConfig<TI>,
 	TI: 'static,
-	<T as Config<TI>>::InboundPayload: From<Vec<u8>>,
-	<T as Config<TI>>::MessageDispatch:
+	<T as BridgeMessagesConfig<TI>>::InboundPayload: From<Vec<u8>>,
+	<T as BridgeMessagesConfig<TI>>::MessageDispatch:
 		MessageDispatch<DispatchLevelResult = XcmBlobMessageDispatchResult>,
 {
 	fn get_source_outbound_messages() -> Vec<BridgeMessage> {
 		// get the source active outbound lanes
-		let active_lanes = S::ActiveOutboundLanes::get();
+		let active_outbound_lanes = OutboundLanes::<S, SI>::iter_keys();
 
 		let mut messages: Vec<BridgeMessage> = Default::default();
 
 		// collect messages from `OutboundMessages` for each active outbound lane in the source
-		for lane in active_lanes {
-			let latest_generated_nonce = OutboundLanes::<S, SI>::get(lane).latest_generated_nonce;
-			let latest_received_nonce = OutboundLanes::<S, SI>::get(lane).latest_received_nonce;
+		for lane in active_outbound_lanes {
+			let latest_generated_nonce =
+				OutboundLanes::<S, SI>::get(lane).unwrap().latest_generated_nonce;
+			let latest_received_nonce =
+				OutboundLanes::<S, SI>::get(lane).unwrap().latest_received_nonce;
 
 			(latest_received_nonce + 1..=latest_generated_nonce).for_each(|nonce| {
-				let encoded_payload: Vec<u8> = Pallet::<S, SI>::outbound_message_data(*lane, nonce)
+				let encoded_payload: Vec<u8> = Pallet::<S, SI>::outbound_message_data(lane, nonce)
 					.expect("Bridge message does not exist")
 					.into();
 				let payload = Vec::<u8>::decode(&mut &encoded_payload[..])
 					.expect("Decoding XCM message failed");
-				let id: u32 = LaneIdWrapper(*lane).into();
-				let message = BridgeMessage { id, nonce, payload };
+				let message = BridgeMessage { lane_id: LaneIdWrapper(lane).into(), nonce, payload };
 
 				messages.push(message);
 			});
@@ -125,10 +127,10 @@ where
 	fn dispatch_target_inbound_message(
 		message: BridgeMessage,
 	) -> Result<(), BridgeMessageDispatchError> {
-		type TargetMessageDispatch<T, I> = <T as Config<I>>::MessageDispatch;
-		type InboundPayload<T, I> = <T as Config<I>>::InboundPayload;
+		type TargetMessageDispatch<T, I> = <T as BridgeMessagesConfig<I>>::MessageDispatch;
+		type InboundPayload<T, I> = <T as BridgeMessagesConfig<I>>::InboundPayload;
 
-		let lane_id = LaneIdWrapper::from(message.id).0;
+		let lane_id = LaneIdWrapper::from(message.lane_id).0;
 		let nonce = message.nonce;
 		let payload = Ok(From::from(message.payload));
 
@@ -151,15 +153,16 @@ where
 		result
 	}
 
-	fn notify_source_message_delivery(lane_id: u32) {
-		let data = OutboundLanes::<S, SI>::get(LaneIdWrapper::from(lane_id).0);
+	fn notify_source_message_delivery(lane_id: BridgeLaneId) {
+		let lane_id = LaneIdWrapper::from(lane_id).0;
+		let data = OutboundLanes::<S, SI>::get(lane_id).unwrap();
 		let new_data = OutboundLaneData {
 			oldest_unpruned_nonce: data.oldest_unpruned_nonce + 1,
 			latest_received_nonce: data.latest_received_nonce + 1,
 			..data
 		};
 
-		OutboundLanes::<S, SI>::insert(LaneIdWrapper::from(lane_id).0, new_data);
+		OutboundLanes::<S, SI>::insert(lane_id, new_data);
 	}
 }
 
@@ -925,3 +928,49 @@ macro_rules! impl_xcm_helpers_for_parachain {
 		}
 	}
 }
+
+#[macro_export]
+macro_rules! impl_bridge_helpers_for_chain {
+	( $chain:ident, $pallet:ident, $pallet_xcm:ident, $runtime_call_wrapper:path ) => {
+		$crate::impls::paste::paste! {
+			impl<N: $crate::impls::Network> $chain<N> {
+				/// Open bridge with `dest`.
+				pub fn open_bridge(
+					bridge_location: $crate::impls::Location,
+					bridge_destination_universal_location: $crate::impls::InteriorLocation,
+					maybe_paid: Option<($crate::impls::Asset, $crate::impls::AccountId)>
+				) {
+					<Self as $crate::impls::TestExt>::execute_with(|| {
+						use $crate::impls::{bx, Chain};
+						use $crate::impls::XcmBridgeHubCall;
+						use $crate::impls::Encode;
+
+						// important to use `root` and `OriginKind::Xcm`
+						let root_origin = <Self as Chain>::RuntimeOrigin::root();
+
+						// construct call
+						let call: $crate::impls::DoubleEncoded<()> = $runtime_call_wrapper(XcmBridgeHubCall::open_bridge {
+							bridge_destination_universal_location: bx!(
+								bridge_destination_universal_location.clone().into()
+							)
+						}).encode().into();
+
+						let xcm = if let Some((fee_asset, beneficiary)) = maybe_paid {
+							$crate::impls::xcm_transact_paid_execution(call, $crate::impls::OriginKind::Xcm, fee_asset, beneficiary)
+						} else {
+							$crate::impls::xcm_transact_unpaid_execution(call, $crate::impls::OriginKind::Xcm)
+						};
+
+						// Send XCM `Transact` with `open_bridge` call
+						$crate::impls::assert_ok!(<Self as [<$chain $pallet>]>::$pallet_xcm::send(
+							root_origin,
+							bx!(bridge_location.into()),
+							bx!(xcm),
+						));
+						Self::assert_xcm_pallet_sent();
+					});
+				}
+			}
+		}
+	}
+}
diff --git a/cumulus/parachains/integration-tests/emulated/common/src/xcm_helpers.rs b/cumulus/parachains/integration-tests/emulated/common/src/xcm_helpers.rs
index 76179c6d82c6e904b122a42bdc76eec86aa74a09..54e0e95a0a6b7c345f0ab9216922e3211a0ba8e7 100644
--- a/cumulus/parachains/integration-tests/emulated/common/src/xcm_helpers.rs
+++ b/cumulus/parachains/integration-tests/emulated/common/src/xcm_helpers.rs
@@ -23,16 +23,16 @@ use xcm::{prelude::*, DoubleEncoded};
 pub fn xcm_transact_paid_execution(
 	call: DoubleEncoded<()>,
 	origin_kind: OriginKind,
-	native_asset: Asset,
+	asset: Asset,
 	beneficiary: AccountId,
 ) -> VersionedXcm<()> {
 	let weight_limit = WeightLimit::Unlimited;
 	let require_weight_at_most = Weight::from_parts(1000000000, 200000);
-	let native_assets: Assets = native_asset.clone().into();
+	let native_assets: Assets = asset.clone().into();
 
 	VersionedXcm::from(Xcm(vec![
 		WithdrawAsset(native_assets),
-		BuyExecution { fees: native_asset, weight_limit },
+		BuyExecution { fees: asset, weight_limit },
 		Transact { require_weight_at_most, origin_kind, call },
 		RefundSurplus,
 		DepositAsset {
diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/Cargo.toml b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/Cargo.toml
index a5787885329d75a05fe50ce18690fd6d4076db51..86ace7d564e8a877016ab350293f1dba94337592 100644
--- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/Cargo.toml
+++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/Cargo.toml
@@ -31,6 +31,7 @@ xcm-executor = { workspace = true }
 
 # Bridges
 pallet-bridge-messages = { workspace = true }
+pallet-xcm-bridge-hub = { workspace = true }
 
 # Cumulus
 cumulus-pallet-xcmp-queue = { workspace = true }
@@ -38,7 +39,7 @@ emulated-integration-tests-common = { workspace = true }
 parachains-common = { workspace = true, default-features = true }
 rococo-system-emulated-network = { workspace = true }
 rococo-westend-system-emulated-network = { workspace = true }
-testnet-parachains-constants = { features = ["rococo"], workspace = true, default-features = true }
+testnet-parachains-constants = { features = ["rococo", "westend"], workspace = true, default-features = true }
 
 # Snowbridge
 snowbridge-core = { workspace = true }
diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/asset_transfers.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/asset_transfers.rs
index 6053936487b26e97fe8575cd5b666a03cff7ccf6..4929923666978480aa5154e93e0188033f016550 100644
--- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/asset_transfers.rs
+++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/asset_transfers.rs
@@ -25,6 +25,9 @@ fn send_assets_over_bridge<F: FnOnce()>(send_fn: F) {
 	AssetHubRococo::force_xcm_version(asset_hub_westend_location(), XCM_VERSION);
 	BridgeHubRococo::force_xcm_version(bridge_hub_westend_location(), XCM_VERSION);
 
+	// open bridge
+	open_bridge_between_asset_hub_rococo_and_asset_hub_westend();
+
 	// send message over bridge
 	send_fn();
 
diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/mod.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/mod.rs
index ceccf98a0240dade42b8a00372e1ee8737cf1e03..0696a8e5529040cd158851dbc0e8a7a1e8bd6e5d 100644
--- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/mod.rs
+++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/mod.rs
@@ -36,7 +36,10 @@ pub(crate) fn bridged_roc_at_ah_westend() -> Location {
 	Location::new(2, [GlobalConsensus(Rococo)])
 }
 
-// wWND
+// WND and wWND
+pub(crate) fn wnd_at_ah_westend() -> Location {
+	Parent.into()
+}
 pub(crate) fn bridged_wnd_at_ah_rococo() -> Location {
 	Location::new(2, [GlobalConsensus(Westend)])
 }
@@ -210,3 +213,57 @@ pub(crate) fn assert_bridge_hub_westend_message_received() {
 		);
 	})
 }
+
+pub(crate) fn open_bridge_between_asset_hub_rococo_and_asset_hub_westend() {
+	use testnet_parachains_constants::{
+		rococo::currency::UNITS as ROC, westend::currency::UNITS as WND,
+	};
+
+	// open AHR -> AHW
+	BridgeHubRococo::fund_para_sovereign(AssetHubRococo::para_id(), ROC * 5);
+	AssetHubRococo::open_bridge(
+		AssetHubRococo::sibling_location_of(BridgeHubRococo::para_id()),
+		[GlobalConsensus(Westend), Parachain(AssetHubWestend::para_id().into())].into(),
+		Some((
+			(roc_at_ah_rococo(), ROC * 1).into(),
+			BridgeHubRococo::sovereign_account_id_of(BridgeHubRococo::sibling_location_of(
+				AssetHubRococo::para_id(),
+			)),
+		)),
+	);
+	BridgeHubRococo::execute_with(|| {
+		type RuntimeEvent = <BridgeHubRococo as Chain>::RuntimeEvent;
+		assert_expected_events!(
+			BridgeHubRococo,
+			vec![
+				RuntimeEvent::XcmOverBridgeHubWestend(
+					pallet_xcm_bridge_hub::Event::BridgeOpened { .. }
+				) => {},
+			]
+		);
+	});
+
+	// open AHW -> AHR
+	BridgeHubWestend::fund_para_sovereign(AssetHubWestend::para_id(), WND * 5);
+	AssetHubWestend::open_bridge(
+		AssetHubWestend::sibling_location_of(BridgeHubWestend::para_id()),
+		[GlobalConsensus(Rococo), Parachain(AssetHubRococo::para_id().into())].into(),
+		Some((
+			(wnd_at_ah_westend(), WND * 1).into(),
+			BridgeHubWestend::sovereign_account_id_of(BridgeHubWestend::sibling_location_of(
+				AssetHubWestend::para_id(),
+			)),
+		)),
+	);
+	BridgeHubWestend::execute_with(|| {
+		type RuntimeEvent = <BridgeHubWestend as Chain>::RuntimeEvent;
+		assert_expected_events!(
+			BridgeHubWestend,
+			vec![
+				RuntimeEvent::XcmOverBridgeHubRococo(
+					pallet_xcm_bridge_hub::Event::BridgeOpened { .. }
+				) => {},
+			]
+		);
+	});
+}
diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/send_xcm.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/send_xcm.rs
index 652447fa56010918d8816187207bc86e2ae99ea5..18752b81d79ef7b83e9c453c46a5f9ef4c6eaac8 100644
--- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/send_xcm.rs
+++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-rococo/src/tests/send_xcm.rs
@@ -79,6 +79,9 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() {
 	// fund sender
 	AssetHubRococo::fund_accounts(vec![(AssetHubRococoSender::get().into(), amount * 10)]);
 
+	// open bridge
+	open_bridge_between_asset_hub_rococo_and_asset_hub_westend();
+
 	// send XCM from AssetHubRococo - fails - destination version not known
 	assert_err!(
 		send_assets_from_asset_hub_rococo(
diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/Cargo.toml b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/Cargo.toml
index 6b83479eaf89a5677a77816b748948c8ba93fa53..2d20cd48474b13289d080894a9ad0f4620fdf97c 100644
--- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/Cargo.toml
+++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/Cargo.toml
@@ -28,9 +28,11 @@ xcm-executor = { workspace = true }
 
 # Bridges
 pallet-bridge-messages = { workspace = true }
+pallet-xcm-bridge-hub = { workspace = true }
 
 # Cumulus
 cumulus-pallet-xcmp-queue = { workspace = true }
 emulated-integration-tests-common = { workspace = true }
 parachains-common = { workspace = true, default-features = true }
 rococo-westend-system-emulated-network = { workspace = true }
+testnet-parachains-constants = { features = ["rococo", "westend"], workspace = true, default-features = true }
diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/asset_transfers.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/asset_transfers.rs
index 0c0b04cd45a91c42592052799ba9580bd6e4219a..baf01ea9d46e43fd612519f80af9346768d49945 100644
--- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/asset_transfers.rs
+++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/asset_transfers.rs
@@ -24,6 +24,9 @@ fn send_assets_over_bridge<F: FnOnce()>(send_fn: F) {
 	AssetHubWestend::force_xcm_version(asset_hub_rococo_location(), XCM_VERSION);
 	BridgeHubWestend::force_xcm_version(bridge_hub_rococo_location(), XCM_VERSION);
 
+	// open bridge
+	open_bridge_between_asset_hub_rococo_and_asset_hub_westend();
+
 	// send message over bridge
 	send_fn();
 
diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/mod.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/mod.rs
index 768b647a13fc19fae244a6ede2f8d527726e9963..194e8bec246593626bc2b1c0231d76872b617291 100644
--- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/mod.rs
+++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/mod.rs
@@ -41,7 +41,10 @@ pub(crate) fn bridged_wnd_at_ah_rococo() -> Location {
 	Location::new(2, [GlobalConsensus(Westend)])
 }
 
-// wROC
+// ROC and wROC
+pub(crate) fn roc_at_ah_rococo() -> Location {
+	Parent.into()
+}
 pub(crate) fn bridged_roc_at_ah_westend() -> Location {
 	Location::new(2, [GlobalConsensus(Rococo)])
 }
@@ -228,3 +231,57 @@ pub(crate) fn assert_bridge_hub_rococo_message_received() {
 		);
 	})
 }
+
+pub(crate) fn open_bridge_between_asset_hub_rococo_and_asset_hub_westend() {
+	use testnet_parachains_constants::{
+		rococo::currency::UNITS as ROC, westend::currency::UNITS as WND,
+	};
+
+	// open AHR -> AHW
+	BridgeHubRococo::fund_para_sovereign(AssetHubRococo::para_id(), ROC * 5);
+	AssetHubRococo::open_bridge(
+		AssetHubRococo::sibling_location_of(BridgeHubRococo::para_id()),
+		[GlobalConsensus(Westend), Parachain(AssetHubWestend::para_id().into())].into(),
+		Some((
+			(roc_at_ah_rococo(), ROC * 1).into(),
+			BridgeHubRococo::sovereign_account_id_of(BridgeHubRococo::sibling_location_of(
+				AssetHubRococo::para_id(),
+			)),
+		)),
+	);
+	BridgeHubRococo::execute_with(|| {
+		type RuntimeEvent = <BridgeHubRococo as Chain>::RuntimeEvent;
+		assert_expected_events!(
+			BridgeHubRococo,
+			vec![
+				RuntimeEvent::XcmOverBridgeHubWestend(
+					pallet_xcm_bridge_hub::Event::BridgeOpened { .. }
+				) => {},
+			]
+		);
+	});
+
+	// open AHW -> AHR
+	BridgeHubWestend::fund_para_sovereign(AssetHubWestend::para_id(), WND * 5);
+	AssetHubWestend::open_bridge(
+		AssetHubWestend::sibling_location_of(BridgeHubWestend::para_id()),
+		[GlobalConsensus(Rococo), Parachain(AssetHubRococo::para_id().into())].into(),
+		Some((
+			(wnd_at_ah_westend(), WND * 1).into(),
+			BridgeHubWestend::sovereign_account_id_of(BridgeHubWestend::sibling_location_of(
+				AssetHubWestend::para_id(),
+			)),
+		)),
+	);
+	BridgeHubWestend::execute_with(|| {
+		type RuntimeEvent = <BridgeHubWestend as Chain>::RuntimeEvent;
+		assert_expected_events!(
+			BridgeHubWestend,
+			vec![
+				RuntimeEvent::XcmOverBridgeHubRococo(
+					pallet_xcm_bridge_hub::Event::BridgeOpened { .. }
+				) => {},
+			]
+		);
+	});
+}
diff --git a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/send_xcm.rs b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/send_xcm.rs
index dee411bea8b7353f07b5542b1a81f08ed2dbd966..ae05e4223b073de9b8f8edb7907b15a7a4cf7ed6 100644
--- a/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/send_xcm.rs
+++ b/cumulus/parachains/integration-tests/emulated/tests/bridges/bridge-hub-westend/src/tests/send_xcm.rs
@@ -79,6 +79,9 @@ fn send_xcm_through_opened_lane_with_different_xcm_version_on_hops_works() {
 	// fund sender
 	AssetHubWestend::fund_accounts(vec![(AssetHubWestendSender::get().into(), amount * 10)]);
 
+	// open bridge
+	open_bridge_between_asset_hub_rococo_and_asset_hub_westend();
+
 	// send XCM from AssetHubWestend - fails - destination version not known
 	assert_err!(
 		send_assets_from_asset_hub_westend(
diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs
index 3305c6a5cf5c9e389faa9ee47404fe9fb5192938..5ba75ec9faf103ac7f78e583192a904172d980c3 100644
--- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs
+++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-rococo/src/lib.rs
@@ -1507,8 +1507,8 @@ impl_runtime_apis! {
 					parachain_head_size: u32,
 					proof_params: bp_runtime::UnverifiedStorageProofParams,
 				) -> (
-					pallet_bridge_parachains::RelayBlockNumber,
-					pallet_bridge_parachains::RelayBlockHash,
+					bp_parachains::RelayBlockNumber,
+					bp_parachains::RelayBlockHash,
 					bp_polkadot_core::parachains::ParaHeadsProof,
 					Vec<(bp_polkadot_core::parachains::ParaId, bp_polkadot_core::parachains::ParaHash)>,
 				) {
diff --git a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs
index 7daf9d4623f7be221b134a64c41f7610e8fcbcb4..11544d051ccf8ff719ac25e11f897ea200457e07 100644
--- a/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs
+++ b/cumulus/parachains/runtimes/bridge-hubs/bridge-hub-westend/src/lib.rs
@@ -1155,8 +1155,8 @@ impl_runtime_apis! {
 					parachain_head_size: u32,
 					proof_params: bp_runtime::UnverifiedStorageProofParams,
 				) -> (
-					pallet_bridge_parachains::RelayBlockNumber,
-					pallet_bridge_parachains::RelayBlockHash,
+					bp_parachains::RelayBlockNumber,
+					bp_parachains::RelayBlockHash,
 					bp_polkadot_core::parachains::ParaHeadsProof,
 					Vec<(bp_polkadot_core::parachains::ParaId, bp_polkadot_core::parachains::ParaHash)>,
 				) {
diff --git a/cumulus/xcm/xcm-emulator/src/lib.rs b/cumulus/xcm/xcm-emulator/src/lib.rs
index 8de3660c223627155a27f5ecc659a3ea030d7b02..afed14278d17560411fc13bb7c9c325890487a1d 100644
--- a/cumulus/xcm/xcm-emulator/src/lib.rs
+++ b/cumulus/xcm/xcm-emulator/src/lib.rs
@@ -296,9 +296,11 @@ impl Bridge for () {
 	fn init() {}
 }
 
+pub type BridgeLaneId = Vec<u8>;
+
 #[derive(Clone, Default, Debug)]
 pub struct BridgeMessage {
-	pub id: u32,
+	pub lane_id: BridgeLaneId,
 	pub nonce: u64,
 	pub payload: Vec<u8>,
 }
@@ -310,7 +312,7 @@ pub trait BridgeMessageHandler {
 		message: BridgeMessage,
 	) -> Result<(), BridgeMessageDispatchError>;
 
-	fn notify_source_message_delivery(lane_id: u32);
+	fn notify_source_message_delivery(lane_id: BridgeLaneId);
 }
 
 impl BridgeMessageHandler for () {
@@ -324,7 +326,7 @@ impl BridgeMessageHandler for () {
 		Err(BridgeMessageDispatchError(Box::new("Not a bridge")))
 	}
 
-	fn notify_source_message_delivery(_lane_id: u32) {}
+	fn notify_source_message_delivery(_lane_id: BridgeLaneId) {}
 }
 
 #[derive(Debug)]
@@ -1079,12 +1081,12 @@ macro_rules! decl_test_networks {
 						});
 
 						match dispatch_result {
-							Err(e) => panic!("Error {:?} processing bridged message: {:?}", e, msg.clone()),
+							Err(e) => panic!("Error {:?} processing bridged message: {:?}", e, msg),
 							Ok(()) => {
 								<<Self::Bridge as Bridge>::Source as TestExt>::ext_wrapper(|| {
-									<<Self::Bridge as Bridge>::Handler as BridgeMessageHandler>::notify_source_message_delivery(msg.id);
+									<<Self::Bridge as Bridge>::Handler as BridgeMessageHandler>::notify_source_message_delivery(msg.lane_id.clone());
 								});
-								$crate::log::debug!(target: concat!("bridge::", stringify!($name)) , "Bridged message processed {:?}", msg.clone());
+								$crate::log::debug!(target: concat!("bridge::", stringify!($name)) , "Bridged message processed {:?}", msg);
 							}
 						}
 					}