Skip to content

Reopen HIP3 support pr#1009

Draft
0xh3rman wants to merge 6 commits intomainfrom
codex/hip-3-perps
Draft

Reopen HIP3 support pr#1009
0xh3rman wants to merge 6 commits intomainfrom
codex/hip-3-perps

Conversation

@0xh3rman
Copy link
Collaborator

No description provided.

Extract active_dex_entries helper to deduplicate DEX iteration across
get_positions, get_perpetuals_data, and get_perpetual_portfolio. Add
is_active filtering to skip inactive builder DEXs. Add unit tests for
merge functions, perp_asset_index, and integration tests for new RPC
endpoints.
@semanticdiff-com
Copy link

semanticdiff-com bot commented Mar 13, 2026

Review changes with  SemanticDiff

Changed Files
File Status
  crates/gem_hypercore/src/rpc/client.rs  17% smaller
  crates/gem_hypercore/src/provider/perpetual.rs  2% smaller
  crates/gem_hypercore/src/models/mod.rs  0% smaller
  crates/gem_hypercore/src/models/perp_dex.rs  0% smaller
  crates/gem_hypercore/src/provider/perpetual_mapper.rs  0% smaller

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly expands the system's capabilities by re-enabling and enhancing support for HIP3, allowing for seamless integration and aggregation of data from multiple perpetual decentralized exchanges. It introduces new data structures to represent DEXs, refactors the core client to interact with these multiple sources, and implements robust logic to combine diverse data streams into a single, comprehensive view for users. This change broadens the scope of supported trading platforms and improves data consistency.

Highlights

  • HIP3 Support Re-enabled: This pull request re-enables and enhances support for HIP3, focusing on integrating and aggregating data from multiple perpetual decentralized exchanges (DEXs).
  • Perpetual DEX Model: A new PerpDex struct was introduced to model perpetual decentralized exchanges, capturing essential information such as name, deployer, and activity status.
  • Multi-DEX Data Aggregation: The HyperCoreClient now fetches perpetual data, including positions, metadata, and user portfolios, from all active DEXs concurrently and aggregates the results into a unified view.
  • Enhanced RPC Client: RPC client methods for fetching clearinghouse state, metadata, open orders, and perpetual portfolios were refactored to optionally query specific DEXs, alongside a new method to retrieve a list of all perpetual DEXs.
  • Unique Asset Indexing: A new perp_asset_index function was added to generate unique identifiers for perpetual assets, ensuring distinct identification across different DEXs, especially for HIP3 assets.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • crates/gem_hypercore/src/models/mod.rs
    • Added the perp_dex module to the models.
  • crates/gem_hypercore/src/models/perp_dex.rs
    • Added the PerpDex struct to represent perpetual decentralized exchange data.
  • crates/gem_hypercore/src/provider/perpetual.rs
    • Refactored get_positions to fetch and aggregate positions from multiple DEXs.
    • Refactored get_perpetuals_data to fetch and aggregate metadata from multiple DEXs.
    • Refactored get_perpetual_portfolio to fetch and aggregate portfolios from multiple DEXs.
    • Added active_dex_entries function to filter active DEXs.
    • Added fetch_positions_for_dex and fetch_portfolio_for_dex helper methods for DEX-specific data retrieval.
    • Included new unit tests for active_dex_entries.
    • Added new integration tests for get_perp_dexs, get_positions, and get_perpetuals_data.
  • crates/gem_hypercore/src/provider/perpetual_mapper.rs
    • Introduced HIP3_PERP_ASSET_OFFSET and HIP3_PERP_ASSET_STRIDE constants for asset indexing.
    • Modified map_perpetuals_data to accept perp_dex_index and utilize perp_asset_index for generating unique identifiers.
    • Added perp_asset_index function for creating unique perpetual asset identifiers across DEXs.
    • Added map_account_summary_aggregate to combine account summaries from multiple positions.
    • Added merge_perpetual_portfolios, merge_portfolio_timeframes, and merge_chart_histories functions for aggregating portfolio data.
    • Updated existing tests for map_perpetuals_data and added new tests for map_account_summary_aggregate, perp_asset_index, merge_chart_histories, merge_perpetual_portfolios, and merge_portfolio_timeframes.
  • crates/gem_hypercore/src/rpc/client.rs
    • Imported the new PerpDex model.
    • Refactored get_clearinghouse_state, get_metadata, get_open_orders, and get_perpetual_portfolio to delegate to new _with_dex variants.
    • Added get_clearinghouse_state_with_dex, get_metadata_with_dex, get_open_orders_with_dex, and get_perpetual_portfolio_with_dex methods to allow specifying a DEX.
    • Added get_perp_dexs method to fetch a list of perpetual DEXs.
