From 6c6aab0c5916efe313a690e88a54722214c03206 Mon Sep 17 00:00:00 2001 From: Florent Tapponnier <160007691+Flotapponnier@users.noreply.github.com> Date: Wed, 29 Jul 2026 15:28:56 +0200 Subject: [PATCH 01/14] feat(pm): add polymarket-us to PM_VENUES seed list --- src/lib/pm-stats.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/lib/pm-stats.ts b/src/lib/pm-stats.ts index bfaff899..26dd8f60 100644 --- a/src/lib/pm-stats.ts +++ b/src/lib/pm-stats.ts @@ -74,10 +74,11 @@ type DataFeedSeed = { }; const PM_VENUES: VenueSeed[] = [ - { slug: "polymarket", name: "Polymarket", type: "onchain", chain: "polygon" }, - { slug: "kalshi", name: "Kalshi", type: "offchain" }, - { slug: "limitless", name: "Limitless", type: "onchain", chain: "base" }, - { slug: "myriad", name: "Myriad", type: "onchain", chain: "abstract" }, + { slug: "polymarket", name: "Polymarket", type: "onchain", chain: "polygon" }, + { slug: "polymarket-us", name: "Polymarket US", type: "offchain" }, + { slug: "kalshi", name: "Kalshi", type: "offchain" }, + { slug: "limitless", name: "Limitless", type: "onchain", chain: "base" }, + { slug: "myriad", name: "Myriad", type: "onchain", chain: "abstract" }, ]; const PM_DATA_FEEDS: DataFeedSeed[] = [ From e280e0e928c13029bbaaa03784048ea2f5eeb776 Mon Sep 17 00:00:00 2001 From: Florent Tapponnier <160007691+Flotapponnier@users.noreply.github.com> Date: Wed, 29 Jul 2026 15:30:06 +0200 Subject: [PATCH 02/14] =?UTF-8?q?feat:=20add=20/data-api=20hub=20=E2=80=94?= =?UTF-8?q?=209=20benches,=20by-benchmark=20+=20by-provider=20views?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/data-api/page.tsx | 306 ++++++++++++++ src/components/data-api-bench-groups.tsx | 271 +++++++++++++ src/components/data-api-hub-tabs.tsx | 79 ++++ src/components/data-api-providers-pivot.tsx | 318 +++++++++++++++ src/components/site-header.tsx | 5 + src/lib/data-api-stats.ts | 417 ++++++++++++++++++++ 6 files changed, 1396 insertions(+) create mode 100644 src/app/data-api/page.tsx create mode 100644 src/components/data-api-bench-groups.tsx create mode 100644 src/components/data-api-hub-tabs.tsx create mode 100644 src/components/data-api-providers-pivot.tsx create mode 100644 src/lib/data-api-stats.ts diff --git a/src/app/data-api/page.tsx b/src/app/data-api/page.tsx new file mode 100644 index 00000000..22159832 --- /dev/null +++ b/src/app/data-api/page.tsx @@ -0,0 +1,306 @@ +import Link from "next/link"; +import { fetchDataApiSnapshot, GROUP_META, fmtDataValue } from "@/lib/data-api-stats"; +import { DataApiHubTabs } from "@/components/data-api-hub-tabs"; +import { pageMetadata } from "@/lib/page-metadata"; +import { safeJsonLd, buildBreadcrumbJsonLd } from "@/lib/jsonld"; +import { SITE } from "@/data/site"; + +/** + * Hub landing page for the data API vertical: price feeds, token metadata, + * portfolio/wallet indexing, DEX coverage, and NFT data. + * + * Blob-only: loads the materialized bench blobs for each of the 9 data-API + * benchmarks. Never touches Prometheus at render time. Graceful degradation + * if blobs are missing — the page renders the "warming up" state with direct + * bench links, never a 404 or throw. + */ + +const DESCRIPTION = + "Live benchmark rankings for crypto data APIs: price feed latency, token metadata coverage, wallet indexing freshness, DEX chain coverage, and NFT data quality."; + +export const metadata: import("next").Metadata = pageMetadata({ + path: "/data-api", + title: "Best Crypto Data API 2026, ranked by benchmark", + description: DESCRIPTION, +}); + +export const revalidate = 60; + +const BENCH_SLUGS = [ + "aggregator-head-lag", + "metadata-coverage", + "asset-registry-coverage", + "token-quote-coverage", + "indexing-freshness", + "portfolio-chain-coverage", + "wallet-labels-coverage", + "dex-network-coverage", + "nft-collection-metadata", +] as const; + +export default async function DataApiHubPage() { + const snapshot = await fetchDataApiSnapshot(); + + const breadcrumbLd = { + "@context": "https://schema.org", + ...buildBreadcrumbJsonLd([ + { name: "Home", item: SITE.url }, + { name: "Data API benchmarks", item: `${SITE.url}/data-api` }, + ]), + }; + + const itemListLd = { + "@context": "https://schema.org", + "@type": "ItemList", + name: "Crypto data API benchmarks by OpenChainBench", + description: DESCRIPTION, + numberOfItems: BENCH_SLUGS.length, + itemListElement: BENCH_SLUGS.map((slug, i) => ({ + "@type": "ListItem", + position: i + 1, + name: slug, + url: `${SITE.url}/benchmarks/${slug}`, + })), + }; + + return ( +
+