From 1978cfc4cfc461837d61cfc071880a7c6f959ede Mon Sep 17 00:00:00 2001 From: Flotapponnier <160007691+Flotapponnier@users.noreply.github.com> Date: Sat, 29 Aug 2026 15:40:29 +0200 Subject: [PATCH 1/6] =?UTF-8?q?merge:=20dev=20=E2=86=92=20main=20(Gains=20?= =?UTF-8?q?carry=20fix=20+=20vault=20fee=20split)=20(#2191)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(harnesses): cap LZ/CCIP/Axelar cardinality to bench-tracked chains only (#2187) * fix(cache): strip heavy fields from aggregate blob to pass 2MB limit (#2188) Hub pages only need card data. Drop seriesByRegion24h, metricPanels, editorial text (seoIntro/faq/findings/methodology/disclaimer/abstract/ perChainExplainer) from the blob aggregate slim. Cuts serialized size from ~4.3 MB to under 2 MB so unstable_cache actually persists the entry instead of silently dropping it on every render. * fix: include still-open Gains positions in carry projection (#2189) * fix(cache): strip heavy fields from aggregate blob to pass 2MB limit Hub pages only need card data. Drop seriesByRegion24h, metricPanels, editorial text (seoIntro/faq/findings/methodology/disclaimer/abstract/ perChainExplainer) from the blob aggregate slim. Cuts serialized size from ~4.3 MB to under 2 MB so unstable_cache actually persists the entry instead of silently dropping it on every render. * fix: include still-open Gains positions in carry projection * fix: update Gains action names v5→v6, handle position size increases (#2190) * fix(cache): strip heavy fields from aggregate blob to pass 2MB limit Hub pages only need card data. Drop seriesByRegion24h, metricPanels, editorial text (seoIntro/faq/findings/methodology/disclaimer/abstract/ perChainExplainer) from the blob aggregate slim. Cuts serialized size from ~4.3 MB to under 2 MB so unstable_cache actually persists the entry instead of silently dropping it on every render. * fix: include still-open Gains positions in carry projection * fix: update Gains open action names to v6 API, handle TradePosSizeIncrease --- .../axelar-gmp-latency/cmd/script/chains.go | 21 +++++++++++ .../axelar-gmp-latency/cmd/script/main.go | 6 ++-- .../cmd/script/chains.go | 26 ++++++++++++++ .../chainlink-ccip-latency/cmd/script/main.go | 4 +++ .../cmd/script/chains.go | 29 +++++++++++++++ .../cmd/script/main.go | 4 +++ src/app/api/fee-compare/route.ts | 15 ++++++-- src/lib/aggregate-blob.ts | 35 +++++++++++++++++-- 8 files changed, 133 insertions(+), 7 deletions(-) diff --git a/harnesses/axelar-gmp-latency/cmd/script/chains.go b/harnesses/axelar-gmp-latency/cmd/script/chains.go index 2c83c54f4..2b62f1769 100644 --- a/harnesses/axelar-gmp-latency/cmd/script/chains.go +++ b/harnesses/axelar-gmp-latency/cmd/script/chains.go @@ -14,6 +14,27 @@ import "strings" // - Cosmos chains (osmosis, injective, sei, celestia, kava) are // Axelar-exclusive coverage vs Wormhole/LayerZero/CCIP/Hyperlane // +// axelarTrackedChains is the set of OCB canonical slugs we record metrics for. +// Only messages where BOTH source AND destination are in this set are +// observed, capping cardinality at len²×buckets. +// Derived from the bench YAML provider slugs. +var axelarTrackedChains = map[string]bool{ + "ethereum": true, + "polygon": true, + "base": true, + "moonbeam": true, + "osmosis": true, + "arbitrum": true, + "avalanche": true, + "bnb": true, + "celo": true, + "injective": true, + "linea": true, + "mantle": true, + "optimism": true, + "scroll": true, +} + // Unknown names fall through to `chain-` so we never drop data. var axelarChainSlug = map[string]string{ // EVM L1s diff --git a/harnesses/axelar-gmp-latency/cmd/script/main.go b/harnesses/axelar-gmp-latency/cmd/script/main.go index a3652e996..55ff6b41a 100644 --- a/harnesses/axelar-gmp-latency/cmd/script/main.go +++ b/harnesses/axelar-gmp-latency/cmd/script/main.go @@ -173,8 +173,10 @@ func poll(ctx context.Context, client *http.Client, seen *lruSet) error { totalMs := float64(m.TimeSpent.Total) * 1000 if totalMs > 0 && totalMs <= maxLatencyMs { dst := canonicalizeAxelarChain(m.Call.ReturnValues.DestinationChain) - axelarE2ELatencyMs.WithLabelValues(src, dst).Observe(totalMs) - axelarSeenTotal.WithLabelValues(src, dst).Inc() + if axelarTrackedChains[src] && axelarTrackedChains[dst] { + axelarE2ELatencyMs.WithLabelValues(src, dst).Observe(totalMs) + axelarSeenTotal.WithLabelValues(src, dst).Inc() + } } seen.add(m.ID) diff --git a/harnesses/chainlink-ccip-latency/cmd/script/chains.go b/harnesses/chainlink-ccip-latency/cmd/script/chains.go index e551d3c46..bb3a17fed 100644 --- a/harnesses/chainlink-ccip-latency/cmd/script/chains.go +++ b/harnesses/chainlink-ccip-latency/cmd/script/chains.go @@ -12,6 +12,32 @@ package main // makes the mapping legible and the audit trail obvious when CCIP // adds a new chain we didn't anticipate. // +// ccipTrackedChains is the set of OCB canonical slugs we record metrics for. +// Only messages where BOTH source AND destination are in this set are +// observed, capping cardinality at len²×buckets. +// Derived from the bench YAML provider slugs. +var ccipTrackedChains = map[string]bool{ + "ethereum": true, + "bnb": true, + "polygon": true, + "avalanche": true, + "arbitrum": true, + "base": true, + "robinhood": true, + "berachain": true, + "celo": true, + "ink": true, + "linea": true, + "mantle": true, + "monad": true, + "moonbeam": true, + "optimism": true, + "scroll": true, + "solana": true, + "unichain": true, + "world-chain": true, +} + // Only mainnet entries are mapped; testnet rows are dropped in main.go // via the `environment != "mainnet"` guard so we never emit test-chain // latency. diff --git a/harnesses/chainlink-ccip-latency/cmd/script/main.go b/harnesses/chainlink-ccip-latency/cmd/script/main.go index 19b6e3c8d..c4a0cece9 100644 --- a/harnesses/chainlink-ccip-latency/cmd/script/main.go +++ b/harnesses/chainlink-ccip-latency/cmd/script/main.go @@ -189,6 +189,10 @@ func poll(ctx context.Context, client *http.Client, seen *lruSet) error { seen.add(m.MessageID) continue } + if !ccipTrackedChains[srcSlug] || !ccipTrackedChains[dstSlug] { + seen.add(m.MessageID) + continue + } ccipLatencyMs.WithLabelValues(srcSlug, dstSlug).Observe(deltaMs) ccipSeenTotal.WithLabelValues(srcSlug, dstSlug).Inc() seen.add(m.MessageID) diff --git a/harnesses/layerzero-message-latency/cmd/script/chains.go b/harnesses/layerzero-message-latency/cmd/script/chains.go index 2c8887410..ded442922 100644 --- a/harnesses/layerzero-message-latency/cmd/script/chains.go +++ b/harnesses/layerzero-message-latency/cmd/script/chains.go @@ -10,6 +10,35 @@ package main // - LayerZero exposes a bunch of exotic chains (orderly, flare, ape, // robinhood, hyperliquid) that map to our slugs where they exist. // +// lzTrackedChains is the set of OCB canonical slugs we record metrics for. +// Only messages where BOTH source AND destination are in this set are +// observed. This caps cardinality at len²×buckets instead of the full +// N×N cross-product of all chains LayerZero supports. +// Derived from the bench YAML provider slugs — add here when adding a +// new chain to the bench. +var lzTrackedChains = map[string]bool{ + "ethereum": true, + "solana": true, + "bnb": true, + "arbitrum": true, + "base": true, + "optimism": true, + "polygon": true, + "avalanche": true, + "robinhood": true, + "monad": true, + "berachain": true, + "celo": true, + "injective": true, + "ink": true, + "linea": true, + "mantle": true, + "moonbeam": true, + "scroll": true, + "sui": true, + "unichain": true, +} + // Unknown names fall through to a synthetic `chain-` slug in // main.go so we never drop data silently. var lzChainSlug = map[string]string{ diff --git a/harnesses/layerzero-message-latency/cmd/script/main.go b/harnesses/layerzero-message-latency/cmd/script/main.go index 5f7a4f6d9..3ccfc0d07 100644 --- a/harnesses/layerzero-message-latency/cmd/script/main.go +++ b/harnesses/layerzero-message-latency/cmd/script/main.go @@ -206,6 +206,10 @@ func poll(ctx context.Context, client *http.Client, seen *lruSet) error { continue } dstSlug := chainSlug(m.Pathway.Receiver.Chain) + if !lzTrackedChains[srcSlug] || !lzTrackedChains[dstSlug] { + seen.add(m.GUID) + continue + } lzLatencyMs.WithLabelValues(srcSlug, dstSlug).Observe(deltaMs) lzSeenTotal.WithLabelValues(srcSlug, dstSlug).Inc() seen.add(m.GUID) diff --git a/src/app/api/fee-compare/route.ts b/src/app/api/fee-compare/route.ts index cd724592e..b4f9e2e12 100644 --- a/src/app/api/fee-compare/route.ts +++ b/src/app/api/fee-compare/route.ts @@ -1110,7 +1110,10 @@ function augmentWithHlOpenPositions( } function reconstructGainsPositions(trades: GainsApiTrade[], cutoffMs: number): PositionSlice[] { - const OPEN_ACTIONS = new Set(["MarketOpened", "LimitOrderExecuted"]); + // v5 names: MarketOpened, LimitOrderExecuted — v6 names: TradeOpenedMarket, TradeOpenedLimit + const OPEN_ACTIONS = new Set(["MarketOpened", "LimitOrderExecuted", "TradeOpenedMarket", "TradeOpenedLimit"]); + // TradePosSizeIncrease updates the position size; use latest size as notional + const INCREASE_ACTIONS = new Set(["TradePosSizeIncrease"]); const CLOSE_ACTIONS = new Set(["TradeClosedMarket", "TradeClosedTP", "TradeClosedSL", "TradeClosedLIQ"]); const byId = new Map(); @@ -1118,19 +1121,25 @@ function reconstructGainsPositions(trades: GainsApiTrade[], cutoffMs: number): P if (!byId.has(t.id)) byId.set(t.id, {}); const e = byId.get(t.id)!; if (OPEN_ACTIONS.has(t.action)) e.open = t; + else if (INCREASE_ACTIONS.has(t.action) && e.open) { + e.open = { ...e.open, size: t.size, leverage: t.leverage }; + } else if (CLOSE_ACTIONS.has(t.action)) e.close = t; } + const now = Date.now(); const slices: PositionSlice[] = []; for (const { open, close } of byId.values()) { - if (!open || !close) continue; + if (!open) continue; const openMs = new Date(open.date).getTime(); if (openMs < cutoffMs) continue; + // Still-open positions use now as close time (same as reconstructHlPositions) + const closeMs = close ? new Date(close.date).getTime() : now; slices.push({ coin: open.pair.split("/")[0], notionalUsd: open.size * open.leverage, openMs, - closeMs: new Date(close.date).getTime(), + closeMs, isLong: open.buy !== false, }); } diff --git a/src/lib/aggregate-blob.ts b/src/lib/aggregate-blob.ts index 0c2ff32e5..f920fb1fd 100644 --- a/src/lib/aggregate-blob.ts +++ b/src/lib/aggregate-blob.ts @@ -26,6 +26,37 @@ import type { Benchmark } from "@/types/benchmark"; import { loadSpecsUncached } from "@/lib/materialize/load"; import { overlayEditorial, slimBenchmarkForCache } from "@/lib/spec"; +// Aggressive slim for the aggregate blob. Hub pages (homepage, categories, +// chains, products) only need card data — they never render editorial text +// or metric panels. Stripping these fields drops the serialized aggregate +// from ~4.3 MB to well under the 2 MB unstable_cache ceiling. +// +// Fields stripped beyond slimBenchmarkForCache (which already removes +// 7d/30d series): +// - extras.seriesByRegion24h (only used on bench detail pages) +// - metricPanels (only used on bench detail pages) +// - seoIntro, faq, disclaimer (editorial, bench detail only) +// - perChainExplainer (bench detail + worker's sitemap.json handles sitemap) +// - findings, methodology (bench detail only; required fields → []) +// - abstract (bench detail only; required field → "") +function slimForBlobAggregate(b: Benchmark): Benchmark { + const base = slimBenchmarkForCache(b); + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { seriesByRegion24h: _sbr, ...slimExtras } = base.extras; + return { + ...base, + extras: slimExtras, + metricPanels: undefined, + seoIntro: undefined, + faq: undefined, + perChainExplainer: undefined, + disclaimer: undefined, + findings: [], + methodology: [], + abstract: "", + }; +} + // On any Vercel deployment (production or preview), use the self-hosted // CDN proxy (/api/aggregate on openchainbench.com) so Vercel functions // pay ~1 ms (edge cache hit) instead of ~12 s fetching the 7.5 MB blob @@ -113,7 +144,7 @@ async function fetchAndProject(): Promise { for (const bench of raw.benches) { const spec = specBySlug.get(bench.slug); if (!spec) continue; // Bench in blob no longer has a spec — skip. - projected.push(slimBenchmarkForCache(overlayEditorial(bench, spec))); + projected.push(slimForBlobAggregate(overlayEditorial(bench, spec))); } return projected.sort((a, b) => (a.number ?? "").localeCompare(b.number ?? ""), @@ -130,6 +161,6 @@ async function fetchAndProject(): Promise { */ export const loadAggregateFromBlob = unstable_cache( fetchAndProject, - ["aggregate-blob-v2"], + ["aggregate-blob-v3"], { revalidate: 60, tags: ["bench-aggregate", "benchmarks"] }, ); From cf6906b552c7cefe76d577ced80039d109886bbb Mon Sep 17 00:00:00 2001 From: Flotapponnier <160007691+Flotapponnier@users.noreply.github.com> Date: Sat, 29 Aug 2026 18:02:33 +0200 Subject: [PATCH 2/6] feat(rpc): Union bench #253 (#2195) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(harnesses): cap LZ/CCIP/Axelar cardinality to bench-tracked chains only (#2187) * fix(cache): strip heavy fields from aggregate blob to pass 2MB limit (#2188) Hub pages only need card data. Drop seriesByRegion24h, metricPanels, editorial text (seoIntro/faq/findings/methodology/disclaimer/abstract/ perChainExplainer) from the blob aggregate slim. Cuts serialized size from ~4.3 MB to under 2 MB so unstable_cache actually persists the entry instead of silently dropping it on every render. * fix: include still-open Gains positions in carry projection (#2189) * fix(cache): strip heavy fields from aggregate blob to pass 2MB limit Hub pages only need card data. Drop seriesByRegion24h, metricPanels, editorial text (seoIntro/faq/findings/methodology/disclaimer/abstract/ perChainExplainer) from the blob aggregate slim. Cuts serialized size from ~4.3 MB to under 2 MB so unstable_cache actually persists the entry instead of silently dropping it on every render. * fix: include still-open Gains positions in carry projection * fix: update Gains action names v5→v6, handle position size increases (#2190) * fix(cache): strip heavy fields from aggregate blob to pass 2MB limit Hub pages only need card data. Drop seriesByRegion24h, metricPanels, editorial text (seoIntro/faq/findings/methodology/disclaimer/abstract/ perChainExplainer) from the blob aggregate slim. Cuts serialized size from ~4.3 MB to under 2 MB so unstable_cache actually persists the entry instead of silently dropping it on every render. * fix: include still-open Gains positions in carry projection * fix: update Gains open action names to v6 API, handle TradePosSizeIncrease * fix: Gains carry projection (v6 action names + still-open positions) * fix(cache): strip heavy fields from aggregate blob to pass 2MB limit Hub pages only need card data. Drop seriesByRegion24h, metricPanels, editorial text (seoIntro/faq/findings/methodology/disclaimer/abstract/ perChainExplainer) from the blob aggregate slim. Cuts serialized size from ~4.3 MB to under 2 MB so unstable_cache actually persists the entry instead of silently dropping it on every render. * fix: include still-open Gains positions in carry projection * fix: update Gains open action names to v6 API, handle TradePosSizeIncrease * fix: widen coin name column for long tickers (xyz:NVDA) * fix(cache): strip heavy fields from aggregate blob to pass 2MB limit Hub pages only need card data. Drop seriesByRegion24h, metricPanels, editorial text (seoIntro/faq/findings/methodology/disclaimer/abstract/ perChainExplainer) from the blob aggregate slim. Cuts serialized size from ~4.3 MB to under 2 MB so unstable_cache actually persists the entry instead of silently dropping it on every render. * fix: include still-open Gains positions in carry projection * fix: update Gains open action names to v6 API, handle TradePosSizeIncrease * fix: widen coin name column in top markets to fit xyz:NVDA * feat(rpc): add Union bench #253 (Nodes.Guru, Stake And Relax, High Stakes) (#2194) --- benchmarks/union-rpc.yml | 138 ++++++++++++++++++ .../rpc-capabilities/cmd/script/config.go | 11 ++ public/logos/union.svg | 4 + src/components/fee-compare-client.tsx | 2 +- src/data/provider-registry.ts | 20 +++ src/lib/brand.ts | 3 +- src/lib/logo-manifest.ts | 1 + 7 files changed, 177 insertions(+), 2 deletions(-) create mode 100644 benchmarks/union-rpc.yml create mode 100644 public/logos/union.svg diff --git a/benchmarks/union-rpc.yml b/benchmarks/union-rpc.yml new file mode 100644 index 000000000..0373e4819 --- /dev/null +++ b/benchmarks/union-rpc.yml @@ -0,0 +1,138 @@ +# OpenChainBench. Bench No 253 + +slug: union-rpc +number: "253" +title: Fastest free Union RPC, live no-key endpoint latency +seo_title: "Fastest free Union RPC 2026" +seo_description: "{{best_name}} leads free Union RPC at {{best_p50}} (block height p50, 24h). 3 providers measured every 60s from 3 regions." +subtitle: HTTP round-trip latency for Tendermint /status queries against every available public Union (union-1) endpoint, audited every 60 seconds from 3 regions. + +category: RPCs +status: live +metric: RPC latency +unit: ms +higher_is_better: false + +seo_intro: | + Union is a trust-minimised, zero-knowledge cross-chain protocol built on a custom Cosmos SDK chain (chain ID union-1). It enables secure interoperability between Cosmos, EVM, and other ecosystems via ZK proof-based consensus verification — no external validators or multisigs required. The chain uses the standard Tendermint RPC interface; block height is fetched via the /status endpoint. Public keyless RPC nodes are provided by Nodes.Guru, Stake And Relax, and High Stakes. Every provider was live-verified with consecutive block-height probes at launch. + +abstract: | + Per-chain member of the RPC latency cluster, extended to Union (union-1). + We measure the round-trip latency of a Tendermint /status query against + every available public Union endpoint that sustains continuous probing: + 3 providers at launch, every 60 seconds, from us-east, eu-west and + Singapore. Each provider is probed via a GET /status request + from which the block number is extracted. + The harness classifies every response (ok / http_err / jsonrpc_err / stale / timeout) + with a Cosmos-scaled staleness gap (20 blocks, around 80 s at 4 s/block). + The cross-chain view lives on the parent rpc-capabilities benchmark; + this page is the Union-scoped answer with per-region breakdowns as + a first-class dimension. + +methodology: + - "Cadence: every 60 seconds per provider, from each of 3 probe regions (us-east Virginia, eu-west Amsterdam, sgp Singapore). Headline p50/p90/p99 aggregate across all 3 regions via Prometheus avg(quantile_over_time(...)); per-region breakdowns are first-class on this page via the region tabs." + - "Payload: GET /status. The result.sync_info.latest_block_height field (string-encoded integer) is extracted as the current block height." + - "Latency: client-side round-trip delta in milliseconds, exposed as both a gauge and a histogram (buckets 50 ms to 10 s), so percentiles are computed via Prometheus quantile_over_time over the last 24 hours." + - "Call-result classification: ok (parsable block height returned), http_err, jsonrpc_err, stale (block more than 20 behind the cross-provider tip), timeout." + - "This page is part of the per-chain RPC cluster derived from the cross-chain rpc-capabilities benchmark; the identical harness, cadence and exclusion rules apply on every chain." + - "Chain scope: every query on this page is pinned to chain=union. Provider coverage at launch: 3 endpoints (Nodes.Guru, Stake And Relax, High Stakes)." + +findings: + - "{{best_name}} leads free Union RPC at {{best_p50}} (Tendermint /status p50, 24h) across 3 measured providers." + +faq: + - q: "What is the fastest free Union RPC right now?" + a: "{{best_name}} currently leads at {{best_p50}} (Union block height p50 over the last 24h), measured against 3 providers probed every 60 seconds from us-east, eu-west and Singapore. The leaderboard re-sorts continuously against fresh Prometheus samples." + - q: "Which Union RPC endpoints work without an API key?" + a: "3 endpoints sustain continuous keyless probing at launch: Nodes.Guru (rpc-1.union.nodes.guru), Stake And Relax (union-rpc.stakeandrelax.net), and High Stakes (union-rpc.highstakes.ch). Every listed endpoint was live-verified before inclusion." + - q: "What is Union and why does its RPC latency matter?" + a: "Union is a ZK-based cross-chain interoperability protocol with a native Cosmos SDK chain (union-1). It connects blockchains without trusted intermediaries by verifying consensus proofs on-chain. Developers building cross-chain applications, bridges, or omnichain protocols on Union need reliable low-latency RPC access to query transactions, proofs, and chain state." + - q: "Does the fastest Union RPC change by region?" + a: "Often. Community validators like Nodes.Guru and High Stakes host in different datacentres. The region tabs re-scope every number to a single probe origin so you can pick the best endpoint for your user base." + - q: "What makes Union different from other cross-chain protocols?" + a: "Union replaces trusted validator sets and multisigs with ZK consensus proofs, making cross-chain message passing verifiable on-chain. This means no external trust assumptions — the security of the bridge reduces to the security of the underlying chains and ZK proof system." + +source: https://github.com/ChainBench/OpenChainBench/tree/main/harnesses/rpc-capabilities + +prometheus: + window: 24h + freshness_metric: rpc_latency_milliseconds + +rank_matrix_query: avg by (provider, region) (ocb:rpc_latency_milliseconds:p50_24h{chain="union"}) + +dimensions: + region: + - { value: all, label: All regions } + - { value: us-east, label: US-East } + - { value: eu-west, label: EU-West } + - { value: sgp, label: Singapore } + +providers: + - slug: nodes-guru + name: Nodes.Guru + tag: Nodes.Guru public Union RPC, no API key required + formula: "50th percentile over 24h of client-side round-trip latency (ms) for a GET /status sent every 60s from 3 regions to rpc-1.union.nodes.guru." + queries: + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="nodes-guru", chain="union"}) + p90: avg(ocb:rpc_latency_milliseconds:p90_24h{provider="nodes-guru", chain="union"}) + p99: avg(ocb:rpc_latency_milliseconds:p99_24h{provider="nodes-guru", chain="union"}) + mean: avg(ocb:rpc_latency_milliseconds:mean_24h{provider="nodes-guru", chain="union"}) + success: sum(ocb:rpc_call:ok_rate_24h{provider="nodes-guru", chain="union"}) / sum(ocb:rpc_call:rate_24h{provider="nodes-guru", chain="union"}) + sample_size: sum(ocb:rpc_call:increase_24h{provider="nodes-guru", chain="union"}) + series: avg(avg_over_time(rpc_latency_milliseconds{provider="nodes-guru", chain="union"}[1h])) + regions: + - region: us-east + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="nodes-guru", chain="union", region="us-east"}) + series: avg_over_time(rpc_latency_milliseconds{provider="nodes-guru", chain="union", region="us-east"}[1h]) + - region: eu-west + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="nodes-guru", chain="union", region="eu-west"}) + series: avg_over_time(rpc_latency_milliseconds{provider="nodes-guru", chain="union", region="eu-west"}[1h]) + - region: ap-southeast + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="nodes-guru", chain="union", region="sgp"}) + series: avg_over_time(rpc_latency_milliseconds{provider="nodes-guru", chain="union", region="sgp"}[1h]) + + - slug: stakeandrelax + name: Stake And Relax + tag: Stake And Relax public Union RPC, no API key required + formula: "50th percentile over 24h of client-side round-trip latency (ms) for a GET /status sent every 60s from 3 regions to union-rpc.stakeandrelax.net." + queries: + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="stakeandrelax", chain="union"}) + p90: avg(ocb:rpc_latency_milliseconds:p90_24h{provider="stakeandrelax", chain="union"}) + p99: avg(ocb:rpc_latency_milliseconds:p99_24h{provider="stakeandrelax", chain="union"}) + mean: avg(ocb:rpc_latency_milliseconds:mean_24h{provider="stakeandrelax", chain="union"}) + success: sum(ocb:rpc_call:ok_rate_24h{provider="stakeandrelax", chain="union"}) / sum(ocb:rpc_call:rate_24h{provider="stakeandrelax", chain="union"}) + sample_size: sum(ocb:rpc_call:increase_24h{provider="stakeandrelax", chain="union"}) + series: avg(avg_over_time(rpc_latency_milliseconds{provider="stakeandrelax", chain="union"}[1h])) + regions: + - region: us-east + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="stakeandrelax", chain="union", region="us-east"}) + series: avg_over_time(rpc_latency_milliseconds{provider="stakeandrelax", chain="union", region="us-east"}[1h]) + - region: eu-west + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="stakeandrelax", chain="union", region="eu-west"}) + series: avg_over_time(rpc_latency_milliseconds{provider="stakeandrelax", chain="union", region="eu-west"}[1h]) + - region: ap-southeast + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="stakeandrelax", chain="union", region="sgp"}) + series: avg_over_time(rpc_latency_milliseconds{provider="stakeandrelax", chain="union", region="sgp"}[1h]) + + - slug: highstakes + name: High Stakes + tag: High Stakes public Union RPC, no API key required + formula: "50th percentile over 24h of client-side round-trip latency (ms) for a GET /status sent every 60s from 3 regions to union-rpc.highstakes.ch." + queries: + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="highstakes", chain="union"}) + p90: avg(ocb:rpc_latency_milliseconds:p90_24h{provider="highstakes", chain="union"}) + p99: avg(ocb:rpc_latency_milliseconds:p99_24h{provider="highstakes", chain="union"}) + mean: avg(ocb:rpc_latency_milliseconds:mean_24h{provider="highstakes", chain="union"}) + success: sum(ocb:rpc_call:ok_rate_24h{provider="highstakes", chain="union"}) / sum(ocb:rpc_call:rate_24h{provider="highstakes", chain="union"}) + sample_size: sum(ocb:rpc_call:increase_24h{provider="highstakes", chain="union"}) + series: avg(avg_over_time(rpc_latency_milliseconds{provider="highstakes", chain="union"}[1h])) + regions: + - region: us-east + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="highstakes", chain="union", region="us-east"}) + series: avg_over_time(rpc_latency_milliseconds{provider="highstakes", chain="union", region="us-east"}[1h]) + - region: eu-west + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="highstakes", chain="union", region="eu-west"}) + series: avg_over_time(rpc_latency_milliseconds{provider="highstakes", chain="union", region="eu-west"}[1h]) + - region: ap-southeast + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="highstakes", chain="union", region="sgp"}) + series: avg_over_time(rpc_latency_milliseconds{provider="highstakes", chain="union", region="sgp"}[1h]) diff --git a/harnesses/rpc-capabilities/cmd/script/config.go b/harnesses/rpc-capabilities/cmd/script/config.go index c985e4479..186460674 100644 --- a/harnesses/rpc-capabilities/cmd/script/config.go +++ b/harnesses/rpc-capabilities/cmd/script/config.go @@ -1693,6 +1693,17 @@ func chains() []Chain { {Slug: "cosmos-directory", Name: "Cosmos Directory", URL: envDefault("RPC_URL_SENTINEL_COSMOSDIRECTORY", "https://rpc.cosmos.directory/sentinel")}, }, }, + // 2026-08-29 wave-12. Union — Cosmos SDK (union-1), Tendermint /status. Nodes.Guru + Stake And Relax + High Stakes. + { + Slug: "union", + Name: "Union", + Kind: "cosmos", + Providers: []Provider{ + {Slug: "nodes-guru", Name: "Nodes.Guru", URL: envDefault("RPC_URL_UNION_NODESGURU", "https://rpc-1.union.nodes.guru")}, + {Slug: "stakeandrelax", Name: "Stake And Relax", URL: envDefault("RPC_URL_UNION_STAKEANDRELAX", "https://union-rpc.stakeandrelax.net")}, + {Slug: "highstakes", Name: "High Stakes", URL: envDefault("RPC_URL_UNION_HIGHSTAKES", "https://union-rpc.highstakes.ch")}, + }, + }, // 2026-08-28 wave-11. Fetch.ai (FetchHub-4) — Cosmos SDK, Tendermint /status. Official + PublicNode + Cosmos Directory. { Slug: "fetchhub", diff --git a/public/logos/union.svg b/public/logos/union.svg new file mode 100644 index 000000000..a1957ae25 --- /dev/null +++ b/public/logos/union.svg @@ -0,0 +1,4 @@ + + + UNO + diff --git a/src/components/fee-compare-client.tsx b/src/components/fee-compare-client.tsx index 6e931a1c0..a7ada7a71 100644 --- a/src/components/fee-compare-client.tsx +++ b/src/components/fee-compare-client.tsx @@ -956,7 +956,7 @@ function HlTopCoinsCard({ key={c.coin} className="flex items-center gap-3 px-5 py-3 hover:bg-ink/2 transition-colors" > - + {c.coin} {c.fills} fills diff --git a/src/data/provider-registry.ts b/src/data/provider-registry.ts index a3e40769c..9046f4ba6 100644 --- a/src/data/provider-registry.ts +++ b/src/data/provider-registry.ts @@ -2619,6 +2619,26 @@ export const PROVIDER_REGISTRY: Record = { "Fetch.ai official public Tendermint RPC node for the FetchHub-4 mainnet. Keyless endpoint maintained by the Fetch.ai / ASI Alliance team.", twitter: "@Fetch_ai", }, + + // ─── Union providers (bench 253) ───────────────────────────────────── + "nodes-guru": { + url: "https://nodes.guru", + description: + "Nodes.Guru community validator and public RPC operator. Runs keyless Tendermint RPC endpoints for multiple Cosmos SDK chains including Union.", + twitter: "@nodes_guru", + }, + stakeandrelax: { + url: "https://stakeandrelax.net", + description: + "Stake And Relax community validator providing public keyless Tendermint RPC for Cosmos SDK chains including Union.", + twitter: "@StakeAndRelax", + }, + highstakes: { + url: "https://highstakes.ch", + description: + "High Stakes Swiss validator and public RPC operator. Provides keyless Tendermint RPC endpoints for multiple Cosmos SDK chains including Union.", + twitter: "@HighStakesCH", + }, }; /** diff --git a/src/lib/brand.ts b/src/lib/brand.ts index 8fb6c311a..453dc405d 100644 --- a/src/lib/brand.ts +++ b/src/lib/brand.ts @@ -173,11 +173,12 @@ const BRANDS: Record = { acala: { color: "#E40C5B" }, // acala red/pink (official brand) interlay: { color: "#1A3BDB" }, // interlay blue (official brand) - // ─── Cosmos SDK chains (benches 247, 250-252) ─── + // ─── Cosmos SDK chains (benches 247, 250-253) ─── babylon: { color: "#F8811A" }, // babylon orange (official brand) chihuahua: { color: "#E05F2A" }, // chihuahua orange-red (official brand) sentinel: { color: "#00C2FF" }, // sentinel cyan (official brand) fetchhub: { color: "#3B2D8E" }, // fetch.ai deep purple (official brand) + union: { color: "#6366F1" }, // union indigo (brand kit) "cosmos-directory": { color: "#1B1B2F", dark: true }, // cosmos directory dark navy // ─── Bitcoin Cash chain + providers (bench 244) ─── diff --git a/src/lib/logo-manifest.ts b/src/lib/logo-manifest.ts index 3fca81c47..d221da4df 100644 --- a/src/lib/logo-manifest.ts +++ b/src/lib/logo-manifest.ts @@ -331,6 +331,7 @@ const RAW: Record = { chihuahua: "/logos/chihuahua.svg", sentinel: "/logos/sentinel.svg", fetchhub: "/logos/fetchai.svg", + union: "/logos/union.svg", "cosmos-directory": "/logos/cosmos-directory.svg", // ─── Oracle deviation (bench 025) — additional brand logos ─── From 4a47227a2f0f2c3c6c696a8aea2b8649ae7ad034 Mon Sep 17 00:00:00 2001 From: Florent Tapponnier <160007691+Flotapponnier@users.noreply.github.com> Date: Sat, 29 Aug 2026 18:13:26 +0200 Subject: [PATCH 3/6] fix(union-rpc): remove em dashes from YAML --- benchmarks/union-rpc.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/benchmarks/union-rpc.yml b/benchmarks/union-rpc.yml index 0373e4819..c075123a4 100644 --- a/benchmarks/union-rpc.yml +++ b/benchmarks/union-rpc.yml @@ -14,7 +14,7 @@ unit: ms higher_is_better: false seo_intro: | - Union is a trust-minimised, zero-knowledge cross-chain protocol built on a custom Cosmos SDK chain (chain ID union-1). It enables secure interoperability between Cosmos, EVM, and other ecosystems via ZK proof-based consensus verification — no external validators or multisigs required. The chain uses the standard Tendermint RPC interface; block height is fetched via the /status endpoint. Public keyless RPC nodes are provided by Nodes.Guru, Stake And Relax, and High Stakes. Every provider was live-verified with consecutive block-height probes at launch. + Union is a trust-minimised, zero-knowledge cross-chain protocol built on a custom Cosmos SDK chain (chain ID union-1). It enables secure interoperability between Cosmos, EVM, and other ecosystems via ZK proof-based consensus verification, with no external validators or multisigs required. The chain uses the standard Tendermint RPC interface; block height is fetched via the /status endpoint. Public keyless RPC nodes are provided by Nodes.Guru, Stake And Relax, and High Stakes. Every provider was live-verified with consecutive block-height probes at launch. abstract: | Per-chain member of the RPC latency cluster, extended to Union (union-1). @@ -50,7 +50,7 @@ faq: - q: "Does the fastest Union RPC change by region?" a: "Often. Community validators like Nodes.Guru and High Stakes host in different datacentres. The region tabs re-scope every number to a single probe origin so you can pick the best endpoint for your user base." - q: "What makes Union different from other cross-chain protocols?" - a: "Union replaces trusted validator sets and multisigs with ZK consensus proofs, making cross-chain message passing verifiable on-chain. This means no external trust assumptions — the security of the bridge reduces to the security of the underlying chains and ZK proof system." + a: "Union replaces trusted validator sets and multisigs with ZK consensus proofs, making cross-chain message passing verifiable on-chain. This means no external trust assumptions: the security of the bridge reduces to the security of the underlying chains and ZK proof system." source: https://github.com/ChainBench/OpenChainBench/tree/main/harnesses/rpc-capabilities From 407e002c2526afe7f5cb5b1ebbfa6069b83fc144 Mon Sep 17 00:00:00 2001 From: Florent Tapponnier <160007691+Flotapponnier@users.noreply.github.com> Date: Sat, 29 Aug 2026 18:36:33 +0200 Subject: [PATCH 4/6] feat(union): add provider SVG logos and brand colors --- public/logos/highstakes.svg | 5 +++++ public/logos/nodes-guru.svg | 5 +++++ public/logos/stakeandrelax.svg | 5 +++++ src/lib/brand.ts | 5 ++++- src/lib/logo-manifest.ts | 3 +++ 5 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 public/logos/highstakes.svg create mode 100644 public/logos/nodes-guru.svg create mode 100644 public/logos/stakeandrelax.svg diff --git a/public/logos/highstakes.svg b/public/logos/highstakes.svg new file mode 100644 index 000000000..220f0fad4 --- /dev/null +++ b/public/logos/highstakes.svg @@ -0,0 +1,5 @@ + + + HIGH + STAKES + diff --git a/public/logos/nodes-guru.svg b/public/logos/nodes-guru.svg new file mode 100644 index 000000000..c55d6fd0c --- /dev/null +++ b/public/logos/nodes-guru.svg @@ -0,0 +1,5 @@ + + + NODES + GURU + diff --git a/public/logos/stakeandrelax.svg b/public/logos/stakeandrelax.svg new file mode 100644 index 000000000..3664a52dd --- /dev/null +++ b/public/logos/stakeandrelax.svg @@ -0,0 +1,5 @@ + + + STAKE + RELAX + diff --git a/src/lib/brand.ts b/src/lib/brand.ts index 453dc405d..bb62f3166 100644 --- a/src/lib/brand.ts +++ b/src/lib/brand.ts @@ -178,7 +178,10 @@ const BRANDS: Record = { chihuahua: { color: "#E05F2A" }, // chihuahua orange-red (official brand) sentinel: { color: "#00C2FF" }, // sentinel cyan (official brand) fetchhub: { color: "#3B2D8E" }, // fetch.ai deep purple (official brand) - union: { color: "#6366F1" }, // union indigo (brand kit) + union: { color: "#6366F1" }, // union indigo (brand kit) + "nodes-guru": { color: "#F59E0B" }, // nodes.guru amber + stakeandrelax: { color: "#10B981" }, // stake and relax emerald + highstakes: { color: "#3B82F6" }, // high stakes blue "cosmos-directory": { color: "#1B1B2F", dark: true }, // cosmos directory dark navy // ─── Bitcoin Cash chain + providers (bench 244) ─── diff --git a/src/lib/logo-manifest.ts b/src/lib/logo-manifest.ts index d221da4df..6aa6d2b7a 100644 --- a/src/lib/logo-manifest.ts +++ b/src/lib/logo-manifest.ts @@ -332,6 +332,9 @@ const RAW: Record = { sentinel: "/logos/sentinel.svg", fetchhub: "/logos/fetchai.svg", union: "/logos/union.svg", + "nodes-guru": "/logos/nodes-guru.svg", + stakeandrelax: "/logos/stakeandrelax.svg", + highstakes: "/logos/highstakes.svg", "cosmos-directory": "/logos/cosmos-directory.svg", // ─── Oracle deviation (bench 025) — additional brand logos ─── From bcd05470ec3d1009a27b4f5dab50e807bec3a3ac Mon Sep 17 00:00:00 2001 From: Flotapponnier <160007691+Flotapponnier@users.noreply.github.com> Date: Sat, 29 Aug 2026 19:19:43 +0200 Subject: [PATCH 5/6] feat: Shentu #254 + MANTRA Chain #255 benches MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(harnesses): cap LZ/CCIP/Axelar cardinality to bench-tracked chains only (#2187) * fix(cache): strip heavy fields from aggregate blob to pass 2MB limit (#2188) Hub pages only need card data. Drop seriesByRegion24h, metricPanels, editorial text (seoIntro/faq/findings/methodology/disclaimer/abstract/ perChainExplainer) from the blob aggregate slim. Cuts serialized size from ~4.3 MB to under 2 MB so unstable_cache actually persists the entry instead of silently dropping it on every render. * fix: include still-open Gains positions in carry projection (#2189) * fix(cache): strip heavy fields from aggregate blob to pass 2MB limit Hub pages only need card data. Drop seriesByRegion24h, metricPanels, editorial text (seoIntro/faq/findings/methodology/disclaimer/abstract/ perChainExplainer) from the blob aggregate slim. Cuts serialized size from ~4.3 MB to under 2 MB so unstable_cache actually persists the entry instead of silently dropping it on every render. * fix: include still-open Gains positions in carry projection * fix: update Gains action names v5→v6, handle position size increases (#2190) * fix(cache): strip heavy fields from aggregate blob to pass 2MB limit Hub pages only need card data. Drop seriesByRegion24h, metricPanels, editorial text (seoIntro/faq/findings/methodology/disclaimer/abstract/ perChainExplainer) from the blob aggregate slim. Cuts serialized size from ~4.3 MB to under 2 MB so unstable_cache actually persists the entry instead of silently dropping it on every render. * fix: include still-open Gains positions in carry projection * fix: update Gains open action names to v6 API, handle TradePosSizeIncrease * fix: Gains carry projection (v6 action names + still-open positions) * fix(cache): strip heavy fields from aggregate blob to pass 2MB limit Hub pages only need card data. Drop seriesByRegion24h, metricPanels, editorial text (seoIntro/faq/findings/methodology/disclaimer/abstract/ perChainExplainer) from the blob aggregate slim. Cuts serialized size from ~4.3 MB to under 2 MB so unstable_cache actually persists the entry instead of silently dropping it on every render. * fix: include still-open Gains positions in carry projection * fix: update Gains open action names to v6 API, handle TradePosSizeIncrease * fix: widen coin name column for long tickers (xyz:NVDA) * fix(cache): strip heavy fields from aggregate blob to pass 2MB limit Hub pages only need card data. Drop seriesByRegion24h, metricPanels, editorial text (seoIntro/faq/findings/methodology/disclaimer/abstract/ perChainExplainer) from the blob aggregate slim. Cuts serialized size from ~4.3 MB to under 2 MB so unstable_cache actually persists the entry instead of silently dropping it on every render. * fix: include still-open Gains positions in carry projection * fix: update Gains open action names to v6 API, handle TradePosSizeIncrease * fix: widen coin name column in top markets to fit xyz:NVDA * feat(rpc): add Union bench #253 (Nodes.Guru, Stake And Relax, High Stakes) (#2194) * fix(union-rpc): remove em dashes from YAML (#2196) * feat(rpc): Shentu #254 + MANTRA Chain #255 (#2199) * feat(rpc): add Shentu bench #254 and MANTRA Chain bench #255 * fix: remove accidental dev-portal submodule --- benchmarks/mantrachain-rpc.yml | 138 ++++++++++++++++++ benchmarks/shentu-rpc.yml | 138 ++++++++++++++++++ .../rpc-capabilities/cmd/script/config.go | 22 +++ public/logos/itrocket.svg | 5 + public/logos/mantrachain.svg | 4 + public/logos/shentu-official.svg | 4 + public/logos/shentu.svg | 4 + src/data/provider-registry.ts | 23 +++ src/lib/brand.ts | 15 +- src/lib/logo-manifest.ts | 5 + 10 files changed, 352 insertions(+), 6 deletions(-) create mode 100644 benchmarks/mantrachain-rpc.yml create mode 100644 benchmarks/shentu-rpc.yml create mode 100644 public/logos/itrocket.svg create mode 100644 public/logos/mantrachain.svg create mode 100644 public/logos/shentu-official.svg create mode 100644 public/logos/shentu.svg diff --git a/benchmarks/mantrachain-rpc.yml b/benchmarks/mantrachain-rpc.yml new file mode 100644 index 000000000..e68ac84f9 --- /dev/null +++ b/benchmarks/mantrachain-rpc.yml @@ -0,0 +1,138 @@ +# OpenChainBench. Bench No 255 + +slug: mantrachain-rpc +number: "255" +title: Fastest free MANTRA RPC, live no-key endpoint latency +seo_title: "Fastest free MANTRA Chain RPC 2026" +seo_description: "{{best_name}} leads free MANTRA RPC at {{best_p50}} (block height p50, 24h). 3 providers measured every 60s from 3 regions." +subtitle: HTTP round-trip latency for Tendermint /status queries against every available public MANTRA Chain (mantra-1) endpoint, audited every 60 seconds from 3 regions. + +category: RPCs +status: live +metric: RPC latency +unit: ms +higher_is_better: false + +seo_intro: | + MANTRA Chain is a Cosmos SDK blockchain (chain ID mantra-1) purpose-built for real-world asset (RWA) tokenization. It is a permissioned, regulatory-compliant Layer 1 focused on bringing tokenized financial assets on-chain, including real estate, bonds, and commodities. The chain uses the standard Tendermint RPC interface; block height is fetched via the /status endpoint. Public keyless RPC nodes are provided by the MANTRA official team, ITRocket, and Polkachu. Every provider was live-verified with consecutive block-height probes at launch. + +abstract: | + Per-chain member of the RPC latency cluster, extended to MANTRA Chain (mantra-1). + We measure the round-trip latency of a Tendermint /status query against + every available public MANTRA endpoint that sustains continuous probing: + 3 providers at launch, every 60 seconds, from us-east, eu-west and + Singapore. Each provider is probed via a GET /status request + from which the block number is extracted. + The harness classifies every response (ok / http_err / jsonrpc_err / stale / timeout) + with a Cosmos-scaled staleness gap (20 blocks, around 120 s at 6 s/block). + The cross-chain view lives on the parent rpc-capabilities benchmark; + this page is the MANTRA-scoped answer with per-region breakdowns as + a first-class dimension. + +methodology: + - "Cadence: every 60 seconds per provider, from each of 3 probe regions (us-east Virginia, eu-west Amsterdam, sgp Singapore). Headline p50/p90/p99 aggregate across all 3 regions via Prometheus avg(quantile_over_time(...)); per-region breakdowns are first-class on this page via the region tabs." + - "Payload: GET /status. The result.sync_info.latest_block_height field (string-encoded integer) is extracted as the current block height." + - "Latency: client-side round-trip delta in milliseconds, exposed as both a gauge and a histogram (buckets 50 ms to 10 s), so percentiles are computed via Prometheus quantile_over_time over the last 24 hours." + - "Call-result classification: ok (parsable block height returned), http_err, jsonrpc_err, stale (block more than 20 behind the cross-provider tip), timeout." + - "This page is part of the per-chain RPC cluster derived from the cross-chain rpc-capabilities benchmark; the identical harness, cadence and exclusion rules apply on every chain." + - "Chain scope: every query on this page is pinned to chain=mantrachain. Provider coverage at launch: 3 endpoints (MANTRA official, ITRocket, Polkachu)." + +findings: + - "{{best_name}} leads free MANTRA Chain RPC at {{best_p50}} (Tendermint /status p50, 24h) across 3 measured providers." + +faq: + - q: "What is the fastest free MANTRA Chain RPC right now?" + a: "{{best_name}} currently leads at {{best_p50}} (MANTRA block height p50 over the last 24h), measured against 3 providers probed every 60 seconds from us-east, eu-west and Singapore. The leaderboard re-sorts continuously against fresh Prometheus samples." + - q: "Which MANTRA Chain RPC endpoints work without an API key?" + a: "3 endpoints sustain continuous keyless probing at launch: MANTRA official (rpc.mantrachain.io), ITRocket (mantra-mainnet-rpc.itrocket.net), and Polkachu (mantra-rpc.polkachu.com). Every listed endpoint was live-verified before inclusion." + - q: "What is MANTRA Chain and why does its RPC latency matter?" + a: "MANTRA Chain is a Cosmos SDK Layer 1 built for real-world asset tokenization under regulatory frameworks. It enables compliant issuance and trading of tokenized financial assets such as real estate, bonds, and commodities. Developers building RWA applications, compliance tooling, or DeFi protocols on MANTRA need reliable low-latency RPC access to query asset state, transactions, and governance." + - q: "Does the fastest MANTRA RPC change by region?" + a: "Often. The official MANTRA node and community validators are hosted across different regions. The region tabs re-scope every number to a single probe origin so you can pick the best endpoint for your user base." + - q: "What is the OM token on MANTRA Chain?" + a: "OM is the native staking and governance token of MANTRA Chain. It is used for validator staking, on-chain governance, and fee payment. The mantra-1 mainnet launched in 2024 with a focus on regulated RWA markets in the Middle East and Asia." + +source: https://github.com/ChainBench/OpenChainBench/tree/main/harnesses/rpc-capabilities + +prometheus: + window: 24h + freshness_metric: rpc_latency_milliseconds + +rank_matrix_query: avg by (provider, region) (ocb:rpc_latency_milliseconds:p50_24h{chain="mantrachain"}) + +dimensions: + region: + - { value: all, label: All regions } + - { value: us-east, label: US-East } + - { value: eu-west, label: EU-West } + - { value: sgp, label: Singapore } + +providers: + - slug: mantrachain-official + name: MANTRA + tag: MANTRA Chain official public RPC node, no API key required + formula: "50th percentile over 24h of client-side round-trip latency (ms) for a GET /status sent every 60s from 3 regions to rpc.mantrachain.io." + queries: + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="mantrachain-official", chain="mantrachain"}) + p90: avg(ocb:rpc_latency_milliseconds:p90_24h{provider="mantrachain-official", chain="mantrachain"}) + p99: avg(ocb:rpc_latency_milliseconds:p99_24h{provider="mantrachain-official", chain="mantrachain"}) + mean: avg(ocb:rpc_latency_milliseconds:mean_24h{provider="mantrachain-official", chain="mantrachain"}) + success: sum(ocb:rpc_call:ok_rate_24h{provider="mantrachain-official", chain="mantrachain"}) / sum(ocb:rpc_call:rate_24h{provider="mantrachain-official", chain="mantrachain"}) + sample_size: sum(ocb:rpc_call:increase_24h{provider="mantrachain-official", chain="mantrachain"}) + series: avg(avg_over_time(rpc_latency_milliseconds{provider="mantrachain-official", chain="mantrachain"}[1h])) + regions: + - region: us-east + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="mantrachain-official", chain="mantrachain", region="us-east"}) + series: avg_over_time(rpc_latency_milliseconds{provider="mantrachain-official", chain="mantrachain", region="us-east"}[1h]) + - region: eu-west + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="mantrachain-official", chain="mantrachain", region="eu-west"}) + series: avg_over_time(rpc_latency_milliseconds{provider="mantrachain-official", chain="mantrachain", region="eu-west"}[1h]) + - region: ap-southeast + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="mantrachain-official", chain="mantrachain", region="sgp"}) + series: avg_over_time(rpc_latency_milliseconds{provider="mantrachain-official", chain="mantrachain", region="sgp"}[1h]) + + - slug: itrocket + name: ITRocket + tag: ITRocket public MANTRA Chain RPC, no API key required + formula: "50th percentile over 24h of client-side round-trip latency (ms) for a GET /status sent every 60s from 3 regions to mantra-mainnet-rpc.itrocket.net." + queries: + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="itrocket", chain="mantrachain"}) + p90: avg(ocb:rpc_latency_milliseconds:p90_24h{provider="itrocket", chain="mantrachain"}) + p99: avg(ocb:rpc_latency_milliseconds:p99_24h{provider="itrocket", chain="mantrachain"}) + mean: avg(ocb:rpc_latency_milliseconds:mean_24h{provider="itrocket", chain="mantrachain"}) + success: sum(ocb:rpc_call:ok_rate_24h{provider="itrocket", chain="mantrachain"}) / sum(ocb:rpc_call:rate_24h{provider="itrocket", chain="mantrachain"}) + sample_size: sum(ocb:rpc_call:increase_24h{provider="itrocket", chain="mantrachain"}) + series: avg(avg_over_time(rpc_latency_milliseconds{provider="itrocket", chain="mantrachain"}[1h])) + regions: + - region: us-east + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="itrocket", chain="mantrachain", region="us-east"}) + series: avg_over_time(rpc_latency_milliseconds{provider="itrocket", chain="mantrachain", region="us-east"}[1h]) + - region: eu-west + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="itrocket", chain="mantrachain", region="eu-west"}) + series: avg_over_time(rpc_latency_milliseconds{provider="itrocket", chain="mantrachain", region="eu-west"}[1h]) + - region: ap-southeast + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="itrocket", chain="mantrachain", region="sgp"}) + series: avg_over_time(rpc_latency_milliseconds{provider="itrocket", chain="mantrachain", region="sgp"}[1h]) + + - slug: polkachu + name: Polkachu + tag: Polkachu public MANTRA Chain RPC, no API key required + formula: "50th percentile over 24h of client-side round-trip latency (ms) for a GET /status sent every 60s from 3 regions to mantra-rpc.polkachu.com." + queries: + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="polkachu", chain="mantrachain"}) + p90: avg(ocb:rpc_latency_milliseconds:p90_24h{provider="polkachu", chain="mantrachain"}) + p99: avg(ocb:rpc_latency_milliseconds:p99_24h{provider="polkachu", chain="mantrachain"}) + mean: avg(ocb:rpc_latency_milliseconds:mean_24h{provider="polkachu", chain="mantrachain"}) + success: sum(ocb:rpc_call:ok_rate_24h{provider="polkachu", chain="mantrachain"}) / sum(ocb:rpc_call:rate_24h{provider="polkachu", chain="mantrachain"}) + sample_size: sum(ocb:rpc_call:increase_24h{provider="polkachu", chain="mantrachain"}) + series: avg(avg_over_time(rpc_latency_milliseconds{provider="polkachu", chain="mantrachain"}[1h])) + regions: + - region: us-east + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="polkachu", chain="mantrachain", region="us-east"}) + series: avg_over_time(rpc_latency_milliseconds{provider="polkachu", chain="mantrachain", region="us-east"}[1h]) + - region: eu-west + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="polkachu", chain="mantrachain", region="eu-west"}) + series: avg_over_time(rpc_latency_milliseconds{provider="polkachu", chain="mantrachain", region="eu-west"}[1h]) + - region: ap-southeast + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="polkachu", chain="mantrachain", region="sgp"}) + series: avg_over_time(rpc_latency_milliseconds{provider="polkachu", chain="mantrachain", region="sgp"}[1h]) diff --git a/benchmarks/shentu-rpc.yml b/benchmarks/shentu-rpc.yml new file mode 100644 index 000000000..49d538b63 --- /dev/null +++ b/benchmarks/shentu-rpc.yml @@ -0,0 +1,138 @@ +# OpenChainBench. Bench No 254 + +slug: shentu-rpc +number: "254" +title: Fastest free Shentu RPC, live no-key endpoint latency +seo_title: "Fastest free Shentu RPC 2026" +seo_description: "{{best_name}} leads free Shentu RPC at {{best_p50}} (block height p50, 24h). 3 providers measured every 60s from 3 regions." +subtitle: HTTP round-trip latency for Tendermint /status queries against every available public Shentu (shentu-2.2) endpoint, audited every 60 seconds from 3 regions. + +category: RPCs +status: live +metric: RPC latency +unit: ms +higher_is_better: false + +seo_intro: | + Shentu is a Cosmos SDK blockchain (chain ID shentu-2.2) focused on blockchain security. It provides a decentralized security oracle, on-chain bug bounty platform (CertiK Shield), and formal verification tools for smart contracts. The chain uses the standard Tendermint RPC interface; block height is fetched via the /status endpoint. Public keyless RPC nodes are provided by the Shentu official team, Polkachu, and High Stakes. Every provider was live-verified with consecutive block-height probes at launch. + +abstract: | + Per-chain member of the RPC latency cluster, extended to Shentu (shentu-2.2). + We measure the round-trip latency of a Tendermint /status query against + every available public Shentu endpoint that sustains continuous probing: + 3 providers at launch, every 60 seconds, from us-east, eu-west and + Singapore. Each provider is probed via a GET /status request + from which the block number is extracted. + The harness classifies every response (ok / http_err / jsonrpc_err / stale / timeout) + with a Cosmos-scaled staleness gap (20 blocks, around 120 s at 6 s/block). + The cross-chain view lives on the parent rpc-capabilities benchmark; + this page is the Shentu-scoped answer with per-region breakdowns as + a first-class dimension. + +methodology: + - "Cadence: every 60 seconds per provider, from each of 3 probe regions (us-east Virginia, eu-west Amsterdam, sgp Singapore). Headline p50/p90/p99 aggregate across all 3 regions via Prometheus avg(quantile_over_time(...)); per-region breakdowns are first-class on this page via the region tabs." + - "Payload: GET /status. The result.sync_info.latest_block_height field (string-encoded integer) is extracted as the current block height." + - "Latency: client-side round-trip delta in milliseconds, exposed as both a gauge and a histogram (buckets 50 ms to 10 s), so percentiles are computed via Prometheus quantile_over_time over the last 24 hours." + - "Call-result classification: ok (parsable block height returned), http_err, jsonrpc_err, stale (block more than 20 behind the cross-provider tip), timeout." + - "This page is part of the per-chain RPC cluster derived from the cross-chain rpc-capabilities benchmark; the identical harness, cadence and exclusion rules apply on every chain." + - "Chain scope: every query on this page is pinned to chain=shentu. Provider coverage at launch: 3 endpoints (Shentu official, Polkachu, High Stakes)." + +findings: + - "{{best_name}} leads free Shentu RPC at {{best_p50}} (Tendermint /status p50, 24h) across 3 measured providers." + +faq: + - q: "What is the fastest free Shentu RPC right now?" + a: "{{best_name}} currently leads at {{best_p50}} (Shentu block height p50 over the last 24h), measured against 3 providers probed every 60 seconds from us-east, eu-west and Singapore. The leaderboard re-sorts continuously against fresh Prometheus samples." + - q: "Which Shentu RPC endpoints work without an API key?" + a: "3 endpoints sustain continuous keyless probing at launch: Shentu official (rpc.shentu.org), Polkachu (shentu-rpc.polkachu.com), and High Stakes (shentu-rpc.highstakes.ch). Every listed endpoint was live-verified before inclusion." + - q: "What is Shentu and why does its RPC latency matter?" + a: "Shentu is a Cosmos SDK blockchain built by CertiK, focused on blockchain security infrastructure. It powers the CertiK Shield decentralized reimbursement platform and a security oracle that scores smart contracts on-chain. Developers integrating with CertiK Shield, querying security scores, or building on the Shentu ecosystem need reliable low-latency RPC access." + - q: "Does the fastest Shentu RPC change by region?" + a: "Yes. The official Shentu node and community validators are hosted in different regions. The region tabs re-scope every number to a single probe origin so you can pick the best endpoint for your user base." + - q: "What is the CTK token on Shentu?" + a: "CTK (CertiK) is the native staking and governance token of the Shentu chain (denominated as uctk on-chain). It is used to stake in the CertiK Shield protection pool, pay for security oracle queries, and participate in on-chain governance." + +source: https://github.com/ChainBench/OpenChainBench/tree/main/harnesses/rpc-capabilities + +prometheus: + window: 24h + freshness_metric: rpc_latency_milliseconds + +rank_matrix_query: avg by (provider, region) (ocb:rpc_latency_milliseconds:p50_24h{chain="shentu"}) + +dimensions: + region: + - { value: all, label: All regions } + - { value: us-east, label: US-East } + - { value: eu-west, label: EU-West } + - { value: sgp, label: Singapore } + +providers: + - slug: shentu-official + name: Shentu + tag: Shentu official public RPC node, no API key required + formula: "50th percentile over 24h of client-side round-trip latency (ms) for a GET /status sent every 60s from 3 regions to rpc.shentu.org." + queries: + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="shentu-official", chain="shentu"}) + p90: avg(ocb:rpc_latency_milliseconds:p90_24h{provider="shentu-official", chain="shentu"}) + p99: avg(ocb:rpc_latency_milliseconds:p99_24h{provider="shentu-official", chain="shentu"}) + mean: avg(ocb:rpc_latency_milliseconds:mean_24h{provider="shentu-official", chain="shentu"}) + success: sum(ocb:rpc_call:ok_rate_24h{provider="shentu-official", chain="shentu"}) / sum(ocb:rpc_call:rate_24h{provider="shentu-official", chain="shentu"}) + sample_size: sum(ocb:rpc_call:increase_24h{provider="shentu-official", chain="shentu"}) + series: avg(avg_over_time(rpc_latency_milliseconds{provider="shentu-official", chain="shentu"}[1h])) + regions: + - region: us-east + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="shentu-official", chain="shentu", region="us-east"}) + series: avg_over_time(rpc_latency_milliseconds{provider="shentu-official", chain="shentu", region="us-east"}[1h]) + - region: eu-west + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="shentu-official", chain="shentu", region="eu-west"}) + series: avg_over_time(rpc_latency_milliseconds{provider="shentu-official", chain="shentu", region="eu-west"}[1h]) + - region: ap-southeast + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="shentu-official", chain="shentu", region="sgp"}) + series: avg_over_time(rpc_latency_milliseconds{provider="shentu-official", chain="shentu", region="sgp"}[1h]) + + - slug: polkachu + name: Polkachu + tag: Polkachu public Shentu RPC, no API key required + formula: "50th percentile over 24h of client-side round-trip latency (ms) for a GET /status sent every 60s from 3 regions to shentu-rpc.polkachu.com." + queries: + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="polkachu", chain="shentu"}) + p90: avg(ocb:rpc_latency_milliseconds:p90_24h{provider="polkachu", chain="shentu"}) + p99: avg(ocb:rpc_latency_milliseconds:p99_24h{provider="polkachu", chain="shentu"}) + mean: avg(ocb:rpc_latency_milliseconds:mean_24h{provider="polkachu", chain="shentu"}) + success: sum(ocb:rpc_call:ok_rate_24h{provider="polkachu", chain="shentu"}) / sum(ocb:rpc_call:rate_24h{provider="polkachu", chain="shentu"}) + sample_size: sum(ocb:rpc_call:increase_24h{provider="polkachu", chain="shentu"}) + series: avg(avg_over_time(rpc_latency_milliseconds{provider="polkachu", chain="shentu"}[1h])) + regions: + - region: us-east + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="polkachu", chain="shentu", region="us-east"}) + series: avg_over_time(rpc_latency_milliseconds{provider="polkachu", chain="shentu", region="us-east"}[1h]) + - region: eu-west + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="polkachu", chain="shentu", region="eu-west"}) + series: avg_over_time(rpc_latency_milliseconds{provider="polkachu", chain="shentu", region="eu-west"}[1h]) + - region: ap-southeast + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="polkachu", chain="shentu", region="sgp"}) + series: avg_over_time(rpc_latency_milliseconds{provider="polkachu", chain="shentu", region="sgp"}[1h]) + + - slug: highstakes + name: High Stakes + tag: High Stakes public Shentu RPC, no API key required + formula: "50th percentile over 24h of client-side round-trip latency (ms) for a GET /status sent every 60s from 3 regions to shentu-rpc.highstakes.ch." + queries: + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="highstakes", chain="shentu"}) + p90: avg(ocb:rpc_latency_milliseconds:p90_24h{provider="highstakes", chain="shentu"}) + p99: avg(ocb:rpc_latency_milliseconds:p99_24h{provider="highstakes", chain="shentu"}) + mean: avg(ocb:rpc_latency_milliseconds:mean_24h{provider="highstakes", chain="shentu"}) + success: sum(ocb:rpc_call:ok_rate_24h{provider="highstakes", chain="shentu"}) / sum(ocb:rpc_call:rate_24h{provider="highstakes", chain="shentu"}) + sample_size: sum(ocb:rpc_call:increase_24h{provider="highstakes", chain="shentu"}) + series: avg(avg_over_time(rpc_latency_milliseconds{provider="highstakes", chain="shentu"}[1h])) + regions: + - region: us-east + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="highstakes", chain="shentu", region="us-east"}) + series: avg_over_time(rpc_latency_milliseconds{provider="highstakes", chain="shentu", region="us-east"}[1h]) + - region: eu-west + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="highstakes", chain="shentu", region="eu-west"}) + series: avg_over_time(rpc_latency_milliseconds{provider="highstakes", chain="shentu", region="eu-west"}[1h]) + - region: ap-southeast + p50: avg(ocb:rpc_latency_milliseconds:p50_24h{provider="highstakes", chain="shentu", region="sgp"}) + series: avg_over_time(rpc_latency_milliseconds{provider="highstakes", chain="shentu", region="sgp"}[1h]) diff --git a/harnesses/rpc-capabilities/cmd/script/config.go b/harnesses/rpc-capabilities/cmd/script/config.go index 186460674..580bbb0eb 100644 --- a/harnesses/rpc-capabilities/cmd/script/config.go +++ b/harnesses/rpc-capabilities/cmd/script/config.go @@ -1693,6 +1693,28 @@ func chains() []Chain { {Slug: "cosmos-directory", Name: "Cosmos Directory", URL: envDefault("RPC_URL_SENTINEL_COSMOSDIRECTORY", "https://rpc.cosmos.directory/sentinel")}, }, }, + // 2026-08-29 wave-12. Shentu — Cosmos SDK (shentu-2.2), Tendermint /status. Shentu official + Polkachu + High Stakes. + { + Slug: "shentu", + Name: "Shentu", + Kind: "cosmos", + Providers: []Provider{ + {Slug: "shentu-official", Name: "Shentu", URL: envDefault("RPC_URL_SHENTU_OFFICIAL", "https://rpc.shentu.org:443")}, + {Slug: "polkachu", Name: "Polkachu", URL: envDefault("RPC_URL_SHENTU_POLKACHU", "https://shentu-rpc.polkachu.com:443")}, + {Slug: "highstakes", Name: "High Stakes", URL: envDefault("RPC_URL_SHENTU_HIGHSTAKES", "https://shentu-rpc.highstakes.ch")}, + }, + }, + // 2026-08-29 wave-12. MANTRA Chain — Cosmos SDK (mantra-1), Tendermint /status. Official + ITRocket + Polkachu. + { + Slug: "mantrachain", + Name: "MANTRA Chain", + Kind: "cosmos", + Providers: []Provider{ + {Slug: "mantrachain-official", Name: "MANTRA", URL: envDefault("RPC_URL_MANTRA_OFFICIAL", "https://rpc.mantrachain.io")}, + {Slug: "itrocket", Name: "ITRocket", URL: envDefault("RPC_URL_MANTRA_ITROCKET", "https://mantra-mainnet-rpc.itrocket.net:443")}, + {Slug: "polkachu", Name: "Polkachu", URL: envDefault("RPC_URL_MANTRA_POLKACHU", "https://mantra-rpc.polkachu.com:443")}, + }, + }, // 2026-08-29 wave-12. Union — Cosmos SDK (union-1), Tendermint /status. Nodes.Guru + Stake And Relax + High Stakes. { Slug: "union", diff --git a/public/logos/itrocket.svg b/public/logos/itrocket.svg new file mode 100644 index 000000000..775cfe671 --- /dev/null +++ b/public/logos/itrocket.svg @@ -0,0 +1,5 @@ + + + ITROCKET + 🚀 + diff --git a/public/logos/mantrachain.svg b/public/logos/mantrachain.svg new file mode 100644 index 000000000..10bcec3c9 --- /dev/null +++ b/public/logos/mantrachain.svg @@ -0,0 +1,4 @@ + + + OM + diff --git a/public/logos/shentu-official.svg b/public/logos/shentu-official.svg new file mode 100644 index 000000000..4ca2baba1 --- /dev/null +++ b/public/logos/shentu-official.svg @@ -0,0 +1,4 @@ + + + CTK + diff --git a/public/logos/shentu.svg b/public/logos/shentu.svg new file mode 100644 index 000000000..4ca2baba1 --- /dev/null +++ b/public/logos/shentu.svg @@ -0,0 +1,4 @@ + + + CTK + diff --git a/src/data/provider-registry.ts b/src/data/provider-registry.ts index 9046f4ba6..8756c7e9e 100644 --- a/src/data/provider-registry.ts +++ b/src/data/provider-registry.ts @@ -2620,6 +2620,29 @@ export const PROVIDER_REGISTRY: Record = { twitter: "@Fetch_ai", }, + // ─── Shentu providers (bench 254) ──────────────────────────────────── + "shentu-official": { + url: "https://www.shentu.technology", + description: + "Shentu Chain official public Tendermint RPC node for the shentu-2.2 mainnet. Keyless endpoint maintained by the CertiK / Shentu Foundation team.", + twitter: "@ShentuChain", + }, + + // ─── MANTRA Chain providers (bench 255) ────────────────────────────── + "mantrachain-official": { + url: "https://www.mantrachain.io", + description: + "MANTRA Chain official public Tendermint RPC node for the mantra-1 mainnet. Keyless endpoint for real-world asset tokenization on Cosmos.", + twitter: "@MANTRA_Chain", + }, + itrocket: { + url: "https://itrocket.net", + description: + "ITRocket community validator and public RPC operator. Provides keyless Tendermint RPC endpoints for multiple Cosmos SDK chains.", + twitter: "@ITRocketTeam", + }, + + // ─── Union providers (bench 253) ───────────────────────────────────── "nodes-guru": { url: "https://nodes.guru", diff --git a/src/lib/brand.ts b/src/lib/brand.ts index bb62f3166..0d2d6e050 100644 --- a/src/lib/brand.ts +++ b/src/lib/brand.ts @@ -173,15 +173,18 @@ const BRANDS: Record = { acala: { color: "#E40C5B" }, // acala red/pink (official brand) interlay: { color: "#1A3BDB" }, // interlay blue (official brand) - // ─── Cosmos SDK chains (benches 247, 250-253) ─── - babylon: { color: "#F8811A" }, // babylon orange (official brand) - chihuahua: { color: "#E05F2A" }, // chihuahua orange-red (official brand) - sentinel: { color: "#00C2FF" }, // sentinel cyan (official brand) - fetchhub: { color: "#3B2D8E" }, // fetch.ai deep purple (official brand) - union: { color: "#6366F1" }, // union indigo (brand kit) + // ─── Cosmos SDK chains (benches 247, 250-255) ─── + babylon: { color: "#F8811A" }, // babylon orange (official brand) + chihuahua: { color: "#E05F2A" }, // chihuahua orange-red (official brand) + sentinel: { color: "#00C2FF" }, // sentinel cyan (official brand) + fetchhub: { color: "#3B2D8E" }, // fetch.ai deep purple (official brand) + union: { color: "#6366F1" }, // union indigo (brand kit) + shentu: { color: "#1A6DFF" }, // shentu blue (certik brand) + mantrachain: { color: "#E8A020" }, // mantra gold (om token brand) "nodes-guru": { color: "#F59E0B" }, // nodes.guru amber stakeandrelax: { color: "#10B981" }, // stake and relax emerald highstakes: { color: "#3B82F6" }, // high stakes blue + itrocket: { color: "#E53E3E" }, // itrocket red "cosmos-directory": { color: "#1B1B2F", dark: true }, // cosmos directory dark navy // ─── Bitcoin Cash chain + providers (bench 244) ─── diff --git a/src/lib/logo-manifest.ts b/src/lib/logo-manifest.ts index 6aa6d2b7a..b5250d683 100644 --- a/src/lib/logo-manifest.ts +++ b/src/lib/logo-manifest.ts @@ -332,9 +332,12 @@ const RAW: Record = { sentinel: "/logos/sentinel.svg", fetchhub: "/logos/fetchai.svg", union: "/logos/union.svg", + shentu: "/logos/shentu.svg", + mantrachain: "/logos/mantrachain.svg", "nodes-guru": "/logos/nodes-guru.svg", stakeandrelax: "/logos/stakeandrelax.svg", highstakes: "/logos/highstakes.svg", + itrocket: "/logos/itrocket.svg", "cosmos-directory": "/logos/cosmos-directory.svg", // ─── Oracle deviation (bench 025) — additional brand logos ─── @@ -747,6 +750,8 @@ const ALIASES: Record = { // Chihuahua + Fetch.ai official node aliases → chain logo "chihuahua-official": "chihuahua", "fetchai-official": "fetchhub", + "shentu-official": "shentu", + "mantrachain-official": "mantrachain", // Non-EVM wave-3 (benches 222-231) — provider-official aliases to chain slug "ecadinfra": "tezos", From 4b79b76e8a932e7b7f3dffedfc00c801227e5b21 Mon Sep 17 00:00:00 2001 From: Florent Tapponnier <160007691+Flotapponnier@users.noreply.github.com> Date: Sat, 29 Aug 2026 23:04:28 +0200 Subject: [PATCH 6/6] fix: bench-blob revalidate 300s to fix perp ISR conflict --- src/lib/bench-blob.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/bench-blob.ts b/src/lib/bench-blob.ts index 07f96cde4..45e825e55 100644 --- a/src/lib/bench-blob.ts +++ b/src/lib/bench-blob.ts @@ -54,7 +54,7 @@ async function fetchJson(url: string): Promise { try { const res = await fetch(url, { signal: AbortSignal.timeout(FETCH_TIMEOUT_MS), - cache: "no-store", + next: { revalidate: 300 }, }); if (!res.ok) return null; return await res.json();