frame_support/traits/tokens/
pay.rs1use codec::{Decode, Encode, FullCodec, MaxEncodedLen};
21use core::fmt::Debug;
22use scale_info::TypeInfo;
23use sp_core::{RuntimeDebug, TypedGet};
24use sp_runtime::DispatchError;
25
26use super::{fungible, fungibles, Balance, Preservation::Expendable};
27
28pub trait Pay {
31 type Balance: Balance;
33 type Beneficiary;
35 type AssetKind;
40 type Id: FullCodec + MaxEncodedLen + TypeInfo + Clone + Eq + PartialEq + Debug + Copy;
42 type Error: Debug;
44 fn pay(
47 who: &Self::Beneficiary,
48 asset_kind: Self::AssetKind,
49 amount: Self::Balance,
50 ) -> Result<Self::Id, Self::Error>;
51 fn check_payment(id: Self::Id) -> PaymentStatus;
56 #[cfg(feature = "runtime-benchmarks")]
59 fn ensure_successful(
60 who: &Self::Beneficiary,
61 asset_kind: Self::AssetKind,
62 amount: Self::Balance,
63 );
64 #[cfg(feature = "runtime-benchmarks")]
67 fn ensure_concluded(id: Self::Id);
68}
69
70#[derive(Encode, Decode, Eq, PartialEq, Clone, TypeInfo, MaxEncodedLen, RuntimeDebug)]
72pub enum PaymentStatus {
73 InProgress,
75 Unknown,
78 Success,
80 Failure,
82}
83
84pub struct PayFromAccount<F, A>(core::marker::PhantomData<(F, A)>);
86impl<A, F> Pay for PayFromAccount<F, A>
87where
88 A: TypedGet,
89 F: fungible::Mutate<A::Type>,
90 A::Type: Eq,
91{
92 type Balance = F::Balance;
93 type Beneficiary = A::Type;
94 type AssetKind = ();
95 type Id = ();
96 type Error = DispatchError;
97 fn pay(
98 who: &Self::Beneficiary,
99 _: Self::AssetKind,
100 amount: Self::Balance,
101 ) -> Result<Self::Id, Self::Error> {
102 <F as fungible::Mutate<_>>::transfer(&A::get(), who, amount, Expendable)?;
103 Ok(())
104 }
105 fn check_payment(_: ()) -> PaymentStatus {
106 PaymentStatus::Success
107 }
108 #[cfg(feature = "runtime-benchmarks")]
109 fn ensure_successful(_: &Self::Beneficiary, _: Self::AssetKind, amount: Self::Balance) {
110 <F as fungible::Mutate<_>>::mint_into(&A::get(), amount).unwrap();
111 }
112 #[cfg(feature = "runtime-benchmarks")]
113 fn ensure_concluded(_: Self::Id) {}
114}
115
116pub struct PayAssetFromAccount<F, A>(core::marker::PhantomData<(F, A)>);
119impl<A, F> frame_support::traits::tokens::Pay for PayAssetFromAccount<F, A>
120where
121 A: TypedGet,
122 F: fungibles::Mutate<A::Type> + fungibles::Create<A::Type>,
123 A::Type: Eq,
124{
125 type Balance = F::Balance;
126 type Beneficiary = A::Type;
127 type AssetKind = F::AssetId;
128 type Id = ();
129 type Error = DispatchError;
130 fn pay(
131 who: &Self::Beneficiary,
132 asset: Self::AssetKind,
133 amount: Self::Balance,
134 ) -> Result<Self::Id, Self::Error> {
135 <F as fungibles::Mutate<_>>::transfer(asset, &A::get(), who, amount, Expendable)?;
136 Ok(())
137 }
138 fn check_payment(_: ()) -> PaymentStatus {
139 PaymentStatus::Success
140 }
141 #[cfg(feature = "runtime-benchmarks")]
142 fn ensure_successful(_: &Self::Beneficiary, asset: Self::AssetKind, amount: Self::Balance) {
143 <F as fungibles::Create<_>>::create(asset.clone(), A::get(), true, amount).unwrap();
144 <F as fungibles::Mutate<_>>::mint_into(asset, &A::get(), amount).unwrap();
145 }
146 #[cfg(feature = "runtime-benchmarks")]
147 fn ensure_concluded(_: Self::Id) {}
148}