use guilder_abstraction::{
GetAccountSnapshot, GetMarketData, ManageOrder, OrderSide, OrderType, TimeInForce,
};
use guilder_client_hyperliquid::HyperliquidClient;
use rust_decimal::Decimal;
use std::str::FromStr;
fn require_auth() -> Option<(String, String)> {
let addr = std::env::var("HYPERLIQUID_WALLET_ADDRESS").ok()?;
let key = std::env::var("HYPERLIQUID_WALLET_KEY").ok()?;
Some((addr, key))
}
#[tokio::test]
async fn test_place_and_cancel_limit_order() {
let Some((addr, key)) = require_auth() else {
eprintln!("SKIP: set HYPERLIQUID_WALLET_ADDRESS and HYPERLIQUID_WALLET_KEY env vars");
return;
};
let client = HyperliquidClient::with_auth(addr, key);
let _ = client.cancel_all_order().await;
let balances = client
.get_spot_balance()
.await
.expect("get_spot_balance failed");
let usdc = balances.iter().find(|b| b.coin == "USDC");
let usdc = usdc.expect("no USDC spot balance found in test wallet");
assert!(
usdc.available > Decimal::ZERO,
"no available USDC in test wallet (total={}, available={}, locked={})",
usdc.total, usdc.available, usdc.locked
);
println!("USDC spot balance: total={} available={} locked={}", usdc.total, usdc.available, usdc.locked);
let price = client
.get_price("BTC".to_string())
.await
.expect("get_price failed");
println!("BTC price: {price}");
let buy_price = (price - Decimal::from_str("100").unwrap()).round_dp(0);
let volume = Decimal::from_str("0.00015").unwrap();
let cloid = format!(
"test-{}",
std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_millis()
);
let order = client
.place_order(
"BTC".to_string(),
OrderSide::Buy,
buy_price,
volume,
OrderType::Limit,
TimeInForce::Gtc,
Some(cloid.clone()),
)
.await
.expect("place_order failed");
use sha3::{Digest, Keccak256};
let hash = Keccak256::new_with_prefix(cloid.as_bytes());
let expected_cloid = format!("0x{}", hex::encode(&hash.finalize()[..16]));
assert_eq!(order.symbol, "BTC");
assert_eq!(order.side, OrderSide::Buy);
assert_eq!(order.cloid.as_deref(), Some(expected_cloid.as_str()));
println!(
"order placed: oid={} cloid={} price={} qty={}",
order.order_id, order.cloid.as_deref().unwrap_or("none"), order.price, order.quantity
);
let open = client
.get_open_orders()
.await
.expect("get_open_orders failed");
let found = open.iter().find(|o| o.order_id == order.order_id);
assert!(
found.is_some(),
"placed order {} not found in open orders",
order.order_id
);
println!("order confirmed in open orders");
let cancelled = client.cancel_order(order.order_id).await;
assert!(
cancelled.is_ok(),
"cancel_order failed: {:?}",
cancelled
);
println!("order {} cancelled", order.order_id);
let open = client
.get_open_orders()
.await
.expect("get_open_orders after cancel failed");
let still_there = open.iter().find(|o| o.order_id == order.order_id);
assert!(
still_there.is_none(),
"cancelled order {} still appears in open orders",
order.order_id
);
println!("order confirmed removed from open orders");
let _ = client.cancel_all_order().await;
}