use super::program_ids;
use super::utils::*;
use crate::core::events::*;
use solana_sdk::{pubkey::Pubkey, signature::Signature};
pub mod discriminators {
pub const TRADE: [u8; 8] = [2, 3, 4, 5, 6, 7, 8, 9];
pub const POOL_CREATE: [u8; 8] = [1, 2, 3, 4, 5, 6, 7, 8];
pub const MIGRATE_AMM: [u8; 8] = [3, 4, 5, 6, 7, 8, 9, 10];
}
pub const PROGRAM_ID_PUBKEY: Pubkey = program_ids::BONK_PROGRAM_ID;
pub fn parse_instruction(
instruction_data: &[u8],
accounts: &[Pubkey],
signature: Signature,
slot: u64,
tx_index: u64,
block_time_us: Option<i64>,
) -> Option<DexEvent> {
if instruction_data.len() < 8 {
return None;
}
let discriminator: [u8; 8] = instruction_data[0..8].try_into().ok()?;
let data = &instruction_data[8..];
match discriminator {
discriminators::TRADE => {
parse_trade_instruction(data, accounts, signature, slot, tx_index, block_time_us)
}
discriminators::POOL_CREATE => {
parse_pool_create_instruction(data, accounts, signature, slot, tx_index, block_time_us)
}
discriminators::MIGRATE_AMM => {
parse_migrate_amm_instruction(data, accounts, signature, slot, tx_index, block_time_us)
}
_ => None,
}
}
#[allow(unused_variables)]
fn parse_trade_instruction(
data: &[u8],
accounts: &[Pubkey],
signature: Signature,
slot: u64,
tx_index: u64,
block_time_us: Option<i64>,
) -> Option<DexEvent> {
let mut offset = 0;
let amount_in = read_u64_le(data, offset)?;
offset += 8;
let amount_out_min = read_u64_le(data, offset)?;
let pool_state = get_account(accounts, 0)?;
let metadata = create_metadata_simple(signature, slot, tx_index, block_time_us, pool_state);
Some(DexEvent::BonkTrade(BonkTradeEvent {
metadata,
pool_state,
user: get_account(accounts, 1).unwrap_or_default(),
amount_in,
amount_out: amount_out_min, is_buy: true, trade_direction: TradeDirection::Buy,
exact_in: true,
}))
}
fn parse_pool_create_instruction(
_data: &[u8],
accounts: &[Pubkey],
signature: Signature,
slot: u64,
tx_index: u64,
block_time_us: Option<i64>,
) -> Option<DexEvent> {
let pool_state = get_account(accounts, 0)?;
let metadata = create_metadata_simple(signature, slot, tx_index, block_time_us, pool_state);
Some(DexEvent::BonkPoolCreate(BonkPoolCreateEvent {
metadata,
base_mint_param: BaseMintParam {
symbol: "BONK".to_string(),
name: "Bonk Pool".to_string(),
uri: "https://bonk.com".to_string(),
decimals: 5,
},
pool_state,
creator: get_account(accounts, 1).unwrap_or_default(),
}))
}
fn parse_migrate_amm_instruction(
data: &[u8],
accounts: &[Pubkey],
signature: Signature,
slot: u64,
tx_index: u64,
block_time_us: Option<i64>,
) -> Option<DexEvent> {
let offset = 0;
let liquidity_amount = read_u64_le(data, offset)?;
let old_pool = get_account(accounts, 0)?;
let metadata = create_metadata_simple(signature, slot, tx_index, block_time_us, old_pool);
Some(DexEvent::BonkMigrateAmm(BonkMigrateAmmEvent {
metadata,
old_pool,
new_pool: get_account(accounts, 1).unwrap_or_default(),
user: get_account(accounts, 2).unwrap_or_default(),
liquidity_amount,
}))
}