Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jli/cli pll claim evict #31

Merged
merged 6 commits into from
Apr 14, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
spl-associated-token-account = { version = "1.1.1", features = [ "no-entrypoint" ] }
phoenix-v1 = { version = "0.2.2", features = ["no-entrypoint"] }
phoenix-sdk = "0.3.6"
phoenix-sdk = "0.4.0"
bytemuck = "1.13.0"
reqwest = "0.11.14"
bincode = "1.3.3"
phoenix-seat-manager = "0.1.0"
25 changes: 18 additions & 7 deletions src/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,7 @@ pub enum PhoenixCLICommand {
/// Get the full order book for a given market
GetFullBook { market_pubkey: Pubkey },
/// Get the market events that occured in a given transaction signature
GetTransaction {
signature: Signature,
},
GetTransaction { signature: Signature },
/// Get the current status of a market
GetMarketStatus { market_pubkey: Pubkey },
/// Get the status and address of a seat for a given market and trader
Expand All @@ -47,11 +45,12 @@ pub enum PhoenixCLICommand {
#[clap(short, long, required = false)]
trader_pubkey: Option<Pubkey>,
},
/// Send a transaction on chain to allocate a seat for the payer on the given market. This will cost ~.0018 SOL for rent.
/// Note that the seat will have to then be approved by the market authority.
/// Send a transaction on chain to allocate a seat for the payer on the given market. This will cost ~.0018 SOL for rent.
/// Note that the seat will have to then be approved by the market authority. Only relevant for permissioned markets.
/// For permissionless markets (with an automated seat manager), you can claim a seat with the claim-seat CLI command.
RequestSeat { market_pubkey: Pubkey },
/// Mint tokens to a recipient for a given ticker string (for example SOL or USDC). Default amount is 100_000_000_000.
/// This is only for markets associated with the ellipsis token faucet.
/// This is only for markets associated with the ellipsis token faucet.
MintTokens {
/// Ticker string, example: SOL
mint_ticker: String,
Expand All @@ -62,7 +61,7 @@ pub enum PhoenixCLICommand {
amount: u64,
},
/// Mint both base and quote tokens to a recipient for a given market. Default amounts are 100_000_000_000 for base and 100_000_000 for quote.
/// This is only for markets associated with the ellipsis token faucet.
/// This is only for markets associated with the ellipsis token faucet.
MintTokensForMarket {
market_pubkey: Pubkey,
/// Pubkey of the recipient of the tokens
Expand All @@ -74,4 +73,16 @@ pub enum PhoenixCLICommand {
#[clap(short, long, required = false, default_value = "100000000")]
quote_amount: u64,
},
/// For the given market, get the seat manager data fields, including authority, successor, and designated market makers.
GetSeatManagerInfo { market_pubkey: Pubkey },
/// On the given market, claim a maker seat for the public key of the keypair at the indicated file path.
/// Indicate a different keypair file to use by specifying the file path with flag `-k`.
ClaimSeat { market_pubkey: Pubkey },
/// Evict a trader from the given market if that market's trader state is at capacity.
/// If no trader is given, this function will greedily find a trader to evict.
/// Note that eviction will not work if the market's trader state is not at capacity.
EvictSeat {
market_pubkey: Pubkey,
trader_to_evict: Option<Pubkey>,
},
}
20 changes: 20 additions & 0 deletions src/lib/helpers/market_helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ use phoenix::state::markets::{Ladder, Market};
use phoenix::state::OrderPacket;

use phoenix_sdk::sdk_client::*;
use phoenix_seat_manager::get_seat_manager_address;
use phoenix_seat_manager::seat_manager::SeatManager;
use solana_account_decoder::UiAccountEncoding;
use solana_client::rpc_config::{RpcAccountInfoConfig, RpcProgramAccountsConfig};
use solana_client::rpc_filter::{Memcmp, MemcmpEncodedBytes, RpcFilterType};
Expand Down Expand Up @@ -202,3 +204,21 @@ pub async fn get_market_header(

Ok(*header)
}

pub async fn get_seat_manager_data_with_market(
client: &EllipsisClient,
market: &Pubkey,
) -> anyhow::Result<SeatManager> {
let seat_manager_address = get_seat_manager_address(market).0;
get_seat_manager_data_with_pubkey(client, &seat_manager_address).await
}

pub async fn get_seat_manager_data_with_pubkey(
client: &EllipsisClient,
seat_manager_pubkey: &Pubkey,
) -> anyhow::Result<SeatManager> {
let seat_manager_account = client.get_account(seat_manager_pubkey).await?;
let seat_manager_data = SeatManager::load(&seat_manager_account.data)?;

Ok(*seat_manager_data)
}
3 changes: 3 additions & 0 deletions src/lib/processor/mod.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
pub mod process_claim_seat;
pub mod process_evict_seat;
pub mod process_get_all_markets;
pub mod process_get_book_levels;
pub mod process_get_full_book;
pub mod process_get_market;
pub mod process_get_market_status;
pub mod process_get_open_orders;
pub mod process_get_seat_info;
pub mod process_get_seat_manager_info;
pub mod process_get_top_of_book;
pub mod process_get_traders_for_market;
pub mod process_get_transaction;
Expand Down
21 changes: 21 additions & 0 deletions src/lib/processor/process_claim_seat.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use ellipsis_client::EllipsisClient;
use phoenix_sdk::utils::create_claim_seat_ix_if_needed;
throwbackjams marked this conversation as resolved.
Show resolved Hide resolved
use solana_sdk::{pubkey::Pubkey, signer::Signer};

pub async fn process_claim_seat(
client: &EllipsisClient,
market_pubkey: &Pubkey,
) -> anyhow::Result<()> {
let claim_seat_ix =
create_claim_seat_ix_if_needed(client, market_pubkey, &client.payer.pubkey()).await?;
println!("Claiming seat for pubkey: {}", client.payer.pubkey());

if !claim_seat_ix.is_empty() {
let tx = client.sign_send_instructions(claim_seat_ix, vec![]).await?;
println!("Claim seat transaction: {}", tx);
} else {
println!("Seat already created for pubkey: {}", client.payer.pubkey());
}

Ok(())
}
50 changes: 50 additions & 0 deletions src/lib/processor/process_evict_seat.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,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>,
throwbackjams marked this conversation as resolved.
Show resolved Hide resolved
) -> 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(())
}
35 changes: 35 additions & 0 deletions src/lib/processor/process_get_seat_manager_info.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
use ellipsis_client::EllipsisClient;
use phoenix_seat_manager::{get_seat_manager_address, seat_manager::SeatManager};
use solana_sdk::pubkey::Pubkey;

