use serde::Deserialize;
use crate::client::http::{ApiError, Call, Transport, read};
use crate::markets::listed;
use crate::utils::ids::whole;
use crate::utils::{AccountIndex, Address};
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
pub struct SystemConfig {
#[serde(deserialize_with = "whole")]
pub liquidity_pool_index: u64,
#[serde(deserialize_with = "whole")]
pub staking_pool_index: u64,
#[serde(deserialize_with = "whole")]
pub funding_fee_rebate_account_index: u64,
#[serde(default, deserialize_with = "whole")]
pub market_maker_incentive_account_index: u64,
#[serde(deserialize_with = "whole")]
pub fee_collector_account_index: u64,
#[serde(deserialize_with = "whole")]
pub liquidity_pool_cooldown_period: u64,
#[serde(deserialize_with = "whole")]
pub staking_pool_lockup_period: u64,
pub max_integrator_spot_taker_fee: u32,
pub max_integrator_spot_maker_fee: u32,
pub max_integrator_perps_taker_fee: u32,
pub max_integrator_perps_maker_fee: u32,
}
impl SystemConfig {
#[must_use]
pub fn liquidity_pool(&self) -> Option<AccountIndex> {
AccountIndex::new(self.liquidity_pool_index).ok()
}
#[must_use]
pub fn staking_pool(&self) -> Option<AccountIndex> {
AccountIndex::new(self.staking_pool_index).ok()
}
}
#[must_use]
pub fn system_config_call() -> Call {
Call::get("systemConfig")
}
pub async fn system_config(transport: &impl Transport) -> Result<SystemConfig, ApiError> {
read(transport, system_config_call()).await
}
#[derive(Deserialize)]
struct ZkLighterInfo {
contract_address: Address,
}
#[must_use]
pub fn info_call() -> Call {
Call::get("/info")
}
pub async fn contract_address(transport: &impl Transport) -> Result<Address, ApiError> {
Ok(read::<ZkLighterInfo>(transport, info_call()).await?.contract_address)
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
pub struct L1Provider {
#[serde(rename = "chainId", deserialize_with = "whole")]
pub chain_id: u64,
#[serde(rename = "networkId", deserialize_with = "whole")]
pub network_id: u64,
#[serde(rename = "latestBlockNumber", default, deserialize_with = "whole")]
pub latest_block_number: u64,
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
pub struct Validator {
pub address: Address,
pub is_active: bool,
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
pub struct NamedContract {
pub name: String,
pub address: Address,
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
pub struct L1Info {
#[serde(default, deserialize_with = "listed")]
pub l1_providers: Vec<L1Provider>,
pub l1_providers_health: bool,
#[serde(default, deserialize_with = "listed")]
pub validator_info: Vec<Validator>,
#[serde(default, deserialize_with = "listed")]
pub contract_addresses: Vec<NamedContract>,
#[serde(default, deserialize_with = "whole")]
pub latest_l1_generic_block: u64,
#[serde(default, deserialize_with = "whole")]
pub latest_l1_governance_block: u64,
#[serde(default, deserialize_with = "whole")]
pub latest_l1_desert_block: u64,
}
impl L1Info {
#[must_use]
pub fn contract(&self, name: &str) -> Option<Address> {
self.contract_addresses.iter().find(|contract| contract.name == name).map(|contract| contract.address)
}
#[must_use]
pub fn chain_id(&self) -> Option<u64> {
self.l1_providers.first().map(|provider| provider.chain_id)
}
}
#[must_use]
pub fn layer1_basic_info_call() -> Call {
Call::get("layer1BasicInfo")
}
pub async fn layer1_basic_info(transport: &impl Transport) -> Result<L1Info, ApiError> {
read(transport, layer1_basic_info_call()).await
}
#[derive(Deserialize)]
struct WithdrawalDelay {
#[serde(deserialize_with = "whole")]
seconds: u64,
}
#[must_use]
pub fn withdrawal_delay_call() -> Call {
Call::get("withdrawalDelay")
}
pub async fn withdrawal_delay(transport: &impl Transport) -> Result<u64, ApiError> {
Ok(read::<WithdrawalDelay>(transport, withdrawal_delay_call()).await?.seconds)
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
pub struct Announcement {
pub title: String,
pub content: String,
#[serde(deserialize_with = "whole")]
pub created_at: u64,
#[serde(default, deserialize_with = "whole")]
pub expired_at: u64,
}
#[derive(Deserialize)]
struct Announcements {
#[serde(default, deserialize_with = "listed")]
announcements: Vec<Announcement>,
}
#[must_use]
pub fn announcements_call() -> Call {
Call::get("announcement")
}
pub async fn announcements(transport: &impl Transport) -> Result<Vec<Announcement>, ApiError> {
Ok(read::<Announcements>(transport, announcements_call()).await?.announcements)
}
#[cfg(test)]
#[path = "tests/system.rs"]
mod tests;