Activity
  • No human activity has been recorded on this pull request yet.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request adds support for multiple perpetual DEXs (HIP3), which is a significant feature. The changes are extensive, touching models, the RPC client, and provider logic to fetch and aggregate data from multiple sources. The implementation appears solid and is accompanied by a good set of unit and integration tests. I have a couple of suggestions to improve code style and use more idiomatic Rust, but overall this is a great contribution.

Comment on lines +64 to +75
let mut positions = Vec::new();
let mut balance = PerpetualBalance {
available: 0.0,
reserved: 0.0,
withdrawable: 0.0,
};
for summary in summaries {
positions.extend(summary.positions);
balance.available += summary.balance.available;
balance.reserved += summary.balance.reserved;
balance.withdrawable += summary.balance.withdrawable;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This aggregation logic can be expressed more concisely and functionally using fold. This would reduce the need for mutable variables and make the intent clearer.

        let (positions, balance) = summaries.into_iter().fold(
            (Vec::new(), PerpetualBalance { available: 0.0, reserved: 0.0, withdrawable: 0.0 }),
            |(mut acc_pos, mut acc_bal), summary| {
                acc_pos.extend(summary.positions);
                acc_bal.available += summary.balance.available;
                acc_bal.reserved += summary.balance.reserved;
                acc_bal.withdrawable += summary.balance.withdrawable;
                (acc_pos, acc_bal)
            },
        );

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot fix it

Comment on lines +179 to +203
pub fn map_account_summary_aggregate(positions: &[AssetPositions]) -> PerpetualAccountSummary {
let mut account_value = 0.0;
let mut total_ntl_pos = 0.0;
let mut total_margin_used = 0.0;
let mut unrealized_pnl = 0.0;

for positions in positions {
account_value += positions.margin_summary.account_value.parse::<f64>().unwrap_or(0.0);
total_ntl_pos += positions.margin_summary.total_ntl_pos.parse::<f64>().unwrap_or(0.0);
total_margin_used += positions.margin_summary.total_margin_used.parse::<f64>().unwrap_or(0.0);
for position in &positions.asset_positions {
unrealized_pnl += position.position.unrealized_pnl.parse::<f64>().unwrap_or(0.0);
}
}

let account_leverage = if account_value > 0.0 { total_ntl_pos / account_value } else { 0.0 };
let margin_usage = if account_value > 0.0 { total_margin_used / account_value } else { 0.0 };

PerpetualAccountSummary {
account_value,
account_leverage,
margin_usage,
unrealized_pnl,
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This function can be written more idiomatically and concisely using Rust's iterator methods like map, flat_map, and sum. This would eliminate the manual loop and mutable variables, improving readability.

pub fn map_account_summary_aggregate(positions: &[AssetPositions]) -> PerpetualAccountSummary {
    let account_value: f64 = positions.iter().map(|p| p.margin_summary.account_value.parse().unwrap_or(0.0)).sum();
    let total_ntl_pos: f64 = positions.iter().map(|p| p.margin_summary.total_ntl_pos.parse().unwrap_or(0.0)).sum();
    let total_margin_used: f64 = positions.iter().map(|p| p.margin_summary.total_margin_used.parse().unwrap_or(0.0)).sum();
    let unrealized_pnl: f64 = positions.iter().flat_map(|p| &p.asset_positions).map(|p| p.position.unrealized_pnl.parse().unwrap_or(0.0)).sum();

    let account_leverage = if account_value > 0.0 { total_ntl_pos / account_value } else { 0.0 };
    let margin_usage = if account_value > 0.0 { total_margin_used / account_value } else { 0.0 };

    PerpetualAccountSummary {
        account_value,
        account_leverage,
        margin_usage,
        unrealized_pnl,
    }
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot fix it

Comment on lines +161 to +163
if let Some(dex) = dex
&& !dex.is_empty()
{
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The formatting of this if let chain is unconventional and can be hard to read. For better readability, consider putting it on a single line. This comment applies to similar constructs in this file (e.g., lines 175-177, 279-281, and 296-298).

        if let Some(dex) = dex && !dex.is_empty() {

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot fix it

Copy link
Contributor

Copilot AI commented Mar 15, 2026

@gemcoder21 I've opened a new pull request, #1012, to work on those changes. Once the pull request is ready, I'll request review from you.

Copy link
Contributor

Copilot AI commented Mar 15, 2026

@gemcoder21 I've opened a new pull request, #1013, to work on those changes. Once the pull request is ready, I'll request review from you.

Copy link
Contributor

Copilot AI commented Mar 15, 2026

@gemcoder21 I've opened a new pull request, #1014, to work on those changes. Once the pull request is ready, I'll request review from you.

Copilot AI and others added 3 commits March 16, 2026 02:15
…thods (#1012)

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: gemcoder21 <104884878+gemcoder21@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: gemcoder21 <104884878+gemcoder21@users.noreply.github.com>
…itions (#1013)

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: gemcoder21 <104884878+gemcoder21@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants