Struct hyperliquid::Exchange

source ·
pub struct Exchange {
    pub client: Client,
    pub chain: Chain,
}
Expand description

Endpoint to interact with and trade on the Hyperliquid chain.

Fields§

§client: Client§chain: Chain

Implementations§

source§

impl Exchange

source

pub async fn place_order( &self, wallet: Arc<LocalWallet>, orders: Vec<OrderRequest>, vault_address: Option<Address> ) -> Result<Response>

Place an order

§Arguments
  • wallet - The wallet to sign the order with
  • orders - The orders to place
  • vault_address - If trading on behalf of a vault, its onchain address in 42-character hexadecimal format e.g. 0x0000000000000000000000000000000000000000
§Note
  • cloid in argument order is an optional 128 bit hex string, e.g. 0x1234567890abcdef1234567890abcdef
Examples found in repository?
examples/info.rs (line 184)
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
async fn order_status(info: &Info, exchange: &Exchange, wallet: Arc<LocalWallet>) {
    let user = wallet.address();
    let vault_address = None;
    let cloid = Uuid::new_v4();
    let order = OrderRequest {
        asset: 4,
        is_buy: true,
        reduce_only: false,
        limit_px: parse_price(2800.0),
        sz: parse_size(0.0331, 4),
        order_type: OrderType::Limit(Limit { tif: Tif::Gtc }),
        cloid: Some(cloid),
    };

    println!("Placing order with cloid: {}{SEP}", cloid.simple());
    let response = exchange
        .place_order(wallet, vec![order], vault_address)
        .await
        .expect("Failed to place order");

    println!("Response: {:?}", response);

    tokio::time::sleep(tokio::time::Duration::from_secs(3)).await;

    let order_status = info.order_status(user, Oid::Cloid(cloid)).await.unwrap();

    println!(
        "Order status for {} \n{:?}{SEP}",
        cloid.simple(),
        order_status
    );
}
More examples
Hide additional examples
examples/agent.rs (line 62)
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
async fn main() {
    // Key was randomly generated for testing and shouldn't be used with any real funds
    let wallet: Arc<LocalWallet> = Arc::new(
        "e908f86dbb4d55ac876378565aafeabc187f6690f046459397b17d9b9a19688e"
            .parse()
            .unwrap(),
    );

    let exchange: Exchange = Hyperliquid::new(Chain::ArbitrumTestnet);

    // Create a new wallet with the agent. This agent can't transfer or withdraw funds
    // but can place orders.

    let agent = LocalWallet::new(&mut thread_rng());

    let agent_address = agent.address();

    println!("Agent address: {:?}", agent_address);

    let res = exchange
        .approve_agent(wallet.clone(), agent_address, Some("WETH".to_string()))
        .await
        .unwrap();

    println!("Response: {:?}", res);

    // place order with agent
    let order_type = OrderType::Limit(Limit { tif: Tif::Gtc });
    let order = OrderRequest {
        asset: 4,
        is_buy: true,
        reduce_only: false,
        limit_px: "1700".to_string(),
        sz: "0.1".to_string(),
        order_type,
        cloid: None,
    };
    let vault_address = None;

    println!("Placing order with agent...");

    let response = exchange
        .place_order(wallet.clone(), vec![order], vault_address)
        .await
        .expect("Failed to place order");

    println!("Response: {:?}", response);
}
examples/order-status.rs (line 47)
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
async fn main() {
    // Key was randomly generated for testing and shouldn't be used with any real funds
    let wallet: Arc<LocalWallet> = Arc::new(
        "e908f86dbb4d55ac876378565aafeabc187f6690f046459397b17d9b9a19688e"
            .parse()
            .unwrap(),
    );

    let exchange: Exchange = Hyperliquid::new(Chain::Dev);
    let info: Info = Hyperliquid::new(Chain::Dev);

    let asset = 4;
    let sz_decimals = 4;

    let order_type = OrderType::Limit(Limit { tif: Tif::Gtc });

    let order = OrderRequest {
        asset,
        is_buy: true,
        reduce_only: false,
        limit_px: parse_price(2800.0),
        sz: parse_size(0.0331, sz_decimals),
        order_type,
        cloid: None,
    };

    let vault_address = None;

    println!("Placing order...");
    let response = exchange
        .place_order(wallet.clone(), vec![order], vault_address)
        .await
        .expect("Failed to place order");

    let response = match response {
        Response::Ok(order) => order,
        Response::Err(error) => panic!("Failed to place order: {:?}", error),
    };

    println!("Response: {:?}", response.data);

    let status_type = &response.data.unwrap();

    let status = match status_type {
        StatusType::Statuses(statuses) => &statuses[0],
        _ => {
            panic!("Failed to place order: {:?}", status_type);
        }
    };

    let oid = match status {
        Status::Filled(order) => order.oid,
        Status::Resting(order) => order.oid,
        _ => panic!("Order is not filled or resting"),
    };

    println!("-----------------");

    println!("Fetching order {} status...", oid);

    let status = info
        .order_status(wallet.address(), Oid::Order(oid))
        .await
        .expect("Failed to fetch order status");

    println!("Order status: {:#?}", status.order);
}
examples/modify-order.rs (line 44)
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
async fn main() {
    // Key was randomly generated for testing and shouldn't be used with any real funds
    let wallet: Arc<LocalWallet> = Arc::new(
        "e908f86dbb4d55ac876378565aafeabc187f6690f046459397b17d9b9a19688e"
            .parse()
            .unwrap(),
    );

    let exchange: Exchange = Hyperliquid::new(Chain::Dev);

    let order_type = OrderType::Limit(Limit { tif: Tif::Gtc });
    let cloid = Uuid::new_v4();

    let order = OrderRequest {
        asset: 4,
        is_buy: true,
        reduce_only: false,
        limit_px: "1800".to_string(),
        sz: "0.1".to_string(),
        order_type,
        cloid: Some(cloid),
    };

    let vault_address = None;

    println!("Placing order...");
    let response = exchange
        .place_order(wallet.clone(), vec![order], vault_address)
        .await
        .expect("Failed to place order");

    let response = match response {
        Response::Ok(order) => order,
        Response::Err(error) => panic!("Failed to place order: {:?}", error),
    };

    let status_type = &response.data.unwrap();

    let status = match status_type {
        StatusType::Statuses(statuses) => &statuses[0],
        _ => {
            panic!("Failed to place order: {:?}", status_type);
        }
    };

    let oid = match status {
        Status::Filled(order) => order.oid,
        Status::Resting(order) => order.oid,
        _ => panic!("Order is not filled or resting"),
    };

    println!("Order placed: {:?}", oid);

    tokio::time::sleep(std::time::Duration::from_secs(5)).await;

    let limit_px = "1710".to_string();
    // Modifying the order
    println!("Modifying order {oid} limit price to {limit_px}.");

    let order = OrderRequest {
        asset: 4,
        is_buy: true,
        reduce_only: false,
        limit_px,
        sz: "0.1".to_string(),
        order_type: OrderType::Limit(Limit { tif: Tif::Gtc }),
        cloid: Some(cloid),
    };

    let order = ModifyRequest { order, oid };

    let response = exchange
        .modify_order(wallet.clone(), order, vault_address)
        .await
        .expect("Failed to modify order");

    println!("Response: {:?}", response);
}
examples/place-order.rs (line 44)
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
async fn main() {
    // Key was randomly generated for testing and shouldn't be used with any real funds
    let wallet: Arc<LocalWallet> = Arc::new(
        "e908f86dbb4d55ac876378565aafeabc187f6690f046459397b17d9b9a19688e"
            .parse()
            .unwrap(),
    );

    let exchange: Exchange = Hyperliquid::new(Chain::Dev);

    let asset = 4;
    let sz_decimals = 4;

    let order_type = OrderType::Limit(Limit { tif: Tif::Gtc });

    let order = OrderRequest {
        asset,
        is_buy: true,
        reduce_only: false,
        limit_px: parse_price(2800.0),
        sz: parse_size(0.0331, sz_decimals),
        order_type,
        cloid: None,
    };

    let vault_address = None;

    println!("Placing order...");
    let response = exchange
        .place_order(wallet.clone(), vec![order], vault_address)
        .await
        .expect("Failed to place order");

    println!("Response: {:?}", response);

    println!("-----------------");
    println!("Placing an order with cloid...");

    let order_type = OrderType::Limit(Limit { tif: Tif::Gtc });

    let cloid = Uuid::new_v4();

    let order = OrderRequest {
        asset,
        is_buy: true,
        reduce_only: false,
        limit_px: parse_price(2800.0),
        sz: parse_size(0.0331, sz_decimals),
        order_type,
        cloid: Some(cloid),
    };

    let response = exchange
        .place_order(wallet.clone(), vec![order], vault_address)
        .await
        .expect("Failed to place order");

    println!("Response: {:?}", response);

    println!("-----------------");
    println!("Placing a trigger order with tpsl...");

    let order_type = OrderType::Trigger(Trigger {
        is_market: false,
        trigger_px: parse_price(2800.0),
        tpsl: TpSl::Tp,
    });

    let order = OrderRequest {
        asset,
        is_buy: true,
        reduce_only: false,
        limit_px: parse_price(2800.0),
        sz: parse_size(0.0331, sz_decimals),
        order_type,
        cloid: Some(cloid),
    };

    let response = exchange
        .place_order(wallet.clone(), vec![order], vault_address)
        .await
        .expect("Failed to place order");

    println!("Response: {:?}", response);
}
examples/cancel-order.rs (line 43)
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
async fn main() {
    // Key was randomly generated for testing and shouldn't be used with any real funds
    let wallet: Arc<LocalWallet> = Arc::new(
        "e908f86dbb4d55ac876378565aafeabc187f6690f046459397b17d9b9a19688e"
            .parse()
            .unwrap(),
    );

    let exchange: Exchange = Hyperliquid::new(Chain::Dev);

    let order_type = OrderType::Limit(Limit { tif: Tif::Gtc });

    let order = OrderRequest {
        asset: 4,
        is_buy: true,
        reduce_only: false,
        limit_px: "1800".to_string(),
        sz: "0.1".to_string(),
        order_type,
        cloid: None,
    };

    let vault_address = None;

    println!("Placing order...");
    let response = exchange
        .place_order(wallet.clone(), vec![order], vault_address)
        .await
        .expect("Failed to place order");

    let response = match response {
        Response::Ok(order) => order,
        Response::Err(error) => panic!("Failed to place order: {:?}", error),
    };

    let status_type = &response.data.unwrap();

    let status = match status_type {
        StatusType::Statuses(statuses) => &statuses[0],
        _ => {
            panic!("Failed to place order: {:?}", status_type);
        }
    };

    let oid = match status {
        Status::Filled(order) => order.oid,
        Status::Resting(order) => order.oid,
        _ => {
            panic!("Order is not filled or resting, status: {:?}", status);
        }
    };

    println!("Order placed: {:?}", oid);

    tokio::time::sleep(std::time::Duration::from_secs(5)).await;

    // Cancel order

    println!("Cancelling order with oid {oid}.");
    let cancel = CancelRequest { asset: 4, oid };

    let vault_address = None;

    let response = exchange
        .cancel_order(wallet.clone(), vec![cancel], vault_address)
        .await
        .expect("Failed to cancel order");

    println!("Response: {:?}", response);

    let cloid = Uuid::new_v4();

    println!("Placing order with cloid: {}", cloid.simple());

    let order_type = OrderType::Limit(Limit { tif: Tif::Gtc });

    let order = OrderRequest {
        asset: 4,
        is_buy: true,
        reduce_only: false,
        limit_px: "1700".to_string(),
        sz: "0.1".to_string(),
        order_type,
        cloid: Some(cloid),
    };

    let vault_address = None;

    let response = exchange
        .place_order(wallet.clone(), vec![order], vault_address)
        .await
        .expect("Failed to place order");

    let response = match response {
        Response::Ok(order) => order,
        Response::Err(error) => panic!("Failed to place order: {:?}", error),
    };

    let data = &response.data.unwrap();
    let status = match data {
        StatusType::Statuses(statuses) => &statuses[0],
        _ => {
            panic!("Failed to place order: {:?}", data);
        }
    };

    let oid = match status {
        Status::Filled(order) => order.oid,
        Status::Resting(order) => order.oid,
        _ => panic!("Order is not filled or resting"),
    };

    println!("Order placed: {:?}", oid);

    tokio::time::sleep(std::time::Duration::from_secs(5)).await;

    println!("Cancelling order with cloid: {}", cloid.simple());
    let cancel = CancelByCloidRequest { asset: 4, cloid };

    let response = exchange
        .cancel_order_by_cloid(wallet.clone(), vec![cancel], vault_address)
        .await
        .expect("Failed to cancel order");

    println!("Response: {:?}", response);
}
source

