use frame_support::traits::{
fungible::{hold::Mutate, Inspect},
tokens::Precision,
};
use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
use scale_info::TypeInfo;
use serde::{Deserialize, Serialize};
use sp_runtime::DispatchError;
#[derive(
Clone, Debug, Encode, Decode, Eq, PartialEq, Ord, PartialOrd, TypeInfo, MaxEncodedLen, Serialize, Deserialize,
)]
pub struct Deposit<Account, Balance> {
pub owner: Account,
pub amount: Balance,
}
pub(crate) fn reserve_deposit<Account, Currency: Mutate<Account>>(
account: Account,
deposit_amount: Currency::Balance,
reason: &Currency::Reason,
) -> Result<Deposit<Account, Currency::Balance>, DispatchError> {
Currency::hold(reason, &account, deposit_amount)?;
Ok(Deposit {
owner: account,
amount: deposit_amount,
})
}
pub(crate) fn free_deposit<Account, Currency: Mutate<Account>>(
deposit: &Deposit<Account, Currency::Balance>,
reason: &Currency::Reason,
) -> Result<<Currency as Inspect<Account>>::Balance, DispatchError> {
let result = Currency::release(reason, &deposit.owner, deposit.amount, Precision::BestEffort);
debug_assert!(
result == Ok(deposit.amount),
"Released deposit amount does not match with expected amount. Expected: {:?}, Released amount: {:?} Error: {:?}",
deposit.amount,
result.ok(),
result.err(),
);
result
}