1234567891011121314151617use cumulus_primitives_core::XcmContext;18use frame_support::{19 traits::{tokens::currency::Currency as CurrencyT, Get, OnUnbalanced as OnUnbalancedT},20 weights::WeightToFeePolynomial,21};22use pallet_foreign_assets::{AssetIds, NativeCurrency};23use sp_runtime::traits::{CheckedConversion, Convert, Zero};24use sp_std::marker::PhantomData;25use staging_xcm::latest::{26 AssetId::Concrete, Error as XcmError, Fungibility::Fungible as XcmFungible, Junction::*,27 Junctions::*, MultiAsset, MultiLocation, Weight,28};29use staging_xcm_builder::{CurrencyAdapter, NativeAsset};30use staging_xcm_executor::{31 traits::{MatchesFungible, WeightTrader},32 Assets,33};34use up_common::types::{AccountId, Balance};3536use super::{LocationToAccountId, RelayLocation};37use crate::{Balances, ParachainInfo};3839pub struct OnlySelfCurrency;40impl<B: TryFrom<u128>> MatchesFungible<B> for OnlySelfCurrency {41 fn matches_fungible(a: &MultiAsset) -> Option<B> {42 let paraid = Parachain(ParachainInfo::parachain_id().into());43 match (&a.id, &a.fun) {44 (45 Concrete(MultiLocation {46 parents: 1,47 interior: X1(loc),48 }),49 XcmFungible(ref amount),50 ) if paraid == *loc => CheckedConversion::checked_from(*amount),51 (52 Concrete(MultiLocation {53 parents: 0,54 interior: Here,55 }),56 XcmFungible(ref amount),57 ) => CheckedConversion::checked_from(*amount),58 _ => None,59 }60 }61}626364pub type LocalAssetTransactor = CurrencyAdapter<65 66 Balances,67 68 OnlySelfCurrency,69 70 LocationToAccountId,71 72 AccountId,73 74 (),75>;7677pub type AssetTransactor = LocalAssetTransactor;7879pub type IsReserve = NativeAsset;8081pub struct UsingOnlySelfCurrencyComponents<82 WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,83 AssetId: Get<MultiLocation>,84 AccountId,85 Currency: CurrencyT<AccountId>,86 OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,87>(88 Weight,89 Currency::Balance,90 PhantomData<(WeightToFee, AssetId, AccountId, Currency, OnUnbalanced)>,91);92impl<93 WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,94 AssetId: Get<MultiLocation>,95 AccountId,96 Currency: CurrencyT<AccountId>,97 OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,98 > WeightTrader99 for UsingOnlySelfCurrencyComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>100{101 fn new() -> Self {102 103 Self(Weight::from_parts(0, 0), Zero::zero(), PhantomData)104 }105106 fn buy_weight(107 &mut self,108 _weight: Weight,109 payment: Assets,110 _xcm: &XcmContext,111 ) -> Result<Assets, XcmError> {112 Ok(payment)113 }114}115impl<116 WeightToFee: WeightToFeePolynomial<Balance = Currency::Balance>,117 AssetId: Get<MultiLocation>,118 AccountId,119 Currency: CurrencyT<AccountId>,120 OnUnbalanced: OnUnbalancedT<Currency::NegativeImbalance>,121 > Drop122 for UsingOnlySelfCurrencyComponents<WeightToFee, AssetId, AccountId, Currency, OnUnbalanced>123{124 fn drop(&mut self) {125 OnUnbalanced::on_unbalanced(Currency::issue(self.1));126 }127}128129pub type Trader<T> = UsingOnlySelfCurrencyComponents<130 pallet_configuration::WeightToFee<T, Balance>,131 RelayLocation,132 AccountId,133 Balances,134 (),135>;136137pub struct CurrencyIdConvert;138impl Convert<AssetIds, Option<MultiLocation>> for CurrencyIdConvert {139 fn convert(id: AssetIds) -> Option<MultiLocation> {140 match id {141 AssetIds::NativeAssetId(NativeCurrency::Here) => Some(MultiLocation::new(142 1,143 X1(Parachain(ParachainInfo::get().into())),144 )),145 _ => None,146 }147 }148}