Skip to content

feat(predict): adds crypto target price client for up/down markets#28694

Open
ghgoodreau wants to merge 4 commits intomainfrom
feat/predict-crypto-target-price-client
Open

feat(predict): adds crypto target price client for up/down markets#28694
ghgoodreau wants to merge 4 commits intomainfrom
feat/predict-crypto-target-price-client

Conversation

@ghgoodreau
Copy link
Copy Markdown
Contributor

@ghgoodreau ghgoodreau commented Apr 10, 2026

Description

Adds the CryptoTargetPriceClient — a query + hook that fetches the "price to beat" for crypto Up/Down market windows from Polymarket's undocumented crypto-price endpoint, returning the openPrice as the target line value.

The target price is immutable once a window opens, so caching is aggressive: a module-level Map<eventId, number> persists across React Query garbage-collection, and staleTime: Infinity prevents refetches. Subsequent calls for the same event return instantly from cache with zero network cost.

When the primary API fails (geo-blocked, endpoint changed, etc.), the client falls back to parsing groupItemThreshold from event outcomes. If both fail, it returns null. Fallback triggers a Logger.log warning (not error) so API breakage is detectable via Sentry breadcrumbs without triggering alerts.

The consumer passes optional pre-loaded outcomes to avoid a redundant getMarket call in the fallback path — the detail screen already has this data.

Consumed by LiveScrollingChart (PRED-778) to render the horizontal target line.

Changelog

CHANGELOG entry: null

Related issues

Fixes:

Manual testing steps

Feature: Crypto target price fetching and caching

  Scenario: Target price loads for a crypto Up/Down market
    Given the user is on a crypto Up/Down market detail screen
    And the device has network connectivity to polymarket.com

    When the detail screen renders
    Then useCryptoTargetPrice fetches the openPrice from the crypto-price API
    And the target price is available as a number for the chart target line

  Scenario: Target price is served from cache on re-entry
    Given the user previously viewed a crypto Up/Down market detail screen
    And the target price was fetched successfully

    When the user navigates back to the same market detail screen
    Then the target price is returned immediately from cache
    And no network request is made to the crypto-price API

  Scenario: Fallback to groupItemThreshold when primary API fails
    Given the user is on a crypto Up/Down market detail screen
    And the crypto-price API is unreachable or geo-blocked

    When the detail screen attempts to fetch the target price
    Then the client falls back to groupItemThreshold from event outcomes
    And a warning breadcrumb is logged for monitoring
    And the target price is still available for the chart

  Scenario: Returns null when both primary and fallback fail
    Given the user is on a crypto Up/Down market detail screen
    And the crypto-price API is unreachable
    And the event outcomes do not contain a groupItemThreshold

    When the detail screen attempts to fetch the target price
    Then the hook returns null
    And the chart renders without a target line

Screenshots/Recordings

Before

After

Pre-merge author checklist

Pre-merge reviewer checklist

  • I've manually tested the PR (e.g. pull and build branch, run the app, test code being changed).
  • I confirm that this PR addresses all acceptance criteria described in the ticket it closes and includes the necessary testing evidence such as recordings and or screenshots.

Note

Medium Risk
Introduces new network fetching logic against an undocumented external endpoint plus a module-level cache, which could impact correctness/memory if parameters or event IDs are mishandled. Changes are otherwise additive and covered by unit tests for success, caching, and fallback behavior.

Overview
Adds a new cryptoTargetPrice React Query client and useCryptoTargetPrice hook to fetch the immutable “price to beat” for crypto Up/Down markets from Polymarket’s crypto-price endpoint (returning openPrice), with staleTime: Infinity.

Implements an event-scoped module cache to persist target prices beyond React Query GC, and adds a fallback path that derives the price from groupItemThreshold (using provided outcomes when available, otherwise calling PredictController.getMarket), logging a warning breadcrumb on API failure. Includes comprehensive unit tests for API success, caching, parameter encoding, and fallback/null scenarios, and wires the new query into predictQueries and hook exports.

Reviewed by Cursor Bugbot for commit 1e20a42. Bugbot is set up for automated code reviews on this repo. Configure here.

ghgoodreau and others added 3 commits April 10, 2026 16:00
Fetches target price from undocumented Polymarket crypto-price endpoint.
Caches per eventId in a module-level Map (immutable once window opens)
alongside React Query staleTime: Infinity. Falls back to groupItemThreshold
from event outcomes when primary API fails; logs warning (not error) for
monitoring.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
Thin wrapper over the query options. Accepts optional pre-loaded outcomes
to avoid redundant network calls in the fallback path. Consumed by
LiveScrollingChart (PRED-778) to render the horizontal target line.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
The undocumented endpoint returns { openPrice, closePrice, timestamp, ... }
not { price }. The openPrice is the target line — the price to beat.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
@github-actions
Copy link
Copy Markdown
Contributor

