Skip to main content

dna_rs/ops/
transfer.rs

1use serde_json::{Value, json};
2use std::collections::HashMap;
3
4use crate::client::DnaClient;
5use crate::error::DnaResult;
6use crate::models::contact::{ContactInput, ContactPayload};
7use crate::models::domain::DomainInfo;
8use crate::models::domain::DomainInfoResponse;
9use crate::models::transfer::{
10    DomainActionPayload, TransferCheckResponse, TransferCheckResult, TransferPayload,
11    TransferStatusResponse,
12};
13use crate::ops::util::{build_contact_payload, parse_domain_info};
14
15impl DnaClient {
16    /// Initiate a domain transfer into the account.
17    pub async fn transfer(
18        &self,
19        domain_name: &str,
20        epp_code: &str,
21        period: u32,
22        contacts: Option<HashMap<&str, ContactInput>>,
23    ) -> DnaResult<DomainInfo> {
24        let payload_contacts: Vec<ContactPayload> = contacts
25            .unwrap_or_default()
26            .iter()
27            .map(|(t, c)| build_contact_payload(c, t))
28            .collect();
29
30        let payload = TransferPayload {
31            domain_name: domain_name.into(),
32            auth_code: epp_code.into(),
33            period,
34            contacts: payload_contacts,
35        };
36
37        let raw: DomainInfoResponse = self.http.post("domains/transfer", &payload).await?;
38        parse_domain_info(raw)
39    }
40
41    /// Check whether a domain can be transferred with the given auth code.
42    pub async fn check_transfer(
43        &self,
44        domain_name: &str,
45        auth_code: &str,
46    ) -> DnaResult<TransferCheckResult> {
47        let payload = json!({ "domainName": domain_name, "authCode": auth_code });
48        let resp: TransferCheckResponse =
49            self.http.post("domains/transfers/check", &payload).await?;
50
51        let available = resp
52            .transfer_availability_status
53            .as_ref()
54            .map(|v| !v.is_null() && v != &Value::Bool(false) && v != &json!(0) && v != &json!(""))
55            .unwrap_or(false);
56
57        Ok(TransferCheckResult {
58            transfer_available: available,
59            auth_code_is_required: resp.auth_code_is_required.unwrap_or(false),
60            auth_code_is_valid: resp.auth_code_is_valid.unwrap_or(false),
61            user_transfer_required: resp.user_transfer_required.unwrap_or(false),
62            transfer_lock: resp.transfer_lock.unwrap_or(false),
63            message: resp.message.unwrap_or_default(),
64            message_key: resp.message_key.unwrap_or_default(),
65        })
66    }
67
68    /// Cancel a pending incoming transfer.
69    pub async fn cancel_transfer(&self, domain_name: &str) -> DnaResult<String> {
70        let payload = DomainActionPayload {
71            domain_name: domain_name.into(),
72        };
73        let resp: TransferStatusResponse =
74            self.http.post("domains/transfers/cancel", &payload).await?;
75        Ok(resp.status.unwrap_or_else(|| "Cancelled".into()))
76    }
77
78    /// Approve a pending outgoing transfer.
79    pub async fn approve_transfer(&self, domain_name: &str) -> DnaResult<String> {
80        let payload = DomainActionPayload {
81            domain_name: domain_name.into(),
82        };
83        let resp: TransferStatusResponse = self
84            .http
85            .post("domains/transfers/approve", &payload)
86            .await?;
87        Ok(resp.status.unwrap_or_else(|| "Approved".into()))
88    }
89
90    /// Reject a pending outgoing transfer.
91    pub async fn reject_transfer(&self, domain_name: &str) -> DnaResult<String> {
92        let payload = DomainActionPayload {
93            domain_name: domain_name.into(),
94        };
95        let resp: TransferStatusResponse =
96            self.http.post("domains/transfers/reject", &payload).await?;
97        Ok(resp.status.unwrap_or_else(|| "Rejected".into()))
98    }
99}