use frame_support::traits::fungible;
use frame_support::traits::{
fungible::NativeOrWithId,
tokens::{Pay, Preservation::Expendable},
};
use moonbeam_core_primitives::{AssetId, Balance};
use sp_core::{Get, U256};
use sp_runtime::DispatchError;
pub struct MultiAssetPaymaster<R, TreasuryAccount, NativeAsset>(
sp_std::marker::PhantomData<(R, TreasuryAccount, NativeAsset)>,
);
impl<R, TreasuryAccount, NativeAsset> Pay for MultiAssetPaymaster<R, TreasuryAccount, NativeAsset>
where
R: frame_system::Config + pallet_moonbeam_foreign_assets::Config,
TreasuryAccount: Get<R::AccountId>,
NativeAsset: fungible::Mutate<R::AccountId> + fungible::Inspect<R::AccountId>,
{
type Balance = Balance;
type Beneficiary = R::AccountId;
type AssetKind = NativeOrWithId<AssetId>;
type Id = ();
type Error = DispatchError;
fn pay(
who: &Self::Beneficiary,
asset_kind: Self::AssetKind,
amount: Self::Balance,
) -> Result<Self::Id, Self::Error> {
match asset_kind {
Self::AssetKind::Native => {
<NativeAsset as fungible::Mutate<_>>::transfer(
&TreasuryAccount::get(),
who,
amount
.try_into()
.map_err(|_| DispatchError::Other("failed to convert amount"))?,
Expendable,
)?;
Ok(())
}
Self::AssetKind::WithId(id) => pallet_moonbeam_foreign_assets::Pallet::<R>::transfer(
id,
TreasuryAccount::get(),
who.clone(),
U256::from(amount as u128),
)
.map_err(|_| Self::Error::Other("failed to transfer amount")),
}
}
fn check_payment(_id: Self::Id) -> frame_support::traits::tokens::PaymentStatus {
frame_support::traits::tokens::PaymentStatus::Success
}
#[cfg(feature = "runtime-benchmarks")]
fn ensure_successful(
_beneficiary: &Self::Beneficiary,
asset: Self::AssetKind,
amount: Self::Balance,
) {
let treasury = TreasuryAccount::get();
match asset {
Self::AssetKind::Native => {
let _ = <NativeAsset as fungible::Mutate<_>>::mint_into(
&treasury,
(amount as u32).into(),
);
}
Self::AssetKind::WithId(id) => {
pallet_moonbeam_foreign_assets::Pallet::<R>::mint_into(
id,
treasury,
U256::from(amount as u128),
)
.expect("failed to mint asset into treasury account");
}
}
}
#[cfg(feature = "runtime-benchmarks")]
fn ensure_concluded(_: Self::Id) {}
}