use crate::{
protocol::marketdata_publisher::Ticker,
types::{Candle, Instrument, Token},
};
use chrono::{DateTime, Utc};
use rust_decimal::Decimal;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use uuid::Uuid;
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct CreateUserRequest {
pub username: String,
pub password: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct CreateUserResponse {
pub user_id: Uuid,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct DeleteUserRequest {
pub username: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct DeleteUserResponse {
pub message: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct ChangePasswordRequest {
pub username: String,
pub password: String,
pub totp: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct ChangePasswordResponse {
pub message: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct CreateApiKeyRequest {
pub username: String,
pub password: String,
pub totp: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct CreateApiKeyResponse {
pub api_key: String,
pub secret: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct GetApiKeysResponse {
pub api_keys: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema, utoipa::IntoParams))]
pub struct RevokeApiKeyRequest {
pub api_key: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct RevokeApiKeyResponse {
pub message: String,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct AuthenticateRequest {
#[serde(flatten)]
pub auth: AuthenticationMethod,
pub expiration_seconds: i32,
pub totp: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[serde(untagged)]
pub enum AuthenticationMethod {
UsernamePassword { username: String, password: String },
ApiKeySecret { api_key: String, secret: String },
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct AuthenticateResponse {
pub token: Token,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct LoginRequest {
#[serde(flatten)]
pub auth: AuthenticationMethod,
pub expiration_seconds: i32,
pub totp: Option<String>,
pub redirect_url: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct RevokeUserTokenRequest {
pub token: Token,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct RevokeUserTokenResponse {
pub message: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct WhoAmIResponse {
pub id: Uuid,
pub username: String,
pub created_at: DateTime<Utc>,
pub enabled_2fa: bool,
pub is_onboarded: bool,
pub is_close_only: bool,
pub is_frozen: bool,
pub is_admin: bool,
pub maker_fee: Decimal,
pub taker_fee: Decimal,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct DecodeTokenRequest {
pub token: Token,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct DecodeTokenResponse {
pub user_id: Uuid,
pub username: String,
pub is_admin_token: bool,
pub can_place_orders: bool,
pub enabled_2fa: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct GetUsersResponse {
pub users: Vec<GetUserResponse>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::IntoParams, utoipa::ToSchema))]
pub struct GetUserRequest {
pub username: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct GetUserResponse {
pub id: Uuid,
pub created_at: DateTime<Utc>,
pub username: String,
pub enabled_2fa: bool,
pub is_onboarded: bool,
pub is_close_only: bool,
pub is_frozen: bool,
pub is_admin: bool,
pub maker_fee: Decimal,
pub taker_fee: Decimal,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct UpdateUserRequest {
pub username: String,
pub is_onboarded: Option<bool>,
pub is_close_only: Option<bool>,
pub is_frozen: Option<bool>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema, utoipa::IntoParams))]
pub struct GetUserRiskSnapshotRequest {
pub username: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct GetUserRiskSnapshotResponse {
pub risk_snapshot: UserRiskSnapshot,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema, utoipa::IntoParams))]
pub struct GetUserRiskProfileRequest {
pub username: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct GetUserRiskProfilesResponse {
pub user_risk_profiles: Vec<GetUserRiskProfileResponse>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct GetUserRiskProfileResponse {
pub user_id: Uuid,
pub risk_score: String,
pub compliance_risk_approved: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema, utoipa::IntoParams))]
pub struct GetInstrumentRequest {
pub symbol: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
#[serde(transparent)]
pub struct GetInstrumentResponse(pub Instrument);
impl GetInstrumentResponse {
pub fn into_inner(self) -> Instrument {
self.0
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct GetInstrumentsResponse {
pub instruments: Vec<GetInstrumentResponse>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema, utoipa::IntoParams))]
pub struct GetTickerRequest {
pub symbol: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct GetTickerResponse {
pub ticker: Ticker,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct GetTickersResponse {
pub tickers: Vec<Ticker>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema, utoipa::IntoParams))]
pub struct GetTransactionsRequest {
pub transaction_types: Vec<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct Transaction {
pub user_id: Uuid,
pub event_id: String,
pub symbol: String,
pub timestamp: DateTime<Utc>,
pub amount: Decimal,
pub transaction_type: String,
pub reference_id: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct GetTransactionsResponse {
pub transactions: Vec<Transaction>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct FundingTransaction {
pub user_id: Uuid,
pub currency: String,
pub timestamp: DateTime<Utc>,
pub transaction_type: String,
pub amount: Decimal,
pub event_id: String,
pub sequence_number: i32,
pub reference_id: Option<String>,
pub symbol: String,
pub funding_rate: Decimal,
pub funding_amount: Decimal,
pub benchmark_price: Decimal,
pub settlement_price: Decimal,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct GetFundingTransactionsResponse {
pub funding_transactions: Vec<FundingTransaction>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct Setup2faResponse {
pub validate_token: String,
pub uri: String,
pub secret: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct Confirm2faRequest {
pub validate_token: String,
pub code: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct Confirm2faResponse {
pub success: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct Disable2faResponse {
pub message: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct SandboxDepositRequest {
pub symbol: String,
pub amount: Decimal,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct SandboxWithdrawalRequest {
pub symbol: String,
pub amount: Decimal,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct GetPositionsResponse {
pub positions: Vec<Position>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct Position {
pub user_id: Uuid,
pub symbol: String,
pub open_quantity: i64,
pub open_notional: Decimal,
pub timestamp: DateTime<Utc>,
pub realized_pnl: Decimal,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct GetFillsResponse {
pub fills: Vec<Fill>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct Fill {
pub execution_id: String,
pub user_id: Uuid,
pub timestamp: DateTime<Utc>,
pub symbol: String,
pub price: Decimal,
pub quantity: i64,
pub is_taker: bool,
pub fee: Decimal,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct GetBalancesResponse {
pub balances: Vec<Balance>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct Balance {
pub symbol: String,
pub amount: Decimal,
}
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct SymbolRiskSnapshot {
pub open_quantity: i64,
pub open_notional: Decimal,
pub average_price: Option<Decimal>,
pub initial_margin_required_position: Decimal,
pub initial_margin_required_open_orders: Decimal,
pub initial_margin_required_total: Decimal,
pub maintenance_margin_required: Decimal,
pub unrealized_pnl: Decimal,
pub liquidation_price: Option<Decimal>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct UserRiskSnapshot {
pub user_id: Uuid,
pub timestamp_ns: DateTime<Utc>,
pub per_symbol: HashMap<String, SymbolRiskSnapshot>,
pub initial_margin_required_for_positions: Decimal,
pub initial_margin_required_for_open_orders: Decimal,
pub initial_margin_required_total: Decimal,
pub maintenance_margin_required: Decimal,
pub unrealized_pnl: Decimal,
pub equity: Decimal,
pub initial_margin_available: Decimal,
pub maintenance_margin_available: Decimal,
pub balance_usd: Decimal,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct GetRiskSnapshotResponse {
pub risk_snapshot: UserRiskSnapshot,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct GetRiskSnapshotsResponse {
pub risk_snapshots: Vec<UserRiskSnapshot>,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_get_user_token_request_serde() {
let json = r#"
{
"username": "testuser",
"password": "password",
"expiration_seconds": 3600
}
"#;
let req: AuthenticateRequest = serde_json::from_str(json).unwrap();
assert_eq!(
req,
AuthenticateRequest {
auth: AuthenticationMethod::UsernamePassword {
username: "testuser".to_string(),
password: "password".to_string()
},
expiration_seconds: 3600,
totp: None
}
);
let json = r#"
{
"api_key": "testapikey",
"secret": "testsecret",
"expiration_seconds": 3600
}
"#;
let req: AuthenticateRequest = serde_json::from_str(json).unwrap();
assert_eq!(
req,
AuthenticateRequest {
auth: AuthenticationMethod::ApiKeySecret {
api_key: "testapikey".to_string(),
secret: "testsecret".to_string()
},
expiration_seconds: 3600,
totp: None
}
);
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema, utoipa::IntoParams))]
pub struct GetCandlesRequest {
pub symbol: String,
pub start_timestamp_ns: u64,
pub end_timestamp_ns: u64,
pub candle_width: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct GetCandlesResponse {
pub candles: Vec<Candle>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema, utoipa::IntoParams))]
pub struct GetCandleRequest {
pub symbol: String,
pub candle_width: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct GetCandleResponse {
pub candle: Candle,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema, utoipa::IntoParams))]
pub struct GetFundingRatesRequest {
pub symbol: String,
pub start_timestamp_ns: u64,
pub end_timestamp_ns: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct GetFundingRatesResponse {
pub funding_rates: Vec<FundingRate>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct FundingRate {
pub symbol: String,
pub timestamp_ns: u64,
pub funding_rate: Decimal,
pub funding_amount: Decimal,
pub benchmark_price: Decimal,
pub settlement_price: Decimal,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema, utoipa::IntoParams))]
pub struct GetExchangeStatsRequest {
pub start_timestamp_ns: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct GetExchangeStatsResponse {
pub exchange_stats: ExchangeStats,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct ExchangeStats {
pub deposits_count: i64,
pub deposits_notional: Decimal,
pub withdrawals_count: i64,
pub withdrawals_notional: Decimal,
pub fees: Decimal,
pub trading_volume: Decimal,
pub open_interest: Decimal,
pub users_count: i64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct CreateInviteRequest {
pub not_valid_after: Option<DateTime<Utc>>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct CreateInviteResponse {
pub code: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct SignupRequest {
pub username: String,
pub password: String,
pub invite_code: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))]
pub struct SignupResponse {
pub user_id: Uuid,
}