use solana_sdk::{
instruction::{AccountMeta, Instruction},
pubkey::Pubkey,
};
use crate::constants::Discriminator;
use crate::types::*;
pub fn build_set_curve(
authority: &Pubkey,
curve_meta_pda: &Pubkey,
curve_prefabs_pda: &Pubkey,
params: &SetCurveParams,
program_id: &Pubkey,
) -> Instruction {
let slot = params.slot.unwrap_or(0);
let x_mode = params.x_mode.unwrap_or(CurveXMode::Native);
let num_points = params.points.len() as u8;
let mut data = Vec::with_capacity(6 + params.points.len() * 21);
data.push(Discriminator::SetCurve as u8);
data.push(slot);
data.push(params.side as u8);
data.push(params.default_interpolation as u8);
data.push(num_points);
data.push(x_mode as u8);
for pt in ¶ms.points {
data.extend_from_slice(&pt.amount_in.to_le_bytes());
data.extend_from_slice(&pt.price_factor_q32.to_le_bytes());
data.push(pt.interpolation.unwrap_or(params.default_interpolation) as u8);
data.extend_from_slice(&pt.params.unwrap_or([0; 4]));
}
let keys = vec![
AccountMeta::new_readonly(*authority, true),
AccountMeta::new(*curve_meta_pda, false),
AccountMeta::new(*curve_prefabs_pda, false),
];
Instruction {
program_id: *program_id,
accounts: keys,
data,
}
}
pub fn build_set_risk_curve(
authority: &Pubkey,
curve_meta_pda: &Pubkey,
curve_prefabs_pda: &Pubkey,
params: &SetRiskCurveParams,
program_id: &Pubkey,
) -> Instruction {
let slot = params.slot.unwrap_or(0);
let x_mode = params.x_mode.unwrap_or(CurveXMode::Native);
let risk_mode = params.risk_mode.unwrap_or(RiskMode::Virtual);
let num_points = params.points.len() as u8;
let mut data = Vec::with_capacity(7 + params.points.len() * 21);
data.push(Discriminator::SetRiskCurve as u8);
data.push(slot);
data.push(params.side as u8);
data.push(params.default_interpolation as u8);
data.push(num_points);
data.push(x_mode as u8);
data.push(risk_mode as u8);
for pt in ¶ms.points {
data.extend_from_slice(&pt.pct_base_q32.to_le_bytes());
data.extend_from_slice(&pt.price_factor_q32.to_le_bytes());
data.push(pt.interpolation.unwrap_or(params.default_interpolation) as u8);
data.extend_from_slice(&pt.params.unwrap_or([0; 4]));
}
let keys = vec![
AccountMeta::new_readonly(*authority, true),
AccountMeta::new(*curve_meta_pda, false),
AccountMeta::new(*curve_prefabs_pda, false),
];
Instruction {
program_id: *program_id,
accounts: keys,
data,
}
}
pub fn build_set_risk_curve_absolute(
authority: &Pubkey,
curve_meta_pda: &Pubkey,
curve_prefabs_pda: &Pubkey,
params: &SetRiskCurveAbsoluteParams,
program_id: &Pubkey,
) -> Instruction {
let slot = params.slot.unwrap_or(0);
let risk_mode = params.risk_mode.unwrap_or(RiskMode::Virtual);
let num_points = params.points.len() as u8;
let mut data = Vec::with_capacity(7 + params.points.len() * 21);
data.push(Discriminator::SetRiskCurve as u8);
data.push(slot);
data.push(params.side as u8);
data.push(params.default_interpolation as u8);
data.push(num_points);
data.push(CurveXMode::Alternate as u8); data.push(risk_mode as u8);
for pt in ¶ms.points {
data.extend_from_slice(&pt.vault_balance.to_le_bytes());
data.extend_from_slice(&pt.price_factor_q32.to_le_bytes());
data.push(pt.interpolation.unwrap_or(params.default_interpolation) as u8);
data.extend_from_slice(&pt.params.unwrap_or([0; 4]));
}
let keys = vec![
AccountMeta::new_readonly(*authority, true),
AccountMeta::new(*curve_meta_pda, false),
AccountMeta::new(*curve_prefabs_pda, false),
];
Instruction {
program_id: *program_id,
accounts: keys,
data,
}
}
pub fn build_set_curve_both(
authority: &Pubkey,
curve_meta_pda: &Pubkey,
curve_prefabs_pda: &Pubkey,
params: &SetCurveBothParams,
program_id: &Pubkey,
) -> [Instruction; 2] {
let bid_params = SetCurveParams {
side: Side::Bid,
default_interpolation: params.bid.default_interpolation,
points: params.bid.points.iter().map(|p| SetCurvePointInput {
amount_in: p.amount_in,
price_factor_q32: p.price_factor_q32,
interpolation: p.interpolation,
params: p.params,
}).collect(),
slot: params.bid.slot,
x_mode: params.bid.x_mode,
};
let ask_params = SetCurveParams {
side: Side::Ask,
default_interpolation: params.ask.default_interpolation,
points: params.ask.points.iter().map(|p| SetCurvePointInput {
amount_in: p.amount_in,
price_factor_q32: p.price_factor_q32,
interpolation: p.interpolation,
params: p.params,
}).collect(),
slot: params.ask.slot,
x_mode: params.ask.x_mode,
};
[
build_set_curve(authority, curve_meta_pda, curve_prefabs_pda, &bid_params, program_id),
build_set_curve(authority, curve_meta_pda, curve_prefabs_pda, &ask_params, program_id),
]
}
pub fn build_set_risk_curve_both(
authority: &Pubkey,
curve_meta_pda: &Pubkey,
curve_prefabs_pda: &Pubkey,
params: &SetRiskCurveBothParams,
program_id: &Pubkey,
) -> [Instruction; 2] {
let bid_params = SetRiskCurveParams {
side: Side::Bid,
default_interpolation: params.bid.default_interpolation,
points: params.bid.points.iter().map(|p| SetRiskCurvePointInput {
pct_base_q32: p.pct_base_q32,
price_factor_q32: p.price_factor_q32,
interpolation: p.interpolation,
params: p.params,
}).collect(),
slot: params.bid.slot,
x_mode: params.bid.x_mode,
risk_mode: params.bid.risk_mode,
};
let ask_params = SetRiskCurveParams {
side: Side::Ask,
default_interpolation: params.ask.default_interpolation,
points: params.ask.points.iter().map(|p| SetRiskCurvePointInput {
pct_base_q32: p.pct_base_q32,
price_factor_q32: p.price_factor_q32,
interpolation: p.interpolation,
params: p.params,
}).collect(),
slot: params.ask.slot,
x_mode: params.ask.x_mode,
risk_mode: params.ask.risk_mode,
};
[
build_set_risk_curve(authority, curve_meta_pda, curve_prefabs_pda, &bid_params, program_id),
build_set_risk_curve(authority, curve_meta_pda, curve_prefabs_pda, &ask_params, program_id),
]
}
pub fn build_set_risk_curve_absolute_both(
authority: &Pubkey,
curve_meta_pda: &Pubkey,
curve_prefabs_pda: &Pubkey,
params: &SetRiskCurveAbsoluteBothParams,
program_id: &Pubkey,
) -> [Instruction; 2] {
let bid_params = SetRiskCurveAbsoluteParams {
side: Side::Bid,
default_interpolation: params.bid.default_interpolation,
points: params.bid.points.iter().map(|p| SetRiskCurveAbsolutePointInput {
vault_balance: p.vault_balance,
price_factor_q32: p.price_factor_q32,
interpolation: p.interpolation,
params: p.params,
}).collect(),
slot: params.bid.slot,
risk_mode: params.bid.risk_mode,
};
let ask_params = SetRiskCurveAbsoluteParams {
side: Side::Ask,
default_interpolation: params.ask.default_interpolation,
points: params.ask.points.iter().map(|p| SetRiskCurveAbsolutePointInput {
vault_balance: p.vault_balance,
price_factor_q32: p.price_factor_q32,
interpolation: p.interpolation,
params: p.params,
}).collect(),
slot: params.ask.slot,
risk_mode: params.ask.risk_mode,
};
[
build_set_risk_curve_absolute(authority, curve_meta_pda, curve_prefabs_pda, &bid_params, program_id),
build_set_risk_curve_absolute(authority, curve_meta_pda, curve_prefabs_pda, &ask_params, program_id),
]
}