1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
use frame_support::pallet_prelude::Get;
use frame_support::traits::fungible::Inspect as FungibleInspect;
use frame_support::traits::fungibles::Inspect as FungiblesInspect;
use frame_support::traits::tokens::{DepositConsequence, WithdrawConsequence};

/// An adapter to use inspect functionality for both native and multi currency
pub struct MultiInspectAdapter<AccountId, AssetId, Balance, NativeCurrency, MultiCurrency, GetNativeCurrencyId>(
    sp_std::marker::PhantomData<(
        AccountId,
        AssetId,
        Balance,
        NativeCurrency,
        MultiCurrency,
        GetNativeCurrencyId,
    )>,
);

impl<AccountId, AssetId, Balance, NativeCurrency, MultiCurrency, GetNativeCurrencyId> FungiblesInspect<AccountId>
    for MultiInspectAdapter<AccountId, AssetId, Balance, NativeCurrency, MultiCurrency, GetNativeCurrencyId>
where
    AssetId: frame_support::traits::tokens::AssetId,
    Balance: frame_support::traits::tokens::Balance,
    NativeCurrency: FungibleInspect<AccountId, Balance = Balance>,
    MultiCurrency: FungiblesInspect<AccountId, AssetId = AssetId, Balance = Balance>,
    GetNativeCurrencyId: Get<AssetId>,
{
    type AssetId = AssetId;
    type Balance = Balance;

    fn total_issuance(asset: Self::AssetId) -> Self::Balance {
        if GetNativeCurrencyId::get() == asset {
            NativeCurrency::total_issuance()
        } else {
            MultiCurrency::total_issuance(asset)
        }
    }

    fn minimum_balance(asset: Self::AssetId) -> Self::Balance {
        if GetNativeCurrencyId::get() == asset {
            NativeCurrency::minimum_balance()
        } else {
            MultiCurrency::minimum_balance(asset)
        }
    }

    fn balance(asset: Self::AssetId, who: &AccountId) -> Self::Balance {
        if GetNativeCurrencyId::get() == asset {
            NativeCurrency::balance(who)
        } else {
            MultiCurrency::balance(asset, who)
        }
    }

    fn reducible_balance(asset: Self::AssetId, who: &AccountId, keep_alive: bool) -> Self::Balance {
        if GetNativeCurrencyId::get() == asset {
            NativeCurrency::reducible_balance(who, keep_alive)
        } else {
            MultiCurrency::reducible_balance(asset, who, keep_alive)
        }
    }

    fn can_deposit(asset: Self::AssetId, who: &AccountId, amount: Self::Balance, mint: bool) -> DepositConsequence {
        if GetNativeCurrencyId::get() == asset {
            NativeCurrency::can_deposit(who, amount, mint)
        } else {
            MultiCurrency::can_deposit(asset, who, amount, mint)
        }
    }

    fn can_withdraw(
        asset: Self::AssetId,
        who: &AccountId,
        amount: Self::Balance,
    ) -> WithdrawConsequence<Self::Balance> {
        if GetNativeCurrencyId::get() == asset {
            NativeCurrency::can_withdraw(who, amount)
        } else {
            MultiCurrency::can_withdraw(asset, who, amount)
        }
    }
}