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::v1::{Junction::*, MultiLocation, Junctions::*};23use xcm::latest::{24 AssetId::{Concrete},25 Fungibility::Fungible as XcmFungible,26 MultiAsset, Error as XcmError, Weight,27};28use xcm_builder::{CurrencyAdapter, NativeAsset};29use xcm_executor::{30 Assets,31 traits::{MatchesFungible, WeightTrader},32};33use pallet_foreign_assets::{AssetIds, NativeCurrency};34use sp_std::marker::PhantomData;35use crate::{Balances, ParachainInfo};36use super::{LocationToAccountId, RelayLocation};3738use up_common::types::{AccountId, Balance};3940pub struct OnlySelfCurrency;41impl<B: TryFrom<u128>> MatchesFungible<B> for OnlySelfCurrency {42 fn matches_fungible(a: &MultiAsset) -> Option<B> {43 let paraid = Parachain(ParachainInfo::parachain_id().into());44 match (&a.id, &a.fun) {45 (46 Concrete(MultiLocation {47 parents: 1,48 interior: X1(loc),49 }),50 XcmFungible(ref amount),51 ) if paraid == *loc => CheckedConversion::checked_from(*amount),52 (53 Concrete(MultiLocation {54 parents: 0,55 interior: Here,56 }),57 XcmFungible(ref amount),58 ) => CheckedConversion::checked_from(*amount),59 _ => None,60 }61 }62}636465pub type LocalAssetTransactor = CurrencyAdapter<66 67 Balances,68 69 OnlySelfCurrency,70 71 LocationToAccountId,72 73 AccountId,74 75 (),76>;7778pub type AssetTransactors = LocalAssetTransactor;7980pub type IsReserve = NativeAsset;8182pub struct UsingOnlySelfCurrencyComponents<83 WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,84 AssetId: Get<MultiLocation>,85 AccountId,86 Currency: CurrencyT<AccountId>,87 OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,88>(89 Weight,90 Currency::Balance,91 PhantomData<(WeightToFee, AssetId, AccountId, Currency, OnUnbalanced)>,92);93impl<94 WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,95 AssetId: Get<MultiLocation>,96 AccountId,97 Currency: CurrencyT<AccountId>,98 OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,99 > WeightTrader100 for UsingOnlySelfCurrencyComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>101{102 fn new() -> Self {103 Self(0, Zero::zero(), PhantomData)104 }105106 fn buy_weight(&mut self, _weight: Weight, payment: Assets) -> Result<Assets, XcmError> {107 Ok(payment)108 }109}110impl<111 WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,112 AssetId: Get<MultiLocation>,113 AccountId,114 Currency: CurrencyT<AccountId>,115 OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,116 > Drop117 for UsingOnlySelfCurrencyComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>118{119 fn drop(&mut self) {120 OnUnbalanced::on_unbalanced(Currency::issue(self.1));121 }122}123124pub type Trader<T> = UsingOnlySelfCurrencyComponents<125 pallet_configuration::WeightToFee<T, Balance>,126 RelayLocation,127 AccountId,128 Balances,129 (),130>;131132pub struct CurrencyIdConvert;133impl Convert<AssetIds, Option<MultiLocation>> for CurrencyIdConvert {134 fn convert(id: AssetIds) -> Option<MultiLocation> {135 match id {136 AssetIds::NativeAssetId(NativeCurrency::Here) => Some(MultiLocation::new(137 1,138 X1(Parachain(ParachainInfo::get().into())),139 )),140 _ => None,141 }142 }143}