pub struct BulkHttpClient { /* private fields */ }Expand description
HTTP REST API client for Bulk Labs exchange.
Supports both public (unsigned) and private (signed) endpoints.
Construct with None for read-only access or provide a private key
for trading operations.
Implementations§
Source§impl BulkHttpClient
impl BulkHttpClient
Sourcepub fn new(config: &HttpConfig) -> Result<Self>
pub fn new(config: &HttpConfig) -> Result<Self>
Examples found in repository?
31async fn main() -> eyre::Result<()> {
32 tracing_subscriber::fmt()
33 .with_env_filter(
34 EnvFilter::from_default_env().add_directive(tracing::Level::INFO.into())
35 )
36 .init();
37
38 let args = Args::parse();
39
40 info!("Connecting to {} for account: {:?}", args.url, args.account);
41 let client = BulkHttpClient::new(&HttpConfig {
42 base_url: args.url,
43 signer: None,
44 ..Default::default()
45 });
46
47 let addr = Pubkey::from_str(args.account.as_str())?;
48 let account = client?.get_account(addr).await;
49
50 eprintln!("account: {:?}", account);
51 process::exit(0);
52}More examples
31async fn main() -> eyre::Result<()> {
32 tracing_subscriber::fmt()
33 .with_env_filter(
34 EnvFilter::from_default_env().add_directive(tracing::Level::INFO.into())
35 )
36 .init();
37
38 let args = Args::parse();
39
40 info!("Connecting to {} for symbol: {:?}", args.url, args.symbol);
41 let client = BulkHttpClient::new(&HttpConfig {
42 base_url: args.url,
43 signer: None,
44 ..Default::default()
45 }).unwrap();
46
47 let book = client.get_orderbook(&args.symbol, None, None).await?;
48 eprintln!("book: {:?}\n", book);
49
50 let ticker = client.get_ticker(&args.symbol).await?;
51 eprintln!("ticker: {:?}\n", ticker);
52
53 let markets = client.get_exchange_info().await?;
54 eprintln!("markets: {:?}\n", markets);
55
56 process::exit(0);
57}33async fn main() -> eyre::Result<()> {
34 tracing_subscriber::fmt()
35 .with_env_filter(
36 EnvFilter::from_default_env().add_directive(tracing::Level::INFO.into())
37 )
38 .init();
39
40 let args = Args::parse();
41
42 info!("Connecting to {} for execution", args.url);
43 let key = env::var("BULK_PRIVATE_KEY")?;
44 let signer = TransactionSigner::from_private_key(key.as_str())?;
45 let client = BulkHttpClient::new(&HttpConfig {
46 base_url: args.url,
47 signer: Some(signer.clone()),
48 ..Default::default()
49 }).unwrap();
50
51 let account = if false {
52 Pubkey::from_str("8oqBACkDvyJjBoiWNbZPXrnjZvFjzUjMThbi9oahAVvH")?
53 } else {
54 signer.public_key()
55 };
56 let nonce = 1776682154418;
57
58 let mut orders = vec![
59 Action::TakeProfit(StopOrTP {
60 symbol: Arc::from("BTC-USD"),
61 is_above: false,
62 size: 0.480894,
63 threshold: 40000.0,
64 limit: None,
65 meta: ActionMeta {
66 account,
67 nonce,
68 seqno: 0,
69 hash: None,
70 }
71 }),
72 ];
73
74 let results = client.place_tx(orders, Some(account), Some(nonce)).await?;
75 eprintln!("results: {:?}\n", results);
76
77 process::exit(0);
78}30async fn main() -> eyre::Result<()> {
31 tracing_subscriber::fmt()
32 .with_env_filter(
33 EnvFilter::from_default_env().add_directive(tracing::Level::INFO.into())
34 )
35 .init();
36
37 let args = Args::parse();
38
39 info!("Connecting to {} for execution", args.url);
40 let key = env::var("BULK_PRIVATE_KEY")?;
41 let signer = TransactionSigner::from_private_key(key.as_str())?;
42 let client = BulkHttpClient::new(&HttpConfig {
43 base_url: args.url,
44 signer: Some(signer.clone()),
45 ..Default::default()
46 }).unwrap();
47
48 let account = signer.public_key();
49 let nonce = make_nonce();
50
51 let mut orders = vec![
52 Action::LimitOrder(LimitOrder {
53 symbol: Arc::from("BTC-USD"),
54 is_buy: true,
55 price: 1000.0,
56 size: 0.0001,
57 tif: TimeInForce::IOC,
58 reduce_only: false,
59 iso: false,
60 meta: ActionMeta {
61 account,
62 nonce,
63 seqno: 0,
64 hash: None,
65 }
66 }),
67 Action::LimitOrder(LimitOrder {
68 symbol: Arc::from("ETH-USD"),
69 is_buy: true,
70 price: 1000.0,
71 size: 0.0001,
72 tif: TimeInForce::IOC,
73 reduce_only: false,
74 iso: false,
75 meta: ActionMeta {
76 account,
77 nonce,
78 seqno: 1,
79 hash: None,
80 }
81 }),
82 ];
83
84 let oids = orders.iter_mut()
85 .map(|o| o.hash().to_string())
86 .collect::<Vec<_>>();
87
88 eprintln!("order IDs: {:?}", oids);
89
90 let results = client.place_tx(orders, Some(account), Some(nonce)).await?;
91 eprintln!("results: {:?}\n", results);
92
93 process::exit(0);
94}Sourcepub fn with_url(base_url: &str, private_key: Option<&str>) -> Result<Self>
pub fn with_url(base_url: &str, private_key: Option<&str>) -> Result<Self>
Create bulk HTTP client with url, private key
§Arguments
base_url: http client urlprivate_key: optional private key
Sourcepub fn config(&self) -> &HttpConfig
pub fn config(&self) -> &HttpConfig
Channel configuration
Sourcepub fn public_key(&self) -> Option<Pubkey>
pub fn public_key(&self) -> Option<Pubkey>
Pubkeyt associated with this channel
Sourcepub async fn get_exchange_info(&self) -> Result<Vec<MarketInfo>>
pub async fn get_exchange_info(&self) -> Result<Vec<MarketInfo>>
Get exchange information including all available markets.
Examples found in repository?
31async fn main() -> eyre::Result<()> {
32 tracing_subscriber::fmt()
33 .with_env_filter(
34 EnvFilter::from_default_env().add_directive(tracing::Level::INFO.into())
35 )
36 .init();
37
38 let args = Args::parse();
39
40 info!("Connecting to {} for symbol: {:?}", args.url, args.symbol);
41 let client = BulkHttpClient::new(&HttpConfig {
42 base_url: args.url,
43 signer: None,
44 ..Default::default()
45 }).unwrap();
46
47 let book = client.get_orderbook(&args.symbol, None, None).await?;
48 eprintln!("book: {:?}\n", book);
49
50 let ticker = client.get_ticker(&args.symbol).await?;
51 eprintln!("ticker: {:?}\n", ticker);
52
53 let markets = client.get_exchange_info().await?;
54 eprintln!("markets: {:?}\n", markets);
55
56 process::exit(0);
57}Sourcepub async fn get_ticker(&self, symbol: &str) -> Result<Ticker>
pub async fn get_ticker(&self, symbol: &str) -> Result<Ticker>
Get market ticker/statistics for a symbol.
Examples found in repository?
31async fn main() -> eyre::Result<()> {
32 tracing_subscriber::fmt()
33 .with_env_filter(
34 EnvFilter::from_default_env().add_directive(tracing::Level::INFO.into())
35 )
36 .init();
37
38 let args = Args::parse();
39
40 info!("Connecting to {} for symbol: {:?}", args.url, args.symbol);
41 let client = BulkHttpClient::new(&HttpConfig {
42 base_url: args.url,
43 signer: None,
44 ..Default::default()
45 }).unwrap();
46
47 let book = client.get_orderbook(&args.symbol, None, None).await?;
48 eprintln!("book: {:?}\n", book);
49
50 let ticker = client.get_ticker(&args.symbol).await?;
51 eprintln!("ticker: {:?}\n", ticker);
52
53 let markets = client.get_exchange_info().await?;
54 eprintln!("markets: {:?}\n", markets);
55
56 process::exit(0);
57}Sourcepub async fn get_klines(
&self,
symbol: &str,
interval: &str,
start_time: Option<u64>,
end_time: Option<u64>,
limit: Option<u32>,
) -> Result<Vec<Candle>>
pub async fn get_klines( &self, symbol: &str, interval: &str, start_time: Option<u64>, end_time: Option<u64>, limit: Option<u32>, ) -> Result<Vec<Candle>>
Get historical candlestick/OHLCV data.
§Arguments
symbol: Market symbol (e.g. “BTC-USD”)interval: Candle interval (“1m”, “5m”, “15m”, “30m”, “1h”, “4h”, “1d”, “1w”)start_time: Optional start timestamp in millisecondsend_time: Optional end timestamp in millisecondslimit: Maximum candles to return (default 500, max 1000)
Sourcepub async fn get_orderbook(
&self,
symbol: &str,
nlevels: Option<u32>,
aggregation: Option<f64>,
) -> Result<L2Snapshot>
pub async fn get_orderbook( &self, symbol: &str, nlevels: Option<u32>, aggregation: Option<f64>, ) -> Result<L2Snapshot>
Get L2 order book snapshot.
§Arguments
symbol: Market symbolnlevels: Number of price levels per side (default 20, max 1000)aggregation: Optional price aggregation/grouping
Examples found in repository?
31async fn main() -> eyre::Result<()> {
32 tracing_subscriber::fmt()
33 .with_env_filter(
34 EnvFilter::from_default_env().add_directive(tracing::Level::INFO.into())
35 )
36 .init();
37
38 let args = Args::parse();
39
40 info!("Connecting to {} for symbol: {:?}", args.url, args.symbol);
41 let client = BulkHttpClient::new(&HttpConfig {
42 base_url: args.url,
43 signer: None,
44 ..Default::default()
45 }).unwrap();
46
47 let book = client.get_orderbook(&args.symbol, None, None).await?;
48 eprintln!("book: {:?}\n", book);
49
50 let ticker = client.get_ticker(&args.symbol).await?;
51 eprintln!("ticker: {:?}\n", ticker);
52
53 let markets = client.get_exchange_info().await?;
54 eprintln!("markets: {:?}\n", markets);
55
56 process::exit(0);
57}Sourcepub async fn get_account(&self, user: Pubkey) -> Result<AccountData>
pub async fn get_account(&self, user: Pubkey) -> Result<AccountData>
Get complete account state including positions, orders, and margin.
§Arguments
user: user pubkey to query
Examples found in repository?
31async fn main() -> eyre::Result<()> {
32 tracing_subscriber::fmt()
33 .with_env_filter(
34 EnvFilter::from_default_env().add_directive(tracing::Level::INFO.into())
35 )
36 .init();
37
38 let args = Args::parse();
39
40 info!("Connecting to {} for account: {:?}", args.url, args.account);
41 let client = BulkHttpClient::new(&HttpConfig {
42 base_url: args.url,
43 signer: None,
44 ..Default::default()
45 });
46
47 let addr = Pubkey::from_str(args.account.as_str())?;
48 let account = client?.get_account(addr).await;
49
50 eprintln!("account: {:?}", account);
51 process::exit(0);
52}Sourcepub async fn get_open_orders(&self, user: &str) -> Result<Vec<OrderState>>
pub async fn get_open_orders(&self, user: &str) -> Result<Vec<OrderState>>
Sourcepub async fn get_position_history(
&self,
user: &str,
) -> Result<Vec<PositionInfo>>
pub async fn get_position_history( &self, user: &str, ) -> Result<Vec<PositionInfo>>
Sourcepub async fn place_tx(
&self,
actions: Vec<Action>,
account: Option<Pubkey>,
nonce: Option<u64>,
) -> Result<Vec<Response>>
pub async fn place_tx( &self, actions: Vec<Action>, account: Option<Pubkey>, nonce: Option<u64>, ) -> Result<Vec<Response>>
Place multiple order actions in a single signed transaction.
Accepts any mix of limit orders, market orders, cancels, and cancel-alls.
§Example
let resp = client.place_tx(vec![
Action::LimitOrder(LimitOrder { .. }),
Action::CancelAll(CancelAll { .. }),
], None, None).await?;Examples found in repository?
33async fn main() -> eyre::Result<()> {
34 tracing_subscriber::fmt()
35 .with_env_filter(
36 EnvFilter::from_default_env().add_directive(tracing::Level::INFO.into())
37 )
38 .init();
39
40 let args = Args::parse();
41
42 info!("Connecting to {} for execution", args.url);
43 let key = env::var("BULK_PRIVATE_KEY")?;
44 let signer = TransactionSigner::from_private_key(key.as_str())?;
45 let client = BulkHttpClient::new(&HttpConfig {
46 base_url: args.url,
47 signer: Some(signer.clone()),
48 ..Default::default()
49 }).unwrap();
50
51 let account = if false {
52 Pubkey::from_str("8oqBACkDvyJjBoiWNbZPXrnjZvFjzUjMThbi9oahAVvH")?
53 } else {
54 signer.public_key()
55 };
56 let nonce = 1776682154418;
57
58 let mut orders = vec![
59 Action::TakeProfit(StopOrTP {
60 symbol: Arc::from("BTC-USD"),
61 is_above: false,
62 size: 0.480894,
63 threshold: 40000.0,
64 limit: None,
65 meta: ActionMeta {
66 account,
67 nonce,
68 seqno: 0,
69 hash: None,
70 }
71 }),
72 ];
73
74 let results = client.place_tx(orders, Some(account), Some(nonce)).await?;
75 eprintln!("results: {:?}\n", results);
76
77 process::exit(0);
78}More examples
30async fn main() -> eyre::Result<()> {
31 tracing_subscriber::fmt()
32 .with_env_filter(
33 EnvFilter::from_default_env().add_directive(tracing::Level::INFO.into())
34 )
35 .init();
36
37 let args = Args::parse();
38
39 info!("Connecting to {} for execution", args.url);
40 let key = env::var("BULK_PRIVATE_KEY")?;
41 let signer = TransactionSigner::from_private_key(key.as_str())?;
42 let client = BulkHttpClient::new(&HttpConfig {
43 base_url: args.url,
44 signer: Some(signer.clone()),
45 ..Default::default()
46 }).unwrap();
47
48 let account = signer.public_key();
49 let nonce = make_nonce();
50
51 let mut orders = vec![
52 Action::LimitOrder(LimitOrder {
53 symbol: Arc::from("BTC-USD"),
54 is_buy: true,
55 price: 1000.0,
56 size: 0.0001,
57 tif: TimeInForce::IOC,
58 reduce_only: false,
59 iso: false,
60 meta: ActionMeta {
61 account,
62 nonce,
63 seqno: 0,
64 hash: None,
65 }
66 }),
67 Action::LimitOrder(LimitOrder {
68 symbol: Arc::from("ETH-USD"),
69 is_buy: true,
70 price: 1000.0,
71 size: 0.0001,
72 tif: TimeInForce::IOC,
73 reduce_only: false,
74 iso: false,
75 meta: ActionMeta {
76 account,
77 nonce,
78 seqno: 1,
79 hash: None,
80 }
81 }),
82 ];
83
84 let oids = orders.iter_mut()
85 .map(|o| o.hash().to_string())
86 .collect::<Vec<_>>();
87
88 eprintln!("order IDs: {:?}", oids);
89
90 let results = client.place_tx(orders, Some(account), Some(nonce)).await?;
91 eprintln!("results: {:?}\n", results);
92
93 process::exit(0);
94}Sourcepub async fn place_limit_order(
&self,
symbol: &str,
side: Side,
price: f64,
size: f64,
tif: TimeInForce,
reduce_only: bool,
account: Option<Pubkey>,
nonce: Option<u64>,
) -> Result<Response>
pub async fn place_limit_order( &self, symbol: &str, side: Side, price: f64, size: f64, tif: TimeInForce, reduce_only: bool, account: Option<Pubkey>, nonce: Option<u64>, ) -> Result<Response>
Place a single limit order.
Sourcepub async fn place_market_order(
&self,
symbol: &str,
side: Side,
size: f64,
reduce_only: bool,
account: Option<Pubkey>,
nonce: Option<u64>,
) -> Result<Response>
pub async fn place_market_order( &self, symbol: &str, side: Side, size: f64, reduce_only: bool, account: Option<Pubkey>, nonce: Option<u64>, ) -> Result<Response>
Place a single market order.
Sourcepub async fn cancel_order(
&self,
symbol: &str,
order_id: &str,
account: Option<Pubkey>,
nonce: Option<u64>,
) -> Result<Response>
pub async fn cancel_order( &self, symbol: &str, order_id: &str, account: Option<Pubkey>, nonce: Option<u64>, ) -> Result<Response>
Cancel a single order by ID.
Sourcepub async fn cancel_all(
&self,
symbols: Vec<String>,
account: Option<Pubkey>,
nonce: Option<u64>,
) -> Result<Response>
pub async fn cancel_all( &self, symbols: Vec<String>, account: Option<Pubkey>, nonce: Option<u64>, ) -> Result<Response>
Cancel all orders, optionally filtered by symbols.
Sourcepub async fn update_leverage(
&self,
settings: HashMap<String, f64>,
account: Option<Pubkey>,
nonce: Option<u64>,
) -> Result<Response>
pub async fn update_leverage( &self, settings: HashMap<String, f64>, account: Option<Pubkey>, nonce: Option<u64>, ) -> Result<Response>
Update maximum leverage settings for markets.
§Arguments
settings: Map of (symbol, max_leverage) pairs
Sourcepub async fn manage_agent_wallet(
&self,
agent_pubkey: Pubkey,
delete: bool,
account: Option<Pubkey>,
nonce: Option<u64>,
) -> Result<Response>
pub async fn manage_agent_wallet( &self, agent_pubkey: Pubkey, delete: bool, account: Option<Pubkey>, nonce: Option<u64>, ) -> Result<Response>
Create or delete an agent wallet authorization.
§Arguments
agent_pubkey: Agent’s public key (base58)delete:trueto remove the agent,falseto add
Sourcepub async fn whitelist_faucet(
&self,
target_account: Pubkey,
whitelist: bool,
account: Option<Pubkey>,
nonce: Option<u64>,
) -> Result<Response>
pub async fn whitelist_faucet( &self, target_account: Pubkey, whitelist: bool, account: Option<Pubkey>, nonce: Option<u64>, ) -> Result<Response>
Whitelist or unwhitelist an account for testnet faucet access.
Testnet admin only.
§Arguments
target_account: account to be whitelistedwhitelist: if true is added whitelisted, if false removednonce: tx nonce
Sourcepub async fn request_faucet(
&self,
user: Option<Pubkey>,
amount: Option<f64>,
nonce: Option<u64>,
) -> Result<Response>
pub async fn request_faucet( &self, user: Option<Pubkey>, amount: Option<f64>, nonce: Option<u64>, ) -> Result<Response>
Request testnet faucet funds.
Testnet only.
§Arguments
user: Optional target user public key (defaults to signer’s key)amount: Optional specific amount (only for whitelisted accounts)nonce: Optional nonce
Trait Implementations§
Source§impl Clone for BulkHttpClient
impl Clone for BulkHttpClient
Source§fn clone(&self) -> BulkHttpClient
fn clone(&self) -> BulkHttpClient
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more