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), + } + } +}