use crate::impls::AccountIdOf; use core::marker::PhantomData; use frame_support::{ traits::{fungibles::Inspect, tokens::ConversionToAssetBalance, ContainsPair}, weights::Weight, }; use log; use sp_runtime::traits::Get; use xcm::latest::prelude::*; /// A `ChargeFeeInFungibles` implementation that converts the output of /// a given WeightToFee implementation an amount charged in /// a particular assetId from pallet-assets pub struct AssetFeeAsExistentialDepositMultiplier< Runtime, WeightToFee, BalanceConverter, AssetInstance: 'static, >(PhantomData<(Runtime, WeightToFee, BalanceConverter, AssetInstance)>); impl cumulus_primitives_utility::ChargeWeightInFungibles< AccountIdOf, pallet_assets::Pallet, > for AssetFeeAsExistentialDepositMultiplier where Runtime: pallet_assets::Config, WeightToFee: frame_support::weights::WeightToFee, BalanceConverter: ConversionToAssetBalance< CurrencyBalance, >::AssetId, >::Balance, >, AccountIdOf: From + Into, { fn charge_weight_in_fungibles( asset_id: as Inspect< AccountIdOf, >>::AssetId, weight: Weight, ) -> Result< as Inspect>>::Balance, XcmError, > { let amount = WeightToFee::weight_to_fee(&weight); // If the amount gotten is not at least the ED, then make it be the ED of the asset // This is to avoid burning assets and decreasing the supply let asset_amount = BalanceConverter::to_asset_balance(amount, asset_id) .map_err(|_| XcmError::TooExpensive)?; Ok(asset_amount) } } /// Accepts an asset if it is a native asset from a particular `MultiLocation`. pub struct ConcreteNativeAssetFrom(PhantomData); impl> ContainsPair for ConcreteNativeAssetFrom { fn contains(asset: &MultiAsset, origin: &MultiLocation) -> bool { log::trace!(target: "xcm::filter_asset_location", "ConcreteNativeAsset asset: {:?}, origin: {:?}, location: {:?}", asset, origin, Location::get()); matches!(asset.id, Concrete(ref id) if id == origin && origin == &Location::get()) } }