pub async fn cancel_order( &self, wallet: Arc<LocalWallet>, cancels: Vec<CancelRequest>, vault_address: Option<Address> ) -> Result<Response>

Cancel an order

§Arguments
  • wallet - The wallet to sign the order with
  • cancels - The orders to cancel
  • vault_address - If trading on behalf of a vault, its onchain address in 42-character hexadecimal format e.g. 0x0000000000000000000000000000000000000000
Examples found in repository?
examples/cancel-order.rs (line 81)
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
async fn main() {
    // Key was randomly generated for testing and shouldn't be used with any real funds
    let wallet: Arc<LocalWallet> = Arc::new(
        "e908f86dbb4d55ac876378565aafeabc187f6690f046459397b17d9b9a19688e"
            .parse()
            .unwrap(),
    );

    let exchange: Exchange = Hyperliquid::new(Chain::Dev);

    let order_type = OrderType::Limit(Limit { tif: Tif::Gtc });

    let order = OrderRequest {
        asset: 4,
        is_buy: true,
        reduce_only: false,
        limit_px: "1800".to_string(),
        sz: "0.1".to_string(),
        order_type,
        cloid: None,
    };

    let vault_address = None;

    println!("Placing order...");
    let response = exchange
        .place_order(wallet.clone(), vec![order], vault_address)
        .await
        .expect("Failed to place order");

    let response = match response {
        Response::Ok(order) => order,
        Response::Err(error) => panic!("Failed to place order: {:?}", error),
    };

    let status_type = &response.data.unwrap();

    let status = match status_type {
        StatusType::Statuses(statuses) => &statuses[0],
        _ => {
            panic!("Failed to place order: {:?}", status_type);
        }
    };

    let oid = match status {
        Status::Filled(order) => order.oid,
        Status::Resting(order) => order.oid,
        _ => {
            panic!("Order is not filled or resting, status: {:?}", status);
        }
    };

    println!("Order placed: {:?}", oid);

    tokio::time::sleep(std::time::Duration::from_secs(5)).await;

    // Cancel order

    println!("Cancelling order with oid {oid}.");
    let cancel = CancelRequest { asset: 4, oid };

    let vault_address = None;

    let response = exchange
        .cancel_order(wallet.clone(), vec![cancel], vault_address)
        .await
        .expect("Failed to cancel order");

    println!("Response: {:?}", response);

    let cloid = Uuid::new_v4();

    println!("Placing order with cloid: {}", cloid.simple());

    let order_type = OrderType::Limit(Limit { tif: Tif::Gtc });

    let order = OrderRequest {
        asset: 4,
        is_buy: true,
        reduce_only: false,
        limit_px: "1700".to_string(),
        sz: "0.1".to_string(),
        order_type,
        cloid: Some(cloid),
    };

    let vault_address = None;

    let response = exchange
        .place_order(wallet.clone(), vec![order], vault_address)
        .await
        .expect("Failed to place order");

    let response = match response {
        Response::Ok(order) => order,
        Response::Err(error) => panic!("Failed to place order: {:?}", error),
    };

    let data = &response.data.unwrap();
    let status = match data {
        StatusType::Statuses(statuses) => &statuses[0],
        _ => {
            panic!("Failed to place order: {:?}", data);
        }
    };

    let oid = match status {
        Status::Filled(order) => order.oid,
        Status::Resting(order) => order.oid,
        _ => panic!("Order is not filled or resting"),
    };

    println!("Order placed: {:?}", oid);

    tokio::time::sleep(std::time::Duration::from_secs(5)).await;

    println!("Cancelling order with cloid: {}", cloid.simple());
    let cancel = CancelByCloidRequest { asset: 4, cloid };

    let response = exchange
        .cancel_order_by_cloid(wallet.clone(), vec![cancel], vault_address)
        .await
        .expect("Failed to cancel order");

    println!("Response: {:?}", response);
}
source

