use gmsol_programs::gmsol_treasury::{
accounts::{Config, GtBank, TreasuryVaultConfig},
types::{TokenBalance, TokenConfig},
};
use gmsol_utils::{gt::GtBankFlags, token_config::TokenFlag, token_config::TokenMapAccess};
use indexmap::IndexMap;
use solana_sdk::pubkey::Pubkey;
use crate::utils::{Amount, Value};
use super::StringPubkey;
#[derive(Debug, Clone)]
#[cfg_attr(serde, derive(serde::Serialize, serde::Deserialize))]
pub struct SerdeTreasury {
pub store: StringPubkey,
pub vault_config: StringPubkey,
pub gt_factor: Value,
pub buyback_factor: Value,
}
impl<'a> From<&'a Config> for SerdeTreasury {
fn from(config: &'a Config) -> Self {
Self {
store: config.store.into(),
vault_config: config.treasury_vault_config.into(),
gt_factor: Value::from_u128(config.gt_factor),
buyback_factor: Value::from_u128(config.buyback_factor),
}
}
}
#[derive(Debug, Clone)]
#[cfg_attr(serde, derive(serde::Serialize, serde::Deserialize))]
pub struct SerdeTreasuryVaultConfig {
pub index: u16,
pub config: StringPubkey,
pub tokens: IndexMap<StringPubkey, SerdeTreausryTokenConfig>,
}
impl<'a> From<&'a TreasuryVaultConfig> for SerdeTreasuryVaultConfig {
fn from(config: &'a TreasuryVaultConfig) -> Self {
Self {
index: config.index,
config: config.config.into(),
tokens: config
.tokens
.entries()
.map(|(k, v)| (Pubkey::new_from_array(*k).into(), v.into()))
.collect(),
}
}
}
#[derive(Debug, Clone)]
#[cfg_attr(serde, derive(serde::Serialize, serde::Deserialize))]
pub struct SerdeTreausryTokenConfig {
pub is_deposit_allowed: bool,
pub is_withdrawal_allowed: bool,
}
impl<'a> From<&'a TokenConfig> for SerdeTreausryTokenConfig {
fn from(config: &'a TokenConfig) -> Self {
Self {
is_deposit_allowed: config.flags.get_flag(TokenFlag::AllowDeposit),
is_withdrawal_allowed: config.flags.get_flag(TokenFlag::AllowWithdrawal),
}
}
}
#[derive(Debug, Clone)]
#[cfg_attr(serde, derive(serde::Serialize, serde::Deserialize))]
pub struct SerdeGtBank {
pub is_initialized: bool,
pub is_confirmed: bool,
pub is_synced_after_confirmation: bool,
pub treasury_vault_config: StringPubkey,
pub gt_exchange_vault: StringPubkey,
pub remaining_confirmed_gt_amount: Amount,
pub balances: IndexMap<StringPubkey, SerdeGtBankBalance>,
}
impl SerdeGtBank {
pub fn from_gt_bank(
bank: &GtBank,
gt_decimals: u8,
token_map: &impl TokenMapAccess,
) -> crate::Result<Self> {
Ok(Self {
is_initialized: bank.flags.get_flag(GtBankFlags::Initialized),
is_confirmed: bank.flags.get_flag(GtBankFlags::Confirmed),
is_synced_after_confirmation: bank.flags.get_flag(GtBankFlags::SyncedAfterConfirmation),
treasury_vault_config: bank.treasury_vault_config.into(),
gt_exchange_vault: bank.gt_exchange_vault.into(),
remaining_confirmed_gt_amount: Amount::from_u64(
bank.remaining_confirmed_gt_amount,
gt_decimals,
),
balances: bank
.balances
.entries()
.map(|(k, v)| {
let token = Pubkey::new_from_array(*k);
let decimals = token_map
.get(&token)
.ok_or_else(|| crate::Error::NotFound)?
.token_decimals;
Ok((token.into(), SerdeGtBankBalance::from_balance(v, decimals)))
})
.collect::<crate::Result<_>>()?,
})
}
}
#[derive(Debug, Clone)]
#[cfg_attr(serde, derive(serde::Serialize, serde::Deserialize))]
pub struct SerdeGtBankBalance {
pub amount: Amount,
pub receiver_vault_out: Amount,
}
impl SerdeGtBankBalance {
pub fn from_balance(balance: &TokenBalance, token_decimals: u8) -> Self {
Self {
amount: Amount::from_u64(balance.amount, token_decimals),
receiver_vault_out: Amount::from_u64(balance.receiver_vault_out, token_decimals),
}
}
}