Skip to content

Perps portfolio#899

Merged
gemdev111 merged 14 commits intomainfrom
perps_portfolio
Jan 22, 2026
Merged

Perps portfolio#899
gemdev111 merged 14 commits intomainfrom
perps_portfolio

Conversation

@gemdev111
Copy link
Contributor

Introduces PerpetualAccountSummary struct and integrates it into PerpetualPortfolio in both primitives and gemstone models. Updates mapping logic and tests to populate and verify the new account_summary field, providing additional portfolio metrics such as account value, leverage, margin usage, and unrealized PnL.

Replaces generic portfolio types with PerpetualPortfolio-specific types across primitives, gem_hypercore, and gemstone. Updates trait and method names to clarify perpetual-specific functionality, adjusts data structures for type safety (e.g., volume as f64), and updates mapping, serialization, and test code accordingly. This improves clarity and correctness for perpetual trading portfolio data handling.
Introduces PerpetualAccountSummary struct and integrates it into PerpetualPortfolio in both primitives and gemstone models. Updates mapping logic and tests to populate and verify the new account_summary field, providing additional portfolio metrics such as account value, leverage, margin usage, and unrealized PnL.
@gemdev111 gemdev111 self-assigned this Jan 22, 2026
@semanticdiff-com
Copy link

semanticdiff-com bot commented Jan 22, 2026

Review changes with  SemanticDiff

Changed Files
File Status
  crates/primitives/src/lib.rs  41% smaller
  crates/gem_hypercore/src/provider/perpetual_mapper.rs  31% smaller
  gemstone/src/models/portfolio.rs  19% smaller
  crates/gem_hypercore/src/models/portfolio.rs  5% smaller
  crates/gem_hypercore/src/provider/perpetual.rs  0% smaller
  crates/gem_hypercore/src/testkit.rs  0% smaller
  crates/primitives/src/chart.rs  0% smaller
  crates/primitives/src/portfolio.rs  0% smaller
  gemstone/src/models/perpetual.rs  0% smaller

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @gemdev111, 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 enhances the application's ability to track and display perpetual trading portfolio information. It establishes a robust data model for perpetual account summaries and historical performance, integrates this model across the core primitives, gem_hypercore, and gemstone crates, and provides the necessary logic to retrieve and process this data from external sources. This enables users to view detailed metrics such as account value, leverage, margin usage, and unrealized PnL for their perpetual trading activities.

Highlights

  • New Perpetual Portfolio Data Structures: Introduced PerpetualAccountSummary, PerpetualPortfolioDataPoint, PerpetualPortfolioTimeframeData, and PerpetualPortfolio structs in the primitives crate to model perpetual trading account metrics and historical data.
  • Chain Trait Extension: The ChainPerpetual trait in chain_traits now includes a new get_perpetual_portfolio asynchronous method, allowing chains to provide perpetual portfolio data.
  • Hypercore Integration: The gem_hypercore crate has been updated to fetch and map perpetual portfolio data from the Hypercore API, including account summaries and time-series data, and provides an implementation for the new get_perpetual_portfolio trait method.
  • Gemstone Gateway Exposure: The gemstone gateway now exposes the get_perpetual_portfolio functionality, making perpetual portfolio data accessible through the FFI layer.
  • Testing: New integration tests have been added for get_perpetual_portfolio and get_perpetual_candlesticks in gem_hypercore, along with unit tests for the mapping logic.

🧠 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.

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 introduces perpetual portfolio tracking, including account summary metrics. It adds new data structures in primitives and gemstone, and implements the logic to fetch and map this data from the Hypercore provider. The changes are comprehensive, but there are a couple of critical issues that need to be addressed. One is an infinite recursion bug in the provider implementation, and the other is a set of issues in the new gemstone model file that will prevent compilation. My review provides details and suggestions to fix these.

}

