use crate::model::wallet::{AddressBookType, WithdrawalPriorityLevel};
use serde::{Deserialize, Serialize};
use serde_with::skip_serializing_none;
#[skip_serializing_none]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct AddToAddressBookRequest {
pub currency: String,
#[serde(rename = "type")]
pub address_type: AddressBookType,
pub address: String,
pub label: Option<String>,
pub tag: Option<String>,
}
impl AddToAddressBookRequest {
#[must_use]
pub fn new(currency: String, address_type: AddressBookType, address: String) -> Self {
Self {
currency,
address_type,
address,
label: None,
tag: None,
}
}
#[must_use]
pub fn with_label(mut self, label: String) -> Self {
self.label = Some(label);
self
}
#[must_use]
pub fn with_tag(mut self, tag: String) -> Self {
self.tag = Some(tag);
self
}
}
#[skip_serializing_none]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct UpdateInAddressBookRequest {
pub currency: String,
#[serde(rename = "type")]
pub address_type: AddressBookType,
pub address: String,
pub label: String,
pub agreed: bool,
pub personal: bool,
pub beneficiary_vasp_name: String,
pub beneficiary_vasp_did: String,
pub beneficiary_address: String,
pub beneficiary_vasp_website: Option<String>,
pub beneficiary_first_name: Option<String>,
pub beneficiary_last_name: Option<String>,
pub beneficiary_company_name: Option<String>,
pub tag: Option<String>,
}
impl UpdateInAddressBookRequest {
#[must_use]
#[allow(clippy::too_many_arguments)]
pub fn new(
currency: String,
address_type: AddressBookType,
address: String,
label: String,
agreed: bool,
personal: bool,
beneficiary_vasp_name: String,
beneficiary_vasp_did: String,
beneficiary_address: String,
) -> Self {
Self {
currency,
address_type,
address,
label,
agreed,
personal,
beneficiary_vasp_name,
beneficiary_vasp_did,
beneficiary_address,
beneficiary_vasp_website: None,
beneficiary_first_name: None,
beneficiary_last_name: None,
beneficiary_company_name: None,
tag: None,
}
}
#[must_use]
pub fn with_beneficiary_vasp_website(mut self, website: String) -> Self {
self.beneficiary_vasp_website = Some(website);
self
}
#[must_use]
pub fn with_beneficiary_first_name(mut self, first_name: String) -> Self {
self.beneficiary_first_name = Some(first_name);
self
}
#[must_use]
pub fn with_beneficiary_last_name(mut self, last_name: String) -> Self {
self.beneficiary_last_name = Some(last_name);
self
}
#[must_use]
pub fn with_beneficiary_company_name(mut self, company_name: String) -> Self {
self.beneficiary_company_name = Some(company_name);
self
}
#[must_use]
pub fn with_tag(mut self, tag: String) -> Self {
self.tag = Some(tag);
self
}
}
#[skip_serializing_none]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct WithdrawRequest {
pub currency: String,
pub address: String,
pub amount: f64,
pub priority: Option<WithdrawalPriorityLevel>,
}
impl WithdrawRequest {
#[must_use]
pub fn new(currency: String, address: String, amount: f64) -> Self {
Self {
currency,
address,
amount,
priority: None,
}
}
#[must_use]
pub fn with_priority(mut self, priority: WithdrawalPriorityLevel) -> Self {
self.priority = Some(priority);
self
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_add_to_address_book_request_new() {
let req = AddToAddressBookRequest::new(
"BTC".to_string(),
AddressBookType::Withdrawal,
"bc1qtest123".to_string(),
);
assert_eq!(req.currency, "BTC");
assert_eq!(req.address_type, AddressBookType::Withdrawal);
assert_eq!(req.address, "bc1qtest123");
assert!(req.label.is_none());
assert!(req.tag.is_none());
}
#[test]
fn test_add_to_address_book_request_with_options() {
let req = AddToAddressBookRequest::new(
"XRP".to_string(),
AddressBookType::Transfer,
"rTest123".to_string(),
)
.with_label("My XRP wallet".to_string())
.with_tag("12345".to_string());
assert_eq!(req.label, Some("My XRP wallet".to_string()));
assert_eq!(req.tag, Some("12345".to_string()));
}
#[test]
fn test_add_to_address_book_request_serialization() {
let req = AddToAddressBookRequest::new(
"BTC".to_string(),
AddressBookType::Withdrawal,
"bc1qtest".to_string(),
)
.with_label("Test".to_string());
let json = serde_json::to_string(&req).unwrap();
assert!(json.contains("\"currency\":\"BTC\""));
assert!(json.contains("\"type\":\"withdrawal\""));
assert!(json.contains("\"address\":\"bc1qtest\""));
assert!(json.contains("\"label\":\"Test\""));
}
#[test]
fn test_update_in_address_book_request_new() {
let req = UpdateInAddressBookRequest::new(
"BTC".to_string(),
AddressBookType::Withdrawal,
"bc1qtest".to_string(),
"Main wallet".to_string(),
true,
false,
"Test VASP".to_string(),
"did:example:123".to_string(),
"123 Main St".to_string(),
);
assert_eq!(req.currency, "BTC");
assert_eq!(req.address_type, AddressBookType::Withdrawal);
assert!(req.agreed);
assert!(!req.personal);
assert!(req.beneficiary_vasp_website.is_none());
}
#[test]
fn test_update_in_address_book_request_with_options() {
let req = UpdateInAddressBookRequest::new(
"ETH".to_string(),
AddressBookType::Transfer,
"0xtest".to_string(),
"Test".to_string(),
true,
false,
"VASP".to_string(),
"did:test".to_string(),
"Address".to_string(),
)
.with_beneficiary_first_name("John".to_string())
.with_beneficiary_last_name("Doe".to_string())
.with_beneficiary_vasp_website("https://vasp.example.com".to_string());
assert_eq!(req.beneficiary_first_name, Some("John".to_string()));
assert_eq!(req.beneficiary_last_name, Some("Doe".to_string()));
assert_eq!(
req.beneficiary_vasp_website,
Some("https://vasp.example.com".to_string())
);
}
#[test]
fn test_withdraw_request_new() {
let req = WithdrawRequest::new("BTC".to_string(), "bc1qtest".to_string(), 0.5);
assert_eq!(req.currency, "BTC");
assert_eq!(req.address, "bc1qtest");
assert!((req.amount - 0.5).abs() < f64::EPSILON);
assert!(req.priority.is_none());
}
#[test]
fn test_withdraw_request_with_priority() {
let req = WithdrawRequest::new("BTC".to_string(), "bc1qtest".to_string(), 1.0)
.with_priority(WithdrawalPriorityLevel::High);
assert_eq!(req.priority, Some(WithdrawalPriorityLevel::High));
}
#[test]
fn test_withdraw_request_serialization() {
let req = WithdrawRequest::new("ETH".to_string(), "0xtest".to_string(), 2.5)
.with_priority(WithdrawalPriorityLevel::Mid);
let json = serde_json::to_string(&req).unwrap();
assert!(json.contains("\"currency\":\"ETH\""));
assert!(json.contains("\"address\":\"0xtest\""));
assert!(json.contains("\"priority\":\"mid\""));
}
}