Repository navigation
Description
Gap
Core's PaginatedMarketsResult and PaginatedEventsResult interfaces declare total: number as a required field, and every code path in fetchMarketsPaginated/fetchEventsPaginated always populates it (there is no branch that omits or nulls it). Both SDKs instead type total as optional/nullable (total?: number in TypeScript, total: Optional[int] = None in Python), which is a narrower/weaker contract than what core actually guarantees. This is the same class of type-narrowing bug already tracked for UnifiedMarket.description (#1397) and UnifiedEvent.volume24h (#1398), but for a different pair of types that neither of those issues covers.
Core
core/src/BaseExchange.ts:417-423:
export interface PaginatedMarketsResult {
/** The page of unified markets */
data: UnifiedMarket[];
/** Total number of markets in the snapshot */
total: number;
/** Cursor to pass to the next call, or undefined if this is the last page */
nextCursor?: string;
}and :427-433 for the near-identical PaginatedEventsResult. Every return site in fetchMarketsPaginated (BaseExchange.ts:805,824,829) and fetchEventsPaginated (:874,893,898) always sets total: markets.length / total: events.length — there is no code path that returns these types without total.
TypeScript SDK
sdks/typescript/pmxt/models.ts:254-257 and :268-271:
export interface PaginatedMarketsResult {
data: UnifiedMarket[];
/** Total number of markets (if available) */
total?: number;
nextCursor?: string;
}(same optional total?: number pattern for PaginatedEventsResult).
Python SDK
sdks/python/pmxt/models.py:424-434:
class PaginatedMarketsResult:
data: "List[UnifiedMarket]"
total: Optional[int] = None
"""Total number of markets in the snapshot"""
next_cursor: Optional[str] = None(same Optional[int] = None pattern for PaginatedEventsResult, models.py:437-447).
Evidence
Grepped total in core/src/BaseExchange.ts and confirmed the interface declares total: number (required) while every constructing call site always assigns it a real value (markets.length/events.length, never omitted or undefined). Grepped total in sdks/typescript/pmxt/models.ts and read sdks/python/pmxt/models.py:424-447 directly — both SDKs declare the field optional/nullable, which is strictly weaker than what core guarantees.
Impact
Consumers of both SDKs must null-check result.total (TypeScript: result.total ?? 0, Python: if result.total is not None) even though it is always present in practice, adding unnecessary defensive code and hiding a reliable field behind an inaccurate optional type. This is minor on its own but is the same avoidable-narrowing pattern already flagged for other fields (#1397, #1398), and consistency here would let SDK consumers drop the same null-guard everywhere pagination results are used.
Found by automated Core-to-SDK surface coverage audit
Activity