use alloy_primitives::Address;
use alloy_primitives::U256;
use ostium_rust_sdk::{
Network, OpenPositionParams, OstiumClient, PositionSide, UnsignedTransactionParams,
};
use rust_decimal::Decimal;
use std::str::FromStr;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
tracing_subscriber::fmt::init();
println!("🔧 Unsigned Transaction Example");
println!("===============================");
let client = OstiumClient::new(Network::Testnet).await?;
println!("✅ Connected to Ostium testnet (no signer required)");
let trader_address = Address::from_str("0x742d35Cc6634C0532925a3b8D53A2e1c5Bc2D8db")?;
println!("👤 Using trader address: {}", trader_address);
println!("\n📈 Building unsigned transaction for opening a position...");
let position_params = OpenPositionParams {
symbol: "BTC/USD".to_string(),
side: PositionSide::Long,
size: Decimal::from(1000), leverage: Decimal::from(10), take_profit: Some(Decimal::from(45000)),
stop_loss: Some(Decimal::from(35000)),
slippage_tolerance: Decimal::from(1) / Decimal::from(100), };
let tx_params = UnsignedTransactionParams {
from: trader_address,
include_gas_estimates: true,
include_nonce: true,
};
match client
.open_position_unsigned(position_params, trader_address, tx_params.clone())
.await
{
Ok(unsigned_tx) => {
println!("✅ Unsigned transaction built successfully!");
println!("📋 Transaction Details:");
println!(" To: {}", unsigned_tx.to);
println!(" Data length: {} bytes", unsigned_tx.data.len());
println!(" Value: {} ETH", unsigned_tx.value);
println!(" Chain ID: {}", unsigned_tx.chain_id);
if let Some(gas_limit) = unsigned_tx.gas_limit {
println!(" Estimated gas: {}", gas_limit);
}
if let Some(gas_price) = unsigned_tx.gas_price {
println!(
" Gas price: {} gwei",
gas_price / U256::from(1_000_000_000u64)
);
}
if let Some(nonce) = unsigned_tx.nonce {
println!(" Nonce: {}", nonce);
}
let frontend_payload = serde_json::to_string_pretty(&unsigned_tx)?;
println!("\n📤 JSON payload for frontend:");
println!("{}", frontend_payload);
}
Err(e) => {
println!("❌ Failed to build unsigned transaction: {}", e);
}
}
println!("\n🔄 Building multiple unsigned transactions...");
use ostium_rust_sdk::UpdateTPSLParams;
let update_params = UpdateTPSLParams {
position_id: format!("{}:0:0", trader_address), take_profit: Some(Decimal::from(50000)),
stop_loss: Some(Decimal::from(30000)),
};
match client
.update_tp_sl_unsigned(update_params, tx_params.clone())
.await
{
Ok(unsigned_txs) => {
println!(
"✅ Built {} unsigned transactions for TP/SL update",
unsigned_txs.len()
);
for (i, tx) in unsigned_txs.iter().enumerate() {
println!(" Transaction {}: {} bytes", i + 1, tx.data.len());
}
let batch_payload = serde_json::to_string_pretty(&unsigned_txs)?;
println!("\n📤 Batch transactions JSON:");
println!("{}", batch_payload);
}
Err(e) => {
println!("❌ Failed to build TP/SL update transactions: {}", e);
}
}
println!("\n📊 Building unsigned transaction for limit order...");
use ostium_rust_sdk::{AdvancedOrderParams, OrderExecutionType};
let limit_order_params = AdvancedOrderParams {
symbol: "ETH/USD".to_string(),
side: PositionSide::Short,
size: Decimal::from(2000), leverage: Decimal::from(5), order_type: OrderExecutionType::Limit,
price: Some(Decimal::from(2200)), take_profit: Some(Decimal::from(2000)),
stop_loss: Some(Decimal::from(2400)),
slippage_tolerance: Decimal::from(1) / Decimal::from(100), };
match client
.place_advanced_order_unsigned(limit_order_params, trader_address, tx_params)
.await
{
Ok(unsigned_tx) => {
println!("✅ Limit order unsigned transaction built!");
println!(" Gas estimate: {:?}", unsigned_tx.gas_limit);
println!("\n🌐 Frontend Integration Example:");
println!(" 1. Send this transaction data to your frontend");
println!(" 2. Frontend prompts user to sign with their wallet");
println!(" 3. Frontend broadcasts the signed transaction");
println!(" 4. Monitor transaction status via transaction hash");
}
Err(e) => {
println!("❌ Failed to build limit order transaction: {}", e);
}
}
println!("\n✨ Unsigned transaction example completed!");
println!("📚 This demonstrates how to build transactions for frontend signing");
println!("🔐 The SDK never needs access to private keys in this mode");
Ok(())
}