async fn get_perpetual_portfolio(&self, address: String) -> Result<PerpetualPortfolio, Box<dyn Error + Sync + Send>> {
let (response, positions) = try_join!(self.get_perpetual_portfolio(&address), self.get_clearinghouse_state(&address))?;
Copy link
Contributor

Choose a reason for hiding this comment

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

critical

This is an infinite recursive call. The get_perpetual_portfolio method is calling itself. You should call the inherent method on HyperCoreClient that makes the RPC request. You can use fully qualified syntax to disambiguate:

HyperCoreClient::get_perpetual_portfolio(self, &address)

Suggested change
let (response, positions) = try_join!(self.get_perpetual_portfolio(&address), self.get_clearinghouse_state(&address))?;
let (response, positions) = try_join!(HyperCoreClient::get_perpetual_portfolio(self, &address), self.get_clearinghouse_state(&address))?;

Comment on lines 4 to 37
pub type GemPerpetualPortfolio = PerpetualPortfolio;
pub type GemPerpetualPortfolioTimeframeData = PerpetualPortfolioTimeframeData;
pub type GemPerpetualPortfolioDataPoint = PerpetualPortfolioDataPoint;
pub type GemPerpetualAccountSummary = PerpetualAccountSummary;

#[uniffi::remote(Record)]
pub struct GemPerpetualPortfolioDataPoint {
pub date: DateTime<Utc>,
pub value: f64,
}

#[uniffi::remote(Record)]
pub struct GemPerpetualPortfolioTimeframeData {
pub account_value_history: Vec<PerpetualPortfolioDataPoint>,
pub pnl_history: Vec<PerpetualPortfolioDataPoint>,
pub volume: f64,
}

#[uniffi::remote(Record)]
pub struct GemPerpetualAccountSummary {
pub account_value: f64,
pub account_leverage: f64,
pub margin_usage: f64,
pub unrealized_pnl: f64,
}

#[uniffi::remote(Record)]
pub struct GemPerpetualPortfolio {
pub day: Option<PerpetualPortfolioTimeframeData>,
pub week: Option<PerpetualPortfolioTimeframeData>,
pub month: Option<PerpetualPortfolioTimeframeData>,
pub all_time: Option<PerpetualPortfolioTimeframeData>,
pub account_summary: Option<PerpetualAccountSummary>,
}
Copy link
Contributor

Choose a reason for hiding this comment

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

critical

This file has several issues that will prevent it from compiling and working as intended for FFI with uniffi.

  1. Name Collisions: You've defined type aliases and structs with the same names (e.g., GemPerpetualPortfolioDataPoint). This is not allowed in Rust. You should remove the type aliases.
  2. Incorrect Field Types for FFI: The uniffi structs use types from the primitives crate directly in their fields (e.g., Vec<PerpetualPortfolioDataPoint>). For FFI, you must use uniffi-compatible types. In this case, fields should use the Gem... structs you're defining (e.g., Vec<GemPerpetualPortfolioDataPoint>).
  3. Missing Conversions: After fixing the above, you'll need to implement From traits to convert from the primitives structs to your Gem... FFI structs. This will also require a change in gemstone/src/gateway/mod.rs to call .into() on the portfolio result before returning.
  4. uniffi::remote(Record): This appears to be a typo and should likely be #[uniffi::Record].

Here's an example of how GemPerpetualPortfolioDataPoint could be correctly defined with its conversion. You'll need to apply this pattern to all structs in this file.

use primitives::portfolio::{PerpetualPortfolioDataPoint as PrimitivePerpetualPortfolioDataPoint};

#[uniffi::Record]
pub struct GemPerpetualPortfolioDataPoint {
    pub date: DateTime<Utc>,
    pub value: f64,
}

impl From<PrimitivePerpetualPortfolioDataPoint> for GemPerpetualPortfolioDataPoint {
    fn from(value: PrimitivePerpetualPortfolioDataPoint) -> Self {
        Self { date: value.date, value: value.value }
    }
}

Replaces PerpetualPortfolioDataPoint with ChartDateValue in portfolio-related structs and type definitions across primitives, gem_hypercore, and gemstone. Updates relevant imports and type aliases to improve consistency and code reuse for date-value pairs.
@gemdev111 gemdev111 merged commit 96e4881 into main Jan 22, 2026
7 checks passed
@gemdev111 gemdev111 deleted the perps_portfolio branch January 22, 2026 21:46
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.

1 participant