use common_primitives::msa::MsaValidator;
use frame_support::traits::tokens::{fungible::Inspect as InspectFungible, Balance};
use sp_std::marker::PhantomData;
use super::*;
use crate::Config;
pub trait OnChargeCapacityTransaction<T: Config> {
type Balance: Balance;
fn withdraw_fee(
key: &T::AccountId,
fee: Self::Balance,
) -> Result<Self::Balance, TransactionValidityError>;
}
pub struct CapacityAdapter<Curr, Msa>(PhantomData<(Curr, Msa)>);
impl<T, Curr, Msa> OnChargeCapacityTransaction<T> for CapacityAdapter<Curr, Msa>
where
T: Config,
Curr: InspectFungible<<T as frame_system::Config>::AccountId>,
Msa: MsaValidator<AccountId = <T as frame_system::Config>::AccountId>,
BalanceOf<T>: Send + Sync + FixedPointOperand + IsType<CapacityBalanceOf<T>> + MaxEncodedLen,
{
type Balance = BalanceOf<T>;
fn withdraw_fee(
key: &T::AccountId,
fee: Self::Balance,
) -> Result<Self::Balance, TransactionValidityError> {
ensure!(
Curr::total_balance(key) >= Curr::minimum_balance(),
TransactionValidityError::Invalid(InvalidTransaction::Payment)
);
let msa_id = Msa::ensure_valid_msa_key(key)
.map_err(|_| ChargeFrqTransactionPaymentError::InvalidMsaKey.into())?;
if T::Capacity::can_replenish(msa_id) {
ensure!(
T::Capacity::replenish_all_for(msa_id).is_ok(),
TransactionValidityError::Invalid(InvalidTransaction::Payment)
);
}
ensure!(
T::Capacity::deduct(msa_id, fee.into()).is_ok(),
TransactionValidityError::Invalid(InvalidTransaction::Payment)
);
Ok(fee)
}
}