Skip to content

fix(gemini-titan): lazily build symbol index in fetchRawOrderBook (closes #2037) - #2051

Open
chiliec wants to merge 1 commit into
pmxt-dev:mainfrom
chiliec:fix/gemini-titan-orderbook-lazy-index
Open

fix(gemini-titan): lazily build symbol index in fetchRawOrderBook (closes #2037)#2051
chiliec wants to merge 1 commit into
pmxt-dev:mainfrom
chiliec:fix/gemini-titan-orderbook-lazy-index

Conversation

@chiliec

@chiliec chiliec commented Aug 15, 2026

Copy link
Copy Markdown

What

Closes #2037.

GeminiTitanExchange.fetchOrderBook() was unconditionally broken for any credentialed client. fetchRawOrderBook() reads the instance-level symbolToEventTicker index, which is only populated as a side effect of a prior fetchRawEvents/fetchRawMarkets call on the same fetcher instance. Since the server constructs a brand-new GeminiTitanExchange (and a fresh, empty-indexed GeminiFetcher) on every REST dispatch when credentials are present, the index was always empty and fetchRawOrderBook() threw regardless of call order.

Fix

In fetchRawOrderBook(), when the event ticker for the requested symbol isn't in the index, build it lazily by calling fetchRawEvents({}) once, then retry the lookup. Only throw if the symbol is still unknown afterwards. No other behaviour changes — a fetcher that already has a populated index (e.g. after fetchMarkets) skips the extra call.

Tests

Added regression coverage in core/test/exchanges/gemini-titan-fetcher.test.ts:

Validation

  • npx jest gemini-titan-fetcher5 passed (3 existing + 2 new)
  • npx tsc --noEmit (core) → passes

First-time contributor — happy to adjust the approach (e.g. cache/scope of the lazy fetch) to match your preferences.

Closes pmxt-dev#2037. GeminiTitanExchange.fetchOrderBook() depended on the in-memory
symbolToEventTicker index, which is only populated as a side effect of a prior
fetchMarkets/fetchEvents call on the same fetcher instance. The server creates
a fresh GeminiTitanExchange (and a fresh, empty-indexed GeminiFetcher) on every
REST dispatch for a credentialed client, so fetchRawOrderBook() always threw for
any credentialed GeminiTitan SDK client regardless of call order.

Populate the index lazily: when the event ticker for the requested symbol is
not found, call fetchRawEvents once to build the index, then retry the lookup.
Only throw if the symbol is still unknown after that.

Adds regression tests: fetchRawOrderBook succeeds when called first on a fresh
fetcher, and still throws for a genuinely unknown symbol.
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.

GeminiTitan fetchOrderBook() is unconditionally broken through both SDKs for any credentialed client

1 participant