frame_support/traits/tokens/
pay.rs1use codec::{FullCodec, MaxEncodedLen};
21use core::fmt::Debug;
22use scale_info::TypeInfo;
23use sp_core::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;
54 #[cfg(feature = "runtime-benchmarks")]
57 fn ensure_successful(
58 who: &Self::Beneficiary,
59 asset_kind: Self::AssetKind,
60 amount: Self::Balance,
61 );
62 #[cfg(feature = "runtime-benchmarks")]
65 fn ensure_concluded(id: Self::Id);
66}
67
68pub type PaymentStatus = super::transfer::TransferStatus;
70
71pub struct PayFromAccount<F, A>(core::marker::PhantomData<(F, A)>);
73impl<A, F> Pay for PayFromAccount<F, A>
74where
75 A: TypedGet,
76 F: fungible::Mutate<A::Type>,
77 A::Type: Eq,
78{
79 type Balance = F::Balance;
80 type Beneficiary = A::Type;
81 type AssetKind = ();
82 type Id = ();
83 type Error = DispatchError;
84 fn pay(
85 who: &Self::Beneficiary,
86 _: Self::AssetKind,
87 amount: Self::Balance,
88 ) -> Result<Self::Id, Self::Error> {
89 <F as fungible::Mutate<_>>::transfer(&A::get(), who, amount, Expendable)?;
90 Ok(())
91 }
92 fn check_payment(_: ()) -> PaymentStatus {
93 PaymentStatus::Success
94 }
95 #[cfg(feature = "runtime-benchmarks")]
96 fn ensure_successful(_: &Self::Beneficiary, _: Self::AssetKind, amount: Self::Balance) {
97 <F as fungible::Mutate<_>>::mint_into(&A::get(), amount).unwrap();
98 }
99 #[cfg(feature = "runtime-benchmarks")]
100 fn ensure_concluded(_: Self::Id) {}
101}
102
103pub struct PayAssetFromAccount<F, A>(core::marker::PhantomData<(F, A)>);
106impl<A, F> frame_support::traits::tokens::Pay for PayAssetFromAccount<F, A>
107where
108 A: TypedGet,
109 F: fungibles::Mutate<A::Type> + fungibles::Create<A::Type>,
110 A::Type: Eq,
111{
112 type Balance = F::Balance;
113 type Beneficiary = A::Type;
114 type AssetKind = F::AssetId;
115 type Id = ();
116 type Error = DispatchError;
117 fn pay(
118 who: &Self::Beneficiary,
119 asset: Self::AssetKind,
120 amount: Self::Balance,
121 ) -> Result<Self::Id, Self::Error> {
122 <F as fungibles::Mutate<_>>::transfer(asset, &A::get(), who, amount, Expendable)?;
123 Ok(())
124 }
125 fn check_payment(_: ()) -> PaymentStatus {
126 PaymentStatus::Success
127 }
128 #[cfg(feature = "runtime-benchmarks")]
129 fn ensure_successful(_: &Self::Beneficiary, asset: Self::AssetKind, amount: Self::Balance) {
130 <F as fungibles::Create<_>>::create(asset.clone(), A::get(), true, amount).unwrap();
131 <F as fungibles::Mutate<_>>::mint_into(asset, &A::get(), amount).unwrap();
132 }
133 #[cfg(feature = "runtime-benchmarks")]
134 fn ensure_concluded(_: Self::Id) {}
135}
136
137pub trait PayWithSource {
139 type Balance: Balance;
141 type Source;
143 type Beneficiary;
145 type AssetKind;
150 type Id: FullCodec + MaxEncodedLen + TypeInfo + Clone + Eq + PartialEq + Debug + Copy;
152 type Error: Debug;
154 fn pay(
157 source: &Self::Source,
158 beneficiary: &Self::Beneficiary,
159 asset_kind: Self::AssetKind,
160 amount: Self::Balance,
161 ) -> Result<Self::Id, Self::Error>;
162 fn check_payment(id: Self::Id) -> PaymentStatus;
167 #[cfg(feature = "runtime-benchmarks")]
170 fn ensure_successful(
171 source: &Self::Source,
172 beneficiary: &Self::Beneficiary,
173 asset_kind: Self::AssetKind,
174 amount: Self::Balance,
175 );
176 #[cfg(feature = "runtime-benchmarks")]
179 fn ensure_concluded(id: Self::Id);
180}
181
182pub struct PayWithFungibles<F, A>(core::marker::PhantomData<(F, A)>);
185impl<A, F> frame_support::traits::tokens::PayWithSource for PayWithFungibles<F, A>
186where
187 A: Eq + Clone,
188 F: fungibles::Mutate<A> + fungibles::Create<A>,
189{
190 type Balance = F::Balance;
191 type Source = A;
192 type Beneficiary = A;
193 type AssetKind = F::AssetId;
194 type Id = ();
195 type Error = DispatchError;
196 fn pay(
197 source: &Self::Source,
198 beneficiary: &Self::Beneficiary,
199 asset: Self::AssetKind,
200 amount: Self::Balance,
201 ) -> Result<Self::Id, Self::Error> {
202 <F as fungibles::Mutate<_>>::transfer(asset, source, beneficiary, amount, Expendable)?;
203 Ok(())
204 }
205 fn check_payment(_: ()) -> PaymentStatus {
206 PaymentStatus::Success
207 }
208 #[cfg(feature = "runtime-benchmarks")]
209 fn ensure_successful(
210 source: &Self::Source,
211 _: &Self::Beneficiary,
212 asset: Self::AssetKind,
213 amount: Self::Balance,
214 ) {
215 use sp_runtime::traits::Zero;
216
217 if F::total_issuance(asset.clone()).is_zero() {
218 let _ = <F as fungibles::Create<_>>::create(
219 asset.clone(),
220 source.clone(),
221 true,
222 1u32.into(),
223 );
224 }
225 <F as fungibles::Mutate<_>>::mint_into(asset, &source, amount).unwrap();
226 }
227 #[cfg(feature = "runtime-benchmarks")]
228 fn ensure_concluded(_: Self::Id) {}
229}