phoenix_seat_manager/
lib.rs1use ellipsis_macros::declare_id;
2use instruction::SeatManagerInstruction;
3use processor::{
4 process_change_market_status, process_claim_market_authority, process_claim_seat,
5 process_claim_seat_manager_authority, process_confirm_renounce_seat_manager_authority,
6 process_designated_market_maker, process_evict_seat, process_name_successor,
7};
8use solana_program::instruction::Instruction;
9use solana_program::msg;
10use solana_program::pubkey::Pubkey;
11
12use solana_program::{
13 account_info::AccountInfo, entrypoint::ProgramResult, program_error::ProgramError,
14};
15
16use crate::processor::{
17 process_change_market_fee_recipient, process_name_market_authority_successor,
18};
19pub mod instruction;
20pub mod instruction_builders;
21pub mod loaders;
22pub mod processor;
23pub mod seat_manager;
24pub mod shank_structs;
25
26#[cfg(not(feature = "no-entrypoint"))]
27use solana_security_txt::security_txt;
28
29#[cfg(not(feature = "no-entrypoint"))]
30security_txt! {
31 name: "Phoenix Seat Manager V1",
33 project_url: "https://ellipsislabs.xyz/",
34 contacts: "email:maintainers@ellipsislabs.xyz",
35 policy: "https://github.com/Ellipsis-Labs/phoenix-v1/blob/master/SECURITY.md",
36 preferred_languages: "en",
38 source_code: "https://github.com/Ellipsis-Labs/phoenix-seat-manager-v1",
39 auditors: "contact@osec.io"
40}
41
42const MAX_DMMS: u64 = 128;
43
44declare_id!("PSMxQbAoDWDbvd9ezQJgARyq6R9L5kJAasaLDVcZwf1");
45
46pub fn get_seat_manager_seeds(
47 market: &Pubkey,
48 seat_manager: &Pubkey,
49 program_id: &Pubkey,
50) -> Result<Vec<Vec<u8>>, ProgramError> {
51 let mut seeds = vec![market.to_bytes().to_vec()];
52 let (seat_manager_key, bump) = Pubkey::find_program_address(
53 seeds
54 .iter()
55 .map(|seed| seed.as_slice())
56 .collect::<Vec<&[u8]>>()
57 .as_slice(),
58 program_id,
59 );
60 seeds.push(vec![bump]);
61
62 if seat_manager_key == *seat_manager {
63 Ok(seeds)
64 } else {
65 let caller = std::panic::Location::caller();
66 msg!(
67 "Invalid seat manager key, expected: {} found {}.\n{}",
68 seat_manager_key,
69 seat_manager,
70 caller
71 );
72 return Err(ProgramError::InvalidInstructionData.into());
73 }
74}
75
76pub fn get_seat_manager_address(market: &Pubkey) -> (Pubkey, u8) {
77 Pubkey::find_program_address(&[&market.to_bytes()], &crate::id())
78}
79
80pub fn get_seat_deposit_collector_seeds(
81 market: &Pubkey,
82 seat_deposit_collector: &Pubkey,
83 program_id: &Pubkey,
84) -> Result<Vec<Vec<u8>>, ProgramError> {
85 let mut seeds = vec![market.to_bytes().to_vec(), b"deposit".to_vec()];
86 let (seat_deposit_collector_key, bump) = Pubkey::find_program_address(
87 seeds
88 .iter()
89 .map(|seed| seed.as_slice())
90 .collect::<Vec<&[u8]>>()
91 .as_slice(),
92 program_id,
93 );
94 seeds.push(vec![bump]);
95
96 if seat_deposit_collector_key == *seat_deposit_collector {
97 Ok(seeds)
98 } else {
99 let caller = std::panic::Location::caller();
100 msg!(
101 "Invalid seat deposit collector key, expected: {} found {}.\n{}",
102 seat_deposit_collector_key,
103 seat_deposit_collector,
104 caller
105 );
106 return Err(ProgramError::InvalidInstructionData.into());
107 }
108}
109
110pub fn get_seat_deposit_collector_address(market: &Pubkey) -> (Pubkey, u8) {
111 Pubkey::find_program_address(&[&market.to_bytes(), b"deposit"], &crate::id())
112}
113
114pub fn get_accounts_for_instruction<'a, 'info>(
115 instruction: &Instruction,
116 accounts: &'a [AccountInfo<'info>],
117) -> Result<Vec<AccountInfo<'info>>, ProgramError> {
118 let mut accounts_from_instruction = vec![];
119 for account_key in instruction
121 .accounts
122 .iter()
123 .map(|ai| ai.pubkey)
124 .chain([instruction.program_id])
125 {
126 if let Some(account) = accounts.iter().find(|&ai| *ai.key == account_key) {
127 accounts_from_instruction.push(account.clone());
128 } else {
129 msg!("Failed to find key {} for instruction", account_key);
130 return Err(ProgramError::InvalidArgument);
131 }
132 }
133 Ok(accounts_from_instruction)
134}
135
136#[cfg(not(feature = "no-entrypoint"))]
137solana_program::entrypoint!(process_instruction);
138
139pub fn process_instruction(
140 program_id: &Pubkey,
141 accounts: &[AccountInfo],
142 instruction_data: &[u8],
143) -> ProgramResult {
144 let (tag, data) = instruction_data
145 .split_first()
146 .ok_or(ProgramError::InvalidInstructionData)?;
147
148 let instruction =
149 SeatManagerInstruction::try_from(*tag).or(Err(ProgramError::InvalidInstructionData))?;
150
151 match instruction {
152 SeatManagerInstruction::ClaimMarketAuthority => {
153 msg!("SeatManagerInstruction::ClaimMarketAuthority");
154 process_claim_market_authority(program_id, accounts)
155 }
156 SeatManagerInstruction::ClaimSeatAuthorized => {
157 msg!("SeatManagerInstruction::ClaimSeatAuthorized");
158 process_claim_seat(program_id, accounts, true)
159 }
160 SeatManagerInstruction::ClaimSeat => {
161 msg!("SeatManagerInstruction::ClaimSeat");
162 process_claim_seat(program_id, accounts, false)
163 }
164 SeatManagerInstruction::EvictSeat => {
165 msg!("SeatManagerInstruction::EvictSeat");
166 process_evict_seat(program_id, accounts)
167 }
168 SeatManagerInstruction::AddDesignatedMarketMaker => {
169 msg!("SeatManagerInstruction::AddDesignatedMarketMaker");
170 process_designated_market_maker(program_id, accounts, false)
171 }
172 SeatManagerInstruction::RemoveDesignatedMarketMaker => {
173 msg!("SeatManagerInstruction::RemoveDesignatedMarketMaker");
174 process_designated_market_maker(program_id, accounts, true)
175 }
176 SeatManagerInstruction::NameSuccessor => {
177 msg!("SeatManagerInstruction::NameSuccessor");
178 process_name_successor(program_id, accounts)
179 }
180 SeatManagerInstruction::ClaimSeatManagerAuthority => {
181 msg!("SeatManagerInstruction::ClaimSeatManagerAuthority");
182 process_claim_seat_manager_authority(program_id, accounts)
183 }
184 SeatManagerInstruction::ChangeMarketStatus => {
185 msg!("SeatManagerInstruction::ChangeMarketStatus");
186 process_change_market_status(program_id, accounts, data)
187 }
188 SeatManagerInstruction::NameMarketAuthoritySuccessor => {
189 msg!("SeatManagerInstruction::NameMarketAuthoritySuccessor");
190 process_name_market_authority_successor(program_id, accounts, data)
191 }
192 SeatManagerInstruction::ChangeMarketFeeRecipient => {
193 msg!("SeatManagerInstruction::ChangeMarketFeeRecipient");
194 process_change_market_fee_recipient(program_id, accounts)
195 }
196 SeatManagerInstruction::ConfirmRenounceSeatManagerAuthority => {
197 msg!("SeatManagerInstruction::ConfirmRenounceSeatManagerAuthority");
198 process_confirm_renounce_seat_manager_authority(program_id, accounts)
199 }
200 }
201}