1234567891011121314151617use frame_support::{parameter_types, traits::Get};18use orml_traits::location::AbsoluteReserveProvider;19use orml_xcm_support::MultiNativeAsset;20use pallet_foreign_assets::{21 AssetId, AssetIdMapping, CurrencyId, ForeignAssetId, FreeForAll, NativeCurrency, TryAsForeign,22 XcmForeignAssetIdMapping,23};24use sp_runtime::traits::{Convert, MaybeEquivalence};25use sp_std::marker::PhantomData;26use staging_xcm::latest::{prelude::*, MultiAsset, MultiLocation};27use staging_xcm_builder::{ConvertedConcreteId, FungiblesAdapter, NoChecking};28use staging_xcm_executor::traits::{JustTry, TransactAsset};29use up_common::types::{AccountId, Balance};3031use super::{LocationToAccountId, RelayLocation};32use crate::{Balances, ForeignAssets, ParachainInfo, PolkadotXcm, Runtime};3334parameter_types! {35 pub CheckingAccount: AccountId = PolkadotXcm::check_account();36}3738pub struct AsInnerId<ConvertAssetId>(PhantomData<(AssetId, ConvertAssetId)>);39impl<ConvertAssetId: MaybeEquivalence<AssetId, AssetId>> MaybeEquivalence<MultiLocation, AssetId>40 for AsInnerId<ConvertAssetId>41{42 fn convert(id: &MultiLocation) -> Option<AssetId> {43 log::trace!(44 target: "xcm::AsInnerId::Convert",45 "AsInnerId {:?}",46 id47 );4849 let parent = MultiLocation::parent();50 let here = MultiLocation::here();51 let self_location = MultiLocation::new(1, X1(Parachain(ParachainInfo::get().into())));5253 if *id == parent {54 return ConvertAssetId::convert(&AssetId::NativeAssetId(NativeCurrency::Parent));55 }5657 if *id == here || *id == self_location {58 return ConvertAssetId::convert(&AssetId::NativeAssetId(NativeCurrency::Here));59 }6061 match XcmForeignAssetIdMapping::<Runtime>::get_currency_id(*id) {62 Some(AssetId::ForeignAssetId(foreign_asset_id)) => {63 ConvertAssetId::convert(&AssetId::ForeignAssetId(foreign_asset_id))64 }65 _ => None,66 }67 }6869 fn convert_back(asset_id: &AssetId) -> Option<MultiLocation> {70 log::trace!(71 target: "xcm::AsInnerId::Reverse",72 "AsInnerId",73 );7475 let parent_id =76 ConvertAssetId::convert(&AssetId::NativeAssetId(NativeCurrency::Parent)).unwrap();77 let here_id =78 ConvertAssetId::convert(&AssetId::NativeAssetId(NativeCurrency::Here)).unwrap();7980 if asset_id.clone() == parent_id {81 return Some(MultiLocation::parent());82 }8384 if asset_id.clone() == here_id {85 return Some(MultiLocation::new(86 1,87 X1(Parachain(ParachainInfo::get().into())),88 ));89 }9091 let fid =92 <AssetId as TryAsForeign<AssetId, ForeignAssetId>>::try_as_foreign(asset_id.clone())?;93 XcmForeignAssetIdMapping::<Runtime>::get_multi_location(fid)94 }95}969798pub type FungiblesTransactor = FungiblesAdapter<99 100 ForeignAssets,101 102 ConvertedConcreteId<AssetId, Balance, AsInnerId<JustTry>, JustTry>,103 104 LocationToAccountId,105 106 AccountId,107 108 NoChecking,109 110 CheckingAccount,111>;112113114pub struct AssetTransactor;115impl TransactAsset for AssetTransactor {116 fn can_check_in(117 _origin: &MultiLocation,118 _what: &MultiAsset,119 _context: &XcmContext,120 ) -> XcmResult {121 Err(XcmError::Unimplemented)122 }123124 fn check_in(_origin: &MultiLocation, _what: &MultiAsset, _context: &XcmContext) {}125126 fn can_check_out(127 _dest: &MultiLocation,128 _what: &MultiAsset,129 _context: &XcmContext,130 ) -> XcmResult {131 Err(XcmError::Unimplemented)132 }133134 fn check_out(_dest: &MultiLocation, _what: &MultiAsset, _context: &XcmContext) {}135136 fn deposit_asset(what: &MultiAsset, who: &MultiLocation, context: &XcmContext) -> XcmResult {137 FungiblesTransactor::deposit_asset(what, who, context)138 }139140 fn withdraw_asset(141 what: &MultiAsset,142 who: &MultiLocation,143 maybe_context: Option<&XcmContext>,144 ) -> Result<staging_xcm_executor::Assets, XcmError> {145 FungiblesTransactor::withdraw_asset(what, who, maybe_context)146 }147148 fn internal_transfer_asset(149 what: &MultiAsset,150 from: &MultiLocation,151 to: &MultiLocation,152 context: &XcmContext,153 ) -> Result<staging_xcm_executor::Assets, XcmError> {154 FungiblesTransactor::internal_transfer_asset(what, from, to, context)155 }156}157158pub type IsReserve = MultiNativeAsset<AbsoluteReserveProvider>;159160pub type Trader<T> = FreeForAll<161 pallet_configuration::WeightToFee<T, Balance>,162 RelayLocation,163 AccountId,164 Balances,165 (),166>;167168pub struct CurrencyIdConvert;169impl Convert<AssetId, Option<MultiLocation>> for CurrencyIdConvert {170 fn convert(id: AssetId) -> Option<MultiLocation> {171 match id {172 AssetId::NativeAssetId(NativeCurrency::Here) => Some(MultiLocation::new(173 1,174 X1(Parachain(ParachainInfo::get().into())),175 )),176 AssetId::NativeAssetId(NativeCurrency::Parent) => Some(MultiLocation::parent()),177 AssetId::ForeignAssetId(foreign_asset_id) => {178 XcmForeignAssetIdMapping::<Runtime>::get_multi_location(foreign_asset_id)179 }180 }181 }182}183184impl Convert<MultiLocation, Option<CurrencyId>> for CurrencyIdConvert {185 fn convert(location: MultiLocation) -> Option<CurrencyId> {186 if location == MultiLocation::here()187 || location == MultiLocation::new(1, X1(Parachain(ParachainInfo::get().into())))188 {189 return Some(AssetId::NativeAssetId(NativeCurrency::Here));190 }191192 if location == MultiLocation::parent() {193 return Some(AssetId::NativeAssetId(NativeCurrency::Parent));194 }195196 if let Some(currency_id) = XcmForeignAssetIdMapping::<Runtime>::get_currency_id(location) {197 return Some(currency_id);198 }199200 None201 }202}