Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e459f175f5 | |||
| e5e58bef89 |
+1
-1
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "sol-trade-sdk"
|
||||
version = "4.0.15"
|
||||
version = "4.0.17"
|
||||
edition = "2021"
|
||||
authors = [
|
||||
"William <byteblock6@gmail.com>",
|
||||
|
||||
@@ -81,13 +81,13 @@ This SDK is available in multiple languages:
|
||||
|
||||
## 🔖 Current Release
|
||||
|
||||
**Rust crate:** `sol-trade-sdk = "4.0.15"`
|
||||
**Rust crate:** `sol-trade-sdk = "4.0.17"`
|
||||
|
||||
This release refreshes PumpFun V2 and USDC quote-pool handling, keeps the default RPC submit lane active alongside SWQoS lanes, restores the fast-submit result window to 5 seconds, and aligns Raydium CPMM fixed-output swaps with the on-chain `swap_base_out` instruction. Trade execution requires a caller-supplied `recent_blockhash` or durable nonce; hot-path execution does not query RPC for blockhash, account, or balance data.
|
||||
This release refreshes PumpFun V2 WSOL quote-pool handling, keeps the default RPC submit lane active alongside SWQoS lanes, restores the fast-submit result window to 5 seconds, and aligns Raydium CPMM fixed-output swaps with the on-chain `swap_base_out` instruction. Trade execution requires a caller-supplied `recent_blockhash` or durable nonce; hot-path execution does not query RPC for blockhash, account, or balance data.
|
||||
|
||||
## ✨ Features
|
||||
|
||||
1. **PumpFun Trading**: Unified SDK-side `buy`, `sell`, and `buy_exact_quote_in` flow, selecting legacy or V2 on-chain instructions as needed (SOL + USDC)
|
||||
1. **PumpFun Trading**: Unified SDK-side `buy`, `sell`, and `buy_exact_quote_in` flow, selecting legacy or V2 on-chain instructions as needed (SOL/WSOL + USDC)
|
||||
2. **PumpSwap Trading**: Support for PumpSwap pool trading operations
|
||||
3. **Bonk Trading**: Support for Bonk trading operations
|
||||
4. **Raydium CPMM Trading**: Support for Raydium CPMM (Concentrated Pool Market Maker) trading operations
|
||||
@@ -115,14 +115,14 @@ Add the dependency to your `Cargo.toml`:
|
||||
|
||||
```toml
|
||||
# Add to your Cargo.toml
|
||||
sol-trade-sdk = { path = "./sol-trade-sdk", version = "4.0.15" }
|
||||
sol-trade-sdk = { path = "./sol-trade-sdk", version = "4.0.17" }
|
||||
```
|
||||
|
||||
### Use crates.io
|
||||
|
||||
```toml
|
||||
# Add to your Cargo.toml
|
||||
sol-trade-sdk = "4.0.15"
|
||||
sol-trade-sdk = "4.0.17"
|
||||
```
|
||||
|
||||
## 🛠️ Usage Examples
|
||||
|
||||
+5
-5
@@ -81,13 +81,13 @@
|
||||
|
||||
## 🔖 当前版本
|
||||
|
||||
**Rust crate:** `sol-trade-sdk = "4.0.15"`
|
||||
**Rust crate:** `sol-trade-sdk = "4.0.17"`
|
||||
|
||||
本版本刷新 PumpFun V2 与 USDC quote 池处理逻辑,确保默认 RPC 提交通道会和 SWQoS 通道一起发出,快速提交结果等待窗口恢复为 5 秒,并将 Raydium CPMM fixed-output 交易对齐到链上 `swap_base_out` 指令。交易执行必须由调用方传入 `recent_blockhash` 或 durable nonce;热路径不会查询 RPC 获取 blockhash、账户或余额数据。
|
||||
本版本刷新 PumpFun V2 WSOL quote 池处理逻辑,确保默认 RPC 提交通道会和 SWQoS 通道一起发出,快速提交结果等待窗口恢复为 5 秒,并将 Raydium CPMM fixed-output 交易对齐到链上 `swap_base_out` 指令。交易执行必须由调用方传入 `recent_blockhash` 或 durable nonce;热路径不会查询 RPC 获取 blockhash、账户或余额数据。
|
||||
|
||||
## ✨ 项目特性
|
||||
|
||||
1. **PumpFun 交易**: SDK 侧统一为 `buy`、`sell`、`buy_exact_quote_in` 流程,内部按需选择旧版或 V2 链上指令(SOL + USDC)
|
||||
1. **PumpFun 交易**: SDK 侧统一为 `buy`、`sell`、`buy_exact_quote_in` 流程,内部按需选择旧版或 V2 链上指令(SOL/WSOL + USDC)
|
||||
2. **PumpSwap 交易**: 支持 PumpSwap 池的交易操作
|
||||
3. **Bonk 交易**: 支持 Bonk 的交易操作
|
||||
4. **Raydium CPMM 交易**: 支持 Raydium CPMM (Concentrated Pool Market Maker) 的交易操作
|
||||
@@ -115,14 +115,14 @@ git clone https://github.com/0xfnzero/sol-trade-sdk
|
||||
|
||||
```toml
|
||||
# 添加到您的 Cargo.toml
|
||||
sol-trade-sdk = { path = "./sol-trade-sdk", version = "4.0.15" }
|
||||
sol-trade-sdk = { path = "./sol-trade-sdk", version = "4.0.17" }
|
||||
```
|
||||
|
||||
### 使用 crates.io
|
||||
|
||||
```toml
|
||||
# 添加到您的 Cargo.toml
|
||||
sol-trade-sdk = "4.0.15"
|
||||
sol-trade-sdk = "4.0.17"
|
||||
```
|
||||
|
||||
## 🛠️ 使用示例
|
||||
|
||||
@@ -586,7 +586,10 @@ fn build_buy_unified(params: &SwapParams) -> Result<Vec<Instruction>> {
|
||||
}
|
||||
};
|
||||
|
||||
if params.create_input_mint_ata {
|
||||
if params.create_input_mint_ata
|
||||
|| (quote_mint == crate::constants::WSOL_TOKEN_ACCOUNT
|
||||
&& params.input_mint == crate::constants::SOL_TOKEN_ACCOUNT)
|
||||
{
|
||||
push_create_or_wrap_user_token_account(
|
||||
&mut instructions,
|
||||
¶ms.payer.pubkey(),
|
||||
@@ -1025,7 +1028,6 @@ mod tests {
|
||||
fn pumpfun_v2_regular_buy_wraps_max_quote_budget() {
|
||||
let mut params = swap_params_for_buy(pump_mint(), TOKEN_PROGRAM);
|
||||
params.create_output_mint_ata = false;
|
||||
params.create_input_mint_ata = true;
|
||||
params.use_exact_sol_amount = Some(false);
|
||||
if let DexParamEnum::PumpFun(protocol_params) = &mut params.protocol_params {
|
||||
*protocol_params =
|
||||
@@ -1034,6 +1036,7 @@ mod tests {
|
||||
|
||||
let instructions = build_buy(¶ms).unwrap();
|
||||
let transfer_ix = &instructions[1];
|
||||
let buy_ix = instructions.last().unwrap();
|
||||
let system_ix = bincode::deserialize::<
|
||||
solana_system_interface::instruction::SystemInstruction,
|
||||
>(&transfer_ix.data)
|
||||
@@ -1049,6 +1052,63 @@ mod tests {
|
||||
}
|
||||
other => panic!("unexpected system instruction: {:?}", other),
|
||||
}
|
||||
assert_eq!(&buy_ix.data[..8], crate::instruction::utils::pumpfun::BUY_V2_DISCRIMINATOR);
|
||||
assert_eq!(buy_ix.accounts.len(), 27);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pumpfun_from_trade_wsol_quote_regular_buy_selects_buy_v2() {
|
||||
let mint = pump_mint();
|
||||
let mut params = swap_params_for_buy(mint, TOKEN_PROGRAM);
|
||||
params.create_output_mint_ata = false;
|
||||
params.use_exact_sol_amount = Some(false);
|
||||
if let DexParamEnum::PumpFun(protocol_params) = &mut params.protocol_params {
|
||||
*protocol_params = PumpFunParams::from_trade(
|
||||
Pubkey::default(),
|
||||
Pubkey::default(),
|
||||
mint,
|
||||
crate::constants::WSOL_TOKEN_ACCOUNT,
|
||||
protocol_params.effective_creator_for_trade(),
|
||||
protocol_params.creator_vault,
|
||||
protocol_params.bonding_curve.virtual_token_reserves,
|
||||
protocol_params.bonding_curve.virtual_sol_reserves,
|
||||
protocol_params.bonding_curve.real_token_reserves,
|
||||
protocol_params.bonding_curve.real_sol_reserves,
|
||||
None,
|
||||
protocol_params.fee_recipient,
|
||||
TOKEN_PROGRAM,
|
||||
false,
|
||||
Some(false),
|
||||
);
|
||||
}
|
||||
|
||||
let instructions = build_buy(¶ms).unwrap();
|
||||
let buy_ix = instructions.last().unwrap();
|
||||
|
||||
assert_eq!(&buy_ix.data[..8], crate::instruction::utils::pumpfun::BUY_V2_DISCRIMINATOR);
|
||||
assert_eq!(buy_ix.accounts.len(), 27);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pumpfun_v2_wsol_input_does_not_auto_wrap_when_ata_create_disabled() {
|
||||
let mut params = swap_params_for_buy(pump_mint(), TOKEN_PROGRAM);
|
||||
params.input_mint = crate::constants::WSOL_TOKEN_ACCOUNT;
|
||||
params.create_output_mint_ata = false;
|
||||
params.create_input_mint_ata = false;
|
||||
params.use_exact_sol_amount = Some(false);
|
||||
if let DexParamEnum::PumpFun(protocol_params) = &mut params.protocol_params {
|
||||
*protocol_params =
|
||||
protocol_params.clone().with_quote_mint(crate::constants::WSOL_TOKEN_ACCOUNT);
|
||||
}
|
||||
|
||||
let instructions = build_buy(¶ms).unwrap();
|
||||
|
||||
assert_eq!(instructions.len(), 1);
|
||||
assert_eq!(
|
||||
&instructions[0].data[..8],
|
||||
crate::instruction::utils::pumpfun::BUY_V2_DISCRIMINATOR
|
||||
);
|
||||
assert_eq!(instructions[0].accounts.len(), 27);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -1180,6 +1240,23 @@ mod tests {
|
||||
assert_eq!(ix.accounts.len(), 18);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pumpfun_rpc_sol_sentinel_quote_mint_selects_v1() {
|
||||
let mut params = swap_params_for_buy(pump_mint(), TOKEN_PROGRAM);
|
||||
params.create_output_mint_ata = false;
|
||||
if let DexParamEnum::PumpFun(protocol_params) = &mut params.protocol_params {
|
||||
protocol_params.quote_mint = crate::constants::SOL_TOKEN_ACCOUNT;
|
||||
assert_eq!(protocol_params.quote_mint, crate::constants::SOL_TOKEN_ACCOUNT);
|
||||
}
|
||||
|
||||
let ix = build_buy(¶ms).unwrap().pop().unwrap();
|
||||
assert_eq!(
|
||||
&ix.data[..8],
|
||||
crate::instruction::utils::pumpfun::BUY_EXACT_SOL_IN_DISCRIMINATOR
|
||||
);
|
||||
assert_eq!(ix.accounts.len(), 18);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn pumpfun_v2_usdc_buy_rejects_sol_input() {
|
||||
let mut params = swap_params_for_buy(pump_mint(), TOKEN_PROGRAM);
|
||||
|
||||
@@ -57,6 +57,15 @@ impl PumpFunParams {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn quote_mint_for_rpc_return(quote_mint: Pubkey) -> Pubkey {
|
||||
if quote_mint == Pubkey::default() || quote_mint == crate::constants::SOL_TOKEN_ACCOUNT {
|
||||
crate::constants::SOL_TOKEN_ACCOUNT
|
||||
} else {
|
||||
BondingCurveAccount::normalize_quote_mint(quote_mint)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn immediate_sell(
|
||||
creator_vault: Pubkey,
|
||||
token_program: Pubkey,
|
||||
@@ -320,7 +329,7 @@ impl PumpFunParams {
|
||||
close_token_account_when_sell: None,
|
||||
token_program: mint_account.owner,
|
||||
fee_recipient: Pubkey::default(),
|
||||
quote_mint: Self::quote_mint_for_layout(quote_mint),
|
||||
quote_mint: Self::quote_mint_for_rpc_return(quote_mint),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -395,3 +404,32 @@ impl PumpFunParams {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn rpc_return_quote_mint_normalizes_legacy_sol_to_sol_sentinel() {
|
||||
assert_eq!(
|
||||
PumpFunParams::quote_mint_for_rpc_return(Pubkey::default()),
|
||||
crate::constants::SOL_TOKEN_ACCOUNT
|
||||
);
|
||||
assert_eq!(
|
||||
PumpFunParams::quote_mint_for_rpc_return(crate::constants::SOL_TOKEN_ACCOUNT),
|
||||
crate::constants::SOL_TOKEN_ACCOUNT
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rpc_return_quote_mint_keeps_real_quote_mints() {
|
||||
assert_eq!(
|
||||
PumpFunParams::quote_mint_for_rpc_return(crate::constants::USDC_TOKEN_ACCOUNT),
|
||||
crate::constants::USDC_TOKEN_ACCOUNT
|
||||
);
|
||||
assert_eq!(
|
||||
PumpFunParams::quote_mint_for_rpc_return(crate::constants::WSOL_TOKEN_ACCOUNT),
|
||||
crate::constants::WSOL_TOKEN_ACCOUNT
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user