diff --git a/parachains/runtimes/assets/westmint/src/lib.rs b/parachains/runtimes/assets/westmint/src/lib.rs index 1ce1db3ca1..34d53fb462 100644 --- a/parachains/runtimes/assets/westmint/src/lib.rs +++ b/parachains/runtimes/assets/westmint/src/lib.rs @@ -63,7 +63,9 @@ use parachains_common::{ opaque, AccountId, AssetId, AuraId, Balance, BlockNumber, Hash, Header, Index, Signature, AVERAGE_ON_INITIALIZE_RATIO, HOURS, MAXIMUM_BLOCK_WEIGHT, NORMAL_DISPATCH_RATIO, SLOT_DURATION, }; -use xcm_config::{XcmConfig, XcmOriginToTransactDispatchOrigin}; +use xcm_config::{ + ForeignCreators, MultiLocationForAssetId, XcmConfig, XcmOriginToTransactDispatchOrigin, +}; #[cfg(any(feature = "std", test))] pub use sp_runtime::BuildStorage; @@ -244,6 +246,27 @@ impl pallet_assets::Config for Runtime { type AssetAccountDeposit = AssetAccountDeposit; } +/// Assets managed by some foreign location. +type ForeignAssetClasses = pallet_assets::Instance2; +impl pallet_assets::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type Balance = Balance; + type AssetId = MultiLocationForAssetId; + type Currency = Balances; + type CreateOrigin = ForeignCreators; + type ForceOrigin = AssetsForceOrigin; + type AssetDeposit = AssetDeposit; + type MetadataDepositBase = MetadataDepositBase; + type MetadataDepositPerByte = MetadataDepositPerByte; + type ApprovalDeposit = ApprovalDeposit; + type StringLimit = AssetsStringLimit; + type Freezer = (); + type Extra = (); + type WeightInfo = weights::pallet_assets::WeightInfo; + type AssetAccountDeposit = AssetAccountDeposit; + type RemoveItemsLimit = frame_support::traits::ConstU32<1000>; +} + parameter_types! { // One storage item; key size is 32; value is size 4+4+16+32 bytes = 56 bytes. pub const DepositBase: Balance = deposit(1, 88); @@ -514,9 +537,12 @@ impl pallet_asset_tx_payment::Config for Runtime { type RuntimeEvent = RuntimeEvent; // TODO // This should be able to take assets from any pallet instance. - type Fungibles = TrustBackedAssets; + type Fungibles = (ForeignAssets, TrustBackedAssets); type OnChargeAssetTransaction = pallet_asset_tx_payment::FungiblesAdapter< - pallet_assets::BalanceToAssetBalance, + ( + ForeignAssets::BalanceToAssetBalance, + TrustBackedAssets::BalanceToAssetBalance, + ), AssetsToBlockAuthor, >; } @@ -595,6 +621,7 @@ construct_runtime!( // The main stage. TrustBackedAssets: pallet_assets::::{Pallet, Call, Storage, Event} = 50, Uniques: pallet_uniques::{Pallet, Call, Storage, Event} = 51, + ForeignAssets: pallet_assets::::{Pallet, Call, Storage, Event} = 52, } ); @@ -644,6 +671,7 @@ mod benches { define_benchmarks!( [frame_system, SystemBench::] [pallet_assets, TrustBackedAssets] + [pallet_assets, ForeignAssets] [pallet_balances, Balances] [pallet_multisig, Multisig] [pallet_proxy, Proxy] diff --git a/parachains/runtimes/assets/westmint/src/xcm_config.rs b/parachains/runtimes/assets/westmint/src/xcm_config.rs index e2896ed15c..b7e2c9ca25 100644 --- a/parachains/runtimes/assets/westmint/src/xcm_config.rs +++ b/parachains/runtimes/assets/westmint/src/xcm_config.rs @@ -23,6 +23,7 @@ use super::{ use frame_support::{ match_types, parameter_types, traits::{ConstU32, Everything, Nothing, PalletInfoAccess}, + traits::{EnsureOriginWithArg, Everything, PalletInfoAccess}, }; use pallet_xcm::XcmPassthrough; use parachains_common::{ @@ -31,7 +32,7 @@ use parachains_common::{ AssetFeeAsExistentialDepositMultiplier, DenyReserveTransferToRelayChain, DenyThenTry, }, }; -use polkadot_parachain::primitives::Sibling; +use polkadot_parachain::primitives::{Id as ParaId, Sibling}; use sp_runtime::traits::ConvertInto; use xcm::latest::prelude::*; use xcm_builder::{ @@ -253,3 +254,34 @@ impl cumulus_pallet_xcm::Config for Runtime { type RuntimeEvent = RuntimeEvent; type XcmExecutor = XcmExecutor; } + +pub type MultiLocationForAssetId = MultiLocation; + +pub type SovereignAccountOf = ( + SiblingParachainConvertsVia, + AccountId32Aliases, + ParentIsPreset, +); + +// `EnsureOriginWithArg` impl for `CreateOrigin` which allows only XCM origins that are locations +// containing the class location. +pub struct ForeignCreators; +impl EnsureOriginWithArg for ForeignCreators { + type Success = AccountId; + + fn try_origin( + o: RuntimeOrigin, + a: &MultiLocation, + ) -> sp_std::result::Result { + let origin_location = pallet_xcm::EnsureXcm::::try_origin(o.clone())?; + if !a.starts_with(&origin_location) { + return Err(o) + } + SovereignAccountOf::convert(origin_location).map_err(|_| o) + } + + #[cfg(feature = "runtime-benchmarks")] + fn successful_origin(a: &MultiLocation) -> RuntimeOrigin { + pallet_xcm::Origin::Xcm(a.clone()).into() + } +}