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
130
131
132
133
134
135
136
137
138
139
140
141
//! 
//! This is a minimal interface for the [Kraken exchange REST API](https://docs.kraken.com/rest/) using the [async-std](https://async.rs/) runtime.
//! 
//! Being a minimal interface for the API there is just a single method which takes the endpoint name and the parameters as a [Value](https://docs.serde.rs/serde_json/value/enum.Value.html) object from [serde_json](https://docs.serde.rs/serde_json/).  
//! 
//! When querying a private endpoint this library will handle and properly sing the petition to Kraken.
//! 
//! # Prerequisites
//! To use the **```private```** endpoints you will need to generate an **```API-Key```** and an **```API-Secret```** to authenticate to the desired Kraken account.  
//! [How to generate an API key pair?](https://support.kraken.com/hc/en-us/articles/360000919966-How-to-generate-an-API-key-pair-)
//! 
//! # Usage
//! Create the ``KrakenClient`` object with ``new()`` or ``with_credentials(key, secret)`` based on your needs.  
//! 
//! Then call ``api_request(endpoint_name, payload)``. It will return a JSON for you to handle or an error message. You can read about the payload for each endpoint and the returned JSON in the [API documentation](https://docs.kraken.com/rest/).
//! 
//! Available **Public** Endpoint Names:  
//! [Time](https://docs.kraken.com/rest/#operation/getServerTime),
//! [SystemStatus](https://docs.kraken.com/rest/#operation/getSystemStatus),
//! [Assets](https://docs.kraken.com/rest/#operation/getAssetInfo),
//! [AssetPairs](https://docs.kraken.com/rest/#operation/getTradableAssetPairs),
//! [Ticker](https://docs.kraken.com/rest/#operation/getTickerInformation),
//! [OHLC](https://docs.kraken.com/rest/#operation/getOHLCData),
//! [Depth](https://docs.kraken.com/rest/#operation/getOrderBook),
//! [Trades](https://docs.kraken.com/rest/#operation/getRecentTrades),
//! [Spread](https://docs.kraken.com/rest/#operation/getRecentSpreads). 
//!  
//! Available **Private** Endpoint Names:  
//! *User Data*  
//! [Balance](https://docs.kraken.com/rest/#operation/getAccountBalance),
//! [TradeBalance](https://docs.kraken.com/rest/#operation/getTradeBalance),
//! [OpenOrders](https://docs.kraken.com/rest/#operation/getOpenOrders),
//! [ClosedOrders](https://docs.kraken.com/rest/#operation/getClosedOrders),
//! [QueryOrders](https://docs.kraken.com/rest/#operation/getOrdersInfo),
//! [TradesHistory](https://docs.kraken.com/rest/#operation/getTradeHistory),
//! [QueryTrades](https://docs.kraken.com/rest/#operation/getTradesInfo),
//! [OpenPositions](https://docs.kraken.com/rest/#operation/getOpenPositions),
//! [Ledgers](https://docs.kraken.com/rest/#operation/getLedgers),
//! [QueryLedgers](https://docs.kraken.com/rest/#operation/getLedgersInfo),
//! [TradeVolume](https://docs.kraken.com/rest/#operation/getTradeVolume),
//! [AddExport](https://docs.kraken.com/rest/#operation/addExport),
//! [ExportStatus](https://docs.kraken.com/rest/#operation/exportStatus),
//! [RetrieveExport](https://docs.kraken.com/rest/#operation/retrieveExport),
//! [RemoveExport](https://docs.kraken.com/rest/#operation/removeExport).
//!   
//! *User Trading*  
//! [AddOrder](https://docs.kraken.com/rest/#operation/addOrder)
//! [CancelOrder](https://docs.kraken.com/rest/#operation/cancelOrder)
//! [CancellAll](https://docs.kraken.com/rest/#operation/cancelAllOrders)
//! [CancelAllOrdersAfter](https://docs.kraken.com/rest/#operation/cancelAllOrdersAfter).
//! 
//! *User Funding*  
//! [DepositMethods](https://docs.kraken.com/rest/#operation/getDepositMethods),
//! [DepositAddresses](https://docs.kraken.com/rest/#operation/getDepositAddresses),
//! [DepositStatus](https://docs.kraken.com/rest/#operation/getStatusRecentDeposits),
//! [WithdrawInfo](https://docs.kraken.com/rest/#operation/getWithdrawalInformation),
//! [Withdraw](https://docs.kraken.com/rest/#operation/withdrawFunds),
//! [WithdrawStatus](https://docs.kraken.com/rest/#operation/getStatusRecentWithdrawals),
//! [WithdrawCancel](https://docs.kraken.com/rest/#operation/cancelWithdrawal),
//! [WalletTransfer](https://docs.kraken.com/rest/#operation/walletTransfer).
//! 
//! *Websocket Auth*  
//! [GetWebSocketsToken](https://docs.kraken.com/rest/#operation/getWebsocketsToken).
//! 
//! # Example
//! ```rust
//! use async_kraken::client::KrakenClient;
//! 
//! fn get_keys() -> (String, String) {
//!     let content = std::fs::read_to_string("key").expect("File not found");
//!     let lines: Vec<&str> = content.lines().collect();
//! 
//!     let key = String::from(lines[0]);
//!     let secret = String::from(lines[1]);
//! 
//!     (key, secret)
//! }
//! 
//! #[async_std::main]
//! async fn main() {
//!     // # Only public endpoints
//!     // let k = KrakenClient::new();
//! 
//!     // # Public and private enpoints
//!     let (key, secret) = get_keys();
//!     let k = KrakenClient::with_credentials(key, secret);
//! 
//!     match k.api_request("Time", serde_json::json!({})).await {
//!         Ok(json) => println!("{:?}", json),
//!         Err(e) => println!("{:?}", e),
//!     };
//! 
//!     match k.api_request("OHLC", serde_json::json!({"pair":"doteur", "interval":30, "since":0})).await
//!     {
//!         Ok(json) => println!("{:?}", json),
//!         Err(e) => println!("{:?}", e),
//!     };
//! 
//!     match k.api_request("Balance", serde_json::json!({})).await {
//!         Ok(json) => println!("{:?}", json),
//!         Err(e) => println!("{:?}", e),
//!     };
//! }
//! ```
//! # Disclaimer
//! This software comes without any kind of warranties.  
//! You are the sole responsible of your gains or loses.
//! 


use serde::Deserialize;
use serde_json::Value;
use std::{error::Error, fmt};

pub mod client;
mod config;

#[derive(Deserialize)]
struct KrakenResult {
    pub error: Vec<String>,
    #[serde(default)]
    pub result: Value,
}

struct KrakenError {
    pub er_list: Vec<String>,
}

impl Error for KrakenError {}

impl fmt::Display for KrakenError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{:?}", self.er_list)
    }
}

impl fmt::Debug for KrakenError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "Kraken Errors: {:?}", self.er_list)
    }
}