refactor: optimize AccountMeta creation with lazy static constants

- Consolidate protocol constants to unified module
- Pre-build AccountMeta objects using once_cell::Lazy
- Reduce instruction building overhead across all DEX protocols
- Improve code maintainability and performance
This commit is contained in:
ysq
2025-09-07 21:36:57 +08:00
parent 51253c7aaf
commit 544e65318d
17 changed files with 323 additions and 185 deletions
+4 -4
View File
@@ -86,7 +86,7 @@ fn create_event_callback() -> impl Fn(Box<dyn UnifiedEvent>) {
|event: Box<dyn UnifiedEvent>| {
match_event!(event, {
PumpSwapBuyEvent => |e: PumpSwapBuyEvent| {
if e.base_mint == accounts::WSOL_TOKEN_ACCOUNT || e.quote_mint == accounts::WSOL_TOKEN_ACCOUNT {
if e.base_mint == sol_trade_sdk::constants::WSOL_TOKEN_ACCOUNT || e.quote_mint == sol_trade_sdk::constants::WSOL_TOKEN_ACCOUNT {
// Test code, only test one transaction
if !ALREADY_EXECUTED.swap(true, Ordering::SeqCst) {
let event_clone = e.clone();
@@ -100,7 +100,7 @@ fn create_event_callback() -> impl Fn(Box<dyn UnifiedEvent>) {
}
},
PumpSwapSellEvent => |e: PumpSwapSellEvent| {
if e.base_mint == accounts::WSOL_TOKEN_ACCOUNT || e.quote_mint == accounts::WSOL_TOKEN_ACCOUNT {
if e.base_mint == sol_trade_sdk::constants::WSOL_TOKEN_ACCOUNT || e.quote_mint == sol_trade_sdk::constants::WSOL_TOKEN_ACCOUNT {
// Test code, only test one transaction
if !ALREADY_EXECUTED.swap(true, Ordering::SeqCst) {
let event_clone = e.clone();
@@ -147,7 +147,7 @@ async fn create_solana_trade_client() -> AnyResult<SolanaTrade> {
async fn pumpswap_trade_with_grpc_buy_event(trade_info: PumpSwapBuyEvent) -> AnyResult<()> {
let params = PumpSwapParams::from_buy_trade(&trade_info);
let mint = if trade_info.base_mint == accounts::WSOL_TOKEN_ACCOUNT {
let mint = if trade_info.base_mint == sol_trade_sdk::constants::WSOL_TOKEN_ACCOUNT {
trade_info.quote_mint
} else {
trade_info.base_mint
@@ -158,7 +158,7 @@ async fn pumpswap_trade_with_grpc_buy_event(trade_info: PumpSwapBuyEvent) -> Any
async fn pumpswap_trade_with_grpc_sell_event(trade_info: PumpSwapSellEvent) -> AnyResult<()> {
let params = PumpSwapParams::from_sell_trade(&trade_info);
let mint = if trade_info.base_mint == accounts::WSOL_TOKEN_ACCOUNT {
let mint = if trade_info.base_mint == sol_trade_sdk::constants::WSOL_TOKEN_ACCOUNT {
trade_info.quote_mint
} else {
trade_info.base_mint
+1 -1
View File
@@ -134,7 +134,7 @@ async fn raydium_amm_v4_copy_trade_with_grpc(trade_info: RaydiumAmmV4SwapEvent)
let amm_info = fetch_amm_info(&client.rpc, trade_info.amm).await?;
let (coin_reserve, pc_reserve) =
get_multi_token_balances(&client.rpc, &amm_info.token_coin, &amm_info.token_pc).await?;
let mint_pubkey = if amm_info.pc_mint == accounts::WSOL_TOKEN_ACCOUNT {
let mint_pubkey = if amm_info.pc_mint == sol_trade_sdk::constants::WSOL_TOKEN_ACCOUNT {
amm_info.coin_mint
} else {
amm_info.pc_mint
+2 -1
View File
@@ -138,7 +138,8 @@ async fn raydium_cpmm_copy_trade_with_grpc(trade_info: RaydiumCpmmSwapEvent) ->
println!("Testing Raydium_cpmm trading...");
let client = create_solana_trade_client().await?;
let mint_pubkey = if trade_info.input_token_mint == accounts::WSOL_TOKEN_ACCOUNT {
let mint_pubkey = if trade_info.input_token_mint == sol_trade_sdk::constants::WSOL_TOKEN_ACCOUNT
{
trade_info.output_token_mint
} else {
trade_info.input_token_mint
+22
View File
@@ -1,4 +1,26 @@
use solana_sdk::{pubkey, pubkey::Pubkey};
pub mod decimals;
pub mod swqos;
pub mod trade;
pub mod trade_platform;
pub const SYSTEM_PROGRAM: Pubkey = solana_sdk::system_program::ID;
pub const SYSTEM_PROGRAM_META: once_cell::sync::Lazy<solana_sdk::instruction::AccountMeta> =
once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new_readonly(SYSTEM_PROGRAM, false)
});
pub const TOKEN_PROGRAM: Pubkey = spl_token::ID;
pub const TOKEN_PROGRAM_META: once_cell::sync::Lazy<solana_sdk::instruction::AccountMeta> =
once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new_readonly(TOKEN_PROGRAM, false)
});
pub const TOKEN_PROGRAM_2022: Pubkey = spl_token_2022::ID;
pub const WSOL_TOKEN_ACCOUNT: Pubkey = pubkey!("So11111111111111111111111111111111111111112");
pub const WSOL_TOKEN_ACCOUNT_META: once_cell::sync::Lazy<solana_sdk::instruction::AccountMeta> =
once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new_readonly(WSOL_TOKEN_ACCOUNT, false)
});
+27 -27
View File
@@ -37,7 +37,7 @@ impl InstructionBuilder for BonkInstructionBuilder {
.downcast_ref::<BonkParams>()
.ok_or_else(|| anyhow!("Invalid protocol params for Bonk"))?;
let pool_state = get_pool_pda(&params.mint, &accounts::WSOL_TOKEN_ACCOUNT).unwrap();
let pool_state = get_pool_pda(&params.mint, &crate::constants::WSOL_TOKEN_ACCOUNT).unwrap();
// Create user token accounts
let user_base_token_account = spl_associated_token_account::get_associated_token_address(
@@ -46,13 +46,13 @@ impl InstructionBuilder for BonkInstructionBuilder {
);
let user_quote_token_account = spl_associated_token_account::get_associated_token_address(
&params.payer.pubkey(),
&accounts::WSOL_TOKEN_ACCOUNT,
&crate::constants::WSOL_TOKEN_ACCOUNT,
);
// Get pool token accounts
let base_vault_account = get_vault_pda(&pool_state, &params.mint).unwrap();
let quote_vault_account =
get_vault_pda(&pool_state, &accounts::WSOL_TOKEN_ACCOUNT).unwrap();
get_vault_pda(&pool_state, &crate::constants::WSOL_TOKEN_ACCOUNT).unwrap();
let virtual_base = protocol_params.virtual_base;
let virtual_quote = protocol_params.virtual_quote;
@@ -79,8 +79,8 @@ impl InstructionBuilder for BonkInstructionBuilder {
create_associated_token_account_idempotent(
&params.payer.pubkey(),
&params.payer.pubkey(),
&accounts::WSOL_TOKEN_ACCOUNT,
&accounts::TOKEN_PROGRAM,
&crate::constants::WSOL_TOKEN_ACCOUNT,
&crate::constants::TOKEN_PROGRAM,
),
);
instructions.push(
@@ -91,7 +91,7 @@ impl InstructionBuilder for BonkInstructionBuilder {
// Sync wSOL balance
instructions.push(
spl_token::instruction::sync_native(
&accounts::TOKEN_PROGRAM,
&crate::constants::TOKEN_PROGRAM,
&user_quote_token_account,
)
.unwrap(),
@@ -109,8 +109,8 @@ impl InstructionBuilder for BonkInstructionBuilder {
// Create buy instruction
let accounts = vec![
solana_sdk::instruction::AccountMeta::new(params.payer.pubkey(), true), // Payer (signer)
solana_sdk::instruction::AccountMeta::new_readonly(accounts::AUTHORITY, false), // Authority (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(accounts::GLOBAL_CONFIG, false), // Global Config (readonly)
accounts::AUTHORITY_META.clone(), // Authority (readonly)
accounts::GLOBAL_CONFIG_META.clone(), // Global Config (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(
protocol_params.platform_config,
false,
@@ -121,15 +121,15 @@ impl InstructionBuilder for BonkInstructionBuilder {
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_readonly(params.mint, false), // Base Token Mint (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(accounts::WSOL_TOKEN_ACCOUNT, false), // Quote Token Mint (readonly)
crate::constants::WSOL_TOKEN_ACCOUNT_META.clone(), // Quote Token Mint (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(
protocol_params.mint_token_program,
false,
), // Base Token Program (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(accounts::TOKEN_PROGRAM, false), // Quote Token Program (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(accounts::EVENT_AUTHORITY, false), // Event Authority (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(accounts::BONK, false), // Program (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(accounts::SYSTEM_PROGRAM, false), // System Program (readonly)
crate::constants::TOKEN_PROGRAM_META.clone(), // Quote Token Program (readonly)
accounts::EVENT_AUTHORITY_META.clone(), // Event Authority (readonly)
accounts::BONK_META.clone(), // Program (readonly)
crate::constants::SYSTEM_PROGRAM_META.clone(), // System Program (readonly)
solana_sdk::instruction::AccountMeta::new(
protocol_params.platform_associated_account,
false,
@@ -152,7 +152,7 @@ impl InstructionBuilder for BonkInstructionBuilder {
// Close wSOL ATA account, reclaim rent
instructions.push(
spl_token::instruction::close_account(
&accounts::TOKEN_PROGRAM,
&crate::constants::TOKEN_PROGRAM,
&user_quote_token_account,
&params.payer.pubkey(),
&params.payer.pubkey(),
@@ -191,7 +191,7 @@ impl InstructionBuilder for BonkInstructionBuilder {
return Err(anyhow!("Amount cannot be zero"));
}
let pool_state = get_pool_pda(&params.mint, &accounts::WSOL_TOKEN_ACCOUNT).unwrap();
let pool_state = get_pool_pda(&params.mint, &crate::constants::WSOL_TOKEN_ACCOUNT).unwrap();
let virtual_base = protocol_params.virtual_base;
let virtual_quote = protocol_params.virtual_quote;
@@ -217,13 +217,13 @@ impl InstructionBuilder for BonkInstructionBuilder {
);
let user_quote_token_account = spl_associated_token_account::get_associated_token_address(
&params.payer.pubkey(),
&accounts::WSOL_TOKEN_ACCOUNT,
&crate::constants::WSOL_TOKEN_ACCOUNT,
);
// Get pool token accounts
let base_vault_account = get_vault_pda(&pool_state, &params.mint).unwrap();
let quote_vault_account =
get_vault_pda(&pool_state, &accounts::WSOL_TOKEN_ACCOUNT).unwrap();
get_vault_pda(&pool_state, &crate::constants::WSOL_TOKEN_ACCOUNT).unwrap();
let share_fee_rate: u64 = 0;
@@ -235,16 +235,16 @@ impl InstructionBuilder for BonkInstructionBuilder {
create_associated_token_account_idempotent(
&params.payer.pubkey(),
&params.payer.pubkey(),
&accounts::WSOL_TOKEN_ACCOUNT,
&accounts::TOKEN_PROGRAM,
&crate::constants::WSOL_TOKEN_ACCOUNT,
&crate::constants::TOKEN_PROGRAM,
),
);
// Create sell instruction
let accounts = vec![
solana_sdk::instruction::AccountMeta::new(params.payer.pubkey(), true), // Payer (signer)
solana_sdk::instruction::AccountMeta::new_readonly(accounts::AUTHORITY, false), // Authority (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(accounts::GLOBAL_CONFIG, false), // Global Config (readonly)
accounts::AUTHORITY_META.clone(), // Authority (readonly)
accounts::GLOBAL_CONFIG_META.clone(), // Global Config (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(
protocol_params.platform_config,
false,
@@ -255,15 +255,15 @@ impl InstructionBuilder for BonkInstructionBuilder {
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_readonly(params.mint, false), // Base Token Mint (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(accounts::WSOL_TOKEN_ACCOUNT, false), // Quote Token Mint (readonly)
crate::constants::WSOL_TOKEN_ACCOUNT_META.clone(), // Quote Token Mint (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(
protocol_params.mint_token_program,
false,
), // Base Token Program (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(accounts::TOKEN_PROGRAM, false), // Quote Token Program (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(accounts::EVENT_AUTHORITY, false), // Event Authority (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(accounts::BONK, false), // Program (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(accounts::SYSTEM_PROGRAM, false), // System Program (readonly)
crate::constants::TOKEN_PROGRAM_META.clone(), // Quote Token Program (readonly)
accounts::EVENT_AUTHORITY_META.clone(), // Event Authority (readonly)
accounts::BONK_META.clone(), // Program (readonly)
crate::constants::SYSTEM_PROGRAM_META.clone(), // System Program (readonly)
solana_sdk::instruction::AccountMeta::new(
protocol_params.platform_associated_account,
false,
@@ -286,7 +286,7 @@ impl InstructionBuilder for BonkInstructionBuilder {
if protocol_params.auto_handle_wsol {
instructions.push(
close_account(
&accounts::TOKEN_PROGRAM,
&crate::constants::TOKEN_PROGRAM,
&user_quote_token_account,
&params.payer.pubkey(),
&params.payer.pubkey(),
+21 -22
View File
@@ -7,9 +7,8 @@ use spl_token::instruction::close_account;
use crate::{
instruction::utils::pumpfun::{
accounts, get_bonding_curve_pda, get_creator_vault_pda, get_fee_config_pda,
get_global_volume_accumulator_pda, get_user_volume_accumulator_pda,
global_constants::{self, FEE_RECIPIENT},
accounts, get_bonding_curve_pda, get_creator_vault_pda, get_user_volume_accumulator_pda,
global_constants::{self},
},
utils::calc::{
common::{calculate_with_slippage_buy, calculate_with_slippage_sell},
@@ -82,7 +81,7 @@ impl InstructionBuilder for PumpFunInstructionBuilder {
&params.payer.pubkey(),
&params.payer.pubkey(),
&params.mint,
&accounts::TOKEN_PROGRAM,
&crate::constants::TOKEN_PROGRAM,
));
// Create buy instruction data
@@ -96,8 +95,8 @@ impl InstructionBuilder for PumpFunInstructionBuilder {
accounts::PUMPFUN,
&buy_data,
vec![
AccountMeta::new_readonly(global_constants::GLOBAL_ACCOUNT, false),
AccountMeta::new(FEE_RECIPIENT, false),
global_constants::GLOBAL_ACCOUNT_META.clone(),
global_constants::FEE_RECIPIENT_META.clone(),
AccountMeta::new_readonly(params.mint, false),
AccountMeta::new(bonding_curve.account, false),
AccountMeta::new(
@@ -109,18 +108,18 @@ impl InstructionBuilder for PumpFunInstructionBuilder {
false,
),
AccountMeta::new(params.payer.pubkey(), true),
AccountMeta::new_readonly(accounts::SYSTEM_PROGRAM, false),
AccountMeta::new_readonly(accounts::TOKEN_PROGRAM, false),
crate::constants::SYSTEM_PROGRAM_META.clone(),
crate::constants::TOKEN_PROGRAM_META.clone(),
AccountMeta::new(creator_vault_pda, false),
AccountMeta::new_readonly(accounts::EVENT_AUTHORITY, false),
AccountMeta::new_readonly(accounts::PUMPFUN, false),
AccountMeta::new(get_global_volume_accumulator_pda().unwrap(), false),
accounts::EVENT_AUTHORITY_META.clone(),
accounts::PUMPFUN_META.clone(),
accounts::GLOBAL_VOLUME_ACCUMULATOR_META.clone(),
AccountMeta::new(
get_user_volume_accumulator_pda(&params.payer.pubkey()).unwrap(),
false,
),
AccountMeta::new_readonly(get_fee_config_pda().unwrap(), false),
AccountMeta::new_readonly(accounts::FEE_PROGRAM, false),
accounts::FEE_CONFIG_META.clone(),
accounts::FEE_PROGRAM_META.clone(),
],
));
@@ -179,8 +178,8 @@ impl InstructionBuilder for PumpFunInstructionBuilder {
accounts::PUMPFUN,
&sell_data,
vec![
AccountMeta::new_readonly(global_constants::GLOBAL_ACCOUNT, false),
AccountMeta::new(FEE_RECIPIENT, false),
global_constants::GLOBAL_ACCOUNT_META.clone(),
global_constants::FEE_RECIPIENT_META.clone(),
AccountMeta::new_readonly(params.mint, false),
AccountMeta::new(bonding_curve, false),
AccountMeta::new(get_associated_token_address(&bonding_curve, &params.mint), false),
@@ -189,20 +188,20 @@ impl InstructionBuilder for PumpFunInstructionBuilder {
false,
),
AccountMeta::new(params.payer.pubkey(), true),
AccountMeta::new_readonly(accounts::SYSTEM_PROGRAM, false),
crate::constants::SYSTEM_PROGRAM_META.clone(),
AccountMeta::new(creator_vault_pda, false),
AccountMeta::new_readonly(accounts::TOKEN_PROGRAM, false),
AccountMeta::new_readonly(accounts::EVENT_AUTHORITY, false),
AccountMeta::new_readonly(accounts::PUMPFUN, false),
AccountMeta::new_readonly(get_fee_config_pda().unwrap(), false),
AccountMeta::new_readonly(accounts::FEE_PROGRAM, false),
crate::constants::TOKEN_PROGRAM_META.clone(),
accounts::EVENT_AUTHORITY_META.clone(),
accounts::PUMPFUN_META.clone(),
accounts::FEE_CONFIG_META.clone(),
accounts::FEE_PROGRAM_META.clone(),
],
)];
// If selling all tokens, close the account
if protocol_params.close_token_account_when_sell.unwrap_or(false) {
instructions.push(close_account(
&spl_token::ID,
&crate::constants::TOKEN_PROGRAM,
&ata,
&params.payer.pubkey(),
&params.payer.pubkey(),
+35 -49
View File
@@ -7,9 +7,8 @@ use spl_token::instruction::close_account;
use crate::{
constants::trade::trade::DEFAULT_SLIPPAGE,
instruction::utils::pumpswap::{
accounts, coin_creator_vault_ata, fee_recipient_ata, get_fee_config_pda,
get_global_volume_accumulator_pda, get_user_volume_accumulator_pda, BUY_DISCRIMINATOR,
SELL_DISCRIMINATOR,
accounts, coin_creator_vault_ata, fee_recipient_ata, get_user_volume_accumulator_pda,
BUY_DISCRIMINATOR, SELL_DISCRIMINATOR,
},
trading::core::{
params::{BuyParams, PumpSwapParams, SellParams},
@@ -47,13 +46,15 @@ impl InstructionBuilder for PumpSwapInstructionBuilder {
let base_token_program = protocol_params.base_token_program;
let quote_token_program = protocol_params.quote_token_program;
if base_mint != accounts::WSOL_TOKEN_ACCOUNT && quote_mint != accounts::WSOL_TOKEN_ACCOUNT {
if base_mint != crate::constants::WSOL_TOKEN_ACCOUNT
&& quote_mint != crate::constants::WSOL_TOKEN_ACCOUNT
{
return Err(anyhow!("Invalid base mint and quote mint"));
}
if params.rpc.is_none() {
return Err(anyhow!("RPC is not set"));
}
let quote_mint_is_wsol = quote_mint == accounts::WSOL_TOKEN_ACCOUNT;
let quote_mint_is_wsol = quote_mint == crate::constants::WSOL_TOKEN_ACCOUNT;
let mut token_amount = 0;
let mut sol_amount = 0;
@@ -129,8 +130,8 @@ impl InstructionBuilder for PumpSwapInstructionBuilder {
create_associated_token_account_idempotent(
&params.payer.pubkey(),
&params.payer.pubkey(),
&accounts::WSOL_TOKEN_ACCOUNT,
&accounts::TOKEN_PROGRAM,
&crate::constants::WSOL_TOKEN_ACCOUNT,
&crate::constants::TOKEN_PROGRAM,
),
);
instructions.push(
@@ -149,7 +150,7 @@ impl InstructionBuilder for PumpSwapInstructionBuilder {
// Sync wSOL balance
instructions.push(
spl_token::instruction::sync_native(
&accounts::TOKEN_PROGRAM,
&crate::constants::TOKEN_PROGRAM,
if quote_mint_is_wsol {
&user_quote_token_account
} else {
@@ -174,24 +175,21 @@ impl InstructionBuilder for PumpSwapInstructionBuilder {
let mut accounts = vec![
solana_sdk::instruction::AccountMeta::new_readonly(pool, false), // pool_id (readonly)
solana_sdk::instruction::AccountMeta::new(params.payer.pubkey(), true), // user (signer)
solana_sdk::instruction::AccountMeta::new_readonly(accounts::GLOBAL_ACCOUNT, false), // global (readonly)
accounts::GLOBAL_ACCOUNT_META.clone(), // global (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(base_mint, false), // base_mint (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(quote_mint, false), // quote_mint (readonly)
solana_sdk::instruction::AccountMeta::new(user_base_token_account, false), // user_base_token_account
solana_sdk::instruction::AccountMeta::new(user_quote_token_account, false), // user_quote_token_account
solana_sdk::instruction::AccountMeta::new(pool_base_token_account, false), // pool_base_token_account
solana_sdk::instruction::AccountMeta::new(pool_quote_token_account, false), // pool_quote_token_account
solana_sdk::instruction::AccountMeta::new_readonly(accounts::FEE_RECIPIENT, false), // fee_recipient (readonly)
accounts::FEE_RECIPIENT_META.clone(), // fee_recipient (readonly)
solana_sdk::instruction::AccountMeta::new(fee_recipient_ata, false), // fee_recipient_ata
solana_sdk::instruction::AccountMeta::new_readonly(base_token_program, false), // TOKEN_PROGRAM_ID (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(quote_token_program, false), // TOKEN_PROGRAM_ID (readonly, duplicated as in JS)
solana_sdk::instruction::AccountMeta::new_readonly(accounts::SYSTEM_PROGRAM, false), // System Program (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(
accounts::ASSOCIATED_TOKEN_PROGRAM,
false,
), // ASSOCIATED_TOKEN_PROGRAM_ID (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(accounts::EVENT_AUTHORITY, false), // event_authority (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(accounts::AMM_PROGRAM, false), // PUMP_AMM_PROGRAM_ID (readonly)
crate::constants::SYSTEM_PROGRAM_META.clone(), // System Program (readonly)
accounts::ASSOCIATED_TOKEN_PROGRAM_META.clone(), // ASSOCIATED_TOKEN_PROGRAM_ID (readonly)
accounts::EVENT_AUTHORITY_META.clone(), // event_authority (readonly)
accounts::AMM_PROGRAM_META.clone(), // PUMP_AMM_PROGRAM_ID (readonly)
solana_sdk::instruction::AccountMeta::new(params_coin_creator_vault_ata, false), // coin_creator_vault_ata
solana_sdk::instruction::AccountMeta::new_readonly(
params_coin_creator_vault_authority,
@@ -199,19 +197,14 @@ impl InstructionBuilder for PumpSwapInstructionBuilder {
), // coin_creator_vault_authority (readonly)
];
if quote_mint_is_wsol {
accounts.push(solana_sdk::instruction::AccountMeta::new(
get_global_volume_accumulator_pda().unwrap(),
false,
));
accounts.push(accounts::GLOBAL_VOLUME_ACCUMULATOR_META.clone());
accounts.push(solana_sdk::instruction::AccountMeta::new(
get_user_volume_accumulator_pda(&params.payer.pubkey()).unwrap(),
false,
));
}
accounts
.push(solana_sdk::instruction::AccountMeta::new(get_fee_config_pda().unwrap(), false));
accounts
.push(solana_sdk::instruction::AccountMeta::new_readonly(accounts::FEE_PROGRAM, false));
accounts.push(accounts::FEE_CONFIG_META.clone());
accounts.push(accounts::FEE_PROGRAM_META.clone());
// Create instruction data
let mut data = vec![];
@@ -234,7 +227,7 @@ impl InstructionBuilder for PumpSwapInstructionBuilder {
// Close wSOL ATA account, reclaim rent
instructions.push(
spl_token::instruction::close_account(
&accounts::TOKEN_PROGRAM,
&crate::constants::TOKEN_PROGRAM,
if quote_mint_is_wsol {
&user_quote_token_account
} else {
@@ -270,7 +263,9 @@ impl InstructionBuilder for PumpSwapInstructionBuilder {
let base_token_program = protocol_params.base_token_program;
let quote_token_program = protocol_params.quote_token_program;
if base_mint != accounts::WSOL_TOKEN_ACCOUNT && quote_mint != accounts::WSOL_TOKEN_ACCOUNT {
if base_mint != crate::constants::WSOL_TOKEN_ACCOUNT
&& quote_mint != crate::constants::WSOL_TOKEN_ACCOUNT
{
return Err(anyhow!("Invalid base mint and quote mint"));
}
if params.rpc.is_none() {
@@ -280,7 +275,7 @@ impl InstructionBuilder for PumpSwapInstructionBuilder {
return Err(anyhow!("Token amount is not set"));
}
let quote_mint_is_wsol = quote_mint == accounts::WSOL_TOKEN_ACCOUNT;
let quote_mint_is_wsol = quote_mint == crate::constants::WSOL_TOKEN_ACCOUNT;
let mut token_amount = 0;
let mut sol_amount = 0;
@@ -354,8 +349,8 @@ impl InstructionBuilder for PumpSwapInstructionBuilder {
create_associated_token_account_idempotent(
&params.payer.pubkey(),
&params.payer.pubkey(),
&accounts::WSOL_TOKEN_ACCOUNT,
&accounts::TOKEN_PROGRAM,
&crate::constants::WSOL_TOKEN_ACCOUNT,
&crate::constants::TOKEN_PROGRAM,
),
);
@@ -371,24 +366,21 @@ impl InstructionBuilder for PumpSwapInstructionBuilder {
let mut accounts = vec![
solana_sdk::instruction::AccountMeta::new_readonly(pool, false), // pool_id (readonly)
solana_sdk::instruction::AccountMeta::new(params.payer.pubkey(), true), // user (signer)
solana_sdk::instruction::AccountMeta::new_readonly(accounts::GLOBAL_ACCOUNT, false), // global (readonly)
accounts::GLOBAL_ACCOUNT_META.clone(), // global (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(base_mint, false), // mint (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(quote_mint, false), // WSOL_TOKEN_ACCOUNT (readonly)
solana_sdk::instruction::AccountMeta::new(user_base_token_account, false), // user_base_token_account
solana_sdk::instruction::AccountMeta::new(user_quote_token_account, false), // user_quote_token_account
solana_sdk::instruction::AccountMeta::new(pool_base_token_account, false), // pool_base_token_account
solana_sdk::instruction::AccountMeta::new(pool_quote_token_account, false), // pool_quote_token_account
solana_sdk::instruction::AccountMeta::new_readonly(accounts::FEE_RECIPIENT, false), // fee_recipient (readonly)
accounts::FEE_RECIPIENT_META.clone(), // fee_recipient (readonly)
solana_sdk::instruction::AccountMeta::new(fee_recipient_ata, false), // fee_recipient_ata
solana_sdk::instruction::AccountMeta::new_readonly(base_token_program, false), // TOKEN_PROGRAM_ID (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(quote_token_program, false), // TOKEN_PROGRAM_ID (readonly, duplicated as in JS)
solana_sdk::instruction::AccountMeta::new_readonly(accounts::SYSTEM_PROGRAM, false), // System Program (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(
accounts::ASSOCIATED_TOKEN_PROGRAM,
false,
), // ASSOCIATED_TOKEN_PROGRAM_ID (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(accounts::EVENT_AUTHORITY, false), // event_authority (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(accounts::AMM_PROGRAM, false), // PUMP_AMM_PROGRAM_ID (readonly)
crate::constants::SYSTEM_PROGRAM_META.clone(), // System Program (readonly)
accounts::ASSOCIATED_TOKEN_PROGRAM_META.clone(), // ASSOCIATED_TOKEN_PROGRAM_ID (readonly)
accounts::EVENT_AUTHORITY_META.clone(), // event_authority (readonly)
accounts::AMM_PROGRAM_META.clone(), // PUMP_AMM_PROGRAM_ID (readonly)
solana_sdk::instruction::AccountMeta::new(params_coin_creator_vault_ata, false), // coin_creator_vault_ata
solana_sdk::instruction::AccountMeta::new_readonly(
params_coin_creator_vault_authority,
@@ -396,20 +388,15 @@ impl InstructionBuilder for PumpSwapInstructionBuilder {
), // coin_creator_vault_authority (readonly)
];
if !quote_mint_is_wsol {
accounts.push(solana_sdk::instruction::AccountMeta::new(
get_global_volume_accumulator_pda().unwrap(),
false,
));
accounts.push(accounts::GLOBAL_VOLUME_ACCUMULATOR_META.clone());
accounts.push(solana_sdk::instruction::AccountMeta::new(
get_user_volume_accumulator_pda(&params.payer.pubkey()).unwrap(),
false,
));
}
accounts
.push(solana_sdk::instruction::AccountMeta::new(get_fee_config_pda().unwrap(), false));
accounts
.push(solana_sdk::instruction::AccountMeta::new_readonly(accounts::FEE_PROGRAM, false));
accounts.push(accounts::FEE_CONFIG_META.clone());
accounts.push(accounts::FEE_PROGRAM_META.clone());
// Create instruction data
let mut data = vec![];
@@ -432,7 +419,7 @@ impl InstructionBuilder for PumpSwapInstructionBuilder {
if auto_handle_wsol {
instructions.push(
close_account(
&accounts::TOKEN_PROGRAM,
&crate::constants::TOKEN_PROGRAM,
if quote_mint_is_wsol {
&user_quote_token_account
} else {
@@ -448,4 +435,3 @@ impl InstructionBuilder for PumpSwapInstructionBuilder {
Ok(instructions)
}
}
+22 -19
View File
@@ -31,10 +31,10 @@ impl InstructionBuilder for RaydiumAmmV4InstructionBuilder {
let wsol_token_account = spl_associated_token_account::get_associated_token_address(
&params.payer.pubkey(),
&accounts::WSOL_TOKEN_ACCOUNT,
&crate::constants::WSOL_TOKEN_ACCOUNT,
);
let is_base_in = protocol_params.coin_mint == accounts::WSOL_TOKEN_ACCOUNT;
let is_base_in = protocol_params.coin_mint == crate::constants::WSOL_TOKEN_ACCOUNT;
let amount_in: u64 = params.sol_amount;
let swap_result = compute_swap_amount(
@@ -55,8 +55,8 @@ impl InstructionBuilder for RaydiumAmmV4InstructionBuilder {
create_associated_token_account_idempotent(
&params.payer.pubkey(),
&params.payer.pubkey(),
&accounts::WSOL_TOKEN_ACCOUNT,
&accounts::TOKEN_PROGRAM,
&crate::constants::WSOL_TOKEN_ACCOUNT,
&crate::constants::TOKEN_PROGRAM,
),
);
instructions.push(
@@ -66,8 +66,11 @@ impl InstructionBuilder for RaydiumAmmV4InstructionBuilder {
// Sync wSOL balance
instructions.push(
spl_token::instruction::sync_native(&accounts::TOKEN_PROGRAM, &wsol_token_account)
.unwrap(),
spl_token::instruction::sync_native(
&crate::constants::TOKEN_PROGRAM,
&wsol_token_account,
)
.unwrap(),
);
}
@@ -75,12 +78,12 @@ impl InstructionBuilder for RaydiumAmmV4InstructionBuilder {
&params.payer.pubkey(),
&params.payer.pubkey(),
&params.mint,
&accounts::TOKEN_PROGRAM,
&crate::constants::TOKEN_PROGRAM,
));
let user_source_token_account = spl_associated_token_account::get_associated_token_address(
&params.payer.pubkey(),
&accounts::WSOL_TOKEN_ACCOUNT,
&crate::constants::WSOL_TOKEN_ACCOUNT,
);
let user_destination_token_account =
spl_associated_token_account::get_associated_token_address(
@@ -90,9 +93,9 @@ impl InstructionBuilder for RaydiumAmmV4InstructionBuilder {
// Create buy instruction
let accounts = vec![
solana_sdk::instruction::AccountMeta::new_readonly(accounts::TOKEN_PROGRAM, false), // Token Program (readonly)
crate::constants::TOKEN_PROGRAM_META.clone(), // Token Program (readonly)
solana_sdk::instruction::AccountMeta::new(protocol_params.amm, false), // Amm
solana_sdk::instruction::AccountMeta::new_readonly(accounts::AUTHORITY, false), // Authority (readonly)
accounts::AUTHORITY_META.clone(), // Authority (readonly)
solana_sdk::instruction::AccountMeta::new(protocol_params.amm, false), // Amm Open Orders
solana_sdk::instruction::AccountMeta::new(protocol_params.token_coin, false), // Pool Coin Token Account
solana_sdk::instruction::AccountMeta::new(protocol_params.token_pc, false), // Pool Pc Token Account
@@ -120,7 +123,7 @@ impl InstructionBuilder for RaydiumAmmV4InstructionBuilder {
// Close wSOL ATA account, reclaim rent
instructions.push(
spl_token::instruction::close_account(
&accounts::TOKEN_PROGRAM,
&crate::constants::TOKEN_PROGRAM,
&wsol_token_account,
&params.payer.pubkey(),
&params.payer.pubkey(),
@@ -146,10 +149,10 @@ impl InstructionBuilder for RaydiumAmmV4InstructionBuilder {
let wsol_token_account = spl_associated_token_account::get_associated_token_address(
&params.payer.pubkey(),
&accounts::WSOL_TOKEN_ACCOUNT,
&crate::constants::WSOL_TOKEN_ACCOUNT,
);
let is_base_in = protocol_params.pc_mint == accounts::WSOL_TOKEN_ACCOUNT;
let is_base_in = protocol_params.pc_mint == crate::constants::WSOL_TOKEN_ACCOUNT;
let swap_result = compute_swap_amount(
protocol_params.coin_reserve,
protocol_params.pc_reserve,
@@ -167,8 +170,8 @@ impl InstructionBuilder for RaydiumAmmV4InstructionBuilder {
create_associated_token_account_idempotent(
&params.payer.pubkey(),
&params.payer.pubkey(),
&accounts::WSOL_TOKEN_ACCOUNT,
&accounts::TOKEN_PROGRAM,
&crate::constants::WSOL_TOKEN_ACCOUNT,
&crate::constants::TOKEN_PROGRAM,
),
);
@@ -179,14 +182,14 @@ impl InstructionBuilder for RaydiumAmmV4InstructionBuilder {
let user_destination_token_account =
spl_associated_token_account::get_associated_token_address(
&params.payer.pubkey(),
&accounts::WSOL_TOKEN_ACCOUNT,
&crate::constants::WSOL_TOKEN_ACCOUNT,
);
// Create buy instruction
let accounts = vec![
solana_sdk::instruction::AccountMeta::new_readonly(accounts::TOKEN_PROGRAM, false), // Token Program (readonly)
crate::constants::TOKEN_PROGRAM_META.clone(), // Token Program (readonly)
solana_sdk::instruction::AccountMeta::new(protocol_params.amm, false), // Amm
solana_sdk::instruction::AccountMeta::new_readonly(accounts::AUTHORITY, false), // Authority (readonly)
accounts::AUTHORITY_META.clone(), // Authority (readonly)
solana_sdk::instruction::AccountMeta::new(protocol_params.amm, false), // Amm Open Orders
solana_sdk::instruction::AccountMeta::new(protocol_params.token_coin, false), // Pool Coin Token Account
solana_sdk::instruction::AccountMeta::new(protocol_params.token_pc, false), // Pool Pc Token Account
@@ -213,7 +216,7 @@ impl InstructionBuilder for RaydiumAmmV4InstructionBuilder {
if protocol_params.auto_handle_wsol {
instructions.push(
close_account(
&accounts::TOKEN_PROGRAM,
&crate::constants::TOKEN_PROGRAM,
&wsol_token_account,
&params.payer.pubkey(),
&params.payer.pubkey(),
+26 -21
View File
@@ -39,7 +39,7 @@ impl InstructionBuilder for RaydiumCpmmInstructionBuilder {
)
.unwrap();
let is_base_in = protocol_params.base_mint == accounts::WSOL_TOKEN_ACCOUNT;
let is_base_in = protocol_params.base_mint == crate::constants::WSOL_TOKEN_ACCOUNT;
let mint_token_program = if is_base_in {
protocol_params.quote_token_program
} else {
@@ -48,7 +48,7 @@ impl InstructionBuilder for RaydiumCpmmInstructionBuilder {
let wsol_token_account = spl_associated_token_account::get_associated_token_address(
&params.payer.pubkey(),
&accounts::WSOL_TOKEN_ACCOUNT,
&crate::constants::WSOL_TOKEN_ACCOUNT,
);
let mint_token_account =
spl_associated_token_account::get_associated_token_address_with_program_id(
@@ -58,7 +58,8 @@ impl InstructionBuilder for RaydiumCpmmInstructionBuilder {
);
// Get pool token accounts
let wsol_vault_account = get_vault_pda(&pool_state, &accounts::WSOL_TOKEN_ACCOUNT).unwrap();
let wsol_vault_account =
get_vault_pda(&pool_state, &crate::constants::WSOL_TOKEN_ACCOUNT).unwrap();
let mint_vault_account = get_vault_pda(&pool_state, &params.mint).unwrap();
let observation_state_account = get_observation_state_pda(&pool_state).unwrap();
@@ -82,8 +83,8 @@ impl InstructionBuilder for RaydiumCpmmInstructionBuilder {
create_associated_token_account_idempotent(
&params.payer.pubkey(),
&params.payer.pubkey(),
&accounts::WSOL_TOKEN_ACCOUNT,
&accounts::TOKEN_PROGRAM,
&crate::constants::WSOL_TOKEN_ACCOUNT,
&crate::constants::TOKEN_PROGRAM,
),
);
instructions.push(
@@ -93,8 +94,11 @@ impl InstructionBuilder for RaydiumCpmmInstructionBuilder {
// Sync wSOL balance
instructions.push(
spl_token::instruction::sync_native(&accounts::TOKEN_PROGRAM, &wsol_token_account)
.unwrap(),
spl_token::instruction::sync_native(
&crate::constants::TOKEN_PROGRAM,
&wsol_token_account,
)
.unwrap(),
);
}
@@ -108,16 +112,16 @@ impl InstructionBuilder for RaydiumCpmmInstructionBuilder {
// Create buy instruction
let accounts = vec![
solana_sdk::instruction::AccountMeta::new(params.payer.pubkey(), true), // Payer (signer)
solana_sdk::instruction::AccountMeta::new_readonly(accounts::AUTHORITY, false), // Authority (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(accounts::AMM_CONFIG, false), // Amm Config (readonly)
accounts::AUTHORITY_META.clone(), // Authority (readonly)
accounts::AMM_CONFIG_META.clone(), // Amm Config (readonly)
solana_sdk::instruction::AccountMeta::new(pool_state, false), // Pool State
solana_sdk::instruction::AccountMeta::new(wsol_token_account, false), // Input Token Account
solana_sdk::instruction::AccountMeta::new(mint_token_account, false), // Output Token Account
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)
crate::constants::TOKEN_PROGRAM_META.clone(), // Input Token Program (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(mint_token_program, false), // Output Token Program (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(accounts::WSOL_TOKEN_ACCOUNT, false), // Input token mint (readonly)
crate::constants::WSOL_TOKEN_ACCOUNT_META.clone(), // 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
];
@@ -133,7 +137,7 @@ impl InstructionBuilder for RaydiumCpmmInstructionBuilder {
// Close wSOL ATA account, reclaim rent
instructions.push(
spl_token::instruction::close_account(
&accounts::TOKEN_PROGRAM,
&crate::constants::TOKEN_PROGRAM,
&wsol_token_account,
&params.payer.pubkey(),
&params.payer.pubkey(),
@@ -182,7 +186,7 @@ impl InstructionBuilder for RaydiumCpmmInstructionBuilder {
let wsol_token_account = spl_associated_token_account::get_associated_token_address(
&params.payer.pubkey(),
&accounts::WSOL_TOKEN_ACCOUNT,
&crate::constants::WSOL_TOKEN_ACCOUNT,
);
let mint_token_account =
spl_associated_token_account::get_associated_token_address_with_program_id(
@@ -192,7 +196,8 @@ impl InstructionBuilder for RaydiumCpmmInstructionBuilder {
);
// Get pool token accounts
let wsol_vault_account = get_vault_pda(&pool_state, &accounts::WSOL_TOKEN_ACCOUNT).unwrap();
let wsol_vault_account =
get_vault_pda(&pool_state, &crate::constants::WSOL_TOKEN_ACCOUNT).unwrap();
let mint_vault_account = get_vault_pda(&pool_state, &params.mint).unwrap();
let observation_state_account = get_observation_state_pda(&pool_state).unwrap();
@@ -205,25 +210,25 @@ impl InstructionBuilder for RaydiumCpmmInstructionBuilder {
create_associated_token_account_idempotent(
&params.payer.pubkey(),
&params.payer.pubkey(),
&accounts::WSOL_TOKEN_ACCOUNT,
&spl_token::ID,
&crate::constants::WSOL_TOKEN_ACCOUNT,
&crate::constants::TOKEN_PROGRAM,
),
);
// Create sell instruction
let accounts = vec![
solana_sdk::instruction::AccountMeta::new(params.payer.pubkey(), true), // Payer (signer)
solana_sdk::instruction::AccountMeta::new_readonly(accounts::AUTHORITY, false), // Authority (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(accounts::AMM_CONFIG, false), // Amm Config (readonly)
accounts::AUTHORITY_META.clone(), // Authority (readonly)
accounts::AMM_CONFIG_META.clone(), // Amm Config (readonly)
solana_sdk::instruction::AccountMeta::new(pool_state, false), // Pool State
solana_sdk::instruction::AccountMeta::new(mint_token_account, false), // Input Token Account
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(mint_token_program, false), // Input Token Program (readonly)
solana_sdk::instruction::AccountMeta::new_readonly(accounts::TOKEN_PROGRAM, false), // Output Token Program (readonly)
crate::constants::TOKEN_PROGRAM_META.clone(), // 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)
crate::constants::WSOL_TOKEN_ACCOUNT_META.clone(), // Output token mint (readonly)
solana_sdk::instruction::AccountMeta::new(observation_state_account, false), // Observation State Account
];
// Create instruction data
@@ -237,7 +242,7 @@ impl InstructionBuilder for RaydiumCpmmInstructionBuilder {
if protocol_params.auto_handle_wsol {
instructions.push(
close_account(
&accounts::TOKEN_PROGRAM,
&crate::constants::TOKEN_PROGRAM,
&wsol_token_account,
&params.payer.pubkey(),
&params.payer.pubkey(),
+21 -5
View File
@@ -17,15 +17,30 @@ pub mod accounts {
pub const AUTHORITY: Pubkey = pubkey!("WLHv2UAZm6z4KyaaELi5pjdbJh6RESMva1Rnn8pJVVh");
pub const GLOBAL_CONFIG: Pubkey = pubkey!("6s1xP3hpbAfFoNtUNF8mfHsjr2Bd97JxFJRWLbL6aHuX");
pub const TOKEN_PROGRAM: Pubkey = spl_token::ID;
pub const EVENT_AUTHORITY: Pubkey = pubkey!("2DPAtwB8L12vrMRExbLuyGnC7n2J5LNoZQSejeQGpwkr");
pub const WSOL_TOKEN_ACCOUNT: Pubkey = pubkey!("So11111111111111111111111111111111111111112");
pub const BONK: Pubkey = pubkey!("LanMV9sAd7wArD4vJFi2qDdfnVhFxYSUg6eADduJ3uj");
pub const SYSTEM_PROGRAM: Pubkey = solana_sdk::system_program::ID;
pub const PLATFORM_FEE_RATE: u128 = 100; // 1%
pub const PROTOCOL_FEE_RATE: u128 = 25; // 0.25%
pub const SHARE_FEE_RATE: u128 = 0; // 0%
// META
pub const AUTHORITY_META: once_cell::sync::Lazy<solana_sdk::instruction::AccountMeta> =
once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new_readonly(AUTHORITY, false)
});
pub const GLOBAL_CONFIG_META: once_cell::sync::Lazy<solana_sdk::instruction::AccountMeta> =
once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new_readonly(GLOBAL_CONFIG, false)
});
pub const EVENT_AUTHORITY_META: once_cell::sync::Lazy<solana_sdk::instruction::AccountMeta> =
once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new_readonly(EVENT_AUTHORITY, false)
});
pub const BONK_META: once_cell::sync::Lazy<solana_sdk::instruction::AccountMeta> =
once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new_readonly(BONK, false)
});
}
pub const BUY_EXECT_IN_DISCRIMINATOR: [u8; 8] = [250, 234, 13, 123, 213, 156, 19, 236];
@@ -142,14 +157,15 @@ pub fn get_vault_pda(pool_state: &Pubkey, mint: &Pubkey) -> Option<Pubkey> {
}
pub fn get_platform_associated_account(platform_config: &Pubkey) -> Option<Pubkey> {
let seeds: &[&[u8]; 2] = &[platform_config.as_ref(), accounts::WSOL_TOKEN_ACCOUNT.as_ref()];
let seeds: &[&[u8]; 2] =
&[platform_config.as_ref(), crate::constants::WSOL_TOKEN_ACCOUNT.as_ref()];
let program_id: &Pubkey = &accounts::BONK;
let pda: Option<(Pubkey, u8)> = Pubkey::try_find_program_address(seeds, program_id);
pda.map(|pubkey| pubkey.0)
}
pub fn get_creator_associated_account(creator: &Pubkey) -> Option<Pubkey> {
let seeds: &[&[u8]; 2] = &[creator.as_ref(), accounts::WSOL_TOKEN_ACCOUNT.as_ref()];
let seeds: &[&[u8]; 2] = &[creator.as_ref(), crate::constants::WSOL_TOKEN_ACCOUNT.as_ref()];
let program_id: &Pubkey = &accounts::BONK;
let pda: Option<(Pubkey, u8)> = Pubkey::try_find_program_address(seeds, program_id);
pda.map(|pubkey| pubkey.0)
+45 -6
View File
@@ -61,9 +61,19 @@ pub mod global_constants {
/// Public key for the fee recipient
pub const FEE_RECIPIENT: Pubkey = pubkey!("62qc2CNXwrYqQScmEdiZFFAnJR262PxWEuNQtxfafNgV");
/// Static AccountMeta for fee recipient (initialized once)
pub static FEE_RECIPIENT_META: once_cell::sync::Lazy<solana_sdk::instruction::AccountMeta> =
once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new(FEE_RECIPIENT, false)
});
/// Public key for the global PDA
pub const GLOBAL_ACCOUNT: Pubkey = pubkey!("4wTV1YmiEkRvAtNtsSGPtUrqRYQMe5SKy2uB4Jjaxnjf");
/// Static AccountMeta for global account (initialized once)
pub static GLOBAL_ACCOUNT_META: once_cell::sync::Lazy<solana_sdk::instruction::AccountMeta> =
once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new_readonly(GLOBAL_ACCOUNT, false)
});
/// Public key for the authority
pub const AUTHORITY: Pubkey = pubkey!("FFWtrEQ4B4PKQoVuHYzZq8FabGkVatYzDpEVHsK5rrhF");
@@ -85,6 +95,10 @@ pub mod global_constants {
pub mod accounts {
use solana_sdk::{pubkey, pubkey::Pubkey};
use crate::instruction::utils::pumpfun::{
get_fee_config_pda, get_global_volume_accumulator_pda,
};
/// Public key for the Pump.fun program
pub const PUMPFUN: Pubkey = pubkey!("6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P");
@@ -94,12 +108,6 @@ pub mod accounts {
/// Authority for program events
pub const EVENT_AUTHORITY: Pubkey = pubkey!("Ce6TQqeHC9p8KetsN6JsjHK7UTZk7nasjjnr7XxXp9F1");
/// System Program ID
pub const SYSTEM_PROGRAM: Pubkey = pubkey!("11111111111111111111111111111111");
/// Token Program ID
pub const TOKEN_PROGRAM: Pubkey = spl_token::ID;
/// Associated Token Program ID
pub const ASSOCIATED_TOKEN_PROGRAM: Pubkey =
pubkey!("ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL");
@@ -110,6 +118,37 @@ pub mod accounts {
pub const AMM_PROGRAM: Pubkey = pubkey!("675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8");
pub const FEE_PROGRAM: Pubkey = pubkey!("pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ");
// META
pub const PUMPFUN_META: once_cell::sync::Lazy<solana_sdk::instruction::AccountMeta> =
once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new_readonly(PUMPFUN, false)
});
pub const EVENT_AUTHORITY_META: once_cell::sync::Lazy<solana_sdk::instruction::AccountMeta> =
once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new_readonly(EVENT_AUTHORITY, false)
});
pub const FEE_PROGRAM_META: once_cell::sync::Lazy<solana_sdk::instruction::AccountMeta> =
once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new_readonly(FEE_PROGRAM, false)
});
pub const GLOBAL_VOLUME_ACCUMULATOR_META: once_cell::sync::Lazy<
solana_sdk::instruction::AccountMeta,
> = once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new_readonly(
get_global_volume_accumulator_pda().unwrap(),
false,
)
});
pub const FEE_CONFIG_META: once_cell::sync::Lazy<solana_sdk::instruction::AccountMeta> =
once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new_readonly(get_fee_config_pda().unwrap(), false)
});
}
pub struct Symbol;
+57 -11
View File
@@ -1,4 +1,7 @@
use crate::{common::SolanaRpcClient, constants};
use crate::{
common::SolanaRpcClient,
constants::{self, TOKEN_PROGRAM},
};
use anyhow::anyhow;
use solana_account_decoder::UiAccountEncoding;
use solana_sdk::pubkey::Pubkey;
@@ -27,6 +30,10 @@ pub mod seeds {
pub mod accounts {
use solana_sdk::{pubkey, pubkey::Pubkey};
use crate::instruction::utils::pumpswap::{
get_fee_config_pda, get_global_volume_accumulator_pda,
};
/// Public key for the fee recipient
pub const FEE_RECIPIENT: Pubkey = pubkey!("62qc2CNXwrYqQScmEdiZFFAnJR262PxWEuNQtxfafNgV");
@@ -36,14 +43,6 @@ pub mod accounts {
/// Authority for program events
pub const EVENT_AUTHORITY: Pubkey = pubkey!("GS4CU59F31iL7aR2Q8zVS8DRrcRnXX1yjQ66TqNVQnaR");
pub const WSOL_TOKEN_ACCOUNT: Pubkey = pubkey!("So11111111111111111111111111111111111111112");
/// System Program ID
pub const SYSTEM_PROGRAM: Pubkey = pubkey!("11111111111111111111111111111111");
/// Token Program ID
pub const TOKEN_PROGRAM: Pubkey = spl_token::ID;
/// Associated Token Program ID
pub const ASSOCIATED_TOKEN_PROGRAM: Pubkey =
pubkey!("ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL");
@@ -62,6 +61,53 @@ pub mod accounts {
pub const COIN_CREATOR_FEE_BASIS_POINTS: u64 = 5;
pub const FEE_PROGRAM: Pubkey = pubkey!("pfeeUxB6jkeY1Hxd7CsFCAjcbHA9rWtchMGdZ6VojVZ");
// META
pub const GLOBAL_ACCOUNT_META: once_cell::sync::Lazy<solana_sdk::instruction::AccountMeta> =
once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new_readonly(GLOBAL_ACCOUNT, false)
});
pub const FEE_RECIPIENT_META: once_cell::sync::Lazy<solana_sdk::instruction::AccountMeta> =
once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new_readonly(FEE_RECIPIENT, false)
});
pub const ASSOCIATED_TOKEN_PROGRAM_META: once_cell::sync::Lazy<
solana_sdk::instruction::AccountMeta,
> = once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new_readonly(ASSOCIATED_TOKEN_PROGRAM, false)
});
pub const EVENT_AUTHORITY_META: once_cell::sync::Lazy<solana_sdk::instruction::AccountMeta> =
once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new_readonly(EVENT_AUTHORITY, false)
});
pub const AMM_PROGRAM_META: once_cell::sync::Lazy<solana_sdk::instruction::AccountMeta> =
once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new_readonly(AMM_PROGRAM, false)
});
pub const GLOBAL_VOLUME_ACCUMULATOR_META: once_cell::sync::Lazy<
solana_sdk::instruction::AccountMeta,
> = once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new_readonly(
get_global_volume_accumulator_pda().unwrap(),
false,
)
});
pub const FEE_CONFIG_META: once_cell::sync::Lazy<solana_sdk::instruction::AccountMeta> =
once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new_readonly(get_fee_config_pda().unwrap(), false)
});
pub const FEE_PROGRAM_META: once_cell::sync::Lazy<solana_sdk::instruction::AccountMeta> =
once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new_readonly(FEE_PROGRAM, false)
});
}
pub const BUY_DISCRIMINATOR: [u8; 8] = [102, 6, 61, 18, 1, 218, 235, 234];
@@ -87,7 +133,7 @@ pub(crate) fn coin_creator_vault_ata(coin_creator: Pubkey, quote_mint: Pubkey) -
spl_associated_token_account::get_associated_token_address_with_program_id(
&creator_vault_authority,
&quote_mint,
&accounts::TOKEN_PROGRAM,
&TOKEN_PROGRAM,
);
associated_token_creator_vault_authority
}
@@ -97,7 +143,7 @@ pub(crate) fn fee_recipient_ata(fee_recipient: Pubkey, quote_mint: Pubkey) -> Pu
spl_associated_token_account::get_associated_token_address_with_program_id(
&fee_recipient,
&quote_mint,
&accounts::TOKEN_PROGRAM,
&TOKEN_PROGRAM,
);
associated_token_fee_recipient
}
+7 -2
View File
@@ -15,14 +15,19 @@ pub mod seeds {
pub mod accounts {
use solana_sdk::{pubkey, pubkey::Pubkey};
pub const AUTHORITY: Pubkey = pubkey!("5Q544fKrFoe6tsEbD7S8EmxGTJYAKtTVhAW5Q5pge4j1");
pub const TOKEN_PROGRAM: Pubkey = spl_token::ID;
pub const WSOL_TOKEN_ACCOUNT: Pubkey = pubkey!("So11111111111111111111111111111111111111112");
pub const RAYDIUM_AMM_V4: Pubkey = pubkey!("675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8");
pub const TRADE_FEE_NUMERATOR: u64 = 25;
pub const TRADE_FEE_DENOMINATOR: u64 = 10000;
pub const SWAP_FEE_NUMERATOR: u64 = 25;
pub const SWAP_FEE_DENOMINATOR: u64 = 10000;
// META
pub const AUTHORITY_META: once_cell::sync::Lazy<solana_sdk::instruction::AccountMeta> =
once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new_readonly(AUTHORITY, false)
});
}
pub const SWAP_BASE_IN_DISCRIMINATOR: &[u8] = &[9];
+10 -3
View File
@@ -17,15 +17,22 @@ pub mod accounts {
use solana_sdk::{pubkey, pubkey::Pubkey};
pub const AUTHORITY: Pubkey = pubkey!("GpMZbSM2GgvTKHJirzeGfMFoaZ8UR2X7F4v8vHTvxFbL");
pub const AMM_CONFIG: Pubkey = pubkey!("D4FPEruKEHrG5TenZ2mpDGEfu1iUvTiqBxvpU8HLBvC2");
pub const TOKEN_PROGRAM: Pubkey = spl_token::ID;
pub const WSOL_TOKEN_ACCOUNT: Pubkey = pubkey!("So11111111111111111111111111111111111111112");
pub const RAYDIUM_CPMM: Pubkey = pubkey!("CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C");
pub const FEE_RATE_DENOMINATOR_VALUE: u128 = 1_000_000;
pub const TRADE_FEE_RATE: u64 = 2500;
pub const CREATOR_FEE_RATE: u64 = 0;
pub const PROTOCOL_FEE_RATE: u64 = 120000;
pub const FUND_FEE_RATE: u64 = 40000;
// META
pub const AUTHORITY_META: once_cell::sync::Lazy<solana_sdk::instruction::AccountMeta> =
once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new_readonly(AUTHORITY, false)
});
pub const AMM_CONFIG_META: once_cell::sync::Lazy<solana_sdk::instruction::AccountMeta> =
once_cell::sync::Lazy::new(|| {
solana_sdk::instruction::AccountMeta::new_readonly(AMM_CONFIG, false)
});
}
pub const SWAP_BASE_IN_DISCRIMINATOR: &[u8] = &[143, 190, 90, 218, 196, 30, 51, 222];
+15 -6
View File
@@ -18,10 +18,14 @@ pub async fn get_multi_token_balances(
let token0_balance = rpc.get_token_account_balance(&token0_vault).await?;
let token1_balance = rpc.get_token_account_balance(&token1_vault).await?;
// Parse balance string to u64
let token0_amount =
token0_balance.amount.parse::<u64>().map_err(|e| anyhow!("Failed to parse token0 balance: {}", e))?;
let token1_amount =
token1_balance.amount.parse::<u64>().map_err(|e| anyhow!("Failed to parse token1 balance: {}", e))?;
let token0_amount = token0_balance
.amount
.parse::<u64>()
.map_err(|e| anyhow!("Failed to parse token0 balance: {}", e))?;
let token1_amount = token1_balance
.amount
.parse::<u64>()
.map_err(|e| anyhow!("Failed to parse token1 balance: {}", e))?;
Ok((token0_amount, token1_amount))
}
@@ -107,8 +111,13 @@ pub async fn close_token_account(
}
// Build close account instruction
let close_account_ix =
close_account(&spl_token::ID, &ata, &payer.pubkey(), &payer.pubkey(), &[&payer.pubkey()])?;
let close_account_ix = close_account(
&crate::constants::TOKEN_PROGRAM,
&ata,
&payer.pubkey(),
&payer.pubkey(),
&[&payer.pubkey()],
)?;
// Build transaction
let recent_blockhash = rpc.get_latest_blockhash().await?;
+7 -7
View File
@@ -189,13 +189,13 @@ impl PumpSwapParams {
spl_associated_token_account::get_associated_token_address_with_program_id(
&pool_address,
&pool_data.base_mint,
&crate::instruction::utils::pumpswap::accounts::TOKEN_PROGRAM,
&crate::constants::TOKEN_PROGRAM,
);
let quote_token_program_ata =
spl_associated_token_account::get_associated_token_address_with_program_id(
&pool_address,
&pool_data.quote_mint,
&crate::instruction::utils::pumpswap::accounts::TOKEN_PROGRAM,
&crate::constants::TOKEN_PROGRAM,
);
Ok(Self {
@@ -207,14 +207,14 @@ impl PumpSwapParams {
coin_creator_vault_ata: coin_creator_vault_ata,
coin_creator_vault_authority: coin_creator_vault_authority,
base_token_program: if pool_data.pool_base_token_account == base_token_program_ata {
crate::instruction::utils::pumpswap::accounts::TOKEN_PROGRAM
crate::constants::TOKEN_PROGRAM
} else {
spl_token_2022::ID
crate::constants::TOKEN_PROGRAM_2022
},
quote_token_program: if pool_data.pool_quote_token_account == quote_token_program_ata {
crate::instruction::utils::pumpswap::accounts::TOKEN_PROGRAM
crate::constants::TOKEN_PROGRAM
} else {
spl_token_2022::ID
crate::constants::TOKEN_PROGRAM_2022
},
auto_handle_wsol: true,
})
@@ -337,7 +337,7 @@ impl BonkParams {
) -> Result<Self, anyhow::Error> {
let pool_address = crate::instruction::utils::bonk::get_pool_pda(
mint,
&crate::instruction::utils::bonk::accounts::WSOL_TOKEN_ACCOUNT,
&crate::constants::WSOL_TOKEN_ACCOUNT,
)
.unwrap();
let pool_data =
+1 -1
View File
@@ -2,7 +2,7 @@ use solana_streamer_sdk::streaming::event_parser::protocols::bonk::types::PoolSt
use crate::{
constants::decimals::{DEFAULT_TOKEN_DECIMALS, SOL_DECIMALS},
instruction::utils::bonk::accounts::WSOL_TOKEN_ACCOUNT,
constants::WSOL_TOKEN_ACCOUNT,
};
/// Calculate the token price in WSOL based on pool state