use df_hyperliquid_core::utils::Address;
use df_hyperliquid_core::utils::sign::eip712::uint256;
use super::Refusal;
pub const MAX_CLOSE_IDS: usize = 12;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Close {
pub user: Address,
position_ids: Vec<[u8; 32]>,
pub nonce: u128,
pub deadline: u64,
}
impl Close {
pub fn new(user: Address, ids: &[u128], nonce: u128, deadline: u64) -> Result<Self, Refusal> {
Close::of_words(user, ids.iter().map(|id| uint256(*id)).collect(), nonce, deadline)
}
pub fn of_words(user: Address, words: Vec<[u8; 32]>, nonce: u128, deadline: u64) -> Result<Self, Refusal> {
if words.is_empty() || words.len() > MAX_CLOSE_IDS {
return Err(Refusal::CloseCount(words.len()));
}
for (index, word) in words.iter().enumerate() {
if words[..index].contains(word) {
return Err(Refusal::DuplicatePosition);
}
}
Ok(Close { user, position_ids: words, nonce, deadline })
}
pub fn distinct(ids: &[u128]) -> Result<(), Refusal> {
let repeated = ids.iter().enumerate().any(|(index, id)| ids[..index].contains(id));
if repeated { Err(Refusal::DuplicatePosition) } else { Ok(()) }
}
#[must_use]
pub fn position_ids(&self) -> &[[u8; 32]] {
&self.position_ids
}
}