df_papertrade_core/trade/writes/
submit.rs1use df_hyperliquid_core::client::Http;
5use df_hyperliquid_core::utils::Address;
6
7use crate::account::store::{Slot, Store};
8use crate::account::wallet::{Purpose, SignRequest, Wallet};
9use crate::client::{Accepted, Client, Error};
10use crate::trade::{Intent, Signed};
11use crate::utils::{Lane, nonce};
12
13impl<H: Http + Clone> Client<H> {
14 pub async fn take_nonce(&self, store: &impl Store, owner: Address, lane: Lane) -> Result<u128, Error> {
17 let held = store.get(owner, Slot::Nonce(lane)).await?;
18 let next = match held.as_deref().and_then(|bytes| <[u8; 16]>::try_from(bytes).ok()) {
19 Some(bytes) => u128::from_be_bytes(bytes),
20 None => nonce::first(self.random::<3>()?),
21 };
22 store.put(owner, Slot::Nonce(lane), next.saturating_add(1).to_be_bytes().to_vec(), None).await?;
23 Ok(next)
24 }
25
26 pub(crate) async fn wallet_sign(
28 &self,
29 wallet: &impl Wallet,
30 owner: Address,
31 intent: Intent,
32 purpose: Purpose,
33 ) -> Result<Signed, Error> {
34 if wallet.address() != owner {
35 return Err(Error::WrongWallet { wallet: wallet.address().to_hex(), owner: owner.to_hex() });
36 }
37 if intent.user() != owner {
38 return Err(Error::WrongWallet { wallet: intent.user().to_hex(), owner: owner.to_hex() });
39 }
40 let request = SignRequest { purpose, json: intent.wallet_json(), digest: intent.digest() };
41 let signature = wallet.sign(&request).await?;
42 Signed::recover(intent, signature, owner).map_err(|e| Error::Signature(e.to_string()))
43 }
44
45 pub(crate) async fn submit(&self, signed: &Signed) -> Result<Accepted, Error> {
47 let accepted = self.relayer().submit(signed).await?;
48 if accepted.kept() { Ok(accepted) } else { Err(Error::NotKept(accepted)) }
49 }
50}
51
52#[cfg(test)]
53#[path = "tests/submit.rs"]
54mod tests;