df_hyperliquid_core/transfer/
check.rs1use crate::client::{ApiError, Transport, info, info_request};
5use crate::utils::{Address, Dec, Json};
6use serde::Deserialize;
7
8#[must_use]
10pub fn pre_transfer_check_request(recipient: Address, sender: Address) -> String {
11 info_request(
12 "preTransferCheck",
13 &[("user", Json::String(recipient.to_hex())), ("source", Json::String(sender.to_hex()))],
14 )
15}
16
17#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
20#[serde(rename_all = "camelCase")]
21pub struct PreTransferCheck {
22 pub is_sanctioned: bool,
24 pub user_exists: bool,
25 pub fee: Dec,
26 pub user_has_sent_tx: bool,
27}
28
29impl PreTransferCheck {
30 #[must_use]
32 pub fn activation_fee(&self) -> Option<Dec> {
33 self.fee.is_positive().then_some(self.fee)
34 }
35}
36
37pub async fn pre_transfer_check(
38 transport: &impl Transport,
39 recipient: Address,
40 sender: Address,
41) -> Result<PreTransferCheck, ApiError> {
42 info(transport, pre_transfer_check_request(recipient, sender)).await
43}
44
45pub use crate::transfer::system::{HYPE_SYSTEM, is_system_address, system_address};
47
48#[cfg(test)]
49mod tests {
50 use super::*;
51
52 fn address(text: &str) -> Address {
53 text.parse().unwrap()
54 }
55
56 #[test]
57 fn the_check_names_the_recipient_as_user_and_the_sender_as_source() {
58 assert_eq!(
59 pre_transfer_check_request(
60 address("0x0D1d9635D0640821d15e323ac8AdADfA9c111414"),
61 address("0x14791697260E4c9A71f18484C9f997B308e59325")
62 ),
63 concat!(
64 r#"{"type":"preTransferCheck","user":"0x0d1d9635d0640821d15e323ac8adadfa9c111414","#,
65 r#""source":"0x14791697260e4c9a71f18484c9f997b308e59325"}"#
66 )
67 );
68 }
69
70 #[test]
72 fn a_fresh_recipient_costs_a_fee_and_a_known_one_does_not() {
73 let fresh: PreTransferCheck =
74 serde_json::from_str(r#"{"isSanctioned":false,"userExists":false,"fee":"1.0","userHasSentTx":false}"#)
75 .unwrap();
76 assert_eq!(
77 fresh,
78 PreTransferCheck { is_sanctioned: false, user_exists: false, fee: Dec::ONE, user_has_sent_tx: false }
79 );
80 assert_eq!(fresh.activation_fee(), Some(Dec::ONE));
81 let known: PreTransferCheck =
82 serde_json::from_str(r#"{"isSanctioned":false,"userExists":true,"fee":"0.0","userHasSentTx":true}"#)
83 .unwrap();
84 assert!(known.user_exists && known.user_has_sent_tx && !known.is_sanctioned);
85 assert_eq!(known.activation_fee(), None);
86 }
87}