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 == parent_id {81 return Some(MultiLocation::parent());82 }8384 if *asset_id == here_id {85 return Some(MultiLocation::new(86 1,87 X1(Parachain(ParachainInfo::get().into())),88 ));89 }9091 let fid = <AssetId as TryAsForeign<AssetId, ForeignAssetId>>::try_as_foreign(*asset_id)?;92 XcmForeignAssetIdMapping::<Runtime>::get_multi_location(fid)93 }94}959697pub type FungiblesTransactor = FungiblesAdapter<98 99 ForeignAssets,100 101 ConvertedConcreteId<AssetId, Balance, AsInnerId<JustTry>, JustTry>,102 103 LocationToAccountId,104 105 AccountId,106 107 NoChecking,108 109 CheckingAccount,110>;111112113pub struct AssetTransactor;114impl TransactAsset for AssetTransactor {115 fn can_check_in(116 _origin: &MultiLocation,117 _what: &MultiAsset,118 _context: &XcmContext,119 ) -> XcmResult {120 Err(XcmError::Unimplemented)121 }122123 fn check_in(_origin: &MultiLocation, _what: &MultiAsset, _context: &XcmContext) {}124125 fn can_check_out(126 _dest: &MultiLocation,127 _what: &MultiAsset,128 _context: &XcmContext,129 ) -> XcmResult {130 Err(XcmError::Unimplemented)131 }132133 fn check_out(_dest: &MultiLocation, _what: &MultiAsset, _context: &XcmContext) {}134135 fn deposit_asset(what: &MultiAsset, who: &MultiLocation, context: &XcmContext) -> XcmResult {136 FungiblesTransactor::deposit_asset(what, who, context)137 }138139 fn withdraw_asset(140 what: &MultiAsset,141 who: &MultiLocation,142 maybe_context: Option<&XcmContext>,143 ) -> Result<staging_xcm_executor::Assets, XcmError> {144 FungiblesTransactor::withdraw_asset(what, who, maybe_context)145 }146147 fn internal_transfer_asset(148 what: &MultiAsset,149 from: &MultiLocation,150 to: &MultiLocation,151 context: &XcmContext,152 ) -> Result<staging_xcm_executor::Assets, XcmError> {153 FungiblesTransactor::internal_transfer_asset(what, from, to, context)154 }155}156157pub type IsReserve = MultiNativeAsset<AbsoluteReserveProvider>;158159pub type Trader<T> = FreeForAll<160 pallet_configuration::WeightToFee<T, Balance>,161 RelayLocation,162 AccountId,163 Balances,164 (),165>;166167pub struct CurrencyIdConvert;168impl Convert<AssetId, Option<MultiLocation>> for CurrencyIdConvert {169 fn convert(id: AssetId) -> Option<MultiLocation> {170 match id {171 AssetId::NativeAssetId(NativeCurrency::Here) => Some(MultiLocation::new(172 1,173 X1(Parachain(ParachainInfo::get().into())),174 )),175 AssetId::NativeAssetId(NativeCurrency::Parent) => Some(MultiLocation::parent()),176 AssetId::ForeignAssetId(foreign_asset_id) => {177 XcmForeignAssetIdMapping::<Runtime>::get_multi_location(foreign_asset_id)178 }179 }180 }181}182183impl Convert<MultiLocation, Option<CurrencyId>> for CurrencyIdConvert {184 fn convert(location: MultiLocation) -> Option<CurrencyId> {185 if location == MultiLocation::here()186 || location == MultiLocation::new(1, X1(Parachain(ParachainInfo::get().into())))187 {188 return Some(AssetId::NativeAssetId(NativeCurrency::Here));189 }190191 if location == MultiLocation::parent() {192 return Some(AssetId::NativeAssetId(NativeCurrency::Parent));193 }194195 if let Some(currency_id) = XcmForeignAssetIdMapping::<Runtime>::get_currency_id(location) {196 return Some(currency_id);197 }198199 None200 }201}