pub async fn cancel_order_by_cloid( &self, wallet: Arc<LocalWallet>, cancels: Vec<CancelByCloidRequest>, vault_address: Option<Address> ) -> Result<Response>

Cancel order(s) by client order id (cloid)

§Arguments
  • wallet - The wallet to sign the order with
  • cancels - The client orders to cancel
  • vault_address - If trading on behalf of a vault, its onchain address in 42-character hexadecimal format e.g. 0x0000000000000000000000000000000000000000

Note: cloid in argument cancel is a 128 bit hex string, e.g. 0x1234567890abcdef1234567890abcdef

Examples found in repository?
examples/cancel-order.rs (line 137)
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
async fn main() {
    // Key was randomly generated for testing and shouldn't be used with any real funds
    let wallet: Arc<LocalWallet> = Arc::new(
        "e908f86dbb4d55ac876378565aafeabc187f6690f046459397b17d9b9a19688e"
            .parse()
            .unwrap(),
    );

    let exchange: Exchange = Hyperliquid::new(Chain::Dev);

    let order_type = OrderType::Limit(Limit { tif: Tif::Gtc });

    let order = OrderRequest {
        asset: 4,
        is_buy: true,
        reduce_only: false,
        limit_px: "1800".to_string(),
        sz: "0.1".to_string(),
        order_type,
        cloid: None,
    };

    let vault_address = None;

    println!("Placing order...");
    let response = exchange
        .place_order(wallet.clone(), vec![order], vault_address)
        .await
        .expect("Failed to place order");

    let response = match response {
        Response::Ok(order) => order,
        Response::Err(error) => panic!("Failed to place order: {:?}", error),
    };

    let status_type = &response.data.unwrap();

    let status = match status_type {
        StatusType::Statuses(statuses) => &statuses[0],
        _ => {
            panic!("Failed to place order: {:?}", status_type);
        }
    };

    let oid = match status {
        Status::Filled(order) => order.oid,
        Status::Resting(order) => order.oid,
        _ => {
            panic!("Order is not filled or resting, status: {:?}", status);
        }
    };

    println!("Order placed: {:?}", oid);

    tokio::time::sleep(std::time::Duration::from_secs(5)).await;

    // Cancel order

    println!("Cancelling order with oid {oid}.");
    let cancel = CancelRequest { asset: 4, oid };

    let vault_address = None;

    let response = exchange
        .cancel_order(wallet.clone(), vec![cancel], vault_address)
        .await
        .expect("Failed to cancel order");

    println!("Response: {:?}", response);

    let cloid = Uuid::new_v4();

    println!("Placing order with cloid: {}", cloid.simple());

    let order_type = OrderType::Limit(Limit { tif: Tif::Gtc });

    let order = OrderRequest {
        asset: 4,
        is_buy: true,
        reduce_only: false,
        limit_px: "1700".to_string(),
        sz: "0.1".to_string(),
        order_type,
        cloid: Some(cloid),
    };

    let vault_address = None;

    let response = exchange
        .place_order(wallet.clone(), vec![order], vault_address)
        .await
        .expect("Failed to place order");

    let response = match response {
        Response::Ok(order) => order,
        Response::Err(error) => panic!("Failed to place order: {:?}", error),
    };

    let data = &response.data.unwrap();
    let status = match data {
        StatusType::Statuses(statuses) => &statuses[0],
        _ => {
            panic!("Failed to place order: {:?}", data);
        }
    };

    let oid = match status {
        Status::Filled(order) => order.oid,
        Status::Resting(order) => order.oid,
        _ => panic!("Order is not filled or resting"),
    };

    println!("Order placed: {:?}", oid);

    tokio::time::sleep(std::time::Duration::from_secs(5)).await;

    println!("Cancelling order with cloid: {}", cloid.simple());
    let cancel = CancelByCloidRequest { asset: 4, cloid };

    let response = exchange
        .cancel_order_by_cloid(wallet.clone(), vec![cancel], vault_address)
        .await
        .expect("Failed to cancel order");

    println!("Response: {:?}", response);
}
source

