Skip to main content

df_papertrade_core/trade/writes/
staking.rs

1//! Staking and unstaking PAPER and claiming its rewards, signed by the wallet from the staking
2//! lane's nonces.
3
4use df_hyperliquid_core::client::Http;
5use df_hyperliquid_core::utils::Address;
6
7use crate::account::store::Store;
8use crate::account::wallet::{Purpose, Wallet};
9use crate::client::{Accepted, Client, Error};
10use crate::trade::{Claim, Intent, Staking, deadline};
11use crate::utils::Lane;
12
13impl<H: Http + Clone> Client<H> {
14    /// Stakes `amount` PAPER (18 decimals) immediately. The wallet signs.
15    pub async fn stake(&self, store: &impl Store, wallet: &impl Wallet, amount: u128) -> Result<Accepted, Error> {
16        let intent = self.staking(store, wallet.address(), amount).await?;
17        let signed = self.wallet_sign(wallet, wallet.address(), Intent::Stake(intent), Purpose::Stake).await?;
18        self.submit(&signed).await
19    }
20
21    /// Unstakes `amount` PAPER (18 decimals) immediately. Distributed rewards stay claimable. The
22    /// wallet signs.
23    pub async fn unstake(&self, store: &impl Store, wallet: &impl Wallet, amount: u128) -> Result<Accepted, Error> {
24        let intent = self.staking(store, wallet.address(), amount).await?;
25        let signed = self.wallet_sign(wallet, wallet.address(), Intent::Unstake(intent), Purpose::Unstake).await?;
26        self.submit(&signed).await
27    }
28
29    /// Claims every distributed USDC reward into the account's balance. The wallet signs.
30    pub async fn claim(&self, store: &impl Store, wallet: &impl Wallet) -> Result<Accepted, Error> {
31        let owner = wallet.address();
32        let nonce = self.take_nonce(store, owner, Lane::Staking).await?;
33        let claim = Claim { user: owner, nonce, deadline: deadline(self.now_ms()) };
34        let signed = self.wallet_sign(wallet, owner, Intent::Claim(claim), Purpose::Claim).await?;
35        self.submit(&signed).await
36    }
37
38    async fn staking(&self, store: &impl Store, owner: Address, amount: u128) -> Result<Staking, Error> {
39        Staking::check(amount)?;
40        let nonce = self.take_nonce(store, owner, Lane::Staking).await?;
41        Ok(Staking::new(owner, amount, nonce, deadline(self.now_ms()))?)
42    }
43}