1234567891011121314151617use frame_support::{18 traits::{tokens::currency::Currency as CurrencyT, OnUnbalanced as OnUnbalancedT, Get},19 weights::WeightToFeePolynomial,20};21use sp_runtime::traits::{CheckedConversion, Zero, Convert};22use xcm::latest::{23 AssetId::{Concrete},24 Fungibility::Fungible as XcmFungible,25 MultiAsset, Error as XcmError, Weight,26 Junction::*,27 MultiLocation,28 Junctions::*,29};30use xcm_builder::{CurrencyAdapter, NativeAsset};31use xcm_executor::{32 Assets,33 traits::{MatchesFungible, WeightTrader},34};35use pallet_foreign_assets::{AssetIds, NativeCurrency};36use sp_std::marker::PhantomData;37use crate::{Balances, ParachainInfo};38use super::{LocationToAccountId, RelayLocation};3940use up_common::types::{AccountId, Balance};4142pub struct OnlySelfCurrency;43impl<B: TryFrom<u128>> MatchesFungible<B> for OnlySelfCurrency {44 fn matches_fungible(a: &MultiAsset) -> Option<B> {45 let paraid = Parachain(ParachainInfo::parachain_id().into());46 match (&a.id, &a.fun) {47 (48 Concrete(MultiLocation {49 parents: 1,50 interior: X1(loc),51 }),52 XcmFungible(ref amount),53 ) if paraid == *loc => CheckedConversion::checked_from(*amount),54 (55 Concrete(MultiLocation {56 parents: 0,57 interior: Here,58 }),59 XcmFungible(ref amount),60 ) => CheckedConversion::checked_from(*amount),61 _ => None,62 }63 }64}656667pub type LocalAssetTransactor = CurrencyAdapter<68 69 Balances,70 71 OnlySelfCurrency,72 73 LocationToAccountId,74 75 AccountId,76 77 (),78>;7980pub type AssetTransactor = LocalAssetTransactor;8182pub type IsReserve = NativeAsset;8384pub struct UsingOnlySelfCurrencyComponents<85 WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,86 AssetId: Get<MultiLocation>,87 AccountId,88 Currency: CurrencyT<AccountId>,89 OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,90>(91 Weight,92 Currency::Balance,93 PhantomData<(WeightToFee, AssetId, AccountId, Currency, OnUnbalanced)>,94);95impl<96 WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,97 AssetId: Get<MultiLocation>,98 AccountId,99 Currency: CurrencyT<AccountId>,100 OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,101 > WeightTrader102 for UsingOnlySelfCurrencyComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>103{104 fn new() -> Self {105 106 Self(Weight::from_parts(0, 0), Zero::zero(), PhantomData)107 }108109 fn buy_weight(110 &mut self,111 _weight: Weight,112 payment: Assets,113 _xcm: &XcmContext,114 ) -> Result<Assets, XcmError> {115 Ok(payment)116 }117}118impl<119 WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,120 AssetId: Get<MultiLocation>,121 AccountId,122 Currency: CurrencyT<AccountId>,123 OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,124 > Drop125 for UsingOnlySelfCurrencyComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>126{127 fn drop(&mut self) {128 OnUnbalanced::on_unbalanced(Currency::issue(self.1));129 }130}131132pub type Trader<T> = UsingOnlySelfCurrencyComponents<133 pallet_configuration::WeightToFee<T, Balance>,134 RelayLocation,135 AccountId,136 Balances,137 (),138>;139140pub struct CurrencyIdConvert;141impl Convert<AssetIds, Option<MultiLocation>> for CurrencyIdConvert {142 fn convert(id: AssetIds) -> Option<MultiLocation> {143 match id {144 AssetIds::NativeAssetId(NativeCurrency::Here) => Some(MultiLocation::new(145 1,146 X1(Parachain(ParachainInfo::get().into())),147 )),148 _ => None,149 }150 }151}