pub async fn modify_order( &self, wallet: Arc<LocalWallet>, order: ModifyRequest, vault_address: Option<Address> ) -> Result<Response>

Modify an order

§Arguments
  • wallet - The wallet to sign the order with
  • order - The orders to modify
  • vault_address - If trading on behalf of a vault, its onchain address in 42-character hexadecimal format e.g. 0x0000000000000000000000000000000000000000

Note: cloid in argument order is an optional 128 bit hex string, e.g. 0x1234567890abcdef1234567890abcdef

Examples found in repository?
examples/modify-order.rs (line 89)
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
async fn main() {
    // Key was randomly generated for testing and shouldn't be used with any real funds
    let wallet: Arc<LocalWallet> = Arc::new(
        "e908f86dbb4d55ac876378565aafeabc187f6690f046459397b17d9b9a19688e"
            .parse()
            .unwrap(),
    );

    let exchange: Exchange = Hyperliquid::new(Chain::Dev);

    let order_type = OrderType::Limit(Limit { tif: Tif::Gtc });
    let cloid = Uuid::new_v4();

    let order = OrderRequest {
        asset: 4,
        is_buy: true,
        reduce_only: false,
        limit_px: "1800".to_string(),
        sz: "0.1".to_string(),
        order_type,
        cloid: Some(cloid),
    };

    let vault_address = None;

    println!("Placing order...");
    let response = exchange
        .place_order(wallet.clone(), vec![order], vault_address)
        .await
        .expect("Failed to place order");

    let response = match response {
        Response::Ok(order) => order,
        Response::Err(error) => panic!("Failed to place order: {:?}", error),
    };

    let status_type = &response.data.unwrap();

    let status = match status_type {
        StatusType::Statuses(statuses) => &statuses[0],
        _ => {
            panic!("Failed to place order: {:?}", status_type);
        }
    };

    let oid = match status {
        Status::Filled(order) => order.oid,
        Status::Resting(order) => order.oid,
        _ => panic!("Order is not filled or resting"),
    };

    println!("Order placed: {:?}", oid);

    tokio::time::sleep(std::time::Duration::from_secs(5)).await;

    let limit_px = "1710".to_string();
    // Modifying the order
    println!("Modifying order {oid} limit price to {limit_px}.");

    let order = OrderRequest {
        asset: 4,
        is_buy: true,
        reduce_only: false,
        limit_px,
        sz: "0.1".to_string(),
        order_type: OrderType::Limit(Limit { tif: Tif::Gtc }),
        cloid: Some(cloid),
    };

    let order = ModifyRequest { order, oid };

    let response = exchange
        .modify_order(wallet.clone(), order, vault_address)
        .await
        .expect("Failed to modify order");

    println!("Response: {:?}", response);
}
source

