Skip to content

Commit a8fc740

Browse files
committed
fix(predict): preserve sports market details resolution
1 parent ac40f1d commit a8fc740

1 file changed

Lines changed: 69 additions & 8 deletions

File tree

app/components/UI/Predict/providers/polymarket/PolymarketProvider.ts

Lines changed: 69 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,9 @@ import {
8989
fetchCarouselFromPolymarketApi,
9090
getBalance,
9191
getL2Headers,
92+
fetchChildEventsFromGammaApi,
9293
getMarketDetailsFromGammaApi,
94+
mergeChildEventsIntoParent,
9395
getPolymarketEndpoints,
9496
getRawBalance,
9597
parsePolymarketActivity,
@@ -100,6 +102,7 @@ import {
100102
import { PredictFeatureFlags } from '../../types/flags';
101103
import {
102104
extractNeededTeamsFromEvents,
105+
getEventLeague,
103106
isLiveSportsEvent,
104107
} from '../../utils/gameParser';
105108
import { GameCache } from './GameCache';
@@ -184,10 +187,6 @@ export class PolymarketProvider implements PredictProvider {
184187
return this.#getFeatureFlags().extendedSportsMarketsLeagues;
185188
}
186189

187-
#hasExtendedMarketsForLeague(league: string): boolean {
188-
return this.#getExtendedSportsMarketsLeagues().includes(league);
189-
}
190-
191190
#createTeamLookup(
192191
enabled: boolean,
193192
):
@@ -223,6 +222,47 @@ export class PolymarketProvider implements PredictProvider {
223222
);
224223
}
225224

225+
/**
226+
* Extended sports positions can point to child events like player props or
227+
* halftime markets, but the details view should resolve back to the parent
228+
* game and merge the child markets into that game when the league supports it.
229+
*/
230+
async #resolveSportMarketFromPolymarket({
231+
event,
232+
extendedSportsMarketsLeagues,
233+
}: {
234+
event: PolymarketApiEvent;
235+
extendedSportsMarketsLeagues: string[];
236+
}): Promise<{
237+
resolvedEvent: PolymarketApiEvent;
238+
childMarketIds?: string[];
239+
}> {
240+
const eventLeague = getEventLeague(event, extendedSportsMarketsLeagues);
241+
if (!eventLeague || !extendedSportsMarketsLeagues.includes(eventLeague)) {
242+
return { resolvedEvent: event };
243+
}
244+
245+
const resolvedEventId = event.parentEventId ?? event.id;
246+
247+
try {
248+
const allEvents = await fetchChildEventsFromGammaApi({
249+
parentEventId: resolvedEventId,
250+
});
251+
return {
252+
resolvedEvent: mergeChildEventsIntoParent(allEvents),
253+
childMarketIds: allEvents.map(
254+
(resolvedChildEvent) => resolvedChildEvent.id,
255+
),
256+
};
257+
} catch (childFetchError) {
258+
DevLogger.log(
259+
'Failed to fetch child events, using resolved event only:',
260+
childFetchError,
261+
);
262+
return { resolvedEvent: event };
263+
}
264+
}
265+
226266
/**
227267
* Generate standard error context for Logger.error calls with searchable tags and context.
228268
* Enables Sentry dashboard filtering by feature and provider.
@@ -543,19 +583,36 @@ export class PolymarketProvider implements PredictProvider {
543583

544584
const supportedLeagues = this.#getSupportedLeagues();
545585
const liveSportsEnabled = supportedLeagues.length > 0;
586+
const extendedSportsMarketsLeagues =
587+
this.#getExtendedSportsMarketsLeagues();
546588
const isSportsEvent =
547-
liveSportsEnabled && isLiveSportsEvent(event, supportedLeagues);
589+
liveSportsEnabled &&
590+
isLiveSportsEvent(
591+
event,
592+
supportedLeagues,
593+
extendedSportsMarketsLeagues,
594+
);
548595

596+
let mergedEvent = event;
597+
let childMarketIds: string[] | undefined;
549598
if (isSportsEvent) {
550-
await this.#ensureTeamsLoadedForEvents([event], supportedLeagues);
599+
const resolvedSportMarket =
600+
await this.#resolveSportMarketFromPolymarket({
601+
event,
602+
extendedSportsMarketsLeagues,
603+
});
604+
mergedEvent = resolvedSportMarket.resolvedEvent;
605+
childMarketIds = resolvedSportMarket.childMarketIds;
606+
607+
await this.#ensureTeamsLoadedForEvents([mergedEvent], supportedLeagues);
551608
}
552609

553610
const teamLookup = this.#createTeamLookup(isSportsEvent);
554611

555-
const [parsedMarket] = parsePolymarketEvents([event], {
612+
const [parsedMarket] = parsePolymarketEvents([mergedEvent], {
556613
category: PolymarketProvider.FALLBACK_CATEGORY,
557614
teamLookup,
558-
extendedSportsMarketsLeagues: this.#getExtendedSportsMarketsLeagues(),
615+
extendedSportsMarketsLeagues,
559616
});
560617

561618
if (!parsedMarket) {
@@ -566,6 +623,10 @@ export class PolymarketProvider implements PredictProvider {
566623
? GameCache.getInstance().overlayOnMarket(parsedMarket)
567624
: parsedMarket;
568625

626+
if (childMarketIds) {
627+
result.childMarketIds = childMarketIds;
628+
}
629+
569630
return result;
570631
} catch (error) {
571632
DevLogger.log('Error getting market details via Polymarket API:', error);

0 commit comments

Comments
 (0)