Skip to content

Birdeye on bench 001 - #2798

Merged
Flotapponnier merged 1 commit into
mainfrom
feat/birdeye-to-main
Oct 4, 2026
Merged

Flotapponnier merged 1 commit into
mainfrom
feat/birdeye-to-main

Conversation

@Flotapponnier

Copy link
Copy Markdown
Collaborator

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 the public-api.birdeye.so their 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_DATA carries 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: blockUnixTime is 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-source and 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_getLogs that the feed carries every pool swap (266 of 266); that check is running for Birdeye now and is not yet in. Read head_lag_ref_matches_total{aggregator="birdeye"} before trusting the column.

Checks

  • go build ./... and go test ./cmd/script/ clean
  • pnpm validate 235 specs valid

🤖 Generated with Claude Code

… 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>
@Flotapponnier
Flotapponnier merged commit e07a324 into main Oct 4, 2026
2 checks passed
@Flotapponnier
Flotapponnier deleted the feat/birdeye-to-main branch October 4, 2026 12:41
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.

1 participant