pub async fn batch_modify_orders( &self, wallet: Arc<LocalWallet>, orders: Vec<ModifyRequest>, vault_address: Option<Address> ) -> Result<Response>

Batch modify orders

§Arguments
  • wallet - The wallet to sign the order with
  • orders - The orders to modify
  • vault_address - If trading on behalf of a vault, its onchain address in 42-character hexadecimal format e.g. 0x0000000000000000000000000000000000000000
source

pub async fn update_leverage( &self, wallet: Arc<LocalWallet>, leverage: u32, asset: u32, is_cross: bool ) -> Result<Response>

Update cross or isolated leverage on a coin

§Arguments
  • wallet - The wallet to sign the order with
  • leverage - The new leverage to set
  • asset - The asset to set the leverage for
  • is_cross - true if cross leverage, false if isolated leverage
Examples found in repository?
examples/leverage.rs (line 24)
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
async fn main() {
    // Key was randomly generated for testing and shouldn't be used with any real funds
    let wallet: Arc<LocalWallet> = Arc::new(
        "e908f86dbb4d55ac876378565aafeabc187f6690f046459397b17d9b9a19688e"
            .parse()
            .unwrap(),
    );

    let exchange: Exchange = Hyperliquid::new(Chain::Dev);

    let leverage = 2;
    let asset = 4;
    let is_cross = false;

    println!("Updating leverage to {}x ...", leverage);

    let res = exchange
        .update_leverage(wallet.clone(), leverage, asset, is_cross)
        .await
        .unwrap();

    println!("Response: {:?}", res);

    let margin = 1;

    println!("--\nUpdating isolated margin for ETH to {margin}% ...");

    let res = exchange
        .update_isolated_margin(wallet.clone(), margin, asset)
        .await
        .unwrap();

    println!("Response: {:?}", res);

    let info: Info = Hyperliquid::new(Chain::Dev);

    // user state
    let res = info.user_state(wallet.address()).await.unwrap();

    println!("--\nUser state: {:?}", res);
}
source

