From 189d87ab9c32c7ecdc518bf0c4b0d03a9b7fbf5a Mon Sep 17 00:00:00 2001 From: Sree Revoori Date: Sat, 31 Jan 2026 13:25:27 -0500 Subject: [PATCH] Add missing info endpoints Add support for all missing info API endpoints as described in hyperliquid docs. Tested by running example binaries. --- src/bin/info.rs | 284 ++++++++++++++++++++++++++ src/info/info_client.rs | 311 +++++++++++++++++++++++++++- src/info/response_structs.rs | 386 ++++++++++++++++++++++++++++++++++- src/info/sub_structs.rs | 62 ++++++ 4 files changed, 1039 insertions(+), 4 deletions(-) diff --git a/src/bin/info.rs b/src/bin/info.rs index f6df1178..72a5fa2b 100644 --- a/src/bin/info.rs +++ b/src/bin/info.rs @@ -28,6 +28,36 @@ async fn main() { query_order_by_oid_example(&info_client).await; query_referral_state_example(&info_client).await; historical_orders_example(&info_client).await; + frontend_open_orders_example(&info_client).await; + user_fills_by_time_example(&info_client).await; + user_twap_slice_fills_example(&info_client).await; + portfolio_example(&info_client).await; + user_role_example(&info_client).await; + user_rate_limit_example(&info_client).await; + sub_accounts_example(&info_client).await; + vault_details_example(&info_client).await; + user_vault_equities_example(&info_client).await; + max_builder_fee_example(&info_client).await; + delegations_example(&info_client).await; + delegator_summary_example(&info_client).await; + delegator_history_example(&info_client).await; + delegator_rewards_example(&info_client).await; + borrow_lend_user_state_example(&info_client).await; + borrow_lend_reserve_state_example(&info_client).await; + all_borrow_lend_reserve_states_example(&info_client).await; + user_dex_abstraction_example(&info_client).await; + aligned_quote_token_info_example(&info_client).await; + perp_dexs_example(&info_client).await; + user_non_funding_ledger_updates_example(&info_client).await; + predicted_fundings_example(&info_client).await; + perps_at_open_interest_cap_example(&info_client).await; + perp_deploy_auction_status_example(&info_client).await; + perp_dex_limits_example(&info_client).await; + perp_dex_status_example(&info_client).await; + all_perp_metas_example(&info_client).await; + spot_deploy_state_example(&info_client).await; + spot_pair_deploy_auction_status_example(&info_client).await; + token_details_example(&info_client).await; } fn address() -> Address { @@ -205,3 +235,257 @@ async fn historical_orders_example(info_client: &InfoClient) { info_client.historical_orders(user).await.unwrap() ); } + +async fn frontend_open_orders_example(info_client: &InfoClient) { + let user = address(); + info!( + "Frontend open orders for {user}: {:?}", + info_client.frontend_open_orders(user).await.unwrap() + ); +} + +async fn user_fills_by_time_example(info_client: &InfoClient) { + let user = address(); + let start_timestamp = 1690540602225; + let end_timestamp = 1690569402225; + info!( + "User fills by time for {user} between {start_timestamp} and {end_timestamp}: {:?}", + info_client + .user_fills_by_time(user, start_timestamp, Some(end_timestamp), None) + .await + .unwrap() + ); +} + +async fn user_twap_slice_fills_example(info_client: &InfoClient) { + let user = address(); + info!( + "User TWAP slice fills for {user}: {:?}", + info_client.user_twap_slice_fills(user).await.unwrap() + ); +} + +async fn portfolio_example(info_client: &InfoClient) { + let user = address(); + info!( + "Portfolio for {user}: {:?}", + info_client.portfolio(user).await.unwrap() + ); +} + +async fn user_role_example(info_client: &InfoClient) { + let user = address(); + info!( + "User role for {user}: {:?}", + info_client.user_role(user).await.unwrap() + ); +} + +async fn user_rate_limit_example(info_client: &InfoClient) { + let user = address(); + info!( + "User rate limit for {user}: {:?}", + info_client.user_rate_limit(user).await.unwrap() + ); +} + +async fn sub_accounts_example(info_client: &InfoClient) { + let user = address(); + info!( + "Sub accounts for {user}: {:?}", + info_client.sub_accounts(user).await.unwrap() + ); +} + +async fn vault_details_example(info_client: &InfoClient) { + // Example vault address (you may need to replace with a valid vault address) + let vault_address: Address = "0x1234567890123456789012345678901234567890" + .parse() + .unwrap(); + let user = address(); + match info_client.vault_details(vault_address, Some(user)).await { + Ok(details) => info!( + "Vault details for {vault_address} (user: {user}): {:?}", + details + ), + Err(e) => info!("Vault details error (expected if vault doesn't exist): {e}"), + } +} + +async fn user_vault_equities_example(info_client: &InfoClient) { + let user = address(); + info!( + "User vault equities for {user}: {:?}", + info_client.user_vault_equities(user).await.unwrap() + ); +} + +async fn max_builder_fee_example(info_client: &InfoClient) { + let user = address(); + let builder: Address = "0x1234567890123456789012345678901234567890" + .parse() + .unwrap(); + info!( + "Max builder fee for user {user} and builder {builder}: {:?}", + info_client.max_builder_fee(user, builder).await.unwrap() + ); +} + +async fn delegations_example(info_client: &InfoClient) { + let user = address(); + info!( + "Delegations for {user}: {:?}", + info_client.delegations(user).await.unwrap() + ); +} + +async fn delegator_summary_example(info_client: &InfoClient) { + let user = address(); + info!( + "Delegator summary for {user}: {:?}", + info_client.delegator_summary(user).await.unwrap() + ); +} + +async fn delegator_history_example(info_client: &InfoClient) { + let user = address(); + info!( + "Delegator history for {user}: {:?}", + info_client.delegator_history(user).await.unwrap() + ); +} + +async fn delegator_rewards_example(info_client: &InfoClient) { + let user = address(); + info!( + "Delegator rewards for {user}: {:?}", + info_client.delegator_rewards(user).await.unwrap() + ); +} + +async fn borrow_lend_user_state_example(info_client: &InfoClient) { + let user = address(); + info!( + "Borrow/lend user state for {user}: {:?}", + info_client.borrow_lend_user_state(user).await.unwrap() + ); +} + +async fn borrow_lend_reserve_state_example(info_client: &InfoClient) { + let token: u32 = 0; // USDC token index + info!( + "Borrow/lend reserve state for token {token}: {:?}", + info_client.borrow_lend_reserve_state(token).await.unwrap() + ); +} + +async fn all_borrow_lend_reserve_states_example(info_client: &InfoClient) { + info!( + "All borrow/lend reserve states: {:?}", + info_client.all_borrow_lend_reserve_states().await.unwrap() + ); +} + +async fn user_dex_abstraction_example(info_client: &InfoClient) { + let user = address(); + info!( + "User DEX abstraction for {user}: {:?}", + info_client.user_dex_abstraction(user).await.unwrap() + ); +} + +async fn aligned_quote_token_info_example(info_client: &InfoClient) { + let token: u32 = 0; // USDC token index + info!( + "Aligned quote token info for token {token}: {:?}", + info_client.aligned_quote_token_info(token).await.unwrap() + ); +} + +async fn perp_dexs_example(info_client: &InfoClient) { + info!( + "Perpetual DEXs: {:?}", + info_client.perp_dexs().await.unwrap() + ); +} + +async fn user_non_funding_ledger_updates_example(info_client: &InfoClient) { + let user = address(); + let start_timestamp = 1690540602225; + let end_timestamp = 1690569402225; + info!( + "User non-funding ledger updates for {user}: {:?}", + info_client + .user_non_funding_ledger_updates(user, start_timestamp, Some(end_timestamp)) + .await + .unwrap() + ); +} + +async fn predicted_fundings_example(info_client: &InfoClient) { + info!( + "Predicted fundings: {:?}", + info_client.predicted_fundings().await.unwrap() + ); +} + +async fn perps_at_open_interest_cap_example(info_client: &InfoClient) { + info!( + "Perps at open interest cap: {:?}", + info_client.perps_at_open_interest_cap(None).await.unwrap() + ); +} + +async fn perp_deploy_auction_status_example(info_client: &InfoClient) { + info!( + "Perp deploy auction status: {:?}", + info_client.perp_deploy_auction_status().await.unwrap() + ); +} + +async fn perp_dex_limits_example(info_client: &InfoClient) { + // Example DEX name - adjust as needed for a valid builder-deployed DEX + let dex = "example_dex"; + match info_client.perp_dex_limits(dex.to_string()).await { + Ok(limits) => info!("Perp DEX limits for {dex}: {:?}", limits), + Err(e) => info!("Perp DEX limits error (expected if DEX doesn't exist): {e}"), + } +} + +async fn perp_dex_status_example(info_client: &InfoClient) { + info!( + "Perp DEX status: {:?}", + info_client.perp_dex_status(None).await.unwrap() + ); +} + +async fn all_perp_metas_example(info_client: &InfoClient) { + info!( + "All perp metas: {:?}", + info_client.all_perp_metas().await.unwrap() + ); +} + +async fn spot_deploy_state_example(info_client: &InfoClient) { + let user = address(); + info!( + "Spot deploy state for {user}: {:?}", + info_client.spot_deploy_state(user).await.unwrap() + ); +} + +async fn spot_pair_deploy_auction_status_example(info_client: &InfoClient) { + info!( + "Spot pair deploy auction status: {:?}", + info_client.spot_pair_deploy_auction_status().await.unwrap() + ); +} + +async fn token_details_example(info_client: &InfoClient) { + // Example token ID (USDC on testnet - adjust as needed) + let token_id = "0xc1fb593aeffbeb02f85e0308e9956a90"; + match info_client.token_details(token_id.to_string()).await { + Ok(details) => info!("Token details for {token_id}: {:?}", details), + Err(e) => info!("Token details error (expected if token doesn't exist): {e}"), + } +} diff --git a/src/info/info_client.rs b/src/info/info_client.rs index b3d8ba2a..351c7d1b 100644 --- a/src/info/info_client.rs +++ b/src/info/info_client.rs @@ -7,9 +7,16 @@ use tokio::sync::mpsc::UnboundedSender; use crate::{ info::{ - ActiveAssetDataResponse, CandlesSnapshotResponse, FundingHistoryResponse, - L2SnapshotResponse, OpenOrdersResponse, OrderInfo, RecentTradesResponse, UserFillsResponse, - UserStateResponse, + ActiveAssetDataResponse, AlignedQuoteTokenInfoResponse, AllPerpMetasResponse, + BorrowLendReserveStateResponse, BorrowLendUserStateResponse, CandlesSnapshotResponse, + DelegationResponse, DelegatorHistoryEntry, DelegatorRewardsEntry, DelegatorSummaryResponse, + FrontendOpenOrdersResponse, FundingHistoryResponse, L2SnapshotResponse, + MaxBuilderFeeResponse, OpenOrdersResponse, OrderInfo, PerpDeployAuctionStatusResponse, + PerpDex, PerpDexLimitsResponse, PerpDexStatusResponse, PortfolioResponse, PredictedFunding, + RecentTradesResponse, SpotDeployStateResponse, SpotPairDeployAuctionStatusResponse, + SubAccountResponse, TokenDetailsResponse, UserFillsResponse, UserNonFundingLedgerUpdate, + UserRateLimitResponse, UserRoleResponse, UserStateResponse, UserVaultEquityResponse, + VaultDetailsResponse, }, meta::{AssetContext, Meta, SpotMeta, SpotMetaAndAssetCtxs}, prelude::*, @@ -94,6 +101,104 @@ pub enum InfoRequest { user: Address, coin: String, }, + FrontendOpenOrders { + user: Address, + }, + #[serde(rename_all = "camelCase")] + UserFillsByTime { + user: Address, + start_time: u64, + #[serde(skip_serializing_if = "Option::is_none")] + end_time: Option, + #[serde(skip_serializing_if = "Option::is_none")] + aggregate_by_time: Option, + }, + UserTwapSliceFills { + user: Address, + }, + Portfolio { + user: Address, + }, + UserRole { + user: Address, + }, + UserRateLimit { + user: Address, + }, + SubAccounts { + user: Address, + }, + #[serde(rename_all = "camelCase")] + VaultDetails { + vault_address: Address, + #[serde(skip_serializing_if = "Option::is_none")] + user: Option
, + }, + UserVaultEquities { + user: Address, + }, + MaxBuilderFee { + user: Address, + builder: Address, + }, + Delegations { + user: Address, + }, + DelegatorSummary { + user: Address, + }, + DelegatorHistory { + user: Address, + }, + DelegatorRewards { + user: Address, + }, + BorrowLendUserState { + user: Address, + }, + BorrowLendReserveState { + token: u32, + }, + AllBorrowLendReserveStates, + UserDexAbstraction { + user: Address, + }, + AlignedQuoteTokenInfo { + token: u32, + }, + PerpDexs, + #[serde(rename_all = "camelCase")] + UserNonFundingLedgerUpdates { + user: Address, + start_time: u64, + #[serde(skip_serializing_if = "Option::is_none")] + end_time: Option, + }, + PredictedFundings, + #[serde(rename_all = "camelCase")] + PerpsAtOpenInterestCap { + #[serde(skip_serializing_if = "Option::is_none")] + dex: Option, + }, + PerpDeployAuctionStatus, + #[serde(rename_all = "camelCase")] + PerpDexLimits { + dex: String, + }, + #[serde(rename_all = "camelCase")] + PerpDexStatus { + #[serde(skip_serializing_if = "Option::is_none")] + dex: Option, + }, + AllPerpMetas, + SpotDeployState { + user: Address, + }, + SpotPairDeployAuctionStatus, + #[serde(rename_all = "camelCase")] + TokenDetails { + token_id: String, + }, } #[derive(Debug)] @@ -320,4 +425,204 @@ impl InfoClient { let input = InfoRequest::ActiveAssetData { user, coin }; self.send_info_request(input).await } + + pub async fn frontend_open_orders( + &self, + address: Address, + ) -> Result> { + let input = InfoRequest::FrontendOpenOrders { user: address }; + self.send_info_request(input).await + } + + pub async fn user_fills_by_time( + &self, + user: Address, + start_time: u64, + end_time: Option, + aggregate_by_time: Option, + ) -> Result> { + let input = InfoRequest::UserFillsByTime { + user, + start_time, + end_time, + aggregate_by_time, + }; + self.send_info_request(input).await + } + + pub async fn user_twap_slice_fills(&self, address: Address) -> Result> { + let input = InfoRequest::UserTwapSliceFills { user: address }; + self.send_info_request(input).await + } + + pub async fn portfolio(&self, address: Address) -> Result { + let input = InfoRequest::Portfolio { user: address }; + self.send_info_request(input).await + } + + pub async fn user_role(&self, address: Address) -> Result { + let input = InfoRequest::UserRole { user: address }; + self.send_info_request(input).await + } + + pub async fn user_rate_limit(&self, address: Address) -> Result { + let input = InfoRequest::UserRateLimit { user: address }; + self.send_info_request(input).await + } + + pub async fn sub_accounts(&self, address: Address) -> Result> { + let input = InfoRequest::SubAccounts { user: address }; + self.send_info_request(input).await + } + + pub async fn vault_details( + &self, + vault_address: Address, + user: Option
, + ) -> Result { + let input = InfoRequest::VaultDetails { + vault_address, + user, + }; + self.send_info_request(input).await + } + + pub async fn user_vault_equities( + &self, + address: Address, + ) -> Result> { + let input = InfoRequest::UserVaultEquities { user: address }; + self.send_info_request(input).await + } + + pub async fn max_builder_fee( + &self, + user: Address, + builder: Address, + ) -> Result { + let input = InfoRequest::MaxBuilderFee { user, builder }; + self.send_info_request(input).await + } + + pub async fn delegations(&self, address: Address) -> Result> { + let input = InfoRequest::Delegations { user: address }; + self.send_info_request(input).await + } + + pub async fn delegator_summary(&self, address: Address) -> Result { + let input = InfoRequest::DelegatorSummary { user: address }; + self.send_info_request(input).await + } + + pub async fn delegator_history(&self, address: Address) -> Result> { + let input = InfoRequest::DelegatorHistory { user: address }; + self.send_info_request(input).await + } + + pub async fn delegator_rewards(&self, address: Address) -> Result> { + let input = InfoRequest::DelegatorRewards { user: address }; + self.send_info_request(input).await + } + + pub async fn borrow_lend_user_state( + &self, + address: Address, + ) -> Result { + let input = InfoRequest::BorrowLendUserState { user: address }; + self.send_info_request(input).await + } + + pub async fn borrow_lend_reserve_state( + &self, + token: u32, + ) -> Result { + let input = InfoRequest::BorrowLendReserveState { token }; + self.send_info_request(input).await + } + + pub async fn all_borrow_lend_reserve_states( + &self, + ) -> Result> { + let input = InfoRequest::AllBorrowLendReserveStates; + self.send_info_request(input).await + } + + pub async fn user_dex_abstraction(&self, address: Address) -> Result { + let input = InfoRequest::UserDexAbstraction { user: address }; + self.send_info_request(input).await + } + + pub async fn aligned_quote_token_info( + &self, + token: u32, + ) -> Result { + let input = InfoRequest::AlignedQuoteTokenInfo { token }; + self.send_info_request(input).await + } + + pub async fn perp_dexs(&self) -> Result> { + let input = InfoRequest::PerpDexs; + self.send_info_request(input).await + } + + pub async fn user_non_funding_ledger_updates( + &self, + user: Address, + start_time: u64, + end_time: Option, + ) -> Result> { + let input = InfoRequest::UserNonFundingLedgerUpdates { + user, + start_time, + end_time, + }; + self.send_info_request(input).await + } + + pub async fn predicted_fundings(&self) -> Result> { + let input = InfoRequest::PredictedFundings; + self.send_info_request(input).await + } + + pub async fn perps_at_open_interest_cap(&self, dex: Option) -> Result> { + let input = InfoRequest::PerpsAtOpenInterestCap { dex }; + self.send_info_request(input).await + } + + pub async fn perp_deploy_auction_status(&self) -> Result { + let input = InfoRequest::PerpDeployAuctionStatus; + self.send_info_request(input).await + } + + pub async fn perp_dex_limits(&self, dex: String) -> Result { + let input = InfoRequest::PerpDexLimits { dex }; + self.send_info_request(input).await + } + + pub async fn perp_dex_status(&self, dex: Option) -> Result { + let input = InfoRequest::PerpDexStatus { dex }; + self.send_info_request(input).await + } + + pub async fn all_perp_metas(&self) -> Result> { + let input = InfoRequest::AllPerpMetas; + self.send_info_request(input).await + } + + pub async fn spot_deploy_state(&self, user: Address) -> Result { + let input = InfoRequest::SpotDeployState { user }; + self.send_info_request(input).await + } + + pub async fn spot_pair_deploy_auction_status( + &self, + ) -> Result { + let input = InfoRequest::SpotPairDeployAuctionStatus; + self.send_info_request(input).await + } + + pub async fn token_details(&self, token_id: String) -> Result { + let input = InfoRequest::TokenDetails { token_id }; + self.send_info_request(input).await + } } diff --git a/src/info/response_structs.rs b/src/info/response_structs.rs index 221dbf91..a7549657 100644 --- a/src/info/response_structs.rs +++ b/src/info/response_structs.rs @@ -1,9 +1,14 @@ +use std::collections::HashMap; + use serde::Deserialize; use alloy::primitives::Address; use crate::{ - info::{AssetPosition, Level, MarginSummary}, + info::{ + AssetPosition, BorrowLendTokenState, FollowerState, Level, MarginSummary, PortfolioEntry, + UserRoleData, VaultLeaderCommissionInfo, VaultRelationship, + }, DailyUserVlm, Delta, FeeSchedule, Leverage, OrderInfo, Referrer, ReferrerState, UserTokenBalance, }; @@ -151,3 +156,382 @@ pub struct ActiveAssetDataResponse { pub available_to_trade: Vec, pub mark_px: String, } + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct FrontendOpenOrdersResponse { + pub coin: String, + pub limit_px: String, + pub oid: u64, + pub side: String, + pub sz: String, + pub timestamp: u64, + pub cloid: Option, + pub order_type: String, + pub orig_sz: String, + pub trigger_px: Option, + pub is_position_tpsl: bool, + pub reduce_only: bool, + pub tif: Option, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct PortfolioResponse { + pub day: Vec, + pub week: Vec, + pub month: Vec, + pub all_time: Vec, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct UserRoleResponse { + pub role: String, + pub data: Option, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct UserRateLimitResponse { + pub cum_vlm: String, + pub n_requests_used: u64, + pub n_requests_cap: u64, + pub n_requests_surplus: i64, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct SubAccountResponse { + pub name: String, + pub sub_account_user: Address, + pub clearinghouse_state: UserStateResponse, + pub spot_state: Option, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct VaultDetailsResponse { + pub name: String, + pub vault_address: Address, + pub leader: Address, + pub description: String, + pub portfolio: Vec<(f64, f64)>, + pub apr: f64, + pub follower_state: Option, + pub leader_fraction: f64, + pub leader_commission: Option, + pub max_distributable: String, + pub is_closed: bool, + pub allow_deposits: bool, + pub relationship: Option, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct UserVaultEquityResponse { + pub vault_address: Address, + pub equity: String, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct MaxBuilderFeeResponse { + pub max_fee: u64, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct DelegationResponse { + pub validator: Address, + pub amount: String, + pub locked_until_timestamp: Option, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct DelegatorSummaryResponse { + pub delegated: String, + pub undelegated: String, + pub total_pending_withdrawal: String, + pub n_pending_withdrawals: u32, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct DelegatorHistoryEntry { + pub time: u64, + pub hash: String, + pub delta: String, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct DelegatorRewardsEntry { + pub time: u64, + pub source: String, + pub total_amount: String, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct BorrowLendUserStateResponse { + pub token_to_state: HashMap, + pub health: String, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct BorrowLendReserveStateResponse { + pub token: u32, + pub borrow_rate: String, + pub supply_rate: String, + pub utilization: String, + pub total_supplied: String, + pub total_borrowed: String, + pub oracle_px: String, + pub ltv: String, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct AlignedQuoteTokenInfoResponse { + pub is_aligned: bool, + pub first_aligned_time: Option, + pub minted_supply: String, + pub daily_amounts_owed: Vec, + pub predicted_rate: String, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct PerpDex { + pub name: String, + pub full_name: String, + pub deployer: Address, + pub mark_oracle: String, + pub fee_recipient: Option
, + pub streaming_perp_oi_cap: Option, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct UserNonFundingLedgerUpdate { + pub time: u64, + pub hash: String, + pub delta: LedgerUpdateDelta, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +#[serde(tag = "type")] +pub enum LedgerUpdateDelta { + Deposit(DepositDelta), + Withdraw(WithdrawDelta), + InternalTransfer(InternalTransferDelta), + SubAccountTransfer(SubAccountTransferDelta), + AccountClassTransfer(AccountClassTransferDelta), + SpotTransfer(SpotTransferDelta), + VaultCreate(VaultCreateDelta), + VaultDistribution(VaultDistributionDelta), + VaultDeposit(VaultDepositDelta), + VaultWithdraw(VaultWithdrawDelta), + RewardsClaimDelta(RewardsClaimDelta), +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct DepositDelta { + pub usdc: String, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct WithdrawDelta { + pub usdc: String, + pub nonce: u64, + pub fee: String, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct InternalTransferDelta { + pub usdc: String, + pub user: Address, + pub destination: Address, + pub fee: String, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct SubAccountTransferDelta { + pub usdc: String, + pub user: Address, + pub destination: Address, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct AccountClassTransferDelta { + pub usdc: String, + pub to_perp: bool, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct SpotTransferDelta { + pub token: String, + pub amount: String, + pub usdc_value: String, + pub user: Address, + pub destination: Address, + pub fee: String, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct VaultCreateDelta { + pub vault: Address, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct VaultDistributionDelta { + pub vault: Address, + pub usdc: String, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct VaultDepositDelta { + pub vault: Address, + pub usdc: String, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct VaultWithdrawDelta { + pub vault: Address, + pub usdc: String, + pub requested_usd: String, + pub commission: String, + pub closing_cost: String, + pub basis: String, + pub net_withdrawn_usd: String, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct RewardsClaimDelta { + pub amount: String, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct PredictedFunding { + pub coin: String, + pub venue: String, + pub predicted_funding: String, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct PerpDeployAuctionStatusResponse { + pub start_time: u64, + pub duration: u64, + pub start_gas: String, + pub end_gas: String, + pub current_gas: String, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct PerpDexLimitsResponse { + pub total_oi_cap: String, + pub per_asset_oi_cap: String, + pub max_transfer: String, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct PerpDexStatusResponse { + pub total_net_deposit: String, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct AllPerpMetasResponse { + pub dex: String, + pub universe: Vec, + pub asset_ctxs: Vec, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct SpotDeployStateResponse { + pub states: Vec, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct SpotDeployTokenState { + pub token: u32, + pub spec: SpotDeploySpec, + pub genesis_balances: Vec, + pub gas_auction: Option, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct SpotDeploySpec { + pub name: String, + pub sz_decimals: u8, + pub wei_decimals: u8, + pub max_supply: String, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct GenesisBalance { + pub user: Address, + pub balance: String, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct GasAuction { + pub start_time: u64, + pub end_time: u64, + pub start_gas: String, + pub end_gas: String, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct SpotPairDeployAuctionStatusResponse { + pub start_time: u64, + pub duration: u64, + pub start_gas: String, + pub end_gas: String, + pub current_gas: String, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct TokenDetailsResponse { + pub name: String, + pub token_id: String, + pub index: u32, + pub sz_decimals: u8, + pub wei_decimals: u8, + pub total_supply: String, + pub circulating_supply: String, + pub mark_px: String, + pub mid_px: Option, + pub genesis_balances: Vec, + pub deployer: Address, + pub deploy_time: u64, + pub deploy_gas: String, + pub seeded_usdc: String, + pub full_name: Option, +} diff --git a/src/info/sub_structs.rs b/src/info/sub_structs.rs index d244a063..a8c8f0cc 100644 --- a/src/info/sub_structs.rs +++ b/src/info/sub_structs.rs @@ -164,3 +164,65 @@ pub struct ReferrerState { pub struct ReferrerData { pub required: String, } + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct PortfolioEntry { + pub account_value_history: Vec<(u64, String)>, + pub pnl_history: Vec<(u64, String)>, + pub vlm: String, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct BorrowLendTokenState { + pub borrow_basis: String, + pub borrow_value: String, + pub supply_basis: String, + pub supply_value: String, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct FollowerState { + pub pnl: String, + pub alloc: String, + pub vault_entry_time: u64, + pub lockup_until: u64, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct UserRoleData { + pub master: Option
, + pub agent_address: Option
, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct VaultLeaderCommissionInfo { + pub address: Address, + pub fraction: String, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct VaultRelationship { + #[serde(rename = "type")] + pub relationship_type: String, + pub data: VaultRelationshipData, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct VaultRelationshipData { + pub parent_vault: Option
, + pub children: Option>, +} + +#[derive(Deserialize, Debug)] +#[serde(rename_all = "camelCase")] +pub struct VaultChild { + pub address: Address, + pub name: String, +}