use std::vec;
use crate::{program::SWAP_PROGRAM_ID, utils::sqrt_price::SqrtPrice};
use borsh::BorshDeserialize;
use solana_client::rpc_client::RpcClient;
use solana_sdk::pubkey::Pubkey;
use tabled::Tabled;
use super::config::ClmmConfig;
#[derive(BorshDeserialize, Tabled, Copy, Clone, Debug)]
pub struct Clmmpool {
pub clmm_config: Pubkey,
pub token_a: Pubkey,
pub token_b: Pubkey,
pub token_a_vault: Pubkey,
pub token_b_vault: Pubkey,
pub tick_spacing: u16,
pub tick_spacing_seed: u16,
pub fee_rate: u16,
pub liquidity: u128,
pub current_sqrt_price: u128,
pub current_tick_index: i32,
pub fee_growth_global_a: u128,
pub fee_growth_global_b: u128,
pub fee_protocol_token_a: u64,
pub fee_protocol_token_b: u64,
pub bump: u8,
pub reward_infos: Rewarders,
pub reward_last_updated_time: u64,
pub is_pause: bool,
}
#[derive(Copy, Clone, BorshDeserialize, Default, Debug, Eq, PartialEq)]
pub struct Rewarder {
pub mint_wrapper: Pubkey,
pub minter: Pubkey,
pub mint: Pubkey,
pub authority: Pubkey,
pub emissions_per_second: u128,
pub growth_global: u128,
}
impl Rewarder {
pub const LEN: usize = 32 + 32 + 32 + 32 + 16 + 16;
pub fn is_initialized(&self) -> bool {
self.mint.ne(&Pubkey::default())
}
}
#[derive(Copy, Clone, BorshDeserialize, Default, Debug, PartialEq)]
pub struct Rewarders(pub [Rewarder; 3]);
impl std::fmt::Display for Rewarders {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut res: Vec<String> = vec![];
for (i, e) in self.0.iter().enumerate() {
res.push(format!("{}. minter_wrapper: {:?} |", i, e.mint_wrapper));
res.push(format!("minter: {:?} |", e.minter));
res.push(format!("mint: {:?} |\n", e.mint));
res.push(format!("authority: {:?} |", e.authority));
res.push(format!(
"emissions_per_second: {:?} |",
e.emissions_per_second
));
res.push(format!("growth_global: {:?} |\n", e.growth_global));
res.push("\n".to_string());
}
let res_str = res.join("");
write!(f, "{}", res_str)
}
}
impl Clmmpool {
pub const REWARD_NUM: usize = 3;
pub const LEN: usize = 5 * 32
+ 3 * 2
+ 2 * 16
+ 4
+ 2 * 16
+ 2 * 8
+ 1
+ Clmmpool::REWARD_NUM * Rewarder::LEN
+ 8
+ 1;
pub fn find_address(token_a: &Pubkey, token_b: &Pubkey, tick_spacing: u16) -> Pubkey {
let clmm_config = ClmmConfig::find_address();
let (clmmpool_pubkey, _) = if token_a.lt(&token_b) {
Pubkey::find_program_address(
&[
b"clmmpool",
clmm_config.as_ref(),
token_a.as_ref(),
token_b.as_ref(),
tick_spacing.to_le_bytes().as_ref(),
],
&SWAP_PROGRAM_ID,
)
} else {
Pubkey::find_program_address(
&[
b"clmmpool",
clmm_config.as_ref(),
token_b.as_ref(),
token_a.as_ref(),
tick_spacing.to_le_bytes().as_ref(),
],
&SWAP_PROGRAM_ID,
)
};
clmmpool_pubkey
}
pub fn get_info(rpc_client: &RpcClient, pubkey: &Pubkey) -> Self {
let data_slice = &rpc_client.get_account_data(pubkey).unwrap()[8..];
Clmmpool::try_from_slice(data_slice).unwrap()
}
pub fn get_tick_map_address(pool: &Pubkey, program_id: Pubkey) -> Pubkey {
let (expect_address, _) =
Pubkey::find_program_address(&[b"tick_array_map", pool.as_ref()], &program_id);
expect_address
}
pub fn ui_list(self, clmmpool: Pubkey) -> ClmmpoolUiList {
ClmmpoolUiList {
name: String::from(""),
clmmpool,
token_a: self.token_a,
token_b: self.token_b,
tick_spacing: self.tick_spacing,
current_sqrt_price: SqrtPrice::new(self.current_sqrt_price),
current_tick_index: self.current_tick_index,
liquidity: self.liquidity,
}
}
pub fn ui(self) -> ClmmpoolUiDetail {
ClmmpoolUiDetail {
name: String::from(""),
clmm_config: self.clmm_config,
token_a: self.token_a,
token_b: self.token_b,
token_a_vault: self.token_a_vault,
token_b_vault: self.token_b_vault,
tick_spacing: self.tick_spacing,
tick_spacing_seed: self.tick_spacing_seed,
fee_rate: self.fee_rate,
liquidity: self.liquidity,
current_sqrt_price: self.current_sqrt_price,
current_tick_index: self.current_tick_index,
fee_growth_global_a: self.fee_growth_global_a,
fee_growth_global_b: self.fee_growth_global_b,
fee_protocol_token_a: self.fee_protocol_token_a,
fee_protocol_token_b: self.fee_protocol_token_b,
bump: self.bump,
reward_last_updated_time: self.reward_last_updated_time,
is_pause: self.is_pause,
amount_a: 0f64,
amount_b: 0f64,
}
}
}
#[derive(Tabled)]
pub struct ClmmpoolUiList {
pub name: String,
pub clmmpool: Pubkey,
pub token_a: Pubkey,
pub token_b: Pubkey,
pub tick_spacing: u16,
pub current_sqrt_price: SqrtPrice,
pub current_tick_index: i32,
pub liquidity: u128,
}
#[derive(Tabled)]
pub struct ClmmpoolUiDetail {
pub name: String,
pub clmm_config: Pubkey,
pub token_a: Pubkey,
pub token_b: Pubkey,
pub token_a_vault: Pubkey,
pub token_b_vault: Pubkey,
pub tick_spacing: u16,
pub tick_spacing_seed: u16,
pub fee_rate: u16,
pub liquidity: u128,
pub current_sqrt_price: u128,
pub current_tick_index: i32,
pub fee_growth_global_a: u128,
pub fee_growth_global_b: u128,
pub fee_protocol_token_a: u64,
pub fee_protocol_token_b: u64,
pub bump: u8,
pub reward_last_updated_time: u64, pub is_pause: bool,
pub amount_a: f64,
pub amount_b: f64,
}