pub async fn update_isolated_margin( &self, wallet: Arc<LocalWallet>, margin: i64, asset: u32 ) -> Result<Response>

Add or remove margin from isolated position

§Arguments
  • wallet - The wallet to sign the order with
  • margin - The new margin to set
  • asset - The asset to set the margin for
Examples found in repository?
examples/leverage.rs (line 35)
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
async fn main() {
    // Key was randomly generated for testing and shouldn't be used with any real funds
    let wallet: Arc<LocalWallet> = Arc::new(
        "e908f86dbb4d55ac876378565aafeabc187f6690f046459397b17d9b9a19688e"
            .parse()
            .unwrap(),
    );

    let exchange: Exchange = Hyperliquid::new(Chain::Dev);

    let leverage = 2;
    let asset = 4;
    let is_cross = false;

    println!("Updating leverage to {}x ...", leverage);

    let res = exchange
        .update_leverage(wallet.clone(), leverage, asset, is_cross)
        .await
        .unwrap();

    println!("Response: {:?}", res);

    let margin = 1;

    println!("--\nUpdating isolated margin for ETH to {margin}% ...");

    let res = exchange
        .update_isolated_margin(wallet.clone(), margin, asset)
        .await
        .unwrap();

    println!("Response: {:?}", res);

    let info: Info = Hyperliquid::new(Chain::Dev);

    // user state
    let res = info.user_state(wallet.address()).await.unwrap();

    println!("--\nUser state: {:?}", res);
}
source

pub async fn twap_order( &self, wallet: Arc<LocalWallet>, twap: TwapRequest, vault_address: Option<Address> ) -> Result<Response>

Place a TWAP order

§Arguments
  • wallet - The wallet to sign the order with
  • twap - The twap order to place
  • vault_address - If trading on behalf of a vault, its onchain address in 42-character hexadecimal format e.g. 0x0000000000000000000000000000000000000000
