use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use uuid::Uuid;
use crate::repositories::DepositSessionEntity;
#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DepositStatusResponse {
pub session_id: Uuid,
pub status: String,
pub wallet_address: String,
pub amount_lamports: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tx_signature: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub error_message: Option<String>,
pub created_at: DateTime<Utc>,
#[serde(skip_serializing_if = "Option::is_none")]
pub completed_at: Option<DateTime<Utc>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub withdrawal_available_at: Option<DateTime<Utc>>,
}
impl From<&DepositSessionEntity> for DepositStatusResponse {
fn from(entity: &DepositSessionEntity) -> Self {
Self {
session_id: entity.id,
status: entity.status.as_str().to_string(),
wallet_address: entity.wallet_address.clone(),
amount_lamports: entity.deposit_amount_lamports,
tx_signature: entity.privacy_deposit_tx_signature.clone(),
error_message: entity.error_message.clone(),
created_at: entity.created_at,
completed_at: entity.completed_at,
withdrawal_available_at: entity.withdrawal_available_at,
}
}
}
#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DepositConfigResponse {
pub enabled: bool,
pub private_deposits_enabled: bool,
pub privacy_period_secs: u64,
pub company_wallet: String,
pub company_currency: String,
pub sol_price_usd: f64,
pub token_prices: HashMap<String, f64>,
pub private_min_sol: f64,
pub private_min_usd: f64,
pub public_min_usd: f64,
pub sol_micro_max_usd: f64,
pub supported_currencies: Vec<String>,
pub quick_action_tokens: Vec<String>,
pub custom_token_symbols: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub micro_deposit_address: Option<String>,
pub micro_batch_threshold_usd: f64,
pub fee_policy: String,
pub privacy_fee_percent: f64,
pub privacy_fee_fixed_lamports: u64,
pub swap_fee_percent: f64,
pub swap_fee_fixed_lamports: u64,
pub company_fee_percent: f64,
pub company_fee_fixed_lamports: u64,
}
#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DepositQuoteResponse {
pub input_mint: String,
pub output_mint: String,
pub in_amount: String,
pub out_amount: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub in_usd_value: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub out_usd_value: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub slippage_bps: Option<u32>,
pub transaction: String,
pub request_id: String,
}
#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DepositItemResponse {
pub session_id: Uuid,
pub status: String,
pub amount_lamports: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tx_signature: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub withdrawal_tx_signature: Option<String>,
pub created_at: DateTime<Utc>,
#[serde(skip_serializing_if = "Option::is_none")]
pub completed_at: Option<DateTime<Utc>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub withdrawal_available_at: Option<DateTime<Utc>>,
}
impl From<&DepositSessionEntity> for DepositItemResponse {
fn from(entity: &DepositSessionEntity) -> Self {
Self {
session_id: entity.id,
status: entity.status.as_str().to_string(),
amount_lamports: entity.deposit_amount_lamports,
tx_signature: entity.privacy_deposit_tx_signature.clone(),
withdrawal_tx_signature: entity.withdrawal_tx_signature.clone(),
created_at: entity.created_at,
completed_at: entity.completed_at,
withdrawal_available_at: entity.withdrawal_available_at,
}
}
}
#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct DepositListResponse {
pub deposits: Vec<DepositItemResponse>,
pub total: u64,
pub limit: u32,
pub offset: u32,
}
#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct PendingSplDepositItemResponse {
pub id: Uuid,
pub wallet_address: String,
pub token_mint: String,
pub token_amount_raw: String,
pub token_amount: i64,
pub tx_signature: String,
pub created_at: DateTime<Utc>,
pub expires_at: DateTime<Utc>,
}
#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct PendingSplDepositListResponse {
pub deposits: Vec<PendingSplDepositItemResponse>,
pub total: u64,
pub limit: u32,
pub offset: u32,
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ConfirmSplDepositRequest {
pub pending_id: Uuid,
}
#[derive(Debug, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ConfirmSplDepositResponse {
pub success: bool,
pub pending_id: Uuid,
#[serde(skip_serializing_if = "Option::is_none")]
pub deposit_session_id: Option<Uuid>,
#[serde(skip_serializing_if = "Option::is_none")]
pub swap_tx_signature: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub deposit_tx_signature: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub error: Option<String>,
}
#[cfg(test)]
mod tests {
use super::*;
use serde_json::json;
#[test]
fn test_pending_spl_deposit_list_response_serialization() {
let resp = PendingSplDepositListResponse {
deposits: vec![],
total: 0,
limit: 20,
offset: 0,
};
let v = serde_json::to_value(resp).unwrap();
assert_eq!(v, json!({"deposits":[],"total":0,"limit":20,"offset":0}));
}
}