mirror of
https://github.com/0xfnzero/solana-streamer.git
synced 2026-08-16 10:28:05 +00:00
fix: sync all protocol structures with latest IDL definitions
This commit fixes multiple critical issues found when comparing SDK structures with the official IDL repository (https://github.com/0xfnzero/solana-program-idls): 1. PumpSwap GlobalConfig - Add missing reserved_fee_recipients: [Pubkey; 7] field - Update GLOBAL_CONFIG_SIZE constant 2. PumpFun Global - Add missing reserved_fee_recipients: [Pubkey; 7] field - Update GLOBAL_SIZE constant 3. Raydium CPMM AmmConfig - Add missing creator_fee_rate: u64 field - Adjust padding from [u64; 16] to [u64; 15] 4. Raydium CPMM PoolState - Add creator_fee_on: u8 field - Add enable_creator_fee: bool field - Add padding1: [u8; 6] field - Add creator_fees_token_0: u64 field - Add creator_fees_token_1: u64 field - Adjust padding from [u64; 31] to [u64; 28] 5. Bonk (Raydium Launchpad) PoolState - Add AmmCreatorFeeOn enum with borsh discriminant support - Add token_program_flag: u8 field - Add amm_creator_fee_on: AmmCreatorFeeOn field - Add platform_vesting_share: u64 field - Fix padding from [u64; 8] to [u8; 54] with serde_big_array - Update POOL_STATE_SIZE constant 6. Bonk (Raydium Launchpad) PlatformConfig - Add BondingCurveParam and PlatformCurveParam structures - Fix name from Vec<u8> to [u8; 64] with serde_big_array - Fix web from Vec<u8> to [u8; 256] with serde_big_array - Fix img from Vec<u8> to [u8; 256] with serde_big_array - Add cpswap_config: Pubkey field - Add creator_fee_rate: u64 field - Add transfer_fee_extension_auth: Pubkey field - Add platform_vesting_wallet: Pubkey field - Add platform_vesting_scale: u64 field - Add platform_cp_creator: Pubkey field - Fix padding from Vec<u8> to [u8; 108] with serde_big_array - Add curve_params: Vec<PlatformCurveParam> field - Update PLATFORM_CONFIG_SIZE constant 7. PumpSwap buy_exact_quote_in parameter order bug - Create separate parse_buy_exact_quote_in_instruction function - Fix parameter parsing order: spendable_quote_in (SOL) first, then min_base_amount_out (token) - Previous bug: buy_exact_quote_in incorrectly reused parse_buy_instruction which has reversed parameter order - Add detailed comments explaining the parameter order difference All changes have been verified against the official IDL files and compile successfully. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.5
parent
6969d15f08
commit
ce2931046d
@@ -43,13 +43,32 @@ pub struct VestingParams {
|
||||
pub unlock_period: u64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
|
||||
pub enum AmmFeeOn {
|
||||
#[default]
|
||||
QuoteToken,
|
||||
BothToken,
|
||||
}
|
||||
|
||||
impl Default for AmmFeeOn {
|
||||
fn default() -> Self {
|
||||
Self::QuoteToken
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
|
||||
#[borsh(use_discriminant = true)]
|
||||
#[repr(u8)]
|
||||
pub enum AmmCreatorFeeOn {
|
||||
QuoteToken = 0,
|
||||
BothToken = 1,
|
||||
}
|
||||
|
||||
impl Default for AmmCreatorFeeOn {
|
||||
fn default() -> Self {
|
||||
Self::QuoteToken
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
|
||||
pub struct ConstantCurve {
|
||||
pub supply: u64,
|
||||
@@ -94,7 +113,7 @@ pub struct VestingSchedule {
|
||||
pub allocated_share_amount: u64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
|
||||
pub struct PoolState {
|
||||
pub epoch: u64,
|
||||
pub auth_bump: u8,
|
||||
@@ -120,10 +139,49 @@ pub struct PoolState {
|
||||
pub base_vault: Pubkey,
|
||||
pub quote_vault: Pubkey,
|
||||
pub creator: Pubkey,
|
||||
pub padding: [u64; 8],
|
||||
pub token_program_flag: u8,
|
||||
pub amm_creator_fee_on: AmmCreatorFeeOn,
|
||||
pub platform_vesting_share: u64,
|
||||
#[serde(with = "serde_big_array::BigArray")]
|
||||
pub padding: [u8; 54],
|
||||
}
|
||||
|
||||
pub const POOL_STATE_SIZE: usize = 8 + 1 * 5 + 8 * 10 + 32 * 7 + 8 * 8 + 8 * 5;
|
||||
impl Default for PoolState {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
epoch: 0,
|
||||
auth_bump: 0,
|
||||
status: 0,
|
||||
base_decimals: 0,
|
||||
quote_decimals: 0,
|
||||
migrate_type: 0,
|
||||
supply: 0,
|
||||
total_base_sell: 0,
|
||||
virtual_base: 0,
|
||||
virtual_quote: 0,
|
||||
real_base: 0,
|
||||
real_quote: 0,
|
||||
total_quote_fund_raising: 0,
|
||||
quote_protocol_fee: 0,
|
||||
platform_fee: 0,
|
||||
migrate_fee: 0,
|
||||
vesting_schedule: VestingSchedule::default(),
|
||||
global_config: Pubkey::default(),
|
||||
platform_config: Pubkey::default(),
|
||||
base_mint: Pubkey::default(),
|
||||
quote_mint: Pubkey::default(),
|
||||
base_vault: Pubkey::default(),
|
||||
quote_vault: Pubkey::default(),
|
||||
creator: Pubkey::default(),
|
||||
token_program_flag: 0,
|
||||
amm_creator_fee_on: AmmCreatorFeeOn::default(),
|
||||
platform_vesting_share: 0,
|
||||
padding: [0u8; 54],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub const POOL_STATE_SIZE: usize = 8 + 1 * 5 + 8 * 10 + 32 * 7 + 8 * 8 + 8 * 5 + 1 + 1 + 8 + 54;
|
||||
|
||||
pub fn pool_state_decode(data: &[u8]) -> Option<PoolState> {
|
||||
if data.len() < POOL_STATE_SIZE {
|
||||
@@ -207,6 +265,40 @@ pub fn global_config_parser(
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
|
||||
pub struct BondingCurveParam {
|
||||
pub migrate_type: u8,
|
||||
pub migrate_cpmm_fee_on: u8,
|
||||
pub supply: u64,
|
||||
pub total_base_sell: u64,
|
||||
pub total_quote_fund_raising: u64,
|
||||
pub total_locked_amount: u64,
|
||||
pub cliff_period: u64,
|
||||
pub unlock_period: u64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
|
||||
pub struct PlatformCurveParam {
|
||||
pub epoch: u64,
|
||||
pub index: u8,
|
||||
pub global_config: Pubkey,
|
||||
pub bonding_curve_param: BondingCurveParam,
|
||||
#[serde(with = "serde_big_array::BigArray")]
|
||||
pub padding: [u64; 50],
|
||||
}
|
||||
|
||||
impl Default for PlatformCurveParam {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
epoch: 0,
|
||||
index: 0,
|
||||
global_config: Pubkey::default(),
|
||||
bonding_curve_param: BondingCurveParam::default(),
|
||||
padding: [0u64; 50],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, BorshDeserialize)]
|
||||
pub struct PlatformConfig {
|
||||
pub epoch: u64,
|
||||
pub platform_fee_wallet: Pubkey,
|
||||
@@ -215,13 +307,49 @@ pub struct PlatformConfig {
|
||||
pub creator_scale: u64,
|
||||
pub burn_scale: u64,
|
||||
pub fee_rate: u64,
|
||||
pub name: Vec<u8>,
|
||||
pub web: Vec<u8>,
|
||||
pub img: Vec<u8>,
|
||||
pub padding: Vec<u8>,
|
||||
#[serde(with = "serde_big_array::BigArray")]
|
||||
pub name: [u8; 64],
|
||||
#[serde(with = "serde_big_array::BigArray")]
|
||||
pub web: [u8; 256],
|
||||
#[serde(with = "serde_big_array::BigArray")]
|
||||
pub img: [u8; 256],
|
||||
pub cpswap_config: Pubkey,
|
||||
pub creator_fee_rate: u64,
|
||||
pub transfer_fee_extension_auth: Pubkey,
|
||||
pub platform_vesting_wallet: Pubkey,
|
||||
pub platform_vesting_scale: u64,
|
||||
pub platform_cp_creator: Pubkey,
|
||||
#[serde(with = "serde_big_array::BigArray")]
|
||||
pub padding: [u8; 108],
|
||||
pub curve_params: Vec<PlatformCurveParam>,
|
||||
}
|
||||
|
||||
pub const PLATFORM_CONFIG_SIZE: usize = 8 + 32 * 2 + 8 * 4 + 8 * 64 + 8 * 256 + 8 * 256 + 8 * 256;
|
||||
impl Default for PlatformConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
epoch: 0,
|
||||
platform_fee_wallet: Pubkey::default(),
|
||||
platform_nft_wallet: Pubkey::default(),
|
||||
platform_scale: 0,
|
||||
creator_scale: 0,
|
||||
burn_scale: 0,
|
||||
fee_rate: 0,
|
||||
name: [0u8; 64],
|
||||
web: [0u8; 256],
|
||||
img: [0u8; 256],
|
||||
cpswap_config: Pubkey::default(),
|
||||
creator_fee_rate: 0,
|
||||
transfer_fee_extension_auth: Pubkey::default(),
|
||||
platform_vesting_wallet: Pubkey::default(),
|
||||
platform_vesting_scale: 0,
|
||||
platform_cp_creator: Pubkey::default(),
|
||||
padding: [0u8; 108],
|
||||
curve_params: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub const PLATFORM_CONFIG_SIZE: usize = 8 + 32 * 2 + 8 * 4 + 64 + 256 + 256 + 32 + 8 + 32 + 32 + 8 + 32 + 108;
|
||||
|
||||
pub fn platform_config_decode(data: &[u8]) -> Option<PlatformConfig> {
|
||||
if data.len() < PLATFORM_CONFIG_SIZE {
|
||||
|
||||
@@ -77,9 +77,10 @@ pub struct Global {
|
||||
pub whitelist_pda: Pubkey,
|
||||
pub reserved_fee_recipient: Pubkey,
|
||||
pub mayhem_mode_enabled: bool,
|
||||
pub reserved_fee_recipients: [Pubkey; 7],
|
||||
}
|
||||
|
||||
pub const GLOBAL_SIZE: usize = 1 + 32 * 2 + 8 * 5 + 32 + 1 + 8 * 2 + 32 * 7 + 32 * 2 + 1 + 32 * 2 + 1;
|
||||
pub const GLOBAL_SIZE: usize = 1 + 32 * 2 + 8 * 5 + 32 + 1 + 8 * 2 + 32 * 7 + 32 * 2 + 1 + 32 * 2 + 1 + 32 * 7;
|
||||
|
||||
pub fn global_decode(data: &[u8]) -> Option<Global> {
|
||||
if data.len() < GLOBAL_SIZE {
|
||||
|
||||
@@ -24,7 +24,8 @@ pub fn parse_pumpswap_instruction_data(
|
||||
metadata: EventMetadata,
|
||||
) -> Option<DexEvent> {
|
||||
match discriminator {
|
||||
discriminators::BUY_IX | discriminators::BUY_EXACT_QUOTE_IN_IX => parse_buy_instruction(data, accounts, metadata),
|
||||
discriminators::BUY_IX => parse_buy_instruction(data, accounts, metadata),
|
||||
discriminators::BUY_EXACT_QUOTE_IN_IX => parse_buy_exact_quote_in_instruction(data, accounts, metadata),
|
||||
discriminators::SELL_IX => parse_sell_instruction(data, accounts, metadata),
|
||||
discriminators::CREATE_POOL_IX => {
|
||||
parse_create_pool_instruction(data, accounts, metadata)
|
||||
@@ -165,6 +166,47 @@ fn parse_buy_instruction(
|
||||
}))
|
||||
}
|
||||
|
||||
/// 解析 buy_exact_quote_in 指令事件
|
||||
/// 注意:参数顺序与 buy 指令不同
|
||||
/// buy_exact_quote_in: spendable_quote_in (SOL), min_base_amount_out (token)
|
||||
/// buy: base_amount_out (token), max_quote_amount_in (SOL)
|
||||
fn parse_buy_exact_quote_in_instruction(
|
||||
data: &[u8],
|
||||
accounts: &[Pubkey],
|
||||
mut metadata: EventMetadata,
|
||||
) -> Option<DexEvent> {
|
||||
metadata.event_type = EventType::PumpSwapBuy;
|
||||
|
||||
if data.len() < 16 || accounts.len() < 13 {
|
||||
return None;
|
||||
}
|
||||
|
||||
// 注意:buy_exact_quote_in 的参数顺序是先 quote (SOL) 再 base (token)
|
||||
let spendable_quote_in = read_u64_le(data, 0)?;
|
||||
let min_base_amount_out = read_u64_le(data, 8)?;
|
||||
|
||||
Some(DexEvent::PumpSwapBuyEvent(PumpSwapBuyEvent {
|
||||
metadata,
|
||||
base_amount_out: min_base_amount_out,
|
||||
max_quote_amount_in: spendable_quote_in,
|
||||
pool: accounts[0],
|
||||
user: accounts[1],
|
||||
base_mint: accounts[3],
|
||||
quote_mint: accounts[4],
|
||||
user_base_token_account: accounts[5],
|
||||
user_quote_token_account: accounts[6],
|
||||
pool_base_token_account: accounts[7],
|
||||
pool_quote_token_account: accounts[8],
|
||||
protocol_fee_recipient: accounts[9],
|
||||
protocol_fee_recipient_token_account: accounts[10],
|
||||
base_token_program: accounts[11],
|
||||
quote_token_program: accounts[12],
|
||||
coin_creator_vault_ata: accounts.get(17).copied().unwrap_or_default(),
|
||||
coin_creator_vault_authority: accounts.get(18).copied().unwrap_or_default(),
|
||||
..Default::default()
|
||||
}))
|
||||
}
|
||||
|
||||
/// 解析卖出指令事件
|
||||
fn parse_sell_instruction(
|
||||
data: &[u8],
|
||||
|
||||
@@ -23,9 +23,10 @@ pub struct GlobalConfig {
|
||||
pub whitelist_pda: Pubkey,
|
||||
pub reserved_fee_recipient: Pubkey,
|
||||
pub mayhem_mode_enabled: bool,
|
||||
pub reserved_fee_recipients: [Pubkey; 7],
|
||||
}
|
||||
|
||||
pub const GLOBAL_CONFIG_SIZE: usize = 32 + 8 + 8 + 1 + 32 * 8 + 8 + 32 + 32 + 32 + 1;
|
||||
pub const GLOBAL_CONFIG_SIZE: usize = 32 + 8 + 8 + 1 + 32 * 8 + 8 + 32 + 32 + 32 + 1 + 32 * 7;
|
||||
|
||||
pub fn global_config_decode(data: &[u8]) -> Option<GlobalConfig> {
|
||||
if data.len() < GLOBAL_CONFIG_SIZE {
|
||||
|
||||
@@ -24,7 +24,8 @@ pub struct AmmConfig {
|
||||
pub create_pool_fee: u64,
|
||||
pub protocol_owner: Pubkey,
|
||||
pub fund_owner: Pubkey,
|
||||
pub padding: [u64; 16],
|
||||
pub creator_fee_rate: u64,
|
||||
pub padding: [u64; 15],
|
||||
}
|
||||
|
||||
pub const AMM_CONFIG_SIZE: usize = 228;
|
||||
@@ -81,7 +82,12 @@ pub struct PoolState {
|
||||
pub fund_fees_token1: u64,
|
||||
pub open_time: u64,
|
||||
pub recent_epoch: u64,
|
||||
pub padding: [u64; 31],
|
||||
pub creator_fee_on: u8,
|
||||
pub enable_creator_fee: bool,
|
||||
pub padding1: [u8; 6],
|
||||
pub creator_fees_token_0: u64,
|
||||
pub creator_fees_token_1: u64,
|
||||
pub padding: [u64; 28],
|
||||
}
|
||||
|
||||
pub const POOL_STATE_SIZE: usize = 629;
|
||||
|
||||
Reference in New Issue
Block a user