CbClient

Struct CbClient 

Source
pub struct CbClient<'a> { /* private fields */ }
Expand description

Client structure performing http requests to Coinbase Advanced API

Implementations§

Source§

impl<'a> CbClient<'a>

Source

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?
examples/get_accounts.rs (line 14)
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
Hide additional examples
examples/get_fees.rs (line 12)
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}
examples/post_orders.rs (line 12)
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}
examples/get_orders.rs (line 16)
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}
examples/get_products.rs (line 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}
examples/run_all_examples.rs (line 26)
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}
Source

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.

Coinbase API reference

Examples found in repository?
examples/get_accounts.rs (line 22)
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}
Source

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()

Coinbase API reference

Examples found in repository?
examples/get_accounts.rs (line 36)
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}
Source

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.

Coinbase API reference

Examples found in repository?
examples/get_products.rs (line 37)
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}
Source

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.

Coinbase API reference

Examples found in repository?
examples/get_products.rs (line 53)
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}
Source

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.

Coinbase API reference

Examples found in repository?
examples/get_products.rs (line 72)
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}
Source

pub async fn get_product(&self, product_id: &str) -> Result<Product, CbError>

Get information on a single product by product ID.

Coinbase API reference

Examples found in repository?
examples/get_products.rs (line 122)
120pub async fn run_get_product(cb_client: &CbClient<'_>) {
121    let product_id = "OGN-BTC";
122    let product = cb_client.get_product(product_id).await.unwrap();
123    println!("\n{:#?}\n", product);
124}
Source

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.

Coinbase API reference

Examples found in repository?
examples/get_products.rs (line 138)
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}
Source

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.

Coinbase API reference

Examples found in repository?
examples/get_products.rs (line 148)
144pub async fn run_get_market_trades(cb_client: &CbClient<'_>) {
145    let product_id = "OGN-BTC";
146    let limit = 3;
147    let market_trades = cb_client
148        .get_market_trades(product_id, limit)
149        .await
150        .unwrap();
151    println!("\n{:#?}\n", market_trades);
152}
Source

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).

Coinbase API reference

Examples found in repository?
examples/get_orders.rs (lines 37-50)
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}
Source

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).

Coinbase API reference

Examples found in repository?
examples/get_orders.rs (line 71)
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}
Source

pub async fn get_order(&self, order_id: &str) -> Result<Order, CbError>

Get a single order by order ID.

Coinbase API reference

Examples found in repository?
examples/get_orders.rs (line 65)
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}
Source

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.

Coinbase API reference

Examples found in repository?
examples/get_fees.rs (lines 26-32)
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}
Source

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.

Coinbase API reference

Examples found in repository?
examples/post_orders.rs (line 38)
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}
Source

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.

Coinbase API reference

Examples found in repository?
examples/post_orders.rs (line 42)
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}

Auto Trait Implementations§

§

impl<'a> Freeze for CbClient<'a>

§

impl<'a> !RefUnwindSafe for CbClient<'a>

§

impl<'a> !Send for CbClient<'a>

§

impl<'a> !Sync for CbClient<'a>

§

impl<'a> Unpin for CbClient<'a>

§

impl<'a> !UnwindSafe for CbClient<'a>

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> 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, 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> Same for T

Source§

type Output = T

Should always be Self
Source§

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

Source§

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>,

Source§

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> ErasedDestructor for T
where T: 'static,