1
2
3
4
5
6
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
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
//! # Kraapi
//!
//! Asynchronous HTTP client for the Kraken cryptocurrency exchange
//!
//! # Features
//!
//! - Asynchronous
//! - Type-driven and self-validating API
//! - Ergonomic and easy to use
//! - Promotes re-use of structures and avoids unecessary allocations or redundant HTTP clients
//!
//! # General Notes - TLDR
//!
//! - Every [input][api::Input] type is prefixed with KI. Every [output][api::Output]
//! type is prefixed with KO
//! - Every [input][api::Input] type is a builder type for [KrakenInput][api::KrakenInput].
//! All required paramters(per Kraken) are parameters for that type's constructor.
//! Optional parameters are exposed using methods.
//! - Only a [KrakenInput][api::KrakenInput] instance can be passed into the
//! [KrakenClient][client::KrakenClient]. You must fufill any contracts exposed by the
//! type and convert it to a [KrakenInput][api::KrakenInput] by calling
//! [finish()][api::Input::finish] or [finish_clone()][api::Input::finish_clone]
//! which exist for every [input][api::Input] type
//! - You must await the call to request
//! - Deserializing the data returned from Kraken into output structs is done for you. Currently if
//! you pass in the wrong [ouput][api::Output] type, the parsing will fail
//! - Builder methods require ownership so if you must perform some application logic while
//! building a [KrakenInput][api::KrakenInput] you must reassign the variable like so:
//!
//! ```
//! # use kraapi::api::asset::AssetPairInfo;
//! # use kraapi::public::asset_pairs::KIAssetPairs;
//! # use kraapi::api::Input;
//! let some_application_logic = true;
//! // mut to allow reassignment based on application logic
//! let mut input = KIAssetPairs::build();
//!
//! if some_application_logic {
//! input = input.info(AssetPairInfo::Leverage);
//! } else {
//! input = input.info(AssetPairInfo::Margin);
//! }
//!
//! // Now of type KrakenInput so we have to rebind the variable
//! let input = input.finish();
//! ```
//! - Endpoints that allow a list of some items (assets, asset pairs, transaction IDs, etc.) will
//! have methods with the following characteristics:
//! - Methods such as `with_asset(...)` or `with_asset_list(...)` always
//! **append** to the list. Chained calls to `with_asset(...)` is functionally equivalent to one call
//! to `with_asset_list(...)` with the same list of assets
//! - Methods such as `update_transaction_list(...)` will always **overwrite** the current data with
//! the new data
//! - For endpoints not requiring their list to be populated, methods such as
//! `clear_asset_list()` exist to **remove** the previous asset list from the request builder
//! - The above design allows for templating your requests. You can `clone()` a templated request
//! and then change only the data you care about before sending the request.
//! # Examples
//! See <https://www.kraken.com/features/api#example-api-code-php-lib> for more info on these
//! examples
//!
//! ## Public Endpoint - Ticker
//! ```
//! use kraapi::client::KrakenClient;
//! use kraapi::public::ticker::{KITicker, KOTicker};
//! use kraapi::api::asset::{KAsset, KAssetPair};
//! use kraapi::api::Input;
//!
//! # #[tokio::main]
//! # async fn main() -> Result<(), Box<dyn std::error::Error>> {
//! let client = KrakenClient::new("", "");
//!
//! let ticker_input = KITicker::build(KAssetPair(KAsset::XBT, KAsset::USD)).finish();
//!
//! let ticker_output = client.request::<KOTicker>(&ticker_input).await?;
//!
//! println!("{:#?}", ticker_output);
//! # Ok(())
//! # }
//! ```
//! ## Private Endpoint - Add Order
//! ```
//! use kraapi::client::KrakenClient;
//! use kraapi::private::add_order::{
//! KIAddOrder, KOAddOrder, Leverage};
//! use kraapi::api::{
//! asset::{KAsset, KAssetPair},
//! TradeType, OrderType};
//! use kraapi::api::Input;
//!
//! # #[tokio::main]
//! # async fn main() -> Result<(), Box<dyn std::error::Error>> {
//! // Example credentials from Kraken's documentation. Personal credentials will be needed for
//! // private API endpoints
//! let client = KrakenClient::new(
//! "<Your_API_Key>",
//! "<Your_API_Secret>"
//! );
//!
//! let add_order_input = KIAddOrder::build(
//! KAssetPair(KAsset::XBT, KAsset::USD),
//! TradeType::Buy,
//! OrderType::Limit(String::from("101.9901")),
//! 2.12345678)
//! .with_leverage(Leverage::Two)
//! .with_closing_order(OrderType::StopLossLimit(String::from("#5%"), String::from("#10")))
//! .validate(true)
//! .finish();
//!
//! // Valid credentials to be entered above, otherwise this will panic
//! // let add_order_output = client.request::<KOAddOrder>(&add_order_input).await?;
//! # let add_order_output = String::from("");
//!
//! println!("{:#?}", add_order_output);
//! # Ok(())
//! # }
//! ```
//!
//! # P.S.
//!
//! This library is pronounced "crappy"
pub use private;
pub use public;