#[allow(deprecated)]
use solana_sdk::system_program;
use solana_sdk::{
instruction::{AccountMeta, Instruction},
pubkey::Pubkey,
};
use spl_associated_token_account::get_associated_token_address_with_program_id;
use crate::constants::*;
use crate::helpers::derive::*;
use crate::types::*;
pub fn build_initialize(
payer: &Pubkey,
params: &InitializeParams,
program_id: &Pubkey,
) -> Instruction {
let seed = params.seed.unwrap_or(0);
let token_program_x = params
.token_program_x
.unwrap_or(spl_token::id());
let token_program_y = params
.token_program_y
.unwrap_or(spl_token::id());
let (config_pda, _) = get_config_address(seed, ¶ms.mint_x, ¶ms.mint_y, program_id);
let vault_x = get_associated_token_address_with_program_id(
&config_pda,
¶ms.mint_x,
&token_program_x,
);
let vault_y = get_associated_token_address_with_program_id(
&config_pda,
¶ms.mint_y,
&token_program_y,
);
let (oracle_pda, _) =
get_midprice_oracle_address(seed, ¶ms.mint_x, ¶ms.mint_y, program_id);
let (curve_meta_pda, _) =
get_curve_meta_address(seed, ¶ms.mint_x, ¶ms.mint_y, program_id);
let (curve_prefabs_pda, _) =
get_curve_prefabs_address(seed, ¶ms.mint_x, ¶ms.mint_y, program_id);
let (curve_updates_pda, _) =
get_curve_updates_address(seed, ¶ms.mint_x, ¶ms.mint_y, program_id);
let has_oracle_mode = params.oracle_mode.is_some();
let has_custom_slots = params.max_prefab_slots.is_some() || params.max_curve_points.is_some();
let trailing = if has_custom_slots {
3
} else if has_oracle_mode {
1
} else {
0
};
let data_len = 1 + 8 + 32 + 32 + 32 + 8 + trailing;
let mut data = Vec::with_capacity(data_len);
data.push(Discriminator::Initialize as u8);
data.extend_from_slice(&seed.to_le_bytes());
data.extend_from_slice(params.mint_x.as_ref());
data.extend_from_slice(params.mint_y.as_ref());
data.extend_from_slice(params.authority.as_ref());
data.extend_from_slice(¶ms.initial_midprice_q32.to_le_bytes());
if has_oracle_mode || has_custom_slots {
data.push(params.oracle_mode.unwrap_or(OracleMode::Authority) as u8);
}
if has_custom_slots {
data.push(params.max_prefab_slots.unwrap_or(DEFAULT_MAX_PREFAB_SLOTS));
data.push(params.max_curve_points.unwrap_or(DEFAULT_MAX_CURVE_POINTS));
}
let keys = vec![
AccountMeta::new(*payer, true),
AccountMeta::new(config_pda, false),
AccountMeta::new_readonly(params.mint_x, false),
AccountMeta::new_readonly(params.mint_y, false),
AccountMeta::new(vault_x, false),
AccountMeta::new(vault_y, false),
AccountMeta::new_readonly(token_program_x, false),
AccountMeta::new_readonly(token_program_y, false),
AccountMeta::new_readonly(spl_associated_token_account::id(), false),
AccountMeta::new_readonly(system_program::id(), false),
AccountMeta::new(oracle_pda, false),
AccountMeta::new(curve_meta_pda, false),
AccountMeta::new(curve_prefabs_pda, false),
AccountMeta::new(curve_updates_pda, false),
];
Instruction {
program_id: *program_id,
accounts: keys,
data,
}
}
pub fn build_allocate_curve_prefabs(
payer: &Pubkey,
params: &AllocateCurvePrefabsParams,
program_id: &Pubkey,
) -> Instruction {
let (curve_prefabs_pda, _) =
get_curve_prefabs_address(params.seed, ¶ms.mint_x, ¶ms.mint_y, program_id);
let max_slots = params.max_prefab_slots.unwrap_or(DEFAULT_MAX_PREFAB_SLOTS);
let max_points = params.max_curve_points.unwrap_or(DEFAULT_MAX_CURVE_POINTS);
let mut data = Vec::with_capacity(108);
data.push(Discriminator::AllocateCurvePrefabs as u8);
data.extend_from_slice(¶ms.seed.to_le_bytes());
data.extend_from_slice(params.mint_x.as_ref());
data.extend_from_slice(params.mint_y.as_ref());
data.push(max_slots);
data.push(max_points);
data.extend_from_slice(params.authority.as_ref());
let keys = vec![
AccountMeta::new(*payer, true),
AccountMeta::new(curve_prefabs_pda, false),
AccountMeta::new_readonly(system_program::id(), false),
];
Instruction {
program_id: *program_id,
accounts: keys,
data,
}
}