Repository navigation
Upgrade glassnode-api to 1.0.0; recover rate-limited startup metadata - #22
Merged
Merged
Conversation
- glassnode-api 0.29.3 -> 1.0.0. The only source change it needs: bulk values (BulkEntry['v'], since 0.30) can be null — sortAssetsByMcap skips them (treated like a missing value) instead of the whole market-cap fetch failing and silently falling back to alphabetical order. MetricMetadata.parameters is now optional; every read already used `?.` with a fallback. Node >= 22 matches the release PR. - Startup metadata burst: of 1,817 getMetricMetadata calls, ~16% came back 429 (rate limited) even with 1.0's default 2 retries, and were silently dropped — losing display names, and leaking 160 point-in-time variants into the metric list (the is_pit filter needs the metadata). A dedicated startup client (API-key mode only; x402 stays at 0 retries so a paid call is never repeated) retries up to 5 times, and batches drop from 20 to 10. Measured live: 1,807/1,817 metadata kept (was 1,485), PIT leak 160 -> 5, ~89 s first startup (cached for a day). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PzJHgXssByMwBXH1PGbXCL
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PzJHgXssByMwBXH1PGbXCL
… suffix From review of this PR: - The API's 429s carry x-rate-limit-reset (seconds until its 1,200/minute window resets) but no Retry-After, so retries used short jittered backoff and could give up before the reset. rateLimitAwareFetch (startup client only) exposes the reset as Retry-After, which glassnode-api honours, capped at a 60 s maxRetryDelay. Live: 1,817/1,817 metadata (was 1,807), first startup 75 s. - listedMetrics hides point-in-time variants by `_pit` suffix as well as is_pit, so a variant whose metadata failed to load can't leak into the list. - Startup cache key -> startup-data-v2 so a day-old cache that lost metadata to rate limits isn't reused after upgrading. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PzJHgXssByMwBXH1PGbXCL
planadecu
force-pushed
the
chore/glassnode-api-1.0
branch
from
September 29, 2026 23:41
82d9b73 to
556c316
Compare
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed
glassnode-api0.29.3 → 1.0.0, its first stable release. I checked each breaking change in its changelog against the code:BulkEntry['v']can now benull(0.30.0). This is the only source change needed.sortAssetsByMcapskips null market caps and treats them like missing ones. Before, a single null made the whole market-cap fetch throw, and the asset list silently fell back to alphabetical order (Startup has no fallback when API responses drift from glassnode-api schemas #17).MetricMetadata.parameters,refsandqueriedare now optional. Everyparametersread already used?.with a fallback, and nothing readsrefsorqueried.modifiedis now unix seconds. It isn't used.MetricTier,MetricDataType,FetchFn): not used.maxRetriesnow defaults to 2 in API-key mode; x402 mode stays at 0.Startup metadata was being rate-limited. Startup makes 1,817
getMetricMetadatacalls. Measured live, about 16% came back 429 (rate limited) even with 1.0's two retries, and they were dropped silently. That lost those metrics' display names and supported-asset lists. It also leaked 160 point-in-time (_pit) variants into the metric list, because theis_pitfilter needs each metric's metadata.The fix is a dedicated startup client with batches of 10 instead of 20. It retries up to 5 times and waits for the rate-limit window to reset. The API's 429s carry
x-rate-limit-reset(seconds until its 1,200-per-minute window resets) but noRetry-After.rateLimitAwareFetchcopies that value intoRetry-After, which glassnode-api honours, withmaxRetryDelayraised to 60 s. It exists only in API-key mode. In x402 mode calls are paid, and a retry could pay twice, so they stay at 0 retries. Interactive calls keep 1.0's default, so a rate limit doesn't stall the UI.Live comparison of the metadata fetch (earlier settings, before the reset-aware retries):
Added after review:
_pitsuffix as well as byis_pit, so one whose metadata failed to load can't leak into the list. Everyis_pitmetric's path ends in_pit, and no other metric's does.startup-data-v2, so a day-old cache that lost metadata to rate limits isn't reused after upgrading.ink-uplotbumped to 0.2.16.Verification
tscpasses, 43 tests pass, andpnpm auditis clean. New tests cover:sortAssetsByMcapwith anullmarket caprateLimitAwareFetchlistedMetrics, which hides point-in-time variants without their metadataengines.nodeto 22 to match 1.0.HOME, so the cache starts empty) in a pseudo-terminal:429 Rate limit exceeded. None came from 1.0's stricter response checks.Partly addresses #17: null market caps and rate-limited metadata are fixed. Still open there: a fallback when the asset metadata call itself fails.