pub struct CbClient<'a> { /* private fields */ }Expand description
Client structure performing http requests to Coinbase Advanced API
Implementations§
Source§impl<'a> CbClient<'a>
impl<'a> CbClient<'a>
Sourcepub fn new(oauth_cb_client: &'a (dyn AccessTokenProvider + 'a)) -> Self
pub fn new(oauth_cb_client: &'a (dyn AccessTokenProvider + 'a)) -> Self
Instantiate a new client.
The client is relies on an external OAuth2 Token provider. The external provider is responsible for the validity of the Access Token.
Example
// Create / get a provider implementing the [AccessTokenProvider](`basic_oauth::AccessTokenProvider`) trait.
let oauth_cb_client = basic_oauth::OAuthCbClient::new(&client_id, &client_secret, &redirect_url);
// Instantiate the client
let cb_client = client::CbClient::new(&oauth_cb_client);Examples found in repository?
7async fn main() {
8 let (client_id, client_secret, redirect_url) = utils::get_env_variables();
9 let oauth_cb_client = OAuthCbClient::new(&client_id, &client_secret, &redirect_url)
10 .add_scope("wallet:accounts:read")
11 .authorize_once()
12 .await;
13
14 let cb_client = CbClient::new(&oauth_cb_client);
15 run_list_get_accounts(&cb_client).await;
16
17 oauth_cb_client.revoke_access().await;
18}More examples
5async fn main() {
6 let (client_id, client_secret, redirect_url) = utils::get_env_variables();
7 let oauth_cb_client = OAuthCbClient::new(&client_id, &client_secret, &redirect_url)
8 .add_scope("wallet:transactions:read")
9 .authorize_once()
10 .await;
11
12 let cb_client = CbClient::new(&oauth_cb_client);
13 run_get_transactions_summary(&cb_client).await;
14
15 oauth_cb_client.revoke_access().await;
16}5async fn main() {
6 let (client_id, client_secret, redirect_url) = utils::get_env_variables();
7 let oauth_cb_client = OAuthCbClient::new(&client_id, &client_secret, &redirect_url)
8 .add_scope("wallet:buys:create")
9 .authorize_once()
10 .await;
11
12 let cb_client = CbClient::new(&oauth_cb_client);
13 // run_order_and_cancel(&cb_client).await;
14
15 run_cancel_nonexistent_order(&cb_client).await;
16
17 oauth_cb_client.revoke_access().await;
18}9async fn main() {
10 let (client_id, client_secret, redirect_url) = utils::get_env_variables();
11 let oauth_cb_client = OAuthCbClient::new(&client_id, &client_secret, &redirect_url)
12 .add_scope("wallet:transactions:read") // NOT wallet:orders:read as CB's doc says.
13 .authorize_once()
14 .await;
15
16 let cb_client = CbClient::new(&oauth_cb_client);
17 run_list_orders(&cb_client).await;
18 run_list_fills(&cb_client).await;
19
20 oauth_cb_client.revoke_access().await;
21}14async fn main() {
15 let (client_id, client_secret, redirect_url) = utils::get_env_variables();
16 let oauth_cb_client = OAuthCbClient::new(&client_id, &client_secret, &redirect_url)
17 .add_scope("wallet:user:read")
18 .authorize_once()
19 .await;
20
21 let cb_client = CbClient::new(&oauth_cb_client);
22
23 run_get_bid_ask(&cb_client).await;
24 run_get_product_book(&cb_client).await;
25 run_list_products(&cb_client).await;
26 run_get_product(&cb_client).await;
27 run_get_product_candles(&cb_client).await;
28 run_get_market_trades(&cb_client).await;
29
30 oauth_cb_client.revoke_access().await;
31}17async fn main() {
18 let (client_id, client_secret, redirect_url) = utils::get_env_variables();
19 let oauth_cb_client = OAuthCbClient::new(&client_id, &client_secret, &redirect_url)
20 .add_scope("wallet:accounts:read")
21 .add_scope("wallet:transactions:read")
22 .add_scope("wallet:user:read")
23 .authorize_once()
24 .await;
25
26 let cb_client = CbClient::new(&oauth_cb_client);
27
28 run_list_get_accounts(&cb_client).await;
29
30 run_list_orders(&cb_client).await;
31 run_list_fills(&cb_client).await;
32
33 run_get_bid_ask(&cb_client).await;
34 run_get_product_book(&cb_client).await;
35 run_list_products(&cb_client).await;
36 run_get_product(&cb_client).await;
37 run_get_product_candles(&cb_client).await;
38 run_get_market_trades(&cb_client).await;
39 run_get_transactions_summary(&cb_client).await;
40
41 oauth_cb_client.revoke_access().await;
42}Sourcepub fn list_accounts<'b>(
&'b self,
limit: Option<i32>,
cursor: Option<String>,
) -> impl Stream<Item = Result<Vec<Account>, CbError>> + 'b
pub fn list_accounts<'b>( &'b self, limit: Option<i32>, cursor: Option<String>, ) -> impl Stream<Item = Result<Vec<Account>, CbError>> + 'b
List all accounts and return a stream of account batches
limit elements per batches, starting from cursor.
cursor should be None in most cases.
Examples found in repository?
20pub async fn run_list_get_accounts(cb_client: &CbClient<'_>) {
21 let limit = Some(4);
22 let accounts_stream = cb_client.list_accounts(limit, None);
23 pin_mut!(accounts_stream);
24
25 let mut accounts = Vec::<Account>::new();
26 while let Some(account_result) = accounts_stream.next().await {
27 let partial_accounts = account_result.unwrap();
28 println!("Got {} accounts", partial_accounts.len());
29 for account in partial_accounts {
30 accounts.push(account);
31 }
32 }
33 println!("Got {} accounts in total.", accounts.len());
34
35 let account = &accounts[0];
36 let acc = cb_client.get_account(account.uuid).await.unwrap();
37 assert_eq!(account, &acc);
38}Sourcepub async fn get_account(&self, account_uuid: Uuid) -> Result<Account, CbError>
pub async fn get_account(&self, account_uuid: Uuid) -> Result<Account, CbError>
Get a Single Account by id.
A list of valid ids can be retrieve using list_accounts()
Examples found in repository?
20pub async fn run_list_get_accounts(cb_client: &CbClient<'_>) {
21 let limit = Some(4);
22 let accounts_stream = cb_client.list_accounts(limit, None);
23 pin_mut!(accounts_stream);
24
25 let mut accounts = Vec::<Account>::new();
26 while let Some(account_result) = accounts_stream.next().await {
27 let partial_accounts = account_result.unwrap();
28 println!("Got {} accounts", partial_accounts.len());
29 for account in partial_accounts {
30 accounts.push(account);
31 }
32 }
33 println!("Got {} accounts in total.", accounts.len());
34
35 let account = &accounts[0];
36 let acc = cb_client.get_account(account.uuid).await.unwrap();
37 assert_eq!(account, &acc);
38}Sourcepub async fn get_best_bid_ask(
&self,
product_ids: &Option<Vec<&str>>,
) -> Result<Vec<Pricebook>, CbError>
pub async fn get_best_bid_ask( &self, product_ids: &Option<Vec<&str>>, ) -> Result<Vec<Pricebook>, CbError>
Get the best bid/ask for all products. A subset of all products can be returned instead by using the product_ids input.
Examples found in repository?
33pub async fn run_get_bid_ask(cb_client: &CbClient<'_>) {
34 {
35 println!("============= All best bid asks =============\n");
36 let product_ids = None;
37 let pricebooks: Vec<Pricebook> = cb_client.get_best_bid_ask(&product_ids).await.unwrap();
38 println!("Found {:#?} pricebooks.", pricebooks.len());
39 }
40
41 {
42 println!("===== Best bid asks for 2 products ==========\n");
43 let product_ids = Some(vec!["OGN-BTC", "WCFG-USD"]);
44 let pricebooks: Vec<Pricebook> = cb_client.get_best_bid_ask(&product_ids).await.unwrap();
45 println!("{:#?}", pricebooks);
46 }
47}Sourcepub async fn get_product_book(
&self,
product_id: &str,
limit: Option<i32>,
) -> Result<Pricebook, CbError>
pub async fn get_product_book( &self, product_id: &str, limit: Option<i32>, ) -> Result<Pricebook, CbError>
Get a list of bids/asks for a single product. The amount of detail shown can be customized with the limit parameter.
Examples found in repository?
49pub async fn run_get_product_book(cb_client: &CbClient<'_>) {
50 {
51 let product_id = "BAT-ETH";
52 let limit = None;
53 let product_book = cb_client.get_product_book(product_id, limit).await.unwrap();
54 println!(
55 "Found {} bids and {} asks lines in the product book",
56 product_book.bids.len(),
57 product_book.asks.len()
58 );
59 }
60
61 {
62 let product_id = "BAT-ETH";
63 let limit = Some(3);
64 let product_book = cb_client.get_product_book(product_id, limit).await.unwrap();
65 println!("{:#?}", product_book);
66 }
67}Sourcepub async fn list_products(
&self,
limit: Option<i32>,
offset: Option<i32>,
product_type: Option<ProductType>,
product_ids: &Option<Vec<&str>>,
contract_expiry_type: Option<ContractExpiryType>,
) -> Result<Vec<Product>, CbError>
pub async fn list_products( &self, limit: Option<i32>, offset: Option<i32>, product_type: Option<ProductType>, product_ids: &Option<Vec<&str>>, contract_expiry_type: Option<ContractExpiryType>, ) -> Result<Vec<Product>, CbError>
Get a list of the available currency pairs for trading.
Examples found in repository?
69pub async fn run_list_products(cb_client: &CbClient<'_>) {
70 {
71 let products = cb_client
72 .list_products(Some(1), Some(763), None, &None, None)
73 .await
74 .unwrap();
75 println!("Found {:#?} products.", products.len());
76 }
77
78 {
79 let products = cb_client
80 .list_products(Some(4), Some(4), None, &None, None)
81 .await
82 .unwrap();
83 println!("Found {:#?} products.", products.len());
84 }
85
86 {
87 let product_type = Some(ProductType::Spot);
88 let products = cb_client
89 .list_products(None, None, product_type, &None, None)
90 .await
91 .unwrap();
92 println!(
93 "Found {:#?} products of type {:#?}.",
94 products.len(),
95 ProductType::Spot
96 );
97 }
98
99 {
100 let product_ids = Some(vec!["OGN-BTC", "WCFG-USD"]);
101 let products = cb_client
102 .list_products(None, None, None, &product_ids, None)
103 .await
104 .unwrap();
105 println!("Found {:#?} products from Id.", products.len());
106 }
107
108 {
109 let products = cb_client
110 .list_products(None, None, None, &None, Some(ContractExpiryType::Expiring))
111 .await
112 .unwrap();
113 println!(
114 "Found {:#?} products with expiring contracts.",
115 products.len()
116 );
117 }
118}Sourcepub async fn get_product(&self, product_id: &str) -> Result<Product, CbError>
pub async fn get_product(&self, product_id: &str) -> Result<Product, CbError>
Get information on a single product by product ID.
Sourcepub async fn get_product_candles(
&self,
product_id: &str,
start: &DateTime,
end: &DateTime,
granularity: Granularity,
) -> Result<Vec<Candle>, CbError>
pub async fn get_product_candles( &self, product_id: &str, start: &DateTime, end: &DateTime, granularity: Granularity, ) -> Result<Vec<Candle>, CbError>
Get rates for a single product by product ID, grouped in buckets.
Examples found in repository?
126pub async fn run_get_product_candles(cb_client: &CbClient<'_>) {
127 let product_id = "OGN-BTC";
128 let naivedatetime_utc = chrono::naive::NaiveDate::from_ymd_opt(2023, 1, 12)
129 .unwrap()
130 .and_hms_opt(0, 0, 0)
131 .unwrap();
132 let start = chrono::DateTime::from_utc(naivedatetime_utc, chrono::offset::Utc);
133 let end = start
134 .clone()
135 .checked_add_days(chrono::naive::Days::new(2))
136 .unwrap();
137 let candles = cb_client
138 .get_product_candles(product_id, &start, &end, Granularity::OneDay)
139 .await
140 .unwrap();
141 println!("\n{:#?}\n", candles);
142}Sourcepub async fn get_market_trades(
&self,
product_id: &str,
limit: i32,
) -> Result<MarketTrades, CbError>
pub async fn get_market_trades( &self, product_id: &str, limit: i32, ) -> Result<MarketTrades, CbError>
Get snapshot information, by product ID, about the last trades (ticks), best bid/ask, and 24h volume.
Sourcepub fn list_orders<'b>(
&'b self,
product_id: Option<String>,
order_status: Option<Vec<Status>>,
limit: Option<i32>,
start_date: Option<DateTime>,
end_date: Option<DateTime>,
deprecated_user_native_currency: Option<String>,
order_type: Option<OrderType>,
order_side: Option<Side>,
cursor: Option<String>,
product_type: Option<ProductType>,
order_placement_source: Option<OrderPlacementSource>,
contract_expiry_type: Option<ContractExpiryType>,
) -> impl Stream<Item = Result<Vec<Order>, CbError>> + 'b
pub fn list_orders<'b>( &'b self, product_id: Option<String>, order_status: Option<Vec<Status>>, limit: Option<i32>, start_date: Option<DateTime>, end_date: Option<DateTime>, deprecated_user_native_currency: Option<String>, order_type: Option<OrderType>, order_side: Option<Side>, cursor: Option<String>, product_type: Option<ProductType>, order_placement_source: Option<OrderPlacementSource>, contract_expiry_type: Option<ContractExpiryType>, ) -> impl Stream<Item = Result<Vec<Order>, CbError>> + 'b
Get a list of orders filtered by optional query parameters (product_id, order_status, etc).
Examples found in repository?
23pub async fn run_list_orders(cb_client: &CbClient<'_>) {
24 let product_id: Option<String> = None;
25 let order_status: Option<Vec<orders::Status>> = None;
26 let limit: Option<i32> = Some(10);
27 let start_date: Option<DateTime> = None;
28 let end_date: Option<DateTime> = None;
29 let deprecated_user_native_currency: Option<String> = None;
30 let order_type: Option<orders::OrderType> = None;
31 let order_side: Option<orders::OrderSide> = Some(orders::OrderSide::Buy);
32 let cursor: Option<String> = None;
33 let product_type: Option<products::ProductType> = Some(products::ProductType::Spot);
34 let order_placement_source: Option<orders::OrderPlacementSource> = None;
35 let contract_expiry_type: Option<products::ContractExpiryType> = None;
36
37 let orders_stream = cb_client.list_orders(
38 product_id,
39 order_status,
40 limit,
41 start_date,
42 end_date,
43 deprecated_user_native_currency,
44 order_type,
45 order_side,
46 cursor,
47 product_type,
48 order_placement_source,
49 contract_expiry_type,
50 );
51 pin_mut!(orders_stream);
52
53 let mut orders = Vec::<orders::Order>::new();
54 while let Some(orders_result) = orders_stream.next().await {
55 let mut partial_orders = orders_result.unwrap();
56 println!("Got {} orders", partial_orders.len());
57 orders.append(&mut partial_orders);
58
59 if partial_orders.len() > 30 {
60 break;
61 }
62 }
63 println!("Got {} orders in total.", orders.len());
64
65 let order = cb_client.get_order(&orders[0].order_id).await.unwrap();
66 assert_eq!(orders[0], order);
67}Sourcepub fn list_fills<'b>(
&'b self,
order_id: Option<String>,
product_id: Option<String>,
start_sequence_timestamp: Option<DateTime>,
end_sequence_timestamp: Option<DateTime>,
limit: Option<i64>,
cursor: Option<String>,
) -> impl Stream<Item = Result<Vec<Fill>, CbError>> + 'b
pub fn list_fills<'b>( &'b self, order_id: Option<String>, product_id: Option<String>, start_sequence_timestamp: Option<DateTime>, end_sequence_timestamp: Option<DateTime>, limit: Option<i64>, cursor: Option<String>, ) -> impl Stream<Item = Result<Vec<Fill>, CbError>> + 'b
Get a list of fills filtered by optional query parameters (product_id, order_id, etc).
Examples found in repository?
69pub async fn run_list_fills(cb_client: &CbClient<'_>) {
70 let limit = Some(10);
71 let fills_stream = cb_client.list_fills(None, None, None, None, limit, None);
72 pin_mut!(fills_stream);
73
74 let mut fills = Vec::<orders::Fill>::new();
75 while let Some(fills_result) = fills_stream.next().await {
76 let mut partial_fills = fills_result.unwrap();
77 println!("Got {} fills", partial_fills.len());
78 fills.append(&mut partial_fills);
79
80 if fills.len() > 30 {
81 break;
82 }
83 }
84 println!("\nFills\n------------\n{:#?}", fills.len());
85}Sourcepub async fn get_order(&self, order_id: &str) -> Result<Order, CbError>
pub async fn get_order(&self, order_id: &str) -> Result<Order, CbError>
Get a single order by order ID.
Examples found in repository?
23pub async fn run_list_orders(cb_client: &CbClient<'_>) {
24 let product_id: Option<String> = None;
25 let order_status: Option<Vec<orders::Status>> = None;
26 let limit: Option<i32> = Some(10);
27 let start_date: Option<DateTime> = None;
28 let end_date: Option<DateTime> = None;
29 let deprecated_user_native_currency: Option<String> = None;
30 let order_type: Option<orders::OrderType> = None;
31 let order_side: Option<orders::OrderSide> = Some(orders::OrderSide::Buy);
32 let cursor: Option<String> = None;
33 let product_type: Option<products::ProductType> = Some(products::ProductType::Spot);
34 let order_placement_source: Option<orders::OrderPlacementSource> = None;
35 let contract_expiry_type: Option<products::ContractExpiryType> = None;
36
37 let orders_stream = cb_client.list_orders(
38 product_id,
39 order_status,
40 limit,
41 start_date,
42 end_date,
43 deprecated_user_native_currency,
44 order_type,
45 order_side,
46 cursor,
47 product_type,
48 order_placement_source,
49 contract_expiry_type,
50 );
51 pin_mut!(orders_stream);
52
53 let mut orders = Vec::<orders::Order>::new();
54 while let Some(orders_result) = orders_stream.next().await {
55 let mut partial_orders = orders_result.unwrap();
56 println!("Got {} orders", partial_orders.len());
57 orders.append(&mut partial_orders);
58
59 if partial_orders.len() > 30 {
60 break;
61 }
62 }
63 println!("Got {} orders in total.", orders.len());
64
65 let order = cb_client.get_order(&orders[0].order_id).await.unwrap();
66 assert_eq!(orders[0], order);
67}Sourcepub async fn get_transactions_summary(
&self,
start_date: Option<DateTime>,
end_date: Option<DateTime>,
user_native_currency: Option<String>,
product_type: Option<ProductType>,
contract_expiry_type: Option<ContractExpiryType>,
) -> Result<TransactionsSummary, CbError>
pub async fn get_transactions_summary( &self, start_date: Option<DateTime>, end_date: Option<DateTime>, user_native_currency: Option<String>, product_type: Option<ProductType>, contract_expiry_type: Option<ContractExpiryType>, ) -> Result<TransactionsSummary, CbError>
Get a summary of transactions with fee tiers, total volume, and fees.
Examples found in repository?
18pub async fn run_get_transactions_summary(cb_client: &CbClient<'_>) {
19 let start_date = None;
20 let end_date = None;
21 let user_native_currency = None;
22 let product_type = None;
23 let contract_expiry_type = None;
24
25 let transactions_summary = cb_client
26 .get_transactions_summary(
27 start_date,
28 end_date,
29 user_native_currency,
30 product_type,
31 contract_expiry_type,
32 )
33 .await
34 .unwrap();
35
36 println!("{:#?}", transactions_summary);
37}Sourcepub async fn create_order(
&self,
order: &OrderToSend,
) -> Result<CreateOrderResponse, CbError>
pub async fn create_order( &self, order: &OrderToSend, ) -> Result<CreateOrderResponse, CbError>
Create an order with a specified product_id (asset-pair), side (buy/sell), etc.
!Warning! Using to this function might results in a financial loss.
Examples found in repository?
20pub async fn run_order_and_cancel(cb_client: &CbClient<'_>) {
21 let product_id = "BTC-USDT";
22 let side = orders::OrderSide::Buy;
23 let base_size = 1.0; // let's buy a BTC
24 let limit_price = 0.01; // if it's one cent.
25 let end_time = chrono::offset::Utc::now() + chrono::Duration::days(1); // and happen within 1 day
26 let post_only = false;
27
28 let order_to_send = orders::create_limit_order_good_til_date(
29 product_id,
30 side,
31 base_size,
32 limit_price,
33 end_time,
34 post_only,
35 )
36 .unwrap();
37
38 let create_order_response = cb_client.create_order(&order_to_send).await.unwrap();
39 println!("{:#?}", create_order_response);
40
41 let order_ids = vec![create_order_response.order_id];
42 let cancel_response = cb_client.cancel_order(&order_ids).await.unwrap();
43 println!("{:#?}", cancel_response);
44}Sourcepub async fn cancel_order(
&self,
order_ids: &Vec<String>,
) -> Result<Vec<CancelOrderResponse>, CbError>
pub async fn cancel_order( &self, order_ids: &Vec<String>, ) -> Result<Vec<CancelOrderResponse>, CbError>
Initiate cancel requests for one or more orders.
/// !Warning! Using to this function might results in a financial loss.
Examples found in repository?
20pub async fn run_order_and_cancel(cb_client: &CbClient<'_>) {
21 let product_id = "BTC-USDT";
22 let side = orders::OrderSide::Buy;
23 let base_size = 1.0; // let's buy a BTC
24 let limit_price = 0.01; // if it's one cent.
25 let end_time = chrono::offset::Utc::now() + chrono::Duration::days(1); // and happen within 1 day
26 let post_only = false;
27
28 let order_to_send = orders::create_limit_order_good_til_date(
29 product_id,
30 side,
31 base_size,
32 limit_price,
33 end_time,
34 post_only,
35 )
36 .unwrap();
37
38 let create_order_response = cb_client.create_order(&order_to_send).await.unwrap();
39 println!("{:#?}", create_order_response);
40
41 let order_ids = vec![create_order_response.order_id];
42 let cancel_response = cb_client.cancel_order(&order_ids).await.unwrap();
43 println!("{:#?}", cancel_response);
44}
45
46pub async fn run_cancel_nonexistent_order(cb_client: &CbClient<'_>) {
47 let order_ids = vec!["foo".to_string()];
48 let response = cb_client.cancel_order(&order_ids).await;
49
50 match response {
51 Ok(cancel_order_response) => println!("{:#?}", cancel_order_response),
52 Err(err) => match err {
53 CbError::Coinbase(e) => println!("Coinbase error: {:#?}", e),
54 CbError::Serde(e) => println!("Serde error: {:#?}", e),
55 CbError::Http(e) => println!("Http error: {:#?}", e),
56 },
57 }
58}