Orca SDK
A fully functional Orca SDK for interacting with the Orca DEX protocol on Solana. It supports trading, liquidity provisioning, and price monitoring in centralized liquidity pools, standard pools, and stable pools.
简体中文 | English
Feature
- 🏊 Full Orca Protocol Support - Whirlpools (centralized liquidity), Standard Pools, Stable Pools
- 💰 Token Balance Management - Check balance, create token accounts
- 🔄 Trading Functions - Token swap, slippage protection
- 💧 Liquidity Management - Add/remove liquidity, position management
- 📊 Price Data - Real-time price, candlestick chart data, price history
- 🚨 Monitoring Functions - Price change monitoring, pool health check
- 🔍 On-chain Data Analysis - Transaction analysis, pool discovery
Example
Initialize client
use orca_rs::OrcaClient;
use solana_sdk::signature::Keypair;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = OrcaClient::new()?;
let client = std::sync::Arc::new(client);
Ok(())
}
Check token balance
use solana_sdk::pubkey;
async fn check_balances(client: &OrcaClient) -> Result<(), Box<dyn std::error::Error>> {
let owner = pubkey!("YourWalletPublicKeyHere");
let mint = pubkey!("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"); // USDC
let balance = client.get_token_balance(&owner, &mint).await?;
println!("USDC Balance: {}", balance);
let all_balances = client.get_all_token_balances(&owner).await?;
for (mint, balance) in all_balances {
println!("Token: {}, Balance: {}", mint, balance);
}
Ok(())
}
Execute trade
use orca_rs::trade::TradeConfig;
async fn execute_swap(client: &OrcaClient, keypair: &Keypair) -> Result<(), Box<dyn std::error::Error>> {
let input_mint = "So11111111111111111111111111111111111111112"; // SOL
let output_mint = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"; // USDC
let amount = 1_000_000; // 1 SOL
let config = TradeConfig {
slippage: 0.5, // 0.5%
max_iterations: 3,
};
let signature = client.swap(keypair, input_mint, output_mint, amount, Some(config)).await?;
println!("Done: {}", signature);
Ok(())
}
Add liquidity
use orca_rs::liquidity::{LiquidityPosition, AddLiquidityConfig};
async fn add_liquidity(client: &OrcaClient, keypair: &Keypair) -> Result<(), Box<dyn std::error::Error>> {
let pool_address = "whirlpool_address_here";
let pool_info = client.get_pool_state_onchain(pool_address).await?;
let token_a_amount = 1_000_000; // Token A
let token_b_amount = 2_000_000; // TOKEN B
let lower_tick = -1000; // price floor
let upper_tick = 1000; // price ceiling
let config = AddLiquidityConfig {
slippage_tolerance: 0.5,
max_iterations: 3,
};
let signature = client.add_liquidity(
keypair,
&pool_info,
token_a_amount,
token_b_amount,
lower_tick,
upper_tick,
Some(config),
).await?;
println!("Liquidity added successfully! Transaction signature: {}", signature);
Ok(())
}
async fn check_positions(client: &OrcaClient, owner: &Pubkey) -> Result<(), Box<dyn std::error::Error>> {
let positions = client.get_liquidity_positions(owner).await?;
for position in positions {
println!("Liquidity Position: {} LP Tokens", position.lp_token_amount);
println!("Token A: {}, Token B: {}", position.token_a_amount, position.token_b_amount);
println!("Price Range: {} to {}", position.lower_tick, position.upper_tick);
}
Ok(())
}
price monitoring
use orca_rs::events::PriceUpdate;
use std::sync::Arc;
async fn monitor_prices(client: Arc<OrcaClient>) -> Result<(), Box<dyn std::error::Error>> {
let pool_address = "whirlpool_address_here";
let monitor_handle = client.monitor_price_changes_production(
pool_address,
1.0, // 1%
|update: PriceUpdate| {
println!("Price change detected!");
println!("Pool: {}", update.pool_address);
println!("Old price: {}, New price: {}", update.old_price, update.new_price);
println!("Change: {:.2}%", update.change_percent);
println!("Time: {}", update.timestamp);
},
).await?;
// running 60s
tokio::time::sleep(tokio::time::Duration::from_secs(60)).await;
// close
monitor_handle.shutdown().await;
Ok(())
}
Get price data
async fn get_price_data(client: &OrcaClient) -> Result<(), Box<dyn std::error::Error>> {
let base_mint = "So11111111111111111111111111111111111111112"; // SOL
let quote_mint = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"; // USDC
let current_price = client.get_token_price_from_pool(base_mint, quote_mint).await?;
println!("Current SOL/USDC price: {}", current_price);
let pool_address = "whirlpool_sol_usdc_address";
let price_history = client.get_price_history_from_chain(pool_address, 100).await?;
for data in price_history {
println!("Time: {}, Price: {}", data.timestamp, data.price);
}
let ma_20 = client.calculate_moving_average_from_chain(pool_address, 20).await?;
println!("20-period moving average: {}", ma_20);
// KLine data
let klines = client.get_kline_data_production(pool_address, 60, 100).await?; // 1h
for kline in klines {
println!("open: {}, hight: {}, low: {}, close: {}",
kline.open, kline.high, kline.low, kline.close);
}
Ok(())
}
Pool Health Check
async fn check_pool_health(client: &OrcaClient) -> Result<(), Box<dyn std::error::Error>> {
let pool_address = "whirlpool_address_here";
let health = client.monitor_pool_health(pool_address).await?;
println!("Pool Health Report:");
println!("Liquidity: {}", health.liquidity);
println!("24-hour Trading Volume: {}", health.volume_24h);
println!("Fee Growth: {}", health.fee_growth);
println!("Health Score: {:.2}", health.health_score);
if health.health_score > 80.0 {
println!("✅ good");
} else if health.health_score > 50.0 {
println!("⚠️ ordinary");
} else {
println!("❌ poor");
}
Ok(())
}