CLA Signature Action: All authors have signed the CLA. You may need to manually re-run the blocking PR check if it doesn't pass in a few minutes.

@metamaskbot metamaskbot added the team-swaps-and-bridge Swaps and Bridge team label Apr 10, 2026
@ghgoodreau ghgoodreau changed the title Feat/predict crypto target price client feat(predict): adds crypto target price client for up/down markets Apr 10, 2026
@codecov-commenter
Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.34884% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 82.17%. Comparing base (9f195d0) to head (509b49c).
⚠️ Report is 25 commits behind head on main.

Files with missing lines Patch % Lines
...components/UI/Predict/queries/cryptoTargetPrice.ts 94.87% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main   #28694      +/-   ##
==========================================
+ Coverage   82.14%   82.17%   +0.02%     
==========================================
  Files        4949     4951       +2     
  Lines      130070   130305     +235     
  Branches    29004    29041      +37     
==========================================
+ Hits       106851   107081     +230     
- Misses      15923    15927       +4     
- Partials     7296     7297       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@ghgoodreau ghgoodreau marked this pull request as ready for review April 10, 2026 22:26
@ghgoodreau ghgoodreau requested a review from a team as a code owner April 10, 2026 22:26
Aligns with the Predict module convention — every other log call in
Predict uses DevLogger, not Logger.

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
@github-actions github-actions bot added the risk-medium Moderate testing recommended · Possible bug introduction risk label Apr 10, 2026
@github-actions
Copy link
Copy Markdown
Contributor

🔍 Smart E2E Test Selection

  • Selected E2E tags: SmokePredictions, SmokeWalletPlatform, SmokeConfirmations
  • Selected Performance tags: @PerformancePredict
  • Risk Level: medium
  • AI Confidence: 88%
click to see 🤖 AI reasoning details

E2E Test Selection:
The changes introduce a new useCryptoTargetPrice hook and cryptoTargetPrice query within the Predictions feature (app/components/UI/Predict/). These are additive changes that add crypto target price fetching functionality for Polymarket crypto Up/Down markets, with a module-level cache and fallback to PredictController.getMarket().

SmokePredictions is the primary tag since all changes are within the Predict feature area — the new hook/query will be used in prediction market flows (crypto Up/Down markets). The SmokePredictions tag description explicitly requires also selecting SmokeWalletPlatform (Predictions is a section inside Trending tab) and SmokeConfirmations (opening/closing positions are on-chain transactions).

No shared infrastructure (navigation, modals, Engine, controllers) is modified. The changes are purely additive within the Predict module. Risk is medium because new API calls and caching logic are introduced that could affect prediction market display/behavior.

Performance Test Selection:
The new cryptoTargetPrice query introduces a new network API call (to polymarket.com/api/crypto/crypto-price) in the prediction market flow. While the implementation uses staleTime: Infinity and a module-level cache for optimization, the initial fetch adds a new network request to the prediction market rendering path. The @PerformancePredict tag covers prediction market list loading, market details, and balance display — all of which could be affected by this new API call in crypto Up/Down market scenarios.

View GitHub Actions results

Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 1e20a42. Configure here.

DevLogger.log(
`[${PREDICT_CONSTANTS.FEATURE_NAME}] Crypto target price API failed for event ${eventId}, falling back to groupItemThreshold`,
apiError,
);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

DevLogger is a no-op in production, breaking observability

Medium Severity

The code uses DevLogger.log to log the API fallback warning, but DevLogger.log only outputs to console when process.env.SDK_DEV === 'DEV' — it's completely silent in production. The PR description explicitly states the intent is for "API breakage [to be] detectable via Sentry breadcrumbs without triggering alerts," which requires Logger.log from app/util/Logger. Logger.log adds a Sentry breadcrumb in production; DevLogger.log does not. This means crypto-price API failures will go completely undetected in production.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 1e20a42. Configure here.

@github-actions
Copy link
Copy Markdown
Contributor

E2E Fixture Validation — Schema is up to date
17 value mismatches detected (expected — fixture represents an existing user).
View details

@sonarqubecloud
Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk-medium Moderate testing recommended · Possible bug introduction risk size-L team-swaps-and-bridge Swaps and Bridge team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants