Skip to main content

df_papertrade_core/trade/writes/
close.rs

1//! Closing whole positions by id, signed by the session key, one intent per twelve positions.
2
3use df_hyperliquid_core::client::Http;
4use df_hyperliquid_core::utils::Address;
5
6use crate::account::Account;
7use crate::account::store::Store;
8use crate::client::{Accepted, Client, Error};
9use crate::trade::intent::MAX_CLOSE_IDS;
10use crate::trade::{Close, Intent, deadline};
11use crate::utils::Lane;
12
13impl<H: Http + Clone> Client<H> {
14    /// Closes whole positions by id, at most 12 per intent, with one answer per intent. A failure
15    /// after the first leaves the rest unsent.
16    pub async fn close(
17        &self,
18        store: &impl Store,
19        owner: Address,
20        account: Option<&Account>,
21        ids: &[u128],
22    ) -> Result<Vec<Accepted>, Error> {
23        if ids.is_empty() {
24            return Err(Error::Invalid("no positions to close".into()));
25        }
26        Close::distinct(ids)?;
27        let key = self.session_key(store, owner, account).await?;
28        let mut answers = Vec::new();
29        for chunk in ids.chunks(MAX_CLOSE_IDS) {
30            let nonce = self.take_nonce(store, owner, Lane::Exchange).await?;
31            let close = Close::new(owner, chunk, nonce, deadline(self.now_ms()))?;
32            let signed = key.sign(Intent::Close(close), self.now_ms()).map_err(|e| Error::Signature(e.to_string()))?;
33            answers.push(self.submit(&signed).await?);
34        }
35        Ok(answers)
36    }
37}