use crate::helpers::market_helpers::get_seat_manager_data_with_market;

pub async fn process_get_seat_manager_info(
client: &EllipsisClient,
market_pubkey: &Pubkey,
) -> anyhow::Result<()> {
throwbackjams marked this conversation as resolved.
Show resolved Hide resolved
let seat_manager_address = get_seat_manager_address(market_pubkey).0;
let seat_manager_info = get_seat_manager_data_with_market(client, market_pubkey).await?;
print_seat_manager_struct(&seat_manager_info, &seat_manager_address);
Ok(())
}

pub fn print_seat_manager_struct(seat_manager: &SeatManager, seat_manager_pubkey: &Pubkey) {
println!("Seat Manager Address: {}", seat_manager_pubkey);
println!("SM Market: {}", seat_manager.market);
println!("SM Authority: {}", seat_manager.authority);
println!("SM Successor: {}", seat_manager.successor);
println!(
"Number of designated market makers: {}",
seat_manager.num_makers
);

let dmms: Vec<&Pubkey> = seat_manager
.designated_market_makers
.iter()
.filter(|&&dmm| dmm != Pubkey::default())
.collect();
if !dmms.is_empty() {
println!("DMMs: {:?}", dmms);
}
}
23 changes: 20 additions & 3 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ use crate::command::PhoenixCLICommand;
use anyhow::anyhow;
use clap::Parser;
use ellipsis_client::EllipsisClient;
use phoenix_cli_processor::processor::process_claim_seat::process_claim_seat;
use phoenix_cli_processor::processor::process_evict_seat::process_evict_seat;
use phoenix_cli_processor::processor::{
process_get_all_markets::*, process_get_book_levels::*, process_get_full_book::*,
process_get_market::*, process_get_market_status::*, process_get_open_orders::*,
process_get_seat_info::*, process_get_top_of_book::*, process_get_traders_for_market::*,
process_get_transaction::*, process_mint_tokens::*, process_mint_tokens_for_market::*,
process_request_seat::*,
process_get_seat_info::*, process_get_seat_manager_info::*, process_get_top_of_book::*,
process_get_traders_for_market::*, process_get_transaction::*, process_mint_tokens::*,
process_mint_tokens_for_market::*, process_request_seat::*,
};
use phoenix_sdk::sdk_client::*;
use solana_cli_config::{Config, ConfigInput, CONFIG_FILE};
Expand Down Expand Up @@ -154,6 +156,21 @@ async fn main() -> anyhow::Result<()> {
)
.await?
}
PhoenixCLICommand::GetSeatManagerInfo { market_pubkey } => {
sdk.add_market(&market_pubkey).await?;
process_get_seat_manager_info(&sdk.client, &market_pubkey).await?;
}
PhoenixCLICommand::ClaimSeat { market_pubkey } => {
sdk.add_market(&market_pubkey).await?;
process_claim_seat(&sdk.client, &market_pubkey).await?
}
PhoenixCLICommand::EvictSeat {
market_pubkey,
trader_to_evict,
} => {
sdk.add_market(&market_pubkey).await?;
process_evict_seat(&sdk.client, &market_pubkey, &trader_to_evict).await?
}
}

Ok(())
Expand Down