Examples found in repository?
examples/twap-order.rs (line 37)
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
async fn main() {
    // Key was randomly generated for testing and shouldn't be used with any real funds
    let wallet: Arc<LocalWallet> = Arc::new(
        "e908f86dbb4d55ac876378565aafeabc187f6690f046459397b17d9b9a19688e"
            .parse()
            .unwrap(),
    );

    let exchange: Exchange = Hyperliquid::new(Chain::Dev);

    let asset = 0;
    let sz_decimals = 2;

    let twap = TwapRequest {
        asset,
        is_buy: true,
        reduce_only: false,
        duration: 10,
        sz: parse_size(13.85, sz_decimals),
        randomize: true,
    };

    let vault_address = None;

    println!("Placing a TWAP order...");
    let response = exchange
        .twap_order(wallet.clone(), twap, vault_address)
        .await
        .expect("Failed to place twap order");

    println!("Response: {:?}", response);
}
source

pub async fn usdc_transfer( &self, from: Arc<LocalWallet>, destination: Address, amount: String ) -> Result<Response>

Send usd to another address. This transfer does not touch the EVM bridge. The signature format is human readable for wallet interfaces.

§Arguments
  • from - The wallet to sign the transfer with
  • destination - The address to send the usd to
  • amount - The amount of usd to send
Examples found in repository?
examples/usd_transfer.rs (line 31)
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
async fn main() {
    // Key was randomly generated for testing and shouldn't be used with any real funds
    let wallet: Arc<LocalWallet> = Arc::new(
        "e908f86dbb4d55ac876378565aafeabc187f6690f046459397b17d9b9a19688e"
            .parse()
            .unwrap(),
    );

    let exchange: Exchange = Hyperliquid::new(Chain::ArbitrumTestnet);

    let destination = "0x0D1d9635D0640821d15e323ac8AdADfA9c111414"
        .parse()
        .expect("Invalid address");

    let amount = "1".to_string(); // USD

    println!(
        "Transferring ${} from {:?} to {:?}",
        amount,
        wallet.address(),
        destination
    );

    let res = exchange
        .usdc_transfer(wallet.clone(), destination, amount)
        .await
        .unwrap();

    println!("Response: {:?}", res);
}
source

pub async fn withdraw_from_bridge( &self, wallet: Arc<LocalWallet>, destination: Address, usd: String ) -> Result<Response>

Withdraw from bridge

§Arguments
  • wallet - The wallet to sign the withdrawal with
  • destination - The address to send the usd to
  • usd - The amount of usd to send
Examples found in repository?
examples/bridge.rs (line 26)
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
async fn main() {
    // Key was randomly generated for testing and shouldn't be used with any real funds
    let wallet: Arc<LocalWallet> = Arc::new(
        "8547bf37e4ac35e85d1e8afc2a2ba5c7f352b8a11ae916e9f14737737e8e0e47"
            .parse()
            .unwrap(),
    );

    let exchange: Exchange = Hyperliquid::new(Chain::ArbitrumGoerli);

    let destination = "0x0D1d9635D0640821d15e323ac8AdADfA9c111414"
        .parse()
        .expect("Invalid address");

    let usd = "10".to_string(); // USD

    println!("Withdrawing ${} from bridge to {:?}", usd, destination);

    let res = exchange
        .withdraw_from_bridge(wallet.clone(), destination, usd)
        .await
        .unwrap();

    println!("Response: {:?}", res);
}
source

pub async fn approve_agent( &self, wallet: Arc<LocalWallet>, agent_address: Address, extra_agent_name: Option<String> ) -> Result<Response>

Approve an agent to trade on behalf of the user

§Arguments
  • wallet - The wallet to sign the approval with
  • agent_address - The address of the agent to approve
  • extra_agent_name - An optional name for the agent
Examples found in repository?
examples/agent.rs (line 40)
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
async fn main() {
    // Key was randomly generated for testing and shouldn't be used with any real funds
    let wallet: Arc<LocalWallet> = Arc::new(
        "e908f86dbb4d55ac876378565aafeabc187f6690f046459397b17d9b9a19688e"
            .parse()
            .unwrap(),
    );

    let exchange: Exchange = Hyperliquid::new(Chain::ArbitrumTestnet);

    // Create a new wallet with the agent. This agent can't transfer or withdraw funds
    // but can place orders.

    let agent = LocalWallet::new(&mut thread_rng());

    let agent_address = agent.address();

    println!("Agent address: {:?}", agent_address);

    let res = exchange
        .approve_agent(wallet.clone(), agent_address, Some("WETH".to_string()))
        .await
        .unwrap();

    println!("Response: {:?}", res);

    // place order with agent
    let order_type = OrderType::Limit(Limit { tif: Tif::Gtc });
    let order = OrderRequest {
        asset: 4,
        is_buy: true,
        reduce_only: false,
        limit_px: "1700".to_string(),
        sz: "0.1".to_string(),
        order_type,
        cloid: None,
    };
    let vault_address = None;

    println!("Placing order with agent...");

    let response = exchange
        .place_order(wallet.clone(), vec![order], vault_address)
        .await
        .expect("Failed to place order");

    println!("Response: {:?}", response);
}
source

