use crate::client::evm::abi::AbiError;
use crate::client::evm::precompiles::fields::{Fields, tokens};
use crate::client::evm::precompiles::read::{Arg, Read, read};
use crate::utils::Address;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Position {
pub szi: i64,
pub entry_ntl: u64,
pub isolated_raw_usd: i64,
pub leverage: u32,
pub is_isolated: bool,
}
fn decode_position(at: u16, answer: &[u8]) -> Result<Position, AbiError> {
let tokens = tokens(at, answer)?;
let mut fields = Fields::of("position", &tokens)?;
Ok(Position {
szi: fields.i64()?,
entry_ntl: fields.u64()?,
isolated_raw_usd: fields.i64()?,
leverage: fields.u32()?,
is_isolated: fields.bool()?,
})
}
#[must_use]
pub fn position(user: Address, perp: u16) -> Read<Position> {
read(0x800, &[Arg::Address(user), Arg::Uint(u64::from(perp))], |answer| decode_position(0x800, answer))
}
#[must_use]
pub fn position2(user: Address, perp: u32) -> Read<Position> {
read(0x813, &[Arg::Address(user), Arg::Uint(u64::from(perp))], |answer| decode_position(0x813, answer))
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct SpotBalance {
pub total: u64,
pub hold: u64,
pub entry_ntl: u64,
}
#[must_use]
pub fn spot_balance(user: Address, token: u64) -> Read<SpotBalance> {
read(0x801, &[Arg::Address(user), Arg::Uint(token)], |answer| {
let tokens = tokens(0x801, answer)?;
let mut fields = Fields::of("spotBalance", &tokens)?;
Ok(SpotBalance { total: fields.u64()?, hold: fields.u64()?, entry_ntl: fields.u64()? })
})
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct UserVaultEquity {
pub equity: u64,
pub locked_until_timestamp: u64,
}
#[must_use]
pub fn user_vault_equity(user: Address, vault: Address) -> Read<UserVaultEquity> {
read(0x802, &[Arg::Address(user), Arg::Address(vault)], |answer| {
let tokens = tokens(0x802, answer)?;
let mut fields = Fields::of("userVaultEquity", &tokens)?;
Ok(UserVaultEquity { equity: fields.u64()?, locked_until_timestamp: fields.u64()? })
})
}
#[must_use]
pub fn withdrawable(user: Address) -> Read<u64> {
read(0x803, &[Arg::Address(user)], |answer| Fields::of("withdrawable", &tokens(0x803, answer)?)?.u64())
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct AccountMarginSummary {
pub account_value: i64,
pub margin_used: u64,
pub ntl_pos: u64,
pub raw_usd: i64,
}
#[must_use]
pub fn account_margin_summary(perp_dex_index: u32, user: Address) -> Read<AccountMarginSummary> {
read(0x80f, &[Arg::Uint(u64::from(perp_dex_index)), Arg::Address(user)], |answer| {
let tokens = tokens(0x80f, answer)?;
let mut fields = Fields::of("accountMarginSummary", &tokens)?;
Ok(AccountMarginSummary {
account_value: fields.i64()?,
margin_used: fields.u64()?,
ntl_pos: fields.u64()?,
raw_usd: fields.i64()?,
})
})
}
#[must_use]
pub fn core_user_exists(user: Address) -> Read<bool> {
read(0x810, &[Arg::Address(user)], |answer| Fields::of("coreUserExists", &tokens(0x810, answer)?)?.bool())
}
#[cfg(test)]
#[path = "tests/account.rs"]
mod tests;