info/
perps.rs

1use std::{sync::Arc, time::SystemTime};
2
3use ethers::{
4    signers::{LocalWallet, Signer},
5    types::Address,
6};
7use hyperliquid::{
8    types::{
9        exchange::request::{Limit, OrderRequest, OrderType, Tif},
10        Chain, Oid,
11    },
12    utils::{parse_price, parse_size},
13    Exchange, Hyperliquid, Info,
14};
15use uuid::Uuid;
16
17const SEP: &str = "\n---";
18
19#[tokio::main]
20pub async fn main() {
21    // Key was randomly generated for testing and shouldn't be used with any real funds
22    let wallet: Arc<LocalWallet> = Arc::new(
23        "e908f86dbb4d55ac876378565aafeabc187f6690f046459397b17d9b9a19688e"
24            .parse()
25            .unwrap(),
26    );
27
28    let user = wallet.address();
29
30    let info = Hyperliquid::new(Chain::ArbitrumTestnet);
31
32    let exchange = Hyperliquid::new(Chain::ArbitrumTestnet);
33
34    let now = SystemTime::now()
35        .duration_since(SystemTime::UNIX_EPOCH)
36        .expect("Time went backwards");
37
38    let now = now.as_millis() as u64;
39
40    println!("Info Perps API Examples");
41
42    metadata(&info).await;
43    mids(&info).await;
44    contexts(&info).await;
45    user_state(&info, user).await;
46    batch_user_states(&info, vec![user]).await;
47    open_orders(&info, user).await;
48    frontend_open_orders(&info, user).await;
49    user_fills(&info, user).await;
50    user_fills_by_time(&info, user, now - 1000000, Some(now)).await;
51    user_funding(&info, user).await;
52    funding_history(&info).await;
53    l2_book(&info).await;
54    recent_trades(&info).await;
55    candle_snapshot(&info).await;
56    order_status(&info, &exchange, wallet).await;
57    sub_accounts(&info, user).await;
58}
59
60async fn metadata(info: &Info) {
61    let metadata = info.metadata().await.unwrap();
62    println!("{SEP}\nMetadata \n{:?}{SEP}", metadata.universe);
63}
64
65async fn mids(info: &Info) {
66    let mids = info.mids().await.unwrap();
67    println!("Mids \n{:?}{SEP}", mids);
68}
69
70async fn contexts(info: &Info) {
71    let contexts = info.contexts().await.unwrap();
72    println!("Asset Contexts \n{:?}{SEP}", contexts);
73}
74
75async fn user_state(info: &Info, user: Address) {
76    let user_state = info.user_state(user).await.unwrap();
77    println!("User state for {user} \n{:?}{SEP}", user_state);
78}
79
80async fn batch_user_states(info: &Info, users: Vec<Address>) {
81    let user_states = info.user_states(users.clone()).await.unwrap();
82    println!("User states for {:?} \n{:?}{SEP}", users, user_states);
83}
84
85async fn open_orders(info: &Info, user: Address) {
86    let open_orders = info.open_orders(user).await.unwrap();
87    println!("Open orders for {user} \n{:?}{SEP}", open_orders);
88}
89
90async fn frontend_open_orders(info: &Info, user: Address) {
91    let open_orders = info.frontend_open_orders(user).await.unwrap();
92    println!("Frontend Open orders for {user} \n{:?}{SEP}", open_orders);
93}
94
95async fn user_fills(info: &Info, user: Address) {
96    let user_fills = info.user_fills(user).await.unwrap();
97    println!("User fills for {user} \n{:?}{SEP}", user_fills);
98}
99
100async fn user_fills_by_time(info: &Info, user: Address, start_time: u64, end_time: Option<u64>) {
101    let user_fills = info.user_fills_by_time(user, start_time, end_time).await;
102    // .unwrap();
103    println!("User fills by time for {user} \n{:?}{SEP}", user_fills);
104}
105
106async fn user_funding(info: &Info, user: Address) {
107    let start_timestamp = 1690540602225;
108    let end_timestamp = 1690569402225;
109
110    let user_funding = info
111        .user_funding(user, start_timestamp, Some(end_timestamp))
112        .await
113        .unwrap();
114    println!(
115        "User funding for {user} between {start_timestamp} and {end_timestamp} \n{:?}{SEP}",
116        user_funding
117    );
118}
119
120async fn funding_history(info: &Info) {
121    let coin = "ETH";
122
123    let start_timestamp = 1690540602225;
124    let end_timestamp = 1690569402225;
125
126    let funding_history = info
127        .funding_history(coin.to_string(), start_timestamp, Some(end_timestamp))
128        .await
129        .unwrap();
130    println!(
131        "Funding history for {coin} between {start_timestamp} and {end_timestamp} \n{:?}{SEP}",
132        funding_history
133    );
134}
135
136async fn l2_book(info: &Info) {
137    let coin = "ETH";
138
139    let l2_book = info.l2_book(coin.to_string()).await.unwrap();
140    println!("L2 book for {coin} \n{:?}{SEP}", l2_book);
141}
142
143async fn recent_trades(info: &Info) {
144    let coin = "ETH";
145
146    let recent_trades = info.recent_trades(coin.to_string()).await.unwrap();
147    println!("Recent trades for {coin} \n{:?}{SEP}", recent_trades);
148}
149
150async fn candle_snapshot(info: &Info) {
151    let coin = "ETH";
152    let interval = "15m";
153    let start_timestamp = 1690540602225;
154    let end_timestamp = 1690569402225;
155
156    let snapshot = info
157        .candle_snapshot(
158            coin.to_string(),
159            interval.to_string(),
160            start_timestamp,
161            end_timestamp,
162        )
163        .await
164        .unwrap();
165    println!("Candle snapshot for {coin} between {start_timestamp} and {end_timestamp} with interval {interval} \n{:?}{SEP}",snapshot);
166}
167
168async fn order_status(info: &Info, exchange: &Exchange, wallet: Arc<LocalWallet>) {
169    let user = wallet.address();
170    let vault_address = None;
171    let cloid = Uuid::new_v4();
172    let order = OrderRequest {
173        asset: 4,
174        is_buy: true,
175        reduce_only: false,
176        limit_px: parse_price(2800.0),
177        sz: parse_size(0.0331, 4),
178        order_type: OrderType::Limit(Limit { tif: Tif::Gtc }),
179        cloid: Some(cloid),
180    };
181
182    println!("Placing order with cloid: {}{SEP}", cloid.simple());
183    let response = exchange
184        .place_order(wallet, vec![order], vault_address)
185        .await
186        .expect("Failed to place order");
187
188    println!("Response: {:?}", response);
189
190    tokio::time::sleep(tokio::time::Duration::from_secs(3)).await;
191
192    let order_status = info.order_status(user, Oid::Cloid(cloid)).await.unwrap();
193
194    println!(
195        "Order status for {} \n{:?}{SEP}",
196        cloid.simple(),
197        order_status
198    );
199}
200
201async fn sub_accounts(info: &Info, user: Address) {
202    let sub_accounts = info.sub_accounts(user).await.unwrap();
203    println!("Sub accounts for {user} \n{:?}{SEP}", sub_accounts);
204}