diff --git a/polkadot/xcm/xcm-builder/src/lib.rs b/polkadot/xcm/xcm-builder/src/lib.rs
index 9dd62f84305e231c762de36904aac3cd61af9076..ea54f81ce34870141278dffc0d284b49b75f29f5 100644
--- a/polkadot/xcm/xcm-builder/src/lib.rs
+++ b/polkadot/xcm/xcm-builder/src/lib.rs
@@ -18,13 +18,13 @@
 
 mod location_conversion;
 pub use location_conversion::{
-	Account32Hash, ParentIsDefault, ChildParachainConvertsVia, SiblingParachainConvertsVia, AccountId32Aliases
+	Account32Hash, ParentIsDefault, ChildParachainConvertsVia, SiblingParachainConvertsVia, AccountId32Aliases, AccountKey20Aliases,
 };
 
 mod origin_conversion;
 pub use origin_conversion::{
 	SovereignSignedViaLocation, ParentAsSuperuser, ChildSystemParachainAsSuperuser, SiblingSystemParachainAsSuperuser,
-	ChildParachainAsNative, SiblingParachainAsNative, RelayChainAsNative, SignedAccountId32AsNative
+	ChildParachainAsNative, SiblingParachainAsNative, RelayChainAsNative, SignedAccountId32AsNative, SignedAccountKey20AsNative,
 };
 
 mod currency_adapter;
diff --git a/polkadot/xcm/xcm-builder/src/location_conversion.rs b/polkadot/xcm/xcm-builder/src/location_conversion.rs
index 88575b6df61b7698db4a9dd6149420bdebed99b9..be563448e3465dd9389e30018cc28b95059635a4 100644
--- a/polkadot/xcm/xcm-builder/src/location_conversion.rs
+++ b/polkadot/xcm/xcm-builder/src/location_conversion.rs
@@ -124,3 +124,27 @@ impl<
 		Ok(Junction::AccountId32 { id: who.into(), network: Network::get() }.into())
 	}
 }
+
+pub struct AccountKey20Aliases<Network, AccountId>(PhantomData<(Network, AccountId)>);
+
+impl<
+	Network: Get<NetworkId>,
+	AccountId: From<[u8; 20]> + Into<[u8; 20]>
+> LocationConversion<AccountId> for AccountKey20Aliases<Network, AccountId> {
+	fn from_location(location: &MultiLocation) -> Option<AccountId> {
+		if let MultiLocation::X1(Junction::AccountKey20 { key, network }) = location {
+			if matches!(network, NetworkId::Any) || network == &Network::get() {
+				return Some((*key).into());
+			}
+		}
+		None
+	}
+
+	fn try_into_location(who: AccountId) -> Result<MultiLocation, AccountId> {
+		Ok(Junction::AccountKey20 {
+			key: who.into(),
+			network: Network::get(),
+		}
+		.into())
+	}
+}
diff --git a/polkadot/xcm/xcm-builder/src/origin_conversion.rs b/polkadot/xcm/xcm-builder/src/origin_conversion.rs
index 86b9b263609dd3bc2209fd9f0ff963de0a655d84..3c8d05d54bf380c8bcc01084c0683662c3c6221d 100644
--- a/polkadot/xcm/xcm-builder/src/origin_conversion.rs
+++ b/polkadot/xcm/xcm-builder/src/origin_conversion.rs
@@ -148,3 +148,24 @@ impl<
 		}
 	}
 }
+
+pub struct SignedAccountKey20AsNative<Network, Origin>(
+	PhantomData<(Network, Origin)>
+);
+impl<
+	Network: Get<NetworkId>,
+	Origin: OriginTrait
+> ConvertOrigin<Origin> for SignedAccountKey20AsNative<Network, Origin> where
+	Origin::AccountId: From<[u8; 20]>,
+{
+	fn convert_origin(origin: MultiLocation, kind: OriginKind) -> Result<Origin, MultiLocation> {
+		match (kind, origin) {
+			(OriginKind::Native, MultiLocation::X1(Junction::AccountKey20 { key, network }))
+				if matches!(network, NetworkId::Any) || network == Network::get() =>
+			{
+				Ok(Origin::signed(key.into()))
+			}
+			(_, origin) => Err(origin),
+		}
+	}
+}