Repository navigation
rain, gemini-titan, and hyperliquid still absent from sidecar defaultExchanges map — #1158 wrongly closed as duplicate of #1062 (which doesn't cover them) #2410
Description
Gap
rain, gemini-titan, and hyperliquid are still missing from the sidecar's defaultExchanges singleton map. Any unauthenticated request to these three exchanges (e.g. GET /api/rain/fetchMarkets) fails to resolve a default instance, even though createExchange() fully supports all three with env-var fallbacks.
This exact bug was previously filed as #1158, which explicitly named all three exchanges. #1158 was closed as duplicate of #1062 on 2026-07-09. However #1062's title, body, and scope only ever covered suibets and polymarket_us — it explicitly states "gemini-titan and hyperliquid have the same omission and are already tracked in separate issues" (i.e. #1158), so it is not actually a duplicate. #1158's own fix PR (#1163) is still open/unmerged. The result is that this gap currently has no open tracking issue, and the code is unchanged.
Core
defaultExchanges map — core/src/server/app.ts lines 263–276:
const defaultExchanges: Record<string, any> = {
polymarket: null,
limitless: null,
kalshi: null,
"kalshi-demo": null,
probable: null,
baozi: null,
myriad: null,
opinion: null,
metaculus: null,
smarkets: null,
hunch: null,
mock: null,
// rain, gemini-titan, hyperliquid, suibets, polymarket_us all absent
};createExchange() in core/src/server/exchange-factory.ts fully supports "rain", "gemini-titan", and "hyperliquid" (with env-var credential fallbacks), confirming these are implemented exchanges just missing the singleton entry.
core/src/index.ts lines 44, 61-62, 81-82 export Rain, Hyperliquid, and GeminiTitan as first-class exchanges alongside the ones that do have defaultExchanges entries.
TypeScript SDK
No direct code defect — SDK clients (Rain, Hyperliquid, GeminiTitan in sdks/typescript/pmxt/client.ts) route through the sidecar and inherit the failure when called without explicit credentials.
Python SDK
Same indirect impact via sdks/python/pmxt/_exchanges.py's Rain, Hyperliquid, GeminiTitan classes.
Evidence
- Read
core/src/server/app.tsdirectly on the current HEAD (commit4a367d8, dated 2026-07-18 — after bothsuibetsandpolymarket_usabsent from sidecardefaultExchangesmap — unauthenticated requests always fail #1062 andrain,gemini-titan, andhyperliquidabsent from sidecardefaultExchangesmap — unauthenticated requests always fail #1158 were filed/closed) and confirmedrain,gemini-titan,hyperliquidare still absent fromdefaultExchanges. suibetsandpolymarket_usabsent from sidecardefaultExchangesmap — unauthenticated requests always fail #1062 (open) body: "This issue coverssuibetsandpolymarket_us." — does not mention the other three.rain,gemini-titan, andhyperliquidabsent from sidecardefaultExchangesmap — unauthenticated requests always fail #1158 (closed,state_reason: duplicate) explicitly namedrain,gemini-titan,hyperliquidand was closed citingsuibetsandpolymarket_usabsent from sidecardefaultExchangesmap — unauthenticated requests always fail #1062, butsuibetsandpolymarket_usabsent from sidecardefaultExchangesmap — unauthenticated requests always fail #1062 never actually covers them.rain,gemini-titan, andhyperliquidabsent from sidecardefaultExchangesmap — unauthenticated requests always fail #1158's linked fix PR fix(core): register Rain, Gemini Titan, and Hyperliquid defaults #1163 is still open and unmerged.
Impact
Any SDK or HTTP client calling GET /api/rain/fetchMarkets, GET /api/gemini-titan/fetchMarkets, or GET /api/hyperliquid/fetchMarkets without explicit credentials cannot use the default singleton path (either erroring or constructing a fresh, uncached exchange instance per request). This breaks the common pattern of reading public market data without authentication for three of PMXT's seventeen supported venues.
Found by automated Core-to-SDK surface coverage audit
Activity