moonbeam_runtime_common/
impl_multiasset_paymaster.rs1use frame_support::traits::fungible;
18use frame_support::traits::{
19 fungible::NativeOrWithId,
20 tokens::{Pay, Preservation::Expendable},
21};
22use moonbeam_core_primitives::{AssetId, Balance};
23use sp_core::{Get, U256};
24use sp_runtime::DispatchError;
25
26pub struct MultiAssetPaymaster<R, TreasuryAccount, NativeAsset>(
27 sp_std::marker::PhantomData<(R, TreasuryAccount, NativeAsset)>,
28);
29impl<R, TreasuryAccount, NativeAsset> Pay for MultiAssetPaymaster<R, TreasuryAccount, NativeAsset>
30where
31 R: frame_system::Config + pallet_moonbeam_foreign_assets::Config,
32 TreasuryAccount: Get<R::AccountId>,
33 NativeAsset: fungible::Mutate<R::AccountId> + fungible::Inspect<R::AccountId>,
34{
35 type Balance = Balance;
36 type Beneficiary = R::AccountId;
37 type AssetKind = NativeOrWithId<AssetId>;
38 type Id = ();
39 type Error = DispatchError;
40 fn pay(
41 who: &Self::Beneficiary,
42 asset_kind: Self::AssetKind,
43 amount: Self::Balance,
44 ) -> Result<Self::Id, Self::Error> {
45 match asset_kind {
46 Self::AssetKind::Native => {
47 <NativeAsset as fungible::Mutate<_>>::transfer(
48 &TreasuryAccount::get(),
49 who,
50 amount
51 .try_into()
52 .map_err(|_| DispatchError::Other("failed to convert amount"))?,
53 Expendable,
54 )?;
55 Ok(())
56 }
57 Self::AssetKind::WithId(id) => pallet_moonbeam_foreign_assets::Pallet::<R>::transfer(
58 id,
59 TreasuryAccount::get(),
60 who.clone(),
61 U256::from(amount as u128),
62 )
63 .map_err(|_| Self::Error::Other("failed to transfer amount")),
64 }
65 }
66
67 fn check_payment(_id: Self::Id) -> frame_support::traits::tokens::PaymentStatus {
68 frame_support::traits::tokens::PaymentStatus::Success
69 }
70
71 #[cfg(feature = "runtime-benchmarks")]
72 fn ensure_successful(
73 _beneficiary: &Self::Beneficiary,
74 asset: Self::AssetKind,
75 amount: Self::Balance,
76 ) {
77 let treasury = TreasuryAccount::get();
78 match asset {
79 Self::AssetKind::Native => {
80 let _ = <NativeAsset as fungible::Mutate<_>>::mint_into(
81 &treasury,
82 (amount as u32).into(),
83 );
84 }
85 Self::AssetKind::WithId(id) => {
86 pallet_moonbeam_foreign_assets::Pallet::<R>::mint_into(
88 id,
89 treasury,
90 U256::from(amount as u128),
91 )
92 .expect("failed to mint asset into treasury account");
93 }
94 }
95 }
96 #[cfg(feature = "runtime-benchmarks")]
97 fn ensure_concluded(_: Self::Id) {}
98}