feat: add Raydium CLMM protocol support, bump version to 0.2.1

This commit is contained in:
ysq
2025-07-19 21:28:01 +08:00
parent 2ddec98805
commit 7942bea571
16 changed files with 413 additions and 41 deletions
+23 -12
View File
@@ -4,9 +4,7 @@ use spl_associated_token_account::instruction::create_associated_token_account_i
use spl_token::instruction::close_account;
use crate::{
constants::bonk::{
accounts, BUY_EXECT_IN_DISCRIMINATOR, SELL_EXECT_IN_DISCRIMINATOR,
},
constants::bonk::{accounts, BUY_EXECT_IN_DISCRIMINATOR, SELL_EXECT_IN_DISCRIMINATOR},
constants::trade::trade::DEFAULT_SLIPPAGE,
trading::bonk::{
common::{get_amount_out, get_pool_pda, get_vault_pda},
@@ -14,7 +12,7 @@ use crate::{
},
trading::common::utils::get_token_balance,
trading::core::{
params::{BuyParams, BonkParams, SellParams},
params::{BonkParams, BuyParams, SellParams},
traits::InstructionBuilder,
},
};
@@ -70,11 +68,7 @@ impl BonkInstructionBuilder {
let mut real_base = protocol_params.real_base.unwrap_or(0);
let mut real_quote = protocol_params.real_quote.unwrap_or(0);
if virtual_base == 0
|| virtual_quote == 0
|| real_base == 0
|| real_quote == 0
{
if virtual_base == 0 || virtual_quote == 0 || real_base == 0 || real_quote == 0 {
let pool = Pool::fetch(params.rpc.as_ref().unwrap(), &pool_state).await?;
virtual_base = pool.virtual_base as u128;
virtual_quote = pool.virtual_quote as u128;
@@ -147,7 +141,7 @@ impl BonkInstructionBuilder {
solana_sdk::instruction::AccountMeta::new(user_quote_token_account, false), // User Quote Token
solana_sdk::instruction::AccountMeta::new(base_vault_account, false), // Base Vault
solana_sdk::instruction::AccountMeta::new(quote_vault_account, false), // Quote Vault
solana_sdk::instruction::AccountMeta::new(params.mint, false), // Base Token Mint (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(params.mint, false), // Base Token Mint (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(accounts::WSOL_TOKEN_ACCOUNT, false), // Quote Token Mint (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(accounts::TOKEN_PROGRAM, false), // Base Token Program (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(accounts::TOKEN_PROGRAM, false), // Quote Token Program (readonly)
@@ -253,7 +247,7 @@ impl BonkInstructionBuilder {
solana_sdk::instruction::AccountMeta::new(user_quote_token_account, false), // User Quote Token
solana_sdk::instruction::AccountMeta::new(base_vault_account, false), // Base Vault
solana_sdk::instruction::AccountMeta::new(quote_vault_account, false), // Quote Vault
solana_sdk::instruction::AccountMeta::new(params.mint, false), // Base Token Mint (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(params.mint, false), // Base Token Mint (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(accounts::WSOL_TOKEN_ACCOUNT, false), // Quote Token Mint (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(accounts::TOKEN_PROGRAM, false), // Base Token Program (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(accounts::TOKEN_PROGRAM, false), // Quote Token Program (readonly)
@@ -274,7 +268,24 @@ impl BonkInstructionBuilder {
data,
});
instructions.push(close_account(&accounts::TOKEN_PROGRAM, &user_quote_token_account, &params.payer.pubkey(), &params.payer.pubkey(), &[&params.payer.pubkey()]).unwrap());
let protocol_params = params
.protocol_params
.as_any()
.downcast_ref::<BonkParams>()
.ok_or_else(|| anyhow!("Invalid protocol params for Bonk"))?;
if protocol_params.auto_handle_wsol {
instructions.push(
close_account(
&accounts::TOKEN_PROGRAM,
&user_quote_token_account,
&params.payer.pubkey(),
&params.payer.pubkey(),
&[&params.payer.pubkey()],
)
.unwrap(),
);
}
Ok(instructions)
}
+19
View File
@@ -1,6 +1,7 @@
use anyhow::{anyhow, Result};
use solana_sdk::{instruction::Instruction, pubkey::Pubkey, signer::Signer};
use spl_associated_token_account::instruction::create_associated_token_account_idempotent;
use spl_token::instruction::close_account;
use crate::{
constants::pumpswap::{accounts, BUY_DISCRIMINATOR, SELL_DISCRIMINATOR},
@@ -361,6 +362,24 @@ impl PumpSwapInstructionBuilder {
data,
});
let protocol_params = params
.protocol_params
.as_any()
.downcast_ref::<PumpSwapParams>()
.ok_or_else(|| anyhow!("Invalid protocol params for PumpSwap"))?;
if protocol_params.auto_handle_wsol {
instructions.push(
close_account(
&accounts::TOKEN_PROGRAM,
&user_quote_token_account,
&params.payer.pubkey(),
&params.payer.pubkey(),
&[&params.payer.pubkey()],
)
.unwrap(),
);
}
Ok(instructions)
}
}
+53 -17
View File
@@ -49,10 +49,21 @@ impl RaydiumCpmmInstructionBuilder {
let pool_state = if protocol_params.pool_state.is_some() {
protocol_params.pool_state.unwrap()
} else {
let mint_token_in_pool_state_index = protocol_params
.mint_token_in_pool_state_index
.unwrap_or(1);
get_pool_pda(
&accounts::AMM_CONFIG,
&accounts::WSOL_TOKEN_ACCOUNT,
&params.mint,
if mint_token_in_pool_state_index == 1 {
&accounts::WSOL_TOKEN_ACCOUNT
} else {
&params.mint
},
if mint_token_in_pool_state_index == 1 {
&params.mint
} else {
&accounts::WSOL_TOKEN_ACCOUNT
},
)
.unwrap()
};
@@ -124,7 +135,9 @@ impl RaydiumCpmmInstructionBuilder {
&params.payer.pubkey(),
&params.payer.pubkey(),
&params.mint,
&protocol_params.mint_token_program.unwrap_or(accounts::TOKEN_PROGRAM),
&protocol_params
.mint_token_program
.unwrap_or(accounts::TOKEN_PROGRAM),
));
// 创建买入指令
@@ -138,7 +151,12 @@ impl RaydiumCpmmInstructionBuilder {
solana_sdk::instruction::AccountMeta::new(wsol_vault_account, false), // Input Vault Account
solana_sdk::instruction::AccountMeta::new(mint_vault_account, false), // Output Vault Account
solana_sdk::instruction::AccountMeta::new_readonly(accounts::TOKEN_PROGRAM, false), // Input Token Program (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(protocol_params.mint_token_program.unwrap_or(accounts::TOKEN_PROGRAM), false), // Output Token Program (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(
protocol_params
.mint_token_program
.unwrap_or(accounts::TOKEN_PROGRAM),
false,
), // Output Token Program (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(accounts::WSOL_TOKEN_ACCOUNT, false), // Input token mint (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(params.mint, false), // Output token mint (readonly)
solana_sdk::instruction::AccountMeta::new(observation_state_account, false), // Observation State Account
@@ -221,10 +239,21 @@ impl RaydiumCpmmInstructionBuilder {
let pool_state = if protocol_params.pool_state.is_some() {
protocol_params.pool_state.unwrap()
} else {
let mint_token_in_pool_state_index = protocol_params
.mint_token_in_pool_state_index
.unwrap_or(1);
get_pool_pda(
&accounts::AMM_CONFIG,
&accounts::WSOL_TOKEN_ACCOUNT,
&params.mint,
if mint_token_in_pool_state_index == 1 {
&accounts::WSOL_TOKEN_ACCOUNT
} else {
&params.mint
},
if mint_token_in_pool_state_index == 1 {
&params.mint
} else {
&accounts::WSOL_TOKEN_ACCOUNT
},
)
.unwrap()
};
@@ -267,7 +296,12 @@ impl RaydiumCpmmInstructionBuilder {
solana_sdk::instruction::AccountMeta::new(wsol_token_account, false), // Output Token Account
solana_sdk::instruction::AccountMeta::new(mint_vault_account, false), // Input Vault Account
solana_sdk::instruction::AccountMeta::new(wsol_vault_account, false), // Output Vault Account
solana_sdk::instruction::AccountMeta::new_readonly(protocol_params.mint_token_program.unwrap_or(accounts::TOKEN_PROGRAM), false), // Input Token Program (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(
protocol_params
.mint_token_program
.unwrap_or(accounts::TOKEN_PROGRAM),
false,
), // Input Token Program (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(accounts::TOKEN_PROGRAM, false), // Output Token Program (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(params.mint, false), // Input token mint (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(accounts::WSOL_TOKEN_ACCOUNT, false), // Output token mint (readonly)
@@ -285,16 +319,18 @@ impl RaydiumCpmmInstructionBuilder {
data,
});
instructions.push(
close_account(
&accounts::TOKEN_PROGRAM,
&wsol_token_account,
&params.payer.pubkey(),
&params.payer.pubkey(),
&[&params.payer.pubkey()],
)
.unwrap(),
);
if protocol_params.auto_handle_wsol {
instructions.push(
close_account(
&accounts::TOKEN_PROGRAM,
&wsol_token_account,
&params.payer.pubkey(),
&params.payer.pubkey(),
&[&params.payer.pubkey()],
)
.unwrap(),
);
}
Ok(instructions)
}