diff --git a/alternatives/blocknative.yml b/alternatives/blocknative.yml deleted file mode 100644 index 2686aab2..00000000 --- a/alternatives/blocknative.yml +++ /dev/null @@ -1,13 +0,0 @@ -slug: blocknative -target_product: Blocknative -target_url: https://blocknative.com -description: Probability-of-inclusion gas oracle with EIP-1559 tiered predictions -benchmark: gas-estimation - -intro: | - Blocknative publishes a probability-of-inclusion gas oracle that emits EIP-1559 tiered predictions (70, 80, 90, 95, 99 percent confidence) for Ethereum and Polygon, served from a no-key endpoint `?chainid=`. The architecture is deliberate: an inclusion-confidence oracle over-predicts to guarantee landing, while a percentile tracker built on `eth_feeHistory` hugs the realized number by construction. Both choices have implications for a wallet or swap router picking the value to suggest to a user, which is what this benchmark surfaces. The harness polls each oracle at its tier-tolerant cadence (Blocknative every 12 seconds per chain), buffers the predicted priority fee with the predicted block height, and when that block is mined pulls the full block via `eth_getBlockByNumber(.., true)` on the chain's PublicNode RPC. Realized percentiles are computed from actual `maxPriorityFeePerGas` values across every included transaction, and the absolute error per (oracle, tier, chain) lands on both a gauge and a histogram. The table ranks on the p99 gap over 24 hours (the worst 1 percent of blocks) because at current fee levels the typical-minute gaps are fractions of a micro-gwei apart, while gas spikes are where wrong predictions actually cost money. A covered-rate column shows the share of time each prediction sat at or above the realized p50, the inclusion-side risk an absolute gap cannot show. Coverage is Ethereum and Polygon. Avalanche C-Chain was dropped because its auto-tuning fee market drives priority to zero across all oracles; BNB and OP-Stack L2s are excluded for structural reasons. The cohort competing with Blocknative includes PublicNode `eth_feeHistory`, Owlracle (multi-oracle aggregator on a 60-second free quota) and Etherscan v2's free tier. - -seo_title: Blocknative alternatives. Live gas oracle accuracy benchmark -seo_description: Compare Blocknative against PublicNode feeHistory, Owlracle and Etherscan on gwei gap between predicted and realized priority fee, ranked on p99 over 24h. - -status: live diff --git a/alternatives/etherscan.yml b/alternatives/etherscan.yml index 2d075c7f..5baa7b6d 100644 --- a/alternatives/etherscan.yml +++ b/alternatives/etherscan.yml @@ -5,9 +5,9 @@ description: Block explorer and gas tracker covering Ethereum and Polygon benchmark: gas-estimation intro: | - Etherscan is the most-visited block explorer on the web and publishes a gas tracker exposing `SafeGasPrice`, `ProposeGasPrice` and `FastGasPrice` via the v2 API on Ethereum and Polygon (free tier). The tiering was originally designed for the pre-EIP-1559 single-price world and is now mapped onto a priority-fee comparison alongside dedicated oracles. The question every wallet, swap router and bridge UI faces before sending a transaction is which gas oracle actually matches what the next block will charge on the chain their product runs on, rather than what a marketing page claims. This benchmark polls each oracle at its tier-tolerant cadence (Etherscan every 15 seconds with a global rate-gate enforcing at least 6 seconds between any two Etherscan requests across chains, because the no-key limit is 1 req per 5 s per IP shared), buffers the prediction with the predicted block height, and when that block is mined pulls the full block via `eth_getBlockByNumber(.., true)` on the chain's PublicNode RPC. Realized percentiles are computed from actual `maxPriorityFeePerGas` values, and the absolute error per (oracle, tier, chain) lands on both a gauge and a histogram. The ranking metric is the p99 gap over 24 hours, the worst 1 percent of blocks, because typical-minute gaps sit within fractions of a micro-gwei (economically indistinguishable noise) while gas spikes are where a wrong prediction either overpays or misses the block. A covered-rate column shows the share of time each prediction sat at or above the realized p50, the inclusion-side risk an absolute gap cannot show. The cohort competing with Etherscan includes Blocknative (probability-of-inclusion model), PublicNode `eth_feeHistory` (thin wrapper over EIP-1559 reward percentiles) and Owlracle (multi-oracle aggregator). + Etherscan is the most-visited block explorer on the web and publishes a gas tracker exposing `SafeGasPrice`, `ProposeGasPrice` and `FastGasPrice` via the v2 API on Ethereum and Polygon (free tier). The tiering was originally designed for the pre-EIP-1559 single-price world and is now mapped onto a priority-fee comparison alongside dedicated oracles. The question every wallet, swap router and bridge UI faces before sending a transaction is which gas oracle actually matches what the next block will charge on the chain their product runs on, rather than what a marketing page claims. This benchmark polls each oracle at its tier-tolerant cadence (Etherscan every 15 seconds with a global rate-gate enforcing at least 6 seconds between any two Etherscan requests across chains, because the no-key limit is 1 req per 5 s per IP shared), buffers the prediction with the predicted block height, and when that block is mined pulls the full block via `eth_getBlockByNumber(.., true)` on the chain's PublicNode RPC. Realized percentiles are computed from actual `maxPriorityFeePerGas` values, and the absolute error per (oracle, tier, chain) lands on both a gauge and a histogram. The ranking metric is the p99 gap over 24 hours, the worst 1 percent of blocks, because typical-minute gaps sit within fractions of a micro-gwei (economically indistinguishable noise) while gas spikes are where a wrong prediction either overpays or misses the block. A covered-rate column shows the share of time each prediction sat at or above the realized p50, the inclusion-side risk an absolute gap cannot show. The cohort competing with Etherscan includes PublicNode `eth_feeHistory` (thin wrapper over EIP-1559 reward percentiles) and Owlracle (multi-oracle aggregator). seo_title: Etherscan alternatives. Live gas oracle accuracy benchmark -seo_description: Compare Etherscan against Blocknative, PublicNode feeHistory and Owlracle on gwei gap between predicted and realized priority fee, ranked on p99 over 24h. +seo_description: Compare Etherscan against PublicNode feeHistory and Owlracle on gwei gap between predicted and realized priority fee, ranked on p99 over 24h. status: live diff --git a/answers/which-gas-oracle-is-the-most-accurate.yml b/answers/which-gas-oracle-is-the-most-accurate.yml index ee6e9b3f..3de2013e 100644 --- a/answers/which-gas-oracle-is-the-most-accurate.yml +++ b/answers/which-gas-oracle-is-the-most-accurate.yml @@ -1,18 +1,18 @@ slug: which-gas-oracle-is-the-most-accurate question: "Which Ethereum gas oracle is the most accurate in 2026?" short_answer: | - {{best_name}} currently posts the tightest priority fee prediction at {{best_p50}} (gwei, p99 absolute gap, 24h) on Ethereum mainnet across Blocknative, PublicNode feeHistory, Owlracle and Etherscan, ranked on the worst 1% of blocks where gas spikes actually cost money. + {{best_name}} currently posts the tightest priority fee prediction at {{best_p50}} (gwei, p99 absolute gap, 24h) on Ethereum mainnet across PublicNode feeHistory, Owlracle and Etherscan, ranked on the worst 1% of blocks where gas spikes actually cost money. benchmark: gas-estimation intro: | - Every wallet, swap router and bridge UI hits a gas oracle before posting a transaction, and the gap between the predicted priority fee and what the next mined block actually charges is the difference between a transaction landing in 12 seconds and a transaction sitting in the mempool through three gas spikes. Marketing pages quote "fast / standard / slow" tiers without ever publishing the gap between prediction and reality. This page answers one question with live data. Which oracle predicts the next block's realized priority fee most closely, measured per block, on Ethereum mainnet and Polygon PoS. The OpenChainBench gas-estimation harness polls Blocknative, PublicNode `eth_feeHistory`, Owlracle and Etherscan v2 at their tier tolerant cadences, buffers each prediction with its predicted block height, then pulls the full block via `eth_getBlockByNumber` when it lands and computes the realized priority percentile from the actual `maxPriorityFeePerGas` values across every included transaction. The headline ranks on the p99 of the absolute gap over 24 h, the worst 1% of blocks, because typical minute gaps are micro gwei noise while volatile minutes are where a wrong prediction either overpays or misses the block. + Every wallet, swap router and bridge UI hits a gas oracle before posting a transaction, and the gap between the predicted priority fee and what the next mined block actually charges is the difference between a transaction landing in 12 seconds and a transaction sitting in the mempool through three gas spikes. Marketing pages quote "fast / standard / slow" tiers without ever publishing the gap between prediction and reality. This page answers one question with live data. Which oracle predicts the next block's realized priority fee most closely, measured per block, on Ethereum mainnet and Polygon PoS. The OpenChainBench gas-estimation harness polls PublicNode `eth_feeHistory`, Owlracle and Etherscan v2 at their tier tolerant cadences, buffers each prediction with its predicted block height, then pulls the full block via `eth_getBlockByNumber` when it lands and computes the realized priority percentile from the actual `maxPriorityFeePerGas` values across every included transaction. The headline ranks on the p99 of the absolute gap over 24 h, the worst 1% of blocks, because typical minute gaps are micro gwei noise while volatile minutes are where a wrong prediction either overpays or misses the block. methodology: | - Each oracle is polled per chain at its tier tolerant cadence: Blocknative and PublicNode feeHistory every 12 s, Owlracle every 60 s (free quota ceiling), Etherscan every 15 s with a global rate gate enforcing 6 s between any two Etherscan requests across chains (the no key limit is 1 request per 5 s per IP, shared). Each oracle's named tiers (fast, standard, slow, safe, propose) are mapped onto a unified p25, p50, p75, p90, p99 scheme and the leaderboard ranks the p50 tier (the standard speed wallets use by default). Predicted priority fees are buffered with the predicted block height; when that block is mined, the harness pulls the full block via `eth_getBlockByNumber(.., true)` on the chain's PublicNode RPC, computes the realized percentile from actual `maxPriorityFeePerGas` values, and records the absolute error per (oracle, tier, chain) as both a gauge and a histogram. The headline metric is `quantile_over_time(0.99, gas_error_priority_gwei{tier="p50"}[24h])`. A covered rate column (share of time the prediction sat at or above the realized p50) surfaces the inclusion side risk an absolute gap cannot show. BNB Chain is excluded (not EIP-1559), Avalanche C-Chain is excluded (auto tuning fee market drives priority fee toward zero), L2 OP Stack chains are excluded (priority fee near zero because the sequencer is centralised, the relevant cost is L1 data fee). + Each oracle is polled per chain at its tier tolerant cadence: PublicNode feeHistory every 12 s, Owlracle every 60 s (free quota ceiling), Etherscan every 15 s with a global rate gate enforcing 6 s between any two Etherscan requests across chains (the no key limit is 1 request per 5 s per IP, shared). Each oracle's named tiers (fast, standard, slow, safe, propose) are mapped onto a unified p25, p50, p75, p90, p99 scheme and the leaderboard ranks the p50 tier (the standard speed wallets use by default). Predicted priority fees are buffered with the predicted block height; when that block is mined, the harness pulls the full block via `eth_getBlockByNumber(.., true)` on the chain's PublicNode RPC, computes the realized percentile from actual `maxPriorityFeePerGas` values, and records the absolute error per (oracle, tier, chain) as both a gauge and a histogram. The headline metric is `quantile_over_time(0.99, gas_error_priority_gwei{tier="p50"}[24h])`. A covered rate column (share of time the prediction sat at or above the realized p50) surfaces the inclusion side risk an absolute gap cannot show. BNB Chain is excluded (not EIP-1559), Avalanche C-Chain is excluded (auto tuning fee market drives priority fee toward zero), L2 OP Stack chains are excluded (priority fee near zero because the sequencer is centralised, the relevant cost is L1 data fee). limitations: - - "Lower gap is not the same as best oracle. Inclusion confidence oracles (Blocknative, Etherscan) over predict by design to guarantee inclusion; percentile trackers (PublicNode feeHistory, Owlracle) hug the realized number by construction. The leaderboard ranks on p99 to surface tail behaviour and pairs it with the covered column so over prediction (overpay, harmless) and under prediction (transaction misses its block) do not collapse into the same score." + - "Lower gap is not the same as best oracle. Inclusion confidence oracles (Etherscan) over predict by design to guarantee inclusion; percentile trackers (PublicNode feeHistory, Owlracle) hug the realized number by construction. The leaderboard ranks on p99 to surface tail behaviour and pairs it with the covered column so over prediction (overpay, harmless) and under prediction (transaction misses its block) do not collapse into the same score." - "Ethereum mainnet and Polygon PoS are the only ranked chains. BNB Chain is not EIP-1559 (gasPrice only). Avalanche C-Chain auto tunes its fee market toward zero priority fee, which collapses the error metric to noise. L2 OP Stack chains (Optimism, Base, Arbitrum) have priority fee near zero because the sequencer is centralised; the meaningful cost there is the L1 data fee, a different prediction problem." - "The p50 tier is the ranked tier (standard wallet default). Per tier breakdowns (p25, p75, p90, p99) are emitted by the harness and visible in raw Prometheus, but the bench UI does not yet surface them as a tab because the spec schema is restricted to chain and region dimensions." - "Realized percentile is noisy on empty or low transaction count blocks. The harness flags those via `gas_realized_tx_count{chain}` so a low traffic block does not silently inflate the error histogram." @@ -20,11 +20,11 @@ limitations: faq: - q: "Which gas oracle is the most accurate right now?" - a: "{{best_name}} currently leads at {{best_p50}} gwei (p99 absolute gap, 24h) on the active chain tab across 4 measured oracles. The leaderboard refreshes every minute against fresh Prometheus samples; per chain leaders can differ from the cross chain headline so the chain tabs at the top of the bench page expose each ranking separately. Read the gap alongside the covered rate column for the full picture, inclusion confidence oracles trade a wider gap for higher coverage." + a: "{{best_name}} currently leads at {{best_p50}} gwei (p99 absolute gap, 24h) on the active chain tab across 3 measured oracles. The leaderboard refreshes every minute against fresh Prometheus samples; per chain leaders can differ from the cross chain headline so the chain tabs at the top of the bench page expose each ranking separately. Read the gap alongside the covered rate column for the full picture, inclusion confidence oracles trade a wider gap for higher coverage." - q: "Why rank on p99 instead of p50?" a: "At current fee levels the typical minute p50 gaps are fractions of a micro gwei apart across oracles. On a 100k gas transaction a 0.001 gwei error is about a thousandth of a cent, so a p50 ranking orders economically indistinguishable noise. The p99 captures the volatile minutes (mempool spikes, NFT mints, MEV bursts) where predictions actually diverge and a wrong number either overpays or misses the block. The typical p50 and p90 gaps remain visible as secondary columns." - - q: "How does Blocknative compare to Etherscan or PublicNode feeHistory?" - a: "Blocknative publishes a probability of inclusion model across 70, 80, 90, 95 and 99 percent confidence tiers; the parser maps those onto the unified p25 to p99 scheme. Etherscan's `ProposeGasPrice` was designed for the pre EIP-1559 single price world and re uses tier names that map onto the same scheme. PublicNode feeHistory is a thin wrapper over the EIP-1559 reward percentile spec, so it tracks the realized number closely by construction. The three answer different design questions: inclusion confidence, retail recognition, and protocol grounded reading." + - q: "How does Etherscan compare to PublicNode feeHistory or Owlracle?" + a: "Etherscan's `ProposeGasPrice` was designed for the pre EIP-1559 single price world and re uses tier names mapped onto the unified p25 to p99 scheme; it over predicts by design to guarantee inclusion. PublicNode feeHistory is a thin wrapper over the EIP-1559 reward percentile spec, so it tracks the realized number closely by construction. Owlracle aggregates several upstream oracles into a single recommendation, polled every 60 s on the free quota. The three answer different design questions: retail recognition with inclusion bias, protocol grounded reading, and aggregated consensus." - q: "What does the covered rate column mean?" a: "The share of time over 24 h that the oracle's posted p50 tier prediction was at or above the realized p50 priority fee of the latest mined block. Absolute gap treats over prediction and under prediction the same, but they are not symmetric for users: over predicting means slightly overpaying, under predicting means a transaction paying exactly the predicted fee would have ranked below the block's median and risks waiting. Read gap and covered together; low p99 gap plus high covered is the sweet spot." - q: "Why is Avalanche C-Chain excluded?" @@ -32,7 +32,7 @@ faq: - q: "Which oracle should I integrate for my wallet?" a: "Read the p99 gap (does it blow out during spikes?) together with the covered rate (does it err on the side of inclusion or under bid?) for the chain your product runs on. {{best_name}} currently leads the active tab at {{best_p50}} gwei but the right choice depends on whether your UX tolerates over pay (then prefer high covered) or optimises for tail behaviour (then prefer low p99 gap), and whether the oracle's free quota fits your call volume. The bench gives you the live numbers, it cannot tell you which trade off your product wants." - q: "How often is the leaderboard refreshed?" - a: "Per oracle polling runs continuously (12 s for Blocknative and PublicNode feeHistory, 15 s for Etherscan with the 6 s global gate, 60 s for Owlracle). The page reads a rolling 24 h p50, p90 and p99 every minute. A single misprediction during a gas spike cannot move the headline because the p99 window absorbs it across thousands of blocks." + a: "Per oracle polling runs continuously (12 s for PublicNode feeHistory, 15 s for Etherscan with the 6 s global gate, 60 s for Owlracle). The page reads a rolling 24 h p50, p90 and p99 every minute. A single misprediction during a gas spike cannot move the headline because the p99 window absorbs it across thousands of blocks." related: - which-blockchain-has-cheapest-transaction-fees @@ -40,5 +40,5 @@ related: - which-evm-aggregator-has-the-fastest-quote seo_title: "Which Ethereum gas oracle is the most accurate in 2026?" -seo_description: "{{best_name}} leads at {{best_p50}} gwei (p99 absolute gap, 24h) across Blocknative, PublicNode feeHistory, Owlracle and Etherscan on Ethereum and Polygon, measured per block by OpenChainBench." +seo_description: "{{best_name}} leads at {{best_p50}} gwei (p99 absolute gap, 24h) across PublicNode feeHistory, Owlracle and Etherscan on Ethereum and Polygon, measured per block by OpenChainBench." status: live diff --git a/benchmarks/gas-estimation.yml b/benchmarks/gas-estimation.yml index 64164e3c..1f28abe7 100644 --- a/benchmarks/gas-estimation.yml +++ b/benchmarks/gas-estimation.yml @@ -3,7 +3,7 @@ slug: gas-estimation number: "013" title: Most accurate gas oracle, live gap vs realized priority fee -seo_title: "Most accurate gas oracle 2026: Blocknative, Etherscan, Owlracle" +seo_title: "Most accurate gas oracle 2026: Etherscan, Owlracle, PublicNode" seo_description: "Most accurate gas oracle ranked live on Ethereum and Polygon. Gwei gap between predicted and realized priority fee in the next mined block. Ranked on the p99 gap over 24h." subtitle: Absolute gap in gwei between each oracle's predicted priority-fee tier and the realized percentile in the next mined block, measured per chain. Ranked on the p99 gap, the worst 1% of blocks, because that is where gas spikes hurt integrations. @@ -11,7 +11,7 @@ per_chain_explainer: - slug: ethereum h2: "Most accurate Ethereum gas oracle" body: | - {{best_name:chain:ethereum}} currently leads the Ethereum gas-oracle field at {{best_p50:chain:ethereum}} (gwei, p99 absolute gap, 24h) across 4 oracles. Ethereum's EIP-1559 base fee adjusts by up to 12.5 percent per block based on prior gas usage, so percentile trackers (PublicNode `eth_feeHistory`) hug the realized priority fee by construction while inclusion-confidence oracles (Blocknative, Etherscan) deliberately over-predict. Realized priority percentiles are computed per next-mined block from actual `maxPriorityFeePerGas` values. + {{best_name:chain:ethereum}} currently leads the Ethereum gas-oracle field at {{best_p50:chain:ethereum}} (gwei, p99 absolute gap, 24h) across 3 oracles. Ethereum's EIP-1559 base fee adjusts by up to 12.5 percent per block based on prior gas usage, so percentile trackers (PublicNode `eth_feeHistory`) hug the realized priority fee by construction while inclusion-confidence oracles (Etherscan) deliberately over-predict. Realized priority percentiles are computed per next-mined block from actual `maxPriorityFeePerGas` values. - slug: polygon h2: "Most accurate Polygon gas oracle" body: | @@ -24,7 +24,7 @@ unit: count higher_is_better: false disclaimer: | - Lower gap is NOT the same as "best oracle". Inclusion-confidence oracles (Blocknative, Etherscan) over-predict by design to guarantee inclusion; percentile trackers (PublicNode, Owlracle) hug the realized number by construction. The table therefore ranks on the p99 gap (typical p50 gaps are micro-gwei noise) and pairs it with the covered column: share of time the prediction sat at or above the realized p50, the inclusion-side risk a gap alone cannot show. + Lower gap is NOT the same as "best oracle". Inclusion-confidence oracles (Etherscan) over-predict by design to guarantee inclusion; percentile trackers (PublicNode, Owlracle) hug the realized number by construction. The table therefore ranks on the p99 gap (typical p50 gaps are micro-gwei noise) and pairs it with the covered column: share of time the prediction sat at or above the realized p50, the inclusion-side risk a gap alone cannot show. seo_intro: | This benchmark answers the question wallets, swap routers and @@ -42,8 +42,8 @@ seo_intro: | actually diverge. A covered-rate column shows the share of time each prediction sat at or above the realized p50 (the inclusion-side risk an absolute gap cannot show). Coverage. - Ethereum mainnet (Blocknative + PublicNode feeHistory + Owlracle + - Etherscan v2) and Polygon (same four). Use the chain tab above to + Ethereum mainnet (PublicNode feeHistory + Owlracle + Etherscan v2) + and Polygon (same three). Use the chain tab above to slice the leaderboard. Avalanche C-Chain was dropped because its auto-tuning fee market drives the priority fee to ~0 by design, which collapses prediction-error to ~0 across all oracles and makes @@ -68,7 +68,7 @@ abstract: | and records the absolute error per (oracle, tier, chain) as both a gauge and a histogram. p50 / p90 / p99 are computed via Prometheus `quantile_over_time` over the 24 h window. Per-chain - coverage: Ethereum and Polygon both have all four oracles + coverage: Ethereum and Polygon both have all three oracles (Etherscan v2 free tier covers chainid 1 and 137). The Etherscan call goes through a global rate-gate (≥6s between any two Etherscan requests across chains) because the no-key limit @@ -82,9 +82,9 @@ abstract: | methodology: - "Chains: Ethereum mainnet (chainid=1), Polygon PoS (chainid=137). Both are EIP-1559 with proper dynamic base fee, so priority-fee prediction is apples-to-apples comparable. BNB Chain excluded (not EIP-1559). Avalanche C-Chain excluded (auto-tuning drives priority fee to ~0, prediction-error collapses to ~0)." - - "Oracles per chain. Ethereum + Polygon: Blocknative, PublicNode feeHistory, Owlracle, Etherscan v2 (free tier)." - - "Per-oracle endpoints. Blocknative `?chainid=` (no-key); PublicNode `eth_feeHistory` on each chain's RPC; Owlracle `/v4/{eth|poly}/gas` (slug per chain); Etherscan v2 `?chainid=&module=gastracker&action=gasoracle`." - - "Cadences. Blocknative & PublicNode feeHistory every 12s per chain; Owlracle every 60s per chain (free quota ceiling); Etherscan every 15s per chain with a global rate-gate enforcing ≥6s between any two Etherscan requests across chains (no-key limit is 1 req/5s per IP, shared)." + - "Oracles per chain. Ethereum + Polygon: PublicNode feeHistory, Owlracle, Etherscan v2 (free tier)." + - "Per-oracle endpoints. PublicNode `eth_feeHistory` on each chain's RPC; Owlracle `/v4/{eth|poly}/gas` (slug per chain); Etherscan v2 `?chainid=&module=gastracker&action=gasoracle`." + - "Cadences. PublicNode feeHistory every 12s per chain; Owlracle every 60s per chain (free quota ceiling); Etherscan every 15s per chain with a global rate-gate enforcing ≥6s between any two Etherscan requests across chains (no-key limit is 1 req/5s per IP, shared)." - "Tier normalization. Each oracle's named tiers (fast / standard / slow / safe / propose) are mapped onto a unified p25 / p50 / p75 / p90 / p99 scheme. The leaderboard ranks the p50 tier (the standard speed wallets use by default)." - "Realized priority fee. For each pending block, the harness pulls the full block via `eth_getBlockByNumber(.., true)` on the chain's PublicNode RPC and computes the percentile from actual `maxPriorityFeePerGas` values across every included transaction. Empty or low-tx blocks (`gas_realized_tx_count` near zero) are surfaced separately because the realized percentile is noisy when tx count is low." - "Realized base fee. Recorded for completeness as `gas_realized_base_gwei{chain}` and per-oracle baseFee error as `gas_error_base_gwei{oracle, chain}`. Not the ranking signal since every EIP-1559 oracle inherits this from `eth_feeHistory` and converges." @@ -96,7 +96,6 @@ methodology: findings: - "{{best_name}} currently leads at {{best_p50}} (absolute error in gwei, p99, 24 h) on the active chain tab, across {{count}} measured oracles. The ranking uses the p99 gap, the worst 1% of blocks, because typical-minute gaps sit within fractions of a micro-gwei of each other (economically indistinguishable noise) while gas spikes are where a wrong prediction actually costs money." - - "{{name:blocknative}} shows a p99 gap of {{p50:blocknative}}. Blocknative publishes a probability-of-inclusion model per tier (70 / 80 / 90 / 95 / 99% confidence) which we map onto the unified p25 / p50 / p75 / p90 / p99 scheme; the same parser works for every chain via the `?chainid=` query parameter." - "{{name:publicnode-feehistory}} shows a p99 gap of {{p50:publicnode-feehistory}}. PublicNode's `eth_feeHistory` predictor is a thin wrapper over the EIP-1559 spec's reward percentiles, so it tends to agree closely with the realized percentile by construction. the gap is mostly the difference between the rolling lookback window and the next-block reality." - "{{name:owlracle}} shows a p99 gap of {{p50:owlracle}}. Owlracle aggregates several upstream oracles into a recommendation, which compresses tail risk but adds polling latency at the 60s cadence required by the free quota." - "{{name:etherscan}} shows a p99 gap of {{p50:etherscan}}. The most-visited gas tracker on the web; its tiering (`SafeGasPrice` / `ProposeGasPrice` / `FastGasPrice`) was originally designed for the pre-EIP-1559 single-price world. Audited on Ethereum + Polygon, both supported by Etherscan v2's free tier." @@ -108,7 +107,7 @@ faq: - q: "Why rank on the p99 gap instead of the typical p50 gap?" a: "Because at current fee levels the p50 gaps are fractions of a micro-gwei apart across oracles, on a 100k-gas transaction a 0.001 gwei error is about a thousandth of a cent, so a p50 ranking orders economically indistinguishable noise. The p99 gap captures the volatile minutes (mempool spikes, NFT mints, MEV bursts) where predictions genuinely diverge and a wrong number either overpays or misses the block. The typical p50 and p90 gaps remain visible as secondary columns." - q: "What is the covered rate column?" - a: "The share of time over 24h that the oracle's posted p50-tier prediction was at or above the realized p50 priority fee of the latest mined block. Absolute gap treats over-prediction and under-prediction the same, but they are not symmetric for users: over-predicting means slightly overpaying, under-predicting means a transaction paying exactly the predicted fee would have ranked below the block's median and risks waiting. Inclusion-confidence oracles (Blocknative, Etherscan) should score high here by design; percentile trackers sit near 50% by construction. Read gap and covered together: low p99 gap + high covered is the sweet spot." + a: "The share of time over 24h that the oracle's posted p50-tier prediction was at or above the realized p50 priority fee of the latest mined block. Absolute gap treats over-prediction and under-prediction the same, but they are not symmetric for users: over-predicting means slightly overpaying, under-predicting means a transaction paying exactly the predicted fee would have ranked below the block's median and risks waiting. Inclusion-confidence oracles (Etherscan) should score high here by design; percentile trackers sit near 50% by construction. Read gap and covered together: low p99 gap + high covered is the sweet spot." - q: "Why these specific chains (Ethereum, Polygon)?" a: "Both are EIP-1559 with a proper dynamic base fee, which makes 'priority-fee prediction error' an apples-to-apples comparable metric across them. Avalanche C-Chain was dropped because its auto-tuning fee market collapses the priority fee to ~0 by design, which makes the prediction-error metric uniformly ~0 across all oracles and non-informative. BNB Chain is excluded because it isn't EIP-1559 (effective fee = gasPrice only, priority is structural noise). Optimism / Base / Arbitrum and other L2 OP Stack rollups are excluded because their priority fee is ~0 (centralised sequencer, no MEV) and the relevant cost is L1 data fee, a different metric that belongs in a separate bench. Solana uses lamports per CU with Jito MEV, different fee model entirely." - q: "Which oracle should I pick for my wallet?" @@ -176,19 +175,6 @@ metric_panels: higher_is_better: true providers: - - slug: blocknative - name: Blocknative - tag: Probability-of-inclusion model, EIP-1559 tiered - formula: "p99 over 24h of |Blocknative's predicted p50-tier priority fee − realized p50 priority fee| in gwei, computed per next-mined block on the active chain." - queries: - p50: quantile_over_time(0.99, gas_error_priority_gwei{oracle="blocknative", tier="p50"}[24h]) - p90: quantile_over_time(0.90, gas_error_priority_gwei{oracle="blocknative", tier="p50"}[24h]) - p99: quantile_over_time(0.50, gas_error_priority_gwei{oracle="blocknative", tier="p50"}[24h]) - mean: avg_over_time(gas_error_priority_gwei{oracle="blocknative", tier="p50"}[24h]) - success: sum(rate(gas_oracle_call_total{oracle="blocknative", result="ok"}[24h])) / sum(rate(gas_oracle_call_total{oracle="blocknative"}[24h])) - sample_size: sum(increase(gas_oracle_call_total{oracle="blocknative"}[24h])) - series: gas_error_priority_gwei{oracle="blocknative", tier="p50"} - - slug: publicnode-feehistory name: PublicNode tag: Thin wrapper over EIP-1559 reward percentiles diff --git a/harnesses/gas-estimation/README.md b/harnesses/gas-estimation/README.md index 968c3c6f..ae067e4f 100644 --- a/harnesses/gas-estimation/README.md +++ b/harnesses/gas-estimation/README.md @@ -17,12 +17,11 @@ For each gas oracle, capture the priority-fee + base-fee prediction at time T, w | Slug | Endpoint | Auth | Poll cadence | Tier mapping | |---|---|---|---|---| -| `blocknative` | `api.blocknative.com/gasprices/blockprices` | no key (free tier) | 12 s | confidence 70/80/90/95/99 → p25/p50/p75/p90/p99 | | `publicnode-feehistory` | `ethereum-rpc.publicnode.com` `eth_feeHistory` | no key | 12 s | reward[..][0/1/2] → p25/p50/p90 | | `owlracle` | `api.owlracle.info/v4/eth/gas` | no key | 60 s (free quota 100/h) | acceptance 0.35/0.6/0.9/1.0 → p25/p50/p90/p99 | | `etherscan` | `api.etherscan.io/v2/api?chainid=1&module=gastracker&action=gasoracle` | no key (throttled 1/5s) | 15 s | Safe/Propose/Fast − suggestBaseFee → p25/p50/p90 | -Two more oracles (Alchemy `eth_feeHistory`, Blocknative paid Gas Platform) require a free key signup — wired via env vars but disabled by default. See `config.go` for the `GAS_TOKEN_*` and `GAS_URL_*` overrides. +Alchemy `eth_feeHistory` is wired via env vars but disabled by default; it requires a free key signup. See `config.go` for the `GAS_URL_*` overrides. The verification agent confirmed 5 candidates DEAD in 2026: Etherchain (Cloudflare 403), ethgas.watch (deprecated), ethgasstation (defunct), gasstation.network (404), api.ethgas.org / eth.gasprice.network / gastracker.io (DNS gone). @@ -46,7 +45,7 @@ All effective priorities are sorted into a single series; p25/p50/p90 are simple ``` +-----------------+ +-----------------+ | oracle pollers | ---+ | realizer | -| (4 goroutines) | | | head every 12 s | +| (3 goroutines) | | | head every 12 s | +-----------------+ | | catch-up ≤5 blk | v +-----------------+ +---------------+ | @@ -110,8 +109,6 @@ go run ./cmd/script Optional env overrides: ```bash -# Bump Blocknative to a paid key (5 RPS, 100k/day) -GAS_TOKEN_BLOCKNATIVE=your-key-here \ # Use Alchemy feeHistory instead of (or alongside) publicnode GAS_URL_PUBLICNODE_FEEHISTORY=https://eth-mainnet.g.alchemy.com/v2/your-key \ go run ./cmd/script @@ -123,9 +120,9 @@ Standard OCB-miniapp shape — multi-stage Dockerfile, port 2112, internal-only ## Known limits -- **Ethereum mainnet only**. Owlracle covers bsc/poly/avax/arbitrum, feeHistory works on every chain, Blocknative free is mainnet-only, Etherscan v2 free is mainnet-only. Multi-chain bench is a v2 build that swaps the realized RPC + adapts the URL templating. -- **Blob fees not benchmarked**. Blocknative + feeHistory return `baseFeePerBlobGas` but the bench doesn't currently emit it. Add `fee_kind="blob"` axis in a v2 to surface blob predictions. -- **p75/p99 realized values are approximated** — we compute exact p25/p50/p90 from block txs but interpolate p75 = (p50+p90)/2 and p99 = p90. Oracles that emit these tiers (Blocknative, Owlracle) get a comparator, but the bench page should footnote that these are noisier than p25/p50/p90. +- **Ethereum mainnet only**. Owlracle covers bsc/poly/avax/arbitrum, feeHistory works on every chain, Etherscan v2 free is mainnet-only. Multi-chain bench is a v2 build that swaps the realized RPC + adapts the URL templating. +- **Blob fees not benchmarked**. feeHistory returns `baseFeePerBlobGas` but the bench doesn't currently emit it. Add `fee_kind="blob"` axis in a v2 to surface blob predictions. +- **p75/p99 realized values are approximated** — we compute exact p25/p50/p90 from block txs but interpolate p75 = (p50+p90)/2 and p99 = p90. Oracles that emit those tiers (Owlracle) get a comparator, but the bench page should footnote that these are noisier than p25/p50/p90. - **Etherscan no-key throttles at 1/5 s**. With our 15 s cadence we stay well within. If we ever go below 10 s, register a free key. - **Owlracle 100/h no-key quota**. At 60 s cadence we use 60 polls/h = 60% of quota. A free key bumps it to 1000/h. - **Startup window**: first few predictions during the first ~12 s aren't matched (realizer hasn't seen head yet). Owlracle skips buffering during this window; other oracles target an explicit block so are safe. diff --git a/harnesses/gas-estimation/cmd/script/config.go b/harnesses/gas-estimation/cmd/script/config.go index c7650b09..14013bdf 100644 --- a/harnesses/gas-estimation/cmd/script/config.go +++ b/harnesses/gas-estimation/cmd/script/config.go @@ -10,9 +10,9 @@ import ( // Tier is the unified percentile label every oracle's prediction is // mapped onto. We chose p25/p50/p90 because every oracle in the bench // exposes at least three buckets that roughly align with this scheme; -// finer buckets (p75/p99) exist on Blocknative and Owlracle and are -// added back as `tier="p75"`/`tier="p99"` when the oracle supplies -// them. The label is what the OCB site groups by, so the per-oracle +// finer buckets (p75/p99) exist on Owlracle and are added back as +// `tier="p75"`/`tier="p99"` when the oracle supplies them. The label +// is what the OCB site groups by, so the per-oracle // "fast/standard/slow" names never leak into the public metric. type Tier string @@ -28,26 +28,24 @@ const ( // Add an entry to src/data/provider-registry.ts on the OCB side when // onboarding a new oracle. const ( - OracleBlocknative Oracle = "blocknative" - OraclePublicNode Oracle = "publicnode-feehistory" - OracleOwlracle Oracle = "owlracle" - OracleEtherscan Oracle = "etherscan" + OraclePublicNode Oracle = "publicnode-feehistory" + OracleOwlracle Oracle = "owlracle" + OracleEtherscan Oracle = "etherscan" ) type Oracle string // Cadences pinned per oracle. Lifted directly from the verification -// agent's findings: Blocknative tolerates 12 s no-key; PublicNode -// feeHistory is fair-use at 5 req/s; Owlracle free tier is 100/hour, -// so 60 s is the safe ceiling; Etherscan no-key throttles to 1/5 s, -// so 15 s gives a comfortable margin. Cadences are per-chain too: -// running the same oracle against 3 chains at 12 s = 0.25 req/s -// per oracle, well inside every free-tier budget. +// agent's findings: PublicNode feeHistory is fair-use at 5 req/s; +// Owlracle free tier is 100/hour, so 60 s is the safe ceiling; +// Etherscan no-key throttles to 1/5 s, so 15 s gives a comfortable +// margin. Cadences are per-chain too: running the same oracle against +// 3 chains at 12 s = 0.25 req/s per oracle, well inside every +// free-tier budget. var pollIntervals = map[Oracle]time.Duration{ - OracleBlocknative: 12 * time.Second, - OraclePublicNode: 12 * time.Second, - OracleOwlracle: 60 * time.Second, - OracleEtherscan: 15 * time.Second, + OraclePublicNode: 12 * time.Second, + OracleOwlracle: 60 * time.Second, + OracleEtherscan: 15 * time.Second, } // Realized-block poll cadence per chain. Picked close to each chain's @@ -91,8 +89,8 @@ func chains() []Chain { RealizedRPC: envDefault("GAS_REALIZED_RPC_ETHEREUM", "https://ethereum-rpc.publicnode.com"), OwlracleSlug: "eth", BlockTimeSec: 12, - // Etherscan v2 free tier covers chainid=1. All four oracles work. - SupportedSet: []Oracle{OracleBlocknative, OraclePublicNode, OracleOwlracle, OracleEtherscan}, + // Etherscan v2 free tier covers chainid=1. All three oracles work. + SupportedSet: []Oracle{OraclePublicNode, OracleOwlracle, OracleEtherscan}, }, { Slug: "polygon", @@ -100,8 +98,8 @@ func chains() []Chain { RealizedRPC: envDefault("GAS_REALIZED_RPC_POLYGON", "https://polygon-bor-rpc.publicnode.com"), OwlracleSlug: "poly", BlockTimeSec: 2, - // Etherscan v2 free tier covers chainid=137 (verified). All four oracles work. - SupportedSet: []Oracle{OracleBlocknative, OraclePublicNode, OracleOwlracle, OracleEtherscan}, + // Etherscan v2 free tier covers chainid=137 (verified). All three oracles work. + SupportedSet: []Oracle{OraclePublicNode, OracleOwlracle, OracleEtherscan}, }, { Slug: "avalanche", @@ -110,8 +108,8 @@ func chains() []Chain { OwlracleSlug: "avax", BlockTimeSec: 2, // Etherscan v2 returns "Free API access is not supported for this chain" on chainid=43114 — paid plan required. - // Three oracles only (Blocknative + PublicNode feeHistory + Owlracle). - SupportedSet: []Oracle{OracleBlocknative, OraclePublicNode, OracleOwlracle}, + // Two oracles only (PublicNode feeHistory + Owlracle). + SupportedSet: []Oracle{OraclePublicNode, OracleOwlracle}, }, } } @@ -120,13 +118,11 @@ func chains() []Chain { // override without a rebuild. The URL field is the BASE — per-chain // rewriting happens in endpointForChain() below. type OracleEndpoint struct { - URL string - AuthHeader string + URL string } // endpointForChain builds the per-(oracle, chain) URL. // -// - Blocknative: same host, query param `?chainid=`. // - PublicNode feeHistory: per-chain RPC URL from the Chain struct. // - Owlracle: per-chain path slug from the Chain struct. // - Etherscan v2: same host, `?chainid=&module=gastracker&action=gasoracle`. @@ -139,14 +135,9 @@ func endpointForChain(o Oracle, c Chain) OracleEndpoint { strings.ToUpper(c.Slug), ) if override := envDefault(envKey, ""); override != "" { - return OracleEndpoint{URL: override, AuthHeader: oracleAuthHeader(o)} + return OracleEndpoint{URL: override} } switch o { - case OracleBlocknative: - return OracleEndpoint{ - URL: fmt.Sprintf("https://api.blocknative.com/gasprices/blockprices?chainid=%d", c.ChainID), - AuthHeader: envDefault("GAS_TOKEN_BLOCKNATIVE", ""), - } case OraclePublicNode: return OracleEndpoint{URL: c.RealizedRPC} case OracleOwlracle: @@ -161,15 +152,6 @@ func endpointForChain(o Oracle, c Chain) OracleEndpoint { return OracleEndpoint{} } -// oracleAuthHeader returns the optional Authorization header value -// for the given oracle. Currently only Blocknative supports a token. -func oracleAuthHeader(o Oracle) string { - if o == OracleBlocknative { - return envDefault("GAS_TOKEN_BLOCKNATIVE", "") - } - return "" -} - func envDefault(key, def string) string { if v := strings.TrimSpace(os.Getenv(key)); v != "" { return v diff --git a/harnesses/gas-estimation/cmd/script/main.go b/harnesses/gas-estimation/cmd/script/main.go index 0a7b69b2..d45fcec7 100644 --- a/harnesses/gas-estimation/cmd/script/main.go +++ b/harnesses/gas-estimation/cmd/script/main.go @@ -116,7 +116,7 @@ func runOraclePoller(ctx context.Context, o Oracle, ep OracleEndpoint, interval // Stagger startup so all pollers across chains don't fire at t=0. // Jitter folds in both the oracle name AND the chain slug so the - // 3 Blocknative pollers (one per chain) hit at different offsets. + // per-chain pollers for the same oracle hit at different offsets. time.Sleep(jitterFor(string(o) + ":" + chain.Slug)) tick() for { diff --git a/harnesses/gas-estimation/cmd/script/oracles.go b/harnesses/gas-estimation/cmd/script/oracles.go index a630cc58..e21578d4 100644 --- a/harnesses/gas-estimation/cmd/script/oracles.go +++ b/harnesses/gas-estimation/cmd/script/oracles.go @@ -22,10 +22,9 @@ const ( ) // pollResult is what every oracle client returns. TargetBlock is the -// block these predictions apply to (oracle-specific: Blocknative -// gives an explicit next-block number, feeHistory returns the -// projected baseFee for "the next block", Owlracle predicts the -// upcoming few blocks). +// block these predictions apply to (oracle-specific: feeHistory +// returns the projected baseFee for "the next block", Etherscan +// reports lastBlock+1, Owlracle predicts the upcoming few blocks). type pollResult struct { TargetBlock uint64 Predictions []Prediction @@ -42,8 +41,6 @@ type pollResult struct { // adapter. func pollOracle(ctx context.Context, o Oracle, ep OracleEndpoint) pollResult { switch o { - case OracleBlocknative: - return pollBlocknative(ctx, ep) case OraclePublicNode: return pollFeeHistory(ctx, ep) case OracleOwlracle: @@ -55,74 +52,6 @@ func pollOracle(ctx context.Context, o Oracle, ep OracleEndpoint) pollResult { } } -// ─── Blocknative ────────────────────────────────────────────────── - -type bnEstimatedPrice struct { - Confidence int `json:"confidence"` - Price float64 `json:"price"` - MaxPriorityFeePerGas float64 `json:"maxPriorityFeePerGas"` - MaxFeePerGas float64 `json:"maxFeePerGas"` -} - -type bnBlockPrice struct { - BlockNumber uint64 `json:"blockNumber"` - BaseFeePerGas float64 `json:"baseFeePerGas"` - BlobBaseFeePerGas float64 `json:"blobBaseFeePerGas"` - EstimatedTransactions int `json:"estimatedTransactionCount"` - EstimatedPrices []bnEstimatedPrice `json:"estimatedPrices"` -} - -type bnResp struct { - System string `json:"system"` - CurrentBlock uint64 `json:"currentBlockNumber"` - MsSinceLastBlock int `json:"msSinceLastBlock"` - BlockPrices []bnBlockPrice `json:"blockPrices"` -} - -func pollBlocknative(ctx context.Context, ep OracleEndpoint) pollResult { - req, _ := http.NewRequestWithContext(ctx, "GET", ep.URL, nil) - if ep.AuthHeader != "" { - req.Header.Set("Authorization", ep.AuthHeader) - } - body, status, err := httpDo(ctx, req) - if err != nil { - return pollResult{Err: err} - } - if status != 200 { - return pollResult{Err: fmt.Errorf("http %d", status)} - } - var r bnResp - if err := json.Unmarshal(body, &r); err != nil { - return pollResult{Err: fmt.Errorf("parse: %w", err)} - } - if len(r.BlockPrices) == 0 { - return pollResult{Err: fmt.Errorf("empty blockPrices")} - } - bp := r.BlockPrices[0] - // Confidence 70/80/90/95/99 → p25/p50/p75/p90/p99 per spec. - mapping := map[int]Tier{ - 70: TierP25, - 80: TierP50, - 90: TierP75, - 95: TierP90, - 99: TierP99, - } - out := pollResult{TargetBlock: bp.BlockNumber, BaseGwei: bp.BaseFeePerGas} - for _, e := range bp.EstimatedPrices { - tier, ok := mapping[e.Confidence] - if !ok { - continue - } - out.Predictions = append(out.Predictions, Prediction{ - Oracle: OracleBlocknative, - Tier: tier, - PriorityGwei: e.MaxPriorityFeePerGas, - BaseGwei: bp.BaseFeePerGas, - }) - } - return out -} - // ─── eth_feeHistory (PublicNode, Alchemy share this shape) ──────── type fhResult struct { diff --git a/harnesses/gas-estimation/cmd/script/realized.go b/harnesses/gas-estimation/cmd/script/realized.go index 97b5b8b7..3ba5b0eb 100644 --- a/harnesses/gas-estimation/cmd/script/realized.go +++ b/harnesses/gas-estimation/cmd/script/realized.go @@ -232,11 +232,11 @@ func processBlock(ctx context.Context, buf *Buffer, blockNum uint64, chain Chain } realized := map[Tier]float64{TierP25: p25, TierP50: p50, TierP90: p90} - // p75/p99 are emitted by Blocknative & Owlracle; we approximate - // realized p75 = (p50 + p90)/2 and p99 = p90 to give those - // tiers a comparator even though we don't compute them directly. - // Better than dropping the metric — but the realized side is - // noisy for tail tiers, so the bench page should footnote this. + // p75/p99 are emitted by Owlracle; we approximate realized p75 = + // (p50 + p90)/2 and p99 = p90 to give those tiers a comparator + // even though we don't compute them directly. Better than + // dropping the metric — but the realized side is noisy for tail + // tiers, so the bench page should footnote this. realized[TierP75] = (p50 + p90) / 2 realized[TierP99] = p90 diff --git a/public/logos/blocknative.svg b/public/logos/blocknative.svg deleted file mode 100644 index 815dc90b..00000000 --- a/public/logos/blocknative.svg +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/src/app/about/page.tsx b/src/app/about/page.tsx index f1402786..bbc27c9f 100644 --- a/src/app/about/page.tsx +++ b/src/app/about/page.tsx @@ -47,7 +47,7 @@ export default function AboutPage() {
  • ·Bridges. quote latency and effective fee on $300 USDC corridors. Mobula, Relay, LiFi, Debridge.
  • ·Blockchains. L1 finality time across 11 chains. L2 sequencer block time across 9 L2s.
  • ·Trading venues. all-in opening cost on perp DEXes (Hyperliquid, Lighter, dYdX, GMX, gains). Stablecoin peg deviation on USDC, USDT, DAI + USDT-anchored swap-cost on FDUSD, USDe.
  • -
  • ·RPCs. fastest free no-key public RPC across 10 EVM chains × 15 providers (PublicNode, dRPC, 1RPC, Tenderly, Nodies, Lava, Merkle, MeowRPC, Flashbots, Cloudflare, foundation endpoints). Plus gas-oracle prediction error (Blocknative, Owlracle, Etherscan, PublicNode feeHistory) on Ethereum, Polygon, Avalanche.
  • +
  • ·RPCs. fastest free no-key public RPC across 10 EVM chains × 15 providers (PublicNode, dRPC, 1RPC, Tenderly, Nodies, Lava, Merkle, MeowRPC, Flashbots, Cloudflare, foundation endpoints). Plus gas-oracle prediction error (Owlracle, Etherscan, PublicNode feeHistory) on Ethereum, Polygon, Avalanche.
  • 13 live benchmarks. ~150 (provider × chain) probe pairs. Every metric is queryable on the public Prometheus and reproducible from the harness source. diff --git a/src/components/provider-logo.tsx b/src/components/provider-logo.tsx index be5d683d..f843286d 100644 --- a/src/components/provider-logo.tsx +++ b/src/components/provider-logo.tsx @@ -87,7 +87,6 @@ const NEEDS_LIGHT_CHIP = new Set([ "debridge", "tonapi", "1rpc", - "blocknative", "lava", "tenderly", "merkle", diff --git a/src/data/provider-registry.ts b/src/data/provider-registry.ts index a31ac75c..899608b9 100644 --- a/src/data/provider-registry.ts +++ b/src/data/provider-registry.ts @@ -565,12 +565,6 @@ export const PROVIDER_REGISTRY: Record = { }, // ─── Gas oracles ────────────────────────────────────────────── - blocknative: { - url: "https://www.blocknative.com", - description: - "Mempool observability platform with a probability-of-inclusion gas oracle. EIP-1559 tier predictions exposed via the public /gasprices/blockprices endpoint, free tier without an API key.", - twitter: "@blocknative", - }, "publicnode-feehistory": { url: "https://www.publicnode.com", description: diff --git a/src/lib/format.ts b/src/lib/format.ts index 482948f3..89456a9f 100644 --- a/src/lib/format.ts +++ b/src/lib/format.ts @@ -52,9 +52,10 @@ export function fmtUnit(value: number, unit: string) { if (unit === "count") { // Sub-unit values are common when a "count" bench is measuring an // error or gap that converges toward zero (e.g. gas-oracle prediction - // error in gwei — Blocknative's p50 sits around 1e-9, mathematically - // perfect). Default toLocaleString silently rounds those to "0", so - // the headline card reads as "no data" instead of "essentially zero". + // error in gwei — PublicNode feeHistory's p50 sits around 1e-9, + // mathematically perfect). Default toLocaleString silently rounds + // those to "0", so the headline card reads as "no data" instead of + // "essentially zero". if (value > 0 && value < 0.01) return "~0"; if (value > 0 && value < 1) return value.toFixed(3); return formatCompactCount(value); diff --git a/src/lib/logo-manifest.ts b/src/lib/logo-manifest.ts index 2131dc55..a06a54ca 100644 --- a/src/lib/logo-manifest.ts +++ b/src/lib/logo-manifest.ts @@ -109,7 +109,6 @@ const RAW: Record = { // ─── MEV / private mempools (gas-estimation, RPC capabilities) ─── flashbots: "/logos/flashbots.svg", - blocknative: "/logos/blocknative.svg", merkle: "/logos/merkle.svg", // ─── Block explorers / address-label providers ───