use serde::Deserialize;
pub fn default_sidecar_url() -> String {
"http://localhost:3100".to_string()
}
pub fn default_sidecar_timeout_ms() -> u64 {
30_000
}
pub fn default_session_ttl_secs() -> u64 {
86_400
}
pub fn default_min_deposit_lamports() -> u64 {
0
}
pub fn default_max_deposit_lamports() -> u64 {
100_000_000_000 }
pub fn default_max_spend_per_transaction_lamports() -> u64 {
10_000_000_000 }
pub fn default_company_currency() -> String {
"SOL".to_string()
}
fn default_key_id() -> String {
"v1".to_string()
}
pub const USDC_MINT: &str = "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";
pub const USDT_MINT: &str = "Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB";
fn default_spl_token_whitelist() -> Vec<String> {
vec![USDC_MINT.to_string(), USDT_MINT.to_string()]
}
#[derive(Debug, Clone, Deserialize)]
pub struct PrivacyConfig {
#[serde(default)]
pub enabled: bool,
#[serde(default = "default_sidecar_url")]
pub sidecar_url: String,
#[serde(default = "default_sidecar_timeout_ms")]
pub sidecar_timeout_ms: u64,
pub sidecar_api_key: Option<String>,
pub note_encryption_key: Option<String>,
#[serde(default = "default_key_id")]
pub note_encryption_key_id: String,
#[serde(default = "default_min_deposit_lamports")]
pub min_deposit_lamports: u64,
#[serde(default = "default_max_deposit_lamports")]
pub max_deposit_lamports: u64,
#[serde(default = "default_max_spend_per_transaction_lamports")]
pub max_spend_per_transaction_lamports: u64,
#[serde(default = "default_session_ttl_secs")]
pub session_ttl_secs: u64,
pub company_wallet_address: Option<String>,
#[serde(default = "default_company_currency")]
pub company_currency: String,
pub deposit_webhook_secret: Option<String>,
#[serde(default = "default_spl_token_whitelist")]
pub spl_token_whitelist: Vec<String>,
}
impl Default for PrivacyConfig {
fn default() -> Self {
Self {
enabled: false,
sidecar_url: default_sidecar_url(),
sidecar_timeout_ms: default_sidecar_timeout_ms(),
sidecar_api_key: None,
note_encryption_key: None,
note_encryption_key_id: default_key_id(),
min_deposit_lamports: default_min_deposit_lamports(),
max_deposit_lamports: default_max_deposit_lamports(),
max_spend_per_transaction_lamports: default_max_spend_per_transaction_lamports(),
session_ttl_secs: default_session_ttl_secs(),
company_wallet_address: None,
company_currency: default_company_currency(),
deposit_webhook_secret: None,
spl_token_whitelist: default_spl_token_whitelist(),
}
}
}
impl PrivacyConfig {
pub fn get_token_decimals(&self, mint: &str) -> Option<u8> {
if !self.spl_token_whitelist.contains(&mint.to_string()) {
return None;
}
match mint {
USDC_MINT => Some(6),
USDT_MINT => Some(6),
other => {
tracing::warn!(
mint = %other,
assumed_decimals = 6,
"Unknown whitelisted token using assumed 6 decimals — verify correctness"
);
Some(6)
}
}
}
pub fn is_token_whitelisted(&self, mint: &str) -> bool {
self.spl_token_whitelist.contains(&mint.to_string())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn default_sidecar_url_matches_sidecar_service_port() {
assert_eq!(default_sidecar_url(), "http://localhost:3100");
}
}