df_hyperliquid_core/client/evm/precompiles/
account.rs1use crate::client::evm::abi::AbiError;
5use crate::client::evm::precompiles::fields::{Fields, tokens};
6use crate::client::evm::precompiles::read::{Arg, Read, read};
7use crate::utils::Address;
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
11pub struct Position {
12 pub szi: i64,
14 pub entry_ntl: u64,
16 pub isolated_raw_usd: i64,
17 pub leverage: u32,
18 pub is_isolated: bool,
19}
20
21fn decode_position(at: u16, answer: &[u8]) -> Result<Position, AbiError> {
22 let tokens = tokens(at, answer)?;
23 let mut fields = Fields::of("position", &tokens)?;
24 Ok(Position {
25 szi: fields.i64()?,
26 entry_ntl: fields.u64()?,
27 isolated_raw_usd: fields.i64()?,
28 leverage: fields.u32()?,
29 is_isolated: fields.bool()?,
30 })
31}
32
33#[must_use]
36pub fn position(user: Address, perp: u16) -> Read<Position> {
37 read(0x800, &[Arg::Address(user), Arg::Uint(u64::from(perp))], |answer| decode_position(0x800, answer))
38}
39
40#[must_use]
43pub fn position2(user: Address, perp: u32) -> Read<Position> {
44 read(0x813, &[Arg::Address(user), Arg::Uint(u64::from(perp))], |answer| decode_position(0x813, answer))
45}
46
47#[derive(Debug, Clone, Copy, PartialEq, Eq)]
49pub struct SpotBalance {
50 pub total: u64,
51 pub hold: u64,
53 pub entry_ntl: u64,
54}
55
56#[must_use]
59pub fn spot_balance(user: Address, token: u64) -> Read<SpotBalance> {
60 read(0x801, &[Arg::Address(user), Arg::Uint(token)], |answer| {
61 let tokens = tokens(0x801, answer)?;
62 let mut fields = Fields::of("spotBalance", &tokens)?;
63 Ok(SpotBalance { total: fields.u64()?, hold: fields.u64()?, entry_ntl: fields.u64()? })
64 })
65}
66
67#[derive(Debug, Clone, Copy, PartialEq, Eq)]
68pub struct UserVaultEquity {
69 pub equity: u64,
71 pub locked_until_timestamp: u64,
73}
74
75#[must_use]
77pub fn user_vault_equity(user: Address, vault: Address) -> Read<UserVaultEquity> {
78 read(0x802, &[Arg::Address(user), Arg::Address(vault)], |answer| {
79 let tokens = tokens(0x802, answer)?;
80 let mut fields = Fields::of("userVaultEquity", &tokens)?;
81 Ok(UserVaultEquity { equity: fields.u64()?, locked_until_timestamp: fields.u64()? })
82 })
83}
84
85#[must_use]
87pub fn withdrawable(user: Address) -> Read<u64> {
88 read(0x803, &[Arg::Address(user)], |answer| Fields::of("withdrawable", &tokens(0x803, answer)?)?.u64())
89}
90
91#[derive(Debug, Clone, Copy, PartialEq, Eq)]
93pub struct AccountMarginSummary {
94 pub account_value: i64,
95 pub margin_used: u64,
96 pub ntl_pos: u64,
97 pub raw_usd: i64,
98}
99
100#[must_use]
102pub fn account_margin_summary(perp_dex_index: u32, user: Address) -> Read<AccountMarginSummary> {
103 read(0x80f, &[Arg::Uint(u64::from(perp_dex_index)), Arg::Address(user)], |answer| {
104 let tokens = tokens(0x80f, answer)?;
105 let mut fields = Fields::of("accountMarginSummary", &tokens)?;
106 Ok(AccountMarginSummary {
107 account_value: fields.i64()?,
108 margin_used: fields.u64()?,
109 ntl_pos: fields.u64()?,
110 raw_usd: fields.i64()?,
111 })
112 })
113}
114
115#[must_use]
117pub fn core_user_exists(user: Address) -> Read<bool> {
118 read(0x810, &[Arg::Address(user)], |answer| Fields::of("coreUserExists", &tokens(0x810, answer)?)?.bool())
119}
120
121#[cfg(test)]
122#[path = "tests/account.rs"]
123mod tests;