Repository navigation
Birdeye on bench 001 - #2798
Merged
Merged
Birdeye on bench 001#2798
Conversation
… never name (#2797) I said twice that Birdeye could not be reverse engineered. Both times I was wrong, and for a reason worth recording: my probes were testing something other than what I thought. Node's built-in WebSocket does not send custom headers. Every "Birdeye refuses us" result came from a client that never sent the Origin and User-Agent I believed I was sending. Rewritten in Go and swept one factor at a time against the live endpoint: no headers 403 "Just a moment..." Origin only 403 "Just a moment..." Origin + User-Agent 101 Switching Protocols So the gate is Cloudflare's default rule rejecting a client that declares no User-Agent. No TLS fingerprinting is involved and the uTLS machinery in utls_codex.go is not needed, which also retires the question of whether defeating a bot protection was acceptable here: declaring a User-Agent is configuring an HTTP client, not forcing a lock. Two more things that each produced a wrong conclusion first: The socket is multichain-socket.birdeye.so, not the public-api.birdeye.so their documentation names. Probing the documented host is what made this look closed; that one needs a $199/month Premium plan. Frames are zlib-compressed JSON. DevTools labels them "Binary message", which reads like protobuf until you notice the 78 9c magic. Base and Solana only, for the same two structural reasons as OKX: blockUnixTime is in whole seconds, so a chain whose headline reads the provider's own timestamp would publish that quantisation as Birdeye's latency; and Robinhood Chain is not covered upstream. Token-scoped like OKX, so most of what arrives is off-bench and discarded. Only emissions matched to the reference by transaction hash are scored, and birdeye joins tokenScopedAggregators so its unmatched emissions are not counted as misses. Verified with the monitor's OWN decoder against the live endpoint rather than a copy of it: 1,170 trades decoded, 1,170 carrying a hash. That check ships as TestBirdeyeLiveFeed, opt-in so CI never depends on a third party. The OKX integration shipped broken twice because a hand-written probe with its own copy of the struct said the feed was fine. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.
Cherry-pick of #2797, already merged to
dev, with nothing else from that branch. One commit, six files.Birdeye's trades socket needs no credential. It is on
multichain-socket.birdeye.so, not thepublic-api.birdeye.sotheir documentation names (that one needs a $199/month plan), and the dial is answered 403 by Cloudflare unless the client declares a User-Agent. Swept one factor at a time: no headers 403, Origin alone 403, Origin + User-Agent 101.Frames are zlib-compressed JSON; only
TXS_DATAcarries trades. Verified with the monitor's own decoder against the live endpoint: 1,170 trades decoded, 1,170 carrying a hash.Base and Solana only, same two structural reasons as OKX:
blockUnixTimeis in whole seconds, and Robinhood Chain is not covered upstream.Like #2794, this is a harness change, so nothing moves until the three Railway services are redeployed with
--from-sourceand the materialize worker is rebuilt. Merging only puts the spec, copy and registry entry on production.Coverage is unmeasured. For OKX I checked against
eth_getLogsthat the feed carries every pool swap (266 of 266); that check is running for Birdeye now and is not yet in. Readhead_lag_ref_matches_total{aggregator="birdeye"}before trusting the column.Checks
go build ./...andgo test ./cmd/script/cleanpnpm validate235 specs valid🤖 Generated with Claude Code