use o2_sdk::crypto::*;
use o2_sdk::*;
use tokio_stream::StreamExt;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let buy_below_price: UnsignedDecimal = "0.04".parse()?;
let max_quantity = "50";
let mut client = O2Client::new(Network::Testnet);
let wallet = client.generate_wallet()?;
println!("Owner: {}", to_hex_string(&wallet.b256_address));
let account = client.setup_account(&wallet).await?;
let trade_account_id = account.trade_account_id.unwrap();
println!("Trade account: {trade_account_id}");
println!("Waiting for faucet cooldown...");
tokio::time::sleep(std::time::Duration::from_secs(65)).await;
let _ = client.setup_account(&wallet).await;
let markets = client.get_markets().await?;
let market_pair = markets[0].symbol_pair();
let market = &markets[0];
println!("Monitoring: {market_pair}");
let mut session = client
.create_session(
&wallet,
&[market_pair.as_str()],
std::time::Duration::from_secs(30 * 24 * 3600),
)
.await?;
println!("Session created");
let mut depth_stream = client.stream_depth(market.market_id.as_str(), 1).await?;
println!("Listening for depth updates (buy when ask <= {buy_below_price})...");
while let Some(Ok(update)) = depth_stream.next().await {
let sells = update
.view
.as_ref()
.map(|v| &v.asks)
.or_else(|| update.changes.as_ref().map(|c| &c.asks));
if let Some(sell_levels) = sells {
if let Some(best_ask) = sell_levels.first() {
let ask_price: u64 = best_ask.price;
if ask_price == 0 {
continue;
}
let ask_human = market.format_price(ask_price);
if ask_human <= buy_below_price {
println!("Target price hit! Best ask: {ask_human}");
let slippage_factor: UnsignedDecimal = "1.005".parse()?;
let taker_price = ask_human * slippage_factor;
let price = match market.price_from_decimal(taker_price) {
Ok(v) => v,
Err(e) => {
eprintln!("Skipping order due to invalid taker price: {e}");
continue;
}
};
let result = client
.create_order(
&mut session,
market_pair.as_str(),
Side::Buy,
price,
max_quantity,
OrderType::Spot,
true,
true,
)
.await;
match result {
Ok(resp) if resp.is_success() => {
println!("Order placed! tx: {}", resp.tx_id.as_deref().unwrap_or("?"));
}
Ok(resp) => {
eprintln!("Order failed: {:?}", resp.message);
}
Err(e) => {
eprintln!("Order error: {e}");
let _ = client.refresh_nonce(&mut session).await;
}
}
} else {
println!("Best ask: {ask_human} (waiting for <= {buy_below_price})");
}
}
}
}
Ok(())
}