Skip to content

feat(jobs): derive artist coin stats on-chain (shadow of Birdeye CoinStatsJob) - #998

Open
rickyrombo wants to merge 2 commits into
mjp-sync-test-schemafrom
mjp-onchain-coin-stats
Open

feat(jobs): derive artist coin stats on-chain (shadow of Birdeye CoinStatsJob)#998
rickyrombo wants to merge 2 commits into
mjp-sync-test-schemafrom
mjp-onchain-coin-stats

Conversation

@rickyrombo

Copy link
Copy Markdown
Contributor

⚠️ Stacked on #997 (base branch is mjp-sync-test-schema). Merge #997 first; this PR's schema diff shows only the new objects because the pending dump drift lives in #997. After #997 merges, this rebases onto main cleanly.

What

Adds CoinStatsOnchainJob — an on-chain replacement for the Birdeye-backed CoinStatsJob, which is ~99.6% of our Birdeye compute-unit spend. It derives the coin stats the product actually renders from data we already index on-chain, instead of calling Birdeye:

Field Source
price artist_coin_prices view (Meteora DBC/DAMM v2 pools)
holder sol_token_account_balances (distinct owners, balance > 0)
liquidity pool TVL = base-side USD + quote-side USD (real reserves)
total_supply / market_cap RPC getTokenSupply; price × supply
total_volume(_usd) running accumulator over pool quote-vault balance changes
history_24h_price / price_change_24h_percent new hourly price-history table

Shadow rollout

The job writes a new artist_coin_stats_onchain table and runs alongside the existing CoinStatsJob (both every 15 min). Consumers still read the live artist_coin_stats, so there's zero product impact. The new artist_coin_stats_comparison view exposes per-coin Birdeye-vs-on-chain deltas for validation. Once validated, a follow-up PR repoints consumers and deletes CoinStatsJob + the unused Birdeye methods.

AudioPriceJob (the AUDIO→USD anchor, still Birdeye) is intentionally out of scope.

Also

  • New tables: artist_coin_stats_onchain, artist_coin_price_history, artist_coin_volume_accumulator (migrations 0229–0231).
  • database/seed.go: base rows for the new tables + sol_meteora_dbc_pools.
  • Test coin_stats_onchain_test.go seeds a DBC coin and asserts every derived field + the AUDIO no-clobber guard.

Known fidelity gaps vs Birdeye

We track one canonical pool per coin, so a graduated coin with secondary/external markets will have understated liquidity/volume (price stays close via arbitrage); there's also a brief migration-lag window. The comparison view is the detector — review it before cutover. 24h change is blank for the first ~24h after deploy (no snapshot yet).

Test

go test ./jobs/ ./database/ pass; full build/vet clean; regenerated dump loads.

🤖 Generated with Claude Code

rickyrombo and others added 2 commits July 27, 2026 22:47
…StatsJob)

Adds CoinStatsOnchainJob, which computes price, holder count, liquidity
(pool TVL), market cap, all-time volume, and 24h price change from
on-chain data (Meteora DBC/DAMM v2 pools, token-account balances, and an
RPC getTokenSupply) instead of Birdeye. It writes a new shadow table
artist_coin_stats_onchain and runs alongside the existing CoinStatsJob so
the two can be compared via the artist_coin_stats_comparison view before
cutover. Also adds artist_coin_price_history (24h change) and
artist_coin_volume_accumulator (running volume) plus seed base rows for
the new tables. AudioPriceJob (the AUDIO->USD anchor) is unchanged.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
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