1pub mod ed25519;
4pub mod exchanges;
5pub mod hmac;
6pub mod jwt;
7pub mod pem;
8pub mod signature;
9
10#[cfg(test)]
11pub mod ed25519_tests;
12
13use crate::collections::FxHashMap;
14use crate::{Exchange, Result, SmartString};
15use std::fmt::Debug;
16
17pub trait ExchangeAuthentication: Send + Sync + Debug {
19 fn generate_authentication_headers(
21 &self,
22 method: &str,
23 path: &str,
24 parameters: Option<(&str, &str)>,
25 ) -> Result<FxHashMap<SmartString, SmartString>>;
26
27 fn generate_authentication_headers_with_body(
30 &self,
31 method: &str,
32 path: &str,
33 parameters: Option<(&str, &str)>,
34 _body: Option<&str>,
35 ) -> Result<FxHashMap<SmartString, SmartString>> {
36 self.generate_authentication_headers(method, path, parameters)
37 }
38
39 fn generate_websocket_authentication(&self) -> Result<SmartString>;
41
42 fn api_key(&self) -> &str;
44}
45
46#[derive(Debug, Clone)]
48pub struct AuthenticationConfiguration {
49 pub api_key: SmartString,
51 pub secret_key: SmartString,
53 pub passphrase: Option<SmartString>,
55}
56
57impl AuthenticationConfiguration {
58 #[must_use]
59 pub const fn new(api_key: SmartString, secret_key: SmartString) -> Self {
61 Self {
62 api_key,
63 secret_key,
64 passphrase: None,
65 }
66 }
67
68 #[must_use]
69 pub fn with_passphrase(mut self, passphrase: SmartString) -> Self {
71 self.passphrase = Some(passphrase);
72 self
73 }
74}
75
76#[inline]
79#[must_use]
80pub const fn max_hmac_signature_length() -> usize {
81 128 }
83
84#[inline]
86#[must_use]
87pub const fn max_jwt_token_length() -> usize {
88 2048 }
90
91#[inline]
93#[must_use]
94pub const fn max_nonce_length() -> usize {
95 64 }
97
98#[inline]
100#[must_use]
101pub const fn max_auth_headers_count() -> usize {
102 8 }
104
105#[inline]
107#[must_use]
108pub const fn auth_requires_timestamp(exchange: Exchange) -> bool {
109 match exchange {
110 Exchange::Binance | Exchange::Bybit | Exchange::Coinbase => true,
111 Exchange::Upbit | Exchange::Bithumb => false,
112 }
113}
114
115pub use self::ExchangeAuthentication as ExchangeAuth;
117pub type AuthConfig = AuthenticationConfiguration;
120
121#[cfg(test)]
122mod const_fn_tests {
123 use super::*;
124
125 #[test]
126 fn test_auth_const_functions() {
127 const MAX_HMAC_LEN: usize = max_hmac_signature_length();
129 const MAX_JWT_LEN: usize = max_jwt_token_length();
130 const MAX_NONCE_LEN: usize = max_nonce_length();
131 const MAX_HEADERS: usize = max_auth_headers_count();
132 const BINANCE_NEEDS_TIMESTAMP: bool = auth_requires_timestamp(Exchange::Binance);
133 const UPBIT_NEEDS_TIMESTAMP: bool = auth_requires_timestamp(Exchange::Upbit);
134
135 assert_eq!(MAX_HMAC_LEN, 128);
136 assert_eq!(MAX_JWT_LEN, 2048);
137 assert_eq!(MAX_NONCE_LEN, 64);
138 assert_eq!(MAX_HEADERS, 8);
139 assert!(BINANCE_NEEDS_TIMESTAMP);
140 assert!(!UPBIT_NEEDS_TIMESTAMP);
141 }
142}