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
use std::mem::size_of;

use ellipsis_client::EllipsisClient;
use phoenix::program::MarketHeader;
use phoenix_sdk::utils::get_evictable_trader_ix;
use phoenix_seat_manager::instruction_builders::{
    create_evict_seat_instruction, EvictTraderAccountBackup,
};
use solana_sdk::pubkey::Pubkey;

pub async fn process_evict_seat(
    client: &EllipsisClient,
    market_pubkey: &Pubkey,
    trader_to_evict: &Option<Pubkey>,
) -> anyhow::Result<()> {
    let market_bytes = client.get_account_data(market_pubkey).await?;
    let (header_bytes, _market_bytes) = market_bytes.split_at(size_of::<MarketHeader>());
    let market_header = bytemuck::try_from_bytes::<MarketHeader>(header_bytes)
        .map_err(|e| anyhow::anyhow!("Error deserializing market header. Error: {:?}", e))?;

    let maybe_evict_trader_ix = if let Some(trader_pubkey) = trader_to_evict {
        let evict_trader_state = EvictTraderAccountBackup {
            trader_pubkey: *trader_pubkey,
            base_token_account_backup: None,
            quote_token_account_backup: None,
        };
        Some(create_evict_seat_instruction(
            market_pubkey,
            &market_header.base_params.mint_key,
            &market_header.quote_params.mint_key,
            trader_pubkey,
            vec![evict_trader_state],
        ))
    } else {
        get_evictable_trader_ix(client, market_pubkey).await?
    };

    if let Some(evict_trader_ix) = maybe_evict_trader_ix {
        println!("Evicting trader: {}", evict_trader_ix.accounts[13].pubkey);
        let tx = client
            .sign_send_instructions(vec![evict_trader_ix], vec![])
            .await?;
        println!("Evict trader tx: {}", tx);
    } else {
        println!("Cannot evict a trader when the market's trader state is not full.");
        return Ok(());
    }

    Ok(())
}