use crate::client::{ApiError, Transport, info, info_request};
use crate::utils::{Address, Dec, Json};
use serde::Deserialize;
#[must_use]
pub fn pre_transfer_check_request(recipient: Address, sender: Address) -> String {
info_request(
"preTransferCheck",
&[("user", Json::String(recipient.to_hex())), ("source", Json::String(sender.to_hex()))],
)
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct PreTransferCheck {
pub is_sanctioned: bool,
pub user_exists: bool,
pub fee: Dec,
pub user_has_sent_tx: bool,
}
impl PreTransferCheck {
#[must_use]
pub fn activation_fee(&self) -> Option<Dec> {
self.fee.is_positive().then_some(self.fee)
}
}
pub async fn pre_transfer_check(
transport: &impl Transport,
recipient: Address,
sender: Address,
) -> Result<PreTransferCheck, ApiError> {
info(transport, pre_transfer_check_request(recipient, sender)).await
}
#[cfg(test)]
mod tests {
use std::collections::BTreeMap;
use super::*;
#[test]
fn a_fresh_recipient_costs_a_fee_and_a_known_one_does_not() {
let recorded: BTreeMap<String, PreTransferCheck> = serde_json::from_str(include_str!(concat!(
env!("CARGO_MANIFEST_DIR"),
"/fixtures/transfer/pre_transfer_check_mainnet.json"
)))
.unwrap();
let fresh = &recorded["fresh"];
assert_eq!(
*fresh,
PreTransferCheck { is_sanctioned: false, user_exists: false, fee: Dec::ONE, user_has_sent_tx: false }
);
assert_eq!(fresh.activation_fee(), Some(Dec::ONE));
let known = &recorded["known"];
assert!(known.user_exists && known.user_has_sent_tx && !known.is_sanctioned);
assert_eq!(known.activation_fee(), None);
}
}