feat: add Bonk trading examples and fix function naming
- Add comprehensive Bonk trading examples in README - Fix function naming consistency (width -> with) - Enhance BonkParams with from_trade and from_dev_trade methods - Add amount calculation utilities and tests
This commit is contained in:
@@ -216,7 +216,7 @@ use sol_trade_sdk::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
// pumpfun sniper trade
|
// pumpfun sniper trade
|
||||||
async fn test_pumpfun_sniper_trade_width_shreds(trade_info: PumpFunTradeEvent) -> AnyResult<()> {
|
async fn test_pumpfun_sniper_trade_with_shreds(trade_info: PumpFunTradeEvent) -> AnyResult<()> {
|
||||||
println!("Testing PumpFun trading...");
|
println!("Testing PumpFun trading...");
|
||||||
|
|
||||||
// if not dev trade, return
|
// if not dev trade, return
|
||||||
@@ -263,7 +263,7 @@ async fn test_pumpfun_sniper_trade_width_shreds(trade_info: PumpFunTradeEvent) -
|
|||||||
}
|
}
|
||||||
|
|
||||||
// pumpfun copy trade
|
// pumpfun copy trade
|
||||||
async fn test_pumpfun_copy_trade_width_grpc(trade_info: PumpFunTradeEvent) -> AnyResult<()> {
|
async fn test_pumpfun_copy_trade_with_grpc(trade_info: PumpFunTradeEvent) -> AnyResult<()> {
|
||||||
println!("Testing PumpFun trading...");
|
println!("Testing PumpFun trading...");
|
||||||
|
|
||||||
let trade_client = test_create_solana_trade_client().await?;
|
let trade_client = test_create_solana_trade_client().await?;
|
||||||
@@ -367,6 +367,92 @@ async fn test_pumpswap() -> AnyResult<()> {
|
|||||||
### 5. Bonk Trading Operations
|
### 5. Bonk Trading Operations
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
|
|
||||||
|
// bonk sniper trade
|
||||||
|
async fn test_bonk_sniper_trade_with_shreds(trade_info: BonkTradeEvent) -> AnyResult<()> {
|
||||||
|
println!("Testing Bonk trading...");
|
||||||
|
|
||||||
|
if !trade_info.is_dev_create_token_trade {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
let trade_client = test_create_solana_trade_client().await?;
|
||||||
|
let mint_pubkey = Pubkey::from_str("xxxxxxx")?;
|
||||||
|
let buy_sol_cost = 100_000;
|
||||||
|
let slippage_basis_points = Some(100);
|
||||||
|
let recent_blockhash = trade_client.rpc.get_latest_blockhash().await?;
|
||||||
|
|
||||||
|
println!("Buying tokens from letsbonk.fun...");
|
||||||
|
|
||||||
|
// Use dev trade info to build BonkParams, can save transaction time
|
||||||
|
trade_client.buy(
|
||||||
|
DexType::Bonk,
|
||||||
|
mint_pubkey,
|
||||||
|
None,
|
||||||
|
buy_sol_cost,
|
||||||
|
slippage_basis_points,
|
||||||
|
recent_blockhash,
|
||||||
|
None,
|
||||||
|
Some(Box::new(BonkParams::from_dev_trade(trade_info))),
|
||||||
|
).await?;
|
||||||
|
|
||||||
|
println!("Selling tokens from letsbonk.fun...");
|
||||||
|
let amount_token = 0;
|
||||||
|
trade_client.sell(
|
||||||
|
DexType::Bonk,
|
||||||
|
mint_pubkey,
|
||||||
|
None,
|
||||||
|
amount_token,
|
||||||
|
slippage_basis_points,
|
||||||
|
recent_blockhash,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
).await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
// bonk copy trade
|
||||||
|
async fn test_bonk_copy_trade_with_grpc(trade_info: BonkTradeEvent) -> AnyResult<()> {
|
||||||
|
println!("Testing Bonk trading...");
|
||||||
|
|
||||||
|
let trade_client = test_create_solana_trade_client().await?;
|
||||||
|
let mint_pubkey = Pubkey::from_str("xxxxxxx")?;
|
||||||
|
let buy_sol_cost = 100_000;
|
||||||
|
let slippage_basis_points = Some(100);
|
||||||
|
let recent_blockhash = trade_client.rpc.get_latest_blockhash().await?;
|
||||||
|
|
||||||
|
println!("Buying tokens from letsbonk.fun...");
|
||||||
|
|
||||||
|
// Use trade event info to build BonkParams, can save transaction time
|
||||||
|
trade_client.buy(
|
||||||
|
DexType::Bonk,
|
||||||
|
mint_pubkey,
|
||||||
|
None,
|
||||||
|
buy_sol_cost,
|
||||||
|
slippage_basis_points,
|
||||||
|
recent_blockhash,
|
||||||
|
None,
|
||||||
|
Some(Box::new(BonkParams::from_trade(trade_info))),
|
||||||
|
).await?;
|
||||||
|
|
||||||
|
println!("Selling tokens from letsbonk.fun...");
|
||||||
|
let amount_token = 0;
|
||||||
|
trade_client.sell(
|
||||||
|
DexType::Bonk,
|
||||||
|
mint_pubkey,
|
||||||
|
None,
|
||||||
|
amount_token,
|
||||||
|
slippage_basis_points,
|
||||||
|
recent_blockhash,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
).await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
// bonk regular trade
|
||||||
async fn test_bonk() -> Result<(), Box<dyn std::error::Error>> {
|
async fn test_bonk() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
println!("Testing Bonk trading...");
|
println!("Testing Bonk trading...");
|
||||||
|
|
||||||
|
|||||||
+88
-2
@@ -216,7 +216,7 @@ use sol_trade_sdk::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
// pumpfun 狙击者交易
|
// pumpfun 狙击者交易
|
||||||
async fn test_pumpfun_sniper_trade_width_shreds(trade_info: PumpFunTradeEvent) -> AnyResult<()> {
|
async fn test_pumpfun_sniper_trade_with_shreds(trade_info: PumpFunTradeEvent) -> AnyResult<()> {
|
||||||
println!("Testing PumpFun trading...");
|
println!("Testing PumpFun trading...");
|
||||||
|
|
||||||
// 如果不是开发者购买,则返回
|
// 如果不是开发者购买,则返回
|
||||||
@@ -263,7 +263,7 @@ async fn test_pumpfun_sniper_trade_width_shreds(trade_info: PumpFunTradeEvent) -
|
|||||||
}
|
}
|
||||||
|
|
||||||
// pumpfun 跟单交易
|
// pumpfun 跟单交易
|
||||||
async fn test_pumpfun_copy_trade_width_grpc(trade_info: PumpFunTradeEvent) -> AnyResult<()> {
|
async fn test_pumpfun_copy_trade_with_grpc(trade_info: PumpFunTradeEvent) -> AnyResult<()> {
|
||||||
println!("Testing PumpFun trading...");
|
println!("Testing PumpFun trading...");
|
||||||
|
|
||||||
let trade_client = test_create_solana_trade_client().await?;
|
let trade_client = test_create_solana_trade_client().await?;
|
||||||
@@ -365,6 +365,92 @@ async fn test_pumpswap() -> AnyResult<()> {
|
|||||||
### 5. Bonk 交易操作
|
### 5. Bonk 交易操作
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
|
|
||||||
|
// bonk 狙击者交易
|
||||||
|
async fn test_bonk_sniper_trade_with_shreds(trade_info: BonkTradeEvent) -> AnyResult<()> {
|
||||||
|
println!("Testing Bonk trading...");
|
||||||
|
|
||||||
|
if !trade_info.is_dev_create_token_trade {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
let trade_client = test_create_solana_trade_client().await?;
|
||||||
|
let mint_pubkey = Pubkey::from_str("xxxxxxx")?;
|
||||||
|
let buy_sol_cost = 100_000;
|
||||||
|
let slippage_basis_points = Some(100);
|
||||||
|
let recent_blockhash = trade_client.rpc.get_latest_blockhash().await?;
|
||||||
|
|
||||||
|
println!("Buying tokens from letsbonk.fun...");
|
||||||
|
|
||||||
|
// 使用开发者交易信息构建 BonkParams,可以节约交易时间
|
||||||
|
trade_client.buy(
|
||||||
|
DexType::Bonk,
|
||||||
|
mint_pubkey,
|
||||||
|
None,
|
||||||
|
buy_sol_cost,
|
||||||
|
slippage_basis_points,
|
||||||
|
recent_blockhash,
|
||||||
|
None,
|
||||||
|
Some(Box::new(BonkParams::from_dev_trade(trade_info))),
|
||||||
|
).await?;
|
||||||
|
|
||||||
|
println!("Selling tokens from letsbonk.fun...");
|
||||||
|
let amount_token = 0;
|
||||||
|
trade_client.sell(
|
||||||
|
DexType::Bonk,
|
||||||
|
mint_pubkey,
|
||||||
|
None,
|
||||||
|
amount_token,
|
||||||
|
slippage_basis_points,
|
||||||
|
recent_blockhash,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
).await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
// bonk 跟单交易
|
||||||
|
async fn test_bonk_copy_trade_with_grpc(trade_info: BonkTradeEvent) -> AnyResult<()> {
|
||||||
|
println!("Testing Bonk trading...");
|
||||||
|
|
||||||
|
let trade_client = test_create_solana_trade_client().await?;
|
||||||
|
let mint_pubkey = Pubkey::from_str("xxxxxxx")?;
|
||||||
|
let buy_sol_cost = 100_000;
|
||||||
|
let slippage_basis_points = Some(100);
|
||||||
|
let recent_blockhash = trade_client.rpc.get_latest_blockhash().await?;
|
||||||
|
|
||||||
|
println!("Buying tokens from letsbonk.fun...");
|
||||||
|
|
||||||
|
// 使用交易事件信息构建 BonkParams,可以节约交易时间
|
||||||
|
trade_client.buy(
|
||||||
|
DexType::Bonk,
|
||||||
|
mint_pubkey,
|
||||||
|
None,
|
||||||
|
buy_sol_cost,
|
||||||
|
slippage_basis_points,
|
||||||
|
recent_blockhash,
|
||||||
|
None,
|
||||||
|
Some(Box::new(BonkParams::from_trade(trade_info))),
|
||||||
|
).await?;
|
||||||
|
|
||||||
|
println!("Selling tokens from letsbonk.fun...");
|
||||||
|
let amount_token = 0;
|
||||||
|
trade_client.sell(
|
||||||
|
DexType::Bonk,
|
||||||
|
mint_pubkey,
|
||||||
|
None,
|
||||||
|
amount_token,
|
||||||
|
slippage_basis_points,
|
||||||
|
recent_blockhash,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
).await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
// bonk 普通交易
|
||||||
async fn test_bonk() -> Result<(), Box<dyn std::error::Error>> {
|
async fn test_bonk() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
println!("Testing Bonk trading...");
|
println!("Testing Bonk trading...");
|
||||||
|
|
||||||
|
|||||||
+88
-3
@@ -18,7 +18,7 @@ use sol_trade_sdk::{
|
|||||||
ShredStreamGrpc, YellowstoneGrpc,
|
ShredStreamGrpc, YellowstoneGrpc,
|
||||||
},
|
},
|
||||||
swqos::{SwqosConfig, SwqosRegion},
|
swqos::{SwqosConfig, SwqosRegion},
|
||||||
trading::{core::params::PumpFunParams, factory::DexType},
|
trading::{core::params::{BonkParams, PumpFunParams}, factory::DexType},
|
||||||
SolanaTrade,
|
SolanaTrade,
|
||||||
};
|
};
|
||||||
use solana_sdk::{commitment_config::CommitmentConfig, pubkey::Pubkey, signature::Keypair};
|
use solana_sdk::{commitment_config::CommitmentConfig, pubkey::Pubkey, signature::Keypair};
|
||||||
@@ -70,7 +70,7 @@ fn create_trade_config(rpc_url: String, swqos_configs: Vec<SwqosConfig>) -> Trad
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn test_pumpfun_copy_trade_width_grpc(trade_info: PumpFunTradeEvent) -> AnyResult<()> {
|
async fn test_pumpfun_copy_trade_with_grpc(trade_info: PumpFunTradeEvent) -> AnyResult<()> {
|
||||||
println!("Testing PumpFun trading...");
|
println!("Testing PumpFun trading...");
|
||||||
|
|
||||||
let client = test_create_solana_trade_client().await?;
|
let client = test_create_solana_trade_client().await?;
|
||||||
@@ -113,7 +113,7 @@ async fn test_pumpfun_copy_trade_width_grpc(trade_info: PumpFunTradeEvent) -> An
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn test_pumpfun_sniper_trade_width_shreds(trade_info: PumpFunTradeEvent) -> AnyResult<()> {
|
async fn test_pumpfun_sniper_trade_with_shreds(trade_info: PumpFunTradeEvent) -> AnyResult<()> {
|
||||||
println!("Testing PumpFun trading...");
|
println!("Testing PumpFun trading...");
|
||||||
|
|
||||||
if !trade_info.is_dev_create_token_trade {
|
if !trade_info.is_dev_create_token_trade {
|
||||||
@@ -206,6 +206,91 @@ async fn test_pumpswap() -> AnyResult<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
async fn test_bonk_copy_trade_with_grpc(trade_info: BonkTradeEvent) -> AnyResult<()> {
|
||||||
|
println!("Testing Bonk trading...");
|
||||||
|
|
||||||
|
let client = test_create_solana_trade_client().await?;
|
||||||
|
let mint_pubkey = Pubkey::from_str("xxxxxxx")?;
|
||||||
|
let buy_sol_cost = 100_000;
|
||||||
|
let slippage_basis_points = Some(100);
|
||||||
|
let recent_blockhash = client.rpc.get_latest_blockhash().await?;
|
||||||
|
|
||||||
|
// Buy tokens
|
||||||
|
println!("Buying tokens from letsbonk.fun...");
|
||||||
|
client.buy(
|
||||||
|
DexType::Bonk,
|
||||||
|
mint_pubkey,
|
||||||
|
None,
|
||||||
|
buy_sol_cost,
|
||||||
|
slippage_basis_points,
|
||||||
|
recent_blockhash,
|
||||||
|
None,
|
||||||
|
Some(Box::new(BonkParams::from_trade(trade_info))),
|
||||||
|
).await?;
|
||||||
|
|
||||||
|
// Sell tokens
|
||||||
|
println!("Selling tokens from letsbonk.fun...");
|
||||||
|
let amount_token = 0;
|
||||||
|
client.sell(
|
||||||
|
DexType::Bonk,
|
||||||
|
mint_pubkey,
|
||||||
|
None,
|
||||||
|
amount_token,
|
||||||
|
slippage_basis_points,
|
||||||
|
recent_blockhash,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
).await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn test_bonk_sniper_trade_with_shreds(trade_info: BonkTradeEvent) -> AnyResult<()> {
|
||||||
|
println!("Testing Bonk trading...");
|
||||||
|
|
||||||
|
if !trade_info.is_dev_create_token_trade {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
let client = test_create_solana_trade_client().await?;
|
||||||
|
let mint_pubkey = Pubkey::from_str("xxxxxxx")?;
|
||||||
|
let buy_sol_cost = 100_000;
|
||||||
|
let slippage_basis_points = Some(100);
|
||||||
|
let recent_blockhash = client.rpc.get_latest_blockhash().await?;
|
||||||
|
|
||||||
|
// Buy tokens
|
||||||
|
println!("Buying tokens from letsbonk.fun...");
|
||||||
|
client.buy(
|
||||||
|
DexType::Bonk,
|
||||||
|
mint_pubkey,
|
||||||
|
None,
|
||||||
|
buy_sol_cost,
|
||||||
|
slippage_basis_points,
|
||||||
|
recent_blockhash,
|
||||||
|
None,
|
||||||
|
Some(Box::new(BonkParams::from_dev_trade(trade_info))),
|
||||||
|
).await?;
|
||||||
|
|
||||||
|
// Sell tokens
|
||||||
|
println!("Selling tokens from letsbonk.fun...");
|
||||||
|
let amount_token = 0;
|
||||||
|
client.sell(
|
||||||
|
DexType::Bonk,
|
||||||
|
mint_pubkey,
|
||||||
|
None,
|
||||||
|
amount_token,
|
||||||
|
slippage_basis_points,
|
||||||
|
recent_blockhash,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
).await?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
async fn test_bonk() -> Result<(), Box<dyn std::error::Error>> {
|
async fn test_bonk() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
println!("Testing Bonk trading...");
|
println!("Testing Bonk trading...");
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,59 @@
|
|||||||
use crate::constants;
|
use crate::constants;
|
||||||
use solana_sdk::pubkey::Pubkey;
|
use solana_sdk::pubkey::Pubkey;
|
||||||
|
|
||||||
|
pub fn get_amount_in_net(
|
||||||
|
amount_in: u64,
|
||||||
|
protocol_fee_rate: u128,
|
||||||
|
platform_fee_rate: u128,
|
||||||
|
share_fee_rate: u128,
|
||||||
|
) -> u64 {
|
||||||
|
let amount_in_u128 = amount_in as u128;
|
||||||
|
let protocol_fee = (amount_in_u128 * protocol_fee_rate / 10000) as u128;
|
||||||
|
let platform_fee = (amount_in_u128 * platform_fee_rate / 10000) as u128;
|
||||||
|
let share_fee = (amount_in_u128 * share_fee_rate / 10000) as u128;
|
||||||
|
amount_in_u128
|
||||||
|
.checked_sub(protocol_fee)
|
||||||
|
.unwrap()
|
||||||
|
.checked_sub(platform_fee)
|
||||||
|
.unwrap()
|
||||||
|
.checked_sub(share_fee)
|
||||||
|
.unwrap() as u64
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_amount_in(
|
||||||
|
amount_out: u64,
|
||||||
|
protocol_fee_rate: u128,
|
||||||
|
platform_fee_rate: u128,
|
||||||
|
share_fee_rate: u128,
|
||||||
|
virtual_base: u128,
|
||||||
|
virtual_quote: u128,
|
||||||
|
real_base: u128,
|
||||||
|
real_quote: u128,
|
||||||
|
slippage_basis_points: u128,
|
||||||
|
) -> u64 {
|
||||||
|
let amount_out_u128 = amount_out as u128;
|
||||||
|
|
||||||
|
// 考虑滑点,实际需要的输出金额更高
|
||||||
|
let amount_out_with_slippage = amount_out_u128 * 10000 / (10000 - slippage_basis_points);
|
||||||
|
|
||||||
|
let input_reserve = virtual_quote.checked_add(real_quote).unwrap();
|
||||||
|
let output_reserve = virtual_base.checked_sub(real_base).unwrap();
|
||||||
|
|
||||||
|
// 根据 AMM 公式反推: amount_in_net = (amount_out * input_reserve) / (output_reserve - amount_out)
|
||||||
|
let numerator = amount_out_with_slippage.checked_mul(input_reserve).unwrap();
|
||||||
|
let denominator = output_reserve
|
||||||
|
.checked_sub(amount_out_with_slippage)
|
||||||
|
.unwrap();
|
||||||
|
let amount_in_net = numerator.checked_div(denominator).unwrap();
|
||||||
|
|
||||||
|
// 计算总费用率
|
||||||
|
let total_fee_rate = protocol_fee_rate + platform_fee_rate + share_fee_rate;
|
||||||
|
|
||||||
|
let amount_in = amount_in_net * 10000 / (10000 - total_fee_rate);
|
||||||
|
|
||||||
|
amount_in as u64
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_amount_out(
|
pub fn get_amount_out(
|
||||||
amount_in: u64,
|
amount_in: u64,
|
||||||
protocol_fee_rate: u128,
|
protocol_fee_rate: u128,
|
||||||
@@ -80,3 +133,57 @@ pub fn get_token_price(
|
|||||||
|
|
||||||
price
|
price
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::constants::bonk::accounts::{PLATFORM_FEE_RATE, PROTOCOL_FEE_RATE, SHARE_FEE_RATE};
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_amount_in_out_consistency() {
|
||||||
|
// 测试参数
|
||||||
|
let protocol_fee_rate = PROTOCOL_FEE_RATE;
|
||||||
|
let platform_fee_rate = PLATFORM_FEE_RATE;
|
||||||
|
let share_fee_rate = SHARE_FEE_RATE;
|
||||||
|
let virtual_base = 1073025605596382;
|
||||||
|
let virtual_quote = 30000852951;
|
||||||
|
let real_base = 0;
|
||||||
|
let real_quote = 0;
|
||||||
|
let slippage_basis_points = 0;
|
||||||
|
|
||||||
|
let original_amount_in = 2000000000;
|
||||||
|
|
||||||
|
let geet_amount_out_result = get_amount_out(
|
||||||
|
original_amount_in,
|
||||||
|
protocol_fee_rate,
|
||||||
|
platform_fee_rate,
|
||||||
|
share_fee_rate,
|
||||||
|
virtual_base,
|
||||||
|
virtual_quote,
|
||||||
|
real_base,
|
||||||
|
real_quote,
|
||||||
|
slippage_basis_points,
|
||||||
|
);
|
||||||
|
|
||||||
|
let amount_out = 25959582643397;
|
||||||
|
let get_amount_in_result = get_amount_in(
|
||||||
|
amount_out,
|
||||||
|
protocol_fee_rate,
|
||||||
|
platform_fee_rate,
|
||||||
|
share_fee_rate,
|
||||||
|
virtual_base,
|
||||||
|
virtual_quote,
|
||||||
|
real_base,
|
||||||
|
real_quote,
|
||||||
|
slippage_basis_points,
|
||||||
|
);
|
||||||
|
|
||||||
|
println!("Original amount_in: {}", original_amount_in);
|
||||||
|
println!("Amount_out: {}", geet_amount_out_result);
|
||||||
|
println!("Calculated amount_in: {}", get_amount_in_result);
|
||||||
|
|
||||||
|
assert!(geet_amount_out_result == 66275810509273);
|
||||||
|
assert!(get_amount_in_result == 753217040);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,7 +5,11 @@ use std::sync::Arc;
|
|||||||
use super::traits::ProtocolParams;
|
use super::traits::ProtocolParams;
|
||||||
use crate::common::bonding_curve::BondingCurveAccount;
|
use crate::common::bonding_curve::BondingCurveAccount;
|
||||||
use crate::common::{PriorityFee, SolanaRpcClient};
|
use crate::common::{PriorityFee, SolanaRpcClient};
|
||||||
|
use crate::constants::bonk::accounts::{PLATFORM_FEE_RATE, PROTOCOL_FEE_RATE, SHARE_FEE_RATE};
|
||||||
|
use crate::streaming::event_parser::common::EventType;
|
||||||
|
use crate::streaming::event_parser::protocols::bonk::BonkTradeEvent;
|
||||||
use crate::swqos::SwqosClient;
|
use crate::swqos::SwqosClient;
|
||||||
|
use crate::trading::bonk::common::{get_amount_in, get_amount_in_net, get_amount_out};
|
||||||
|
|
||||||
/// 通用买入参数
|
/// 通用买入参数
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@@ -141,6 +145,64 @@ impl BonkParams {
|
|||||||
auto_handle_wsol: true,
|
auto_handle_wsol: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn from_trade(trade_info: BonkTradeEvent) -> Self {
|
||||||
|
Self {
|
||||||
|
virtual_base: Some(trade_info.virtual_base as u128),
|
||||||
|
virtual_quote: Some(trade_info.virtual_quote as u128),
|
||||||
|
real_base: Some(trade_info.real_base_after as u128),
|
||||||
|
real_quote: Some(trade_info.real_quote_after as u128),
|
||||||
|
auto_handle_wsol: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_dev_trade(trade_info: BonkTradeEvent) -> Self {
|
||||||
|
const DEFAULT_VIRTUAL_BASE: u128 = 1073025605596382;
|
||||||
|
const DEFAULT_VIRTUAL_QUOTE: u128 = 30000852951;
|
||||||
|
let amount_in = if trade_info.metadata.event_type == EventType::BonkBuyExactIn {
|
||||||
|
trade_info.amount_in
|
||||||
|
} else {
|
||||||
|
get_amount_in(
|
||||||
|
trade_info.amount_out,
|
||||||
|
PROTOCOL_FEE_RATE,
|
||||||
|
PLATFORM_FEE_RATE,
|
||||||
|
SHARE_FEE_RATE,
|
||||||
|
DEFAULT_VIRTUAL_BASE,
|
||||||
|
DEFAULT_VIRTUAL_QUOTE,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
let real_quote = get_amount_in_net(
|
||||||
|
amount_in,
|
||||||
|
PROTOCOL_FEE_RATE,
|
||||||
|
PLATFORM_FEE_RATE,
|
||||||
|
SHARE_FEE_RATE,
|
||||||
|
) as u128;
|
||||||
|
let amount_out = if trade_info.metadata.event_type == EventType::BonkBuyExactIn {
|
||||||
|
get_amount_out(
|
||||||
|
trade_info.amount_in,
|
||||||
|
PROTOCOL_FEE_RATE,
|
||||||
|
PLATFORM_FEE_RATE,
|
||||||
|
SHARE_FEE_RATE,
|
||||||
|
DEFAULT_VIRTUAL_BASE,
|
||||||
|
DEFAULT_VIRTUAL_QUOTE,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
) as u128
|
||||||
|
} else {
|
||||||
|
trade_info.amount_out as u128
|
||||||
|
};
|
||||||
|
let real_base = amount_out;
|
||||||
|
Self {
|
||||||
|
virtual_base: Some(DEFAULT_VIRTUAL_BASE),
|
||||||
|
virtual_quote: Some(DEFAULT_VIRTUAL_QUOTE),
|
||||||
|
real_base: Some(real_base),
|
||||||
|
real_quote: Some(real_quote),
|
||||||
|
auto_handle_wsol: true,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ProtocolParams for BonkParams {
|
impl ProtocolParams for BonkParams {
|
||||||
|
|||||||
Reference in New Issue
Block a user