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 mod api; mod auth; pub mod client; pub mod error; pub use api::private; pub use api::public;