pub async fn withdraw( &self, from: Arc<LocalWallet>, usd: String ) -> Result<Response>

Initiate a withdrawal request

§Arguments
  • from - The wallet to sign the withdrawal with
  • usd - The amount of usd to send
source

pub async fn create_subaccount( &self, wallet: Arc<LocalWallet>, name: String ) -> Result<Response>

Create subaccount for the user

§Arguments
  • wallet - The wallet to create the subaccount with
  • name - The name of the subaccount
source

pub async fn subaccount_transfer() -> Result<Response>

Transfer funds between subaccounts

§Arguments
  • wallet - The wallet to sign the transfer with
  • from - The subaccount to transfer from
source

pub async fn set_referrer( &self, wallet: Arc<LocalWallet>, code: String ) -> Result<Response>

Set referrer for the user

§Arguments
  • wallet - The wallet to sign the transfer with
  • code - The referrer code
source

pub async fn schedule_cancel( &self, wallet: Arc<LocalWallet>, time: Option<u64> ) -> Result<Response>

Schedule a time in (UTC ms) to cancel all open orders

§Arguments
  • wallet - The wallet to sign the transaction with
  • time - Optional time in milliseconds to cancel all open orders
§Note
  • If time is None, then unsets any cancel time in the future. time must be atleast 5 seconds after the current time
  • Once the time is reached, all open orders will be cancelled and trigger count will be incremented. The max number of triggers is 10 per day. Trigger count resets at 00:00 UTC

Trait Implementations§

source§

impl Hyperliquid for Exchange

source§

fn new(chain: Chain) -> Self

source§

fn new_with_config(chain: Chain, config: &Config) -> Self

Auto Trait Implementations§

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> Conv for T

source§

fn conv<T>(self) -> T
where Self: Into<T>,

Converts self into T using Into<T>. Read more
source§

impl<T> FmtForward for T

source§

fn fmt_binary(self) -> FmtBinary<Self>
where Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
source§

fn fmt_display(self) -> FmtDisplay<Self>
where Self: Display,

Causes self to use its Display implementation when Debug-formatted.
source§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where Self: LowerExp,

Causes self to use its LowerExp implementation when Debug-formatted.
source§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where Self: LowerHex,

Causes self to use its LowerHex implementation when Debug-formatted.
source§

fn fmt_octal(self) -> FmtOctal<Self>
where Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
source§

fn fmt_pointer(self) -> FmtPointer<Self>
where Self: Pointer,

Causes self to use its Pointer implementation when Debug-formatted.
source§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where Self: UpperExp,

Causes self to use its UpperExp implementation when Debug-formatted.
source§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where Self: UpperHex,

Causes self to use its UpperHex implementation when Debug-formatted.
source§

fn fmt_list(self) -> FmtList<Self>
where &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> Pipe for T
where T: ?Sized,

source§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
source§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
source§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
source§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where Self: Borrow<B>, B: 'a + ?Sized, R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
source§

fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R ) -> R
where Self: BorrowMut<B>, B: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe function. Read more
source§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where Self: AsRef<U>, U: 'a + ?Sized, R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
source§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where Self: AsMut<U>, U: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe function.
source§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where Self: Deref<Target = T>, T: 'a + ?Sized, R: 'a,

Borrows self, then passes self.deref() into the pipe function.
source§

fn pipe_deref_mut<'a, T, R>( &'a mut self, func: impl FnOnce(&'a mut T) -> R ) -> R
where Self: DerefMut<Target = T> + Deref, T: 'a + ?Sized, R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe function.
source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T> Tap for T

source§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
source§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
source§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
source§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
source§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
source§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
source§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
source§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
source§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
source§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release builds.
source§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where Self: Borrow<B>, B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release builds.
source§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where Self: BorrowMut<B>, B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release builds.
source§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where Self: AsRef<R>, R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release builds.
source§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where Self: AsMut<R>, R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release builds.
source§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where Self: Deref<Target = T>, T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release builds.
source§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where Self: DerefMut<Target = T> + Deref, T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release builds.
source§

impl<T> TryConv for T

source§

fn try_conv<T>(self) -> Result<T, Self::Error>
where Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

source§

fn vzip(self) -> V

source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
source§

impl<T> JsonSchemaMaybe for T