- 
                Notifications
    
You must be signed in to change notification settings  - Fork 5.3k
 
feat(pages/resources): add pectra countdown and blobscan api #15324
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Changes from 7 commits
8e35750
              25597af
              b9158d7
              a504bc1
              55a27de
              d31aa0e
              040d7bb
              eba75bf
              9771acf
              472b762
              15408bb
              bf9423a
              c35f66d
              2aaa16f
              69de9e1
              195836c
              1dd199b
              File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| 
          
            
          
           | 
    @@ -16,6 +16,7 @@ import RadialChart from "../RadialChart" | |
| 
     | 
||
| import type { DashboardBox, DashboardSection } from "./types" | ||
| 
     | 
||
| import { useEthPrice } from "@/hooks/useEthPrice" | ||
| import { useTranslation } from "@/hooks/useTranslation" | ||
| import IconBeaconchain from "@/public/images/resources/beaconcha-in.png" | ||
| import IconBlobsGuru from "@/public/images/resources/blobsguru.png" | ||
| 
          
            
          
           | 
    @@ -53,16 +54,24 @@ const formatSmallUSD = (value: number, locale: string): string => | |
| new Intl.NumberFormat(locale, { | ||
| style: "currency", | ||
| currency: "USD", | ||
| notation: "compact", | ||
| minimumSignificantDigits: 2, | ||
| maximumSignificantDigits: 2, | ||
| }).format(value) | ||
| 
     | 
||
| export const useResources = ({ txCostsMedianUsd }): DashboardSection[] => { | ||
| export const useResources = ({ | ||
| txCostsMedianUsd, | ||
| totalBlobs, | ||
| avgBlobFee, | ||
| }): DashboardSection[] => { | ||
| const { t } = useTranslation("page-resources") | ||
| const locale = useLocale() | ||
| const localeForNumberFormat = getLocaleForNumberFormat(locale! as Lang) | ||
| 
     | 
||
| const ethPrice = useEthPrice() | ||
| const avgBlobFeeUsd = formatSmallUSD( | ||
| // Converting value from wei to USD | ||
| avgBlobFee * 1e-18 * ethPrice, | ||
| localeForNumberFormat | ||
| ) | ||
| 
     | 
||
| const medianTxCost = | ||
| "error" in txCostsMedianUsd | ||
| ? { error: txCostsMedianUsd.error } | ||
| 
          
            
          
           | 
    @@ -343,7 +352,14 @@ export const useResources = ({ txCostsMedianUsd }): DashboardSection[] => { | |
| const scalingBoxes: DashboardBox[] = [ | ||
| { | ||
| title: t("page-resources-roadmap-title"), | ||
| // TODO: Add metric | ||
| metric: ( | ||
| <div className="grid place-items-center py-5"> | ||
| <div className="text-sm">Next upgrade</div> | ||
                
       | 
||
| <div className="text-5xl font-bold">Pectra</div> | ||
| {/* TODO: Convert date to a countdown */} | ||
| <div className="text-xl font-bold text-body-medium">07 May 2025</div> | ||
                
       | 
||
| </div> | ||
| ), | ||
| items: [ | ||
| { | ||
| title: "Ethereum Roadmap", | ||
| 
        
          
        
         | 
    @@ -355,7 +371,22 @@ export const useResources = ({ txCostsMedianUsd }): DashboardSection[] => { | |
| }, | ||
| { | ||
| title: t("page-resources-blobs-title"), | ||
| // TODO: Add metric | ||
| metric: ( | ||
| <div className="flex [&>*]:grid [&>*]:flex-1 [&>*]:place-items-center"> | ||
| <div> | ||
| <div className="text-[42px] font-bold leading-2xs"> | ||
| {totalBlobs} | ||
| </div> | ||
| <div className="text-sm text-body-medium">Total blobs</div> | ||
| </div> | ||
| <div> | ||
| <div className="text-[42px] font-bold leading-2xs"> | ||
| {avgBlobFeeUsd} | ||
| </div> | ||
| <div className="text-sm text-body-medium">Average Blob Fee</div> | ||
| </div> | ||
| </div> | ||
| ), | ||
| items: [ | ||
| { | ||
| title: "Blob Scan", | ||
| 
          
            
          
           | 
    ||
| 
                       There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. added this file. If you run with   | 
            
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| { | ||
| "avgBlobAsCalldataFee": 18402670294113620, | ||
| "avgBlobFee": 1337454615991715, | ||
| "avgBlobGasPrice": 4657716809.805255, | ||
| "avgMaxBlobGasFee": 19666167416.48503, | ||
| "totalBlobGasUsed": "875492278272", | ||
| "totalBlobAsCalldataGasUsed": "12165759474144", | ||
| "totalBlobFee": "4174952855822794358784", | ||
| "totalBlobAsCalldataFee": "57445149899315095107588", | ||
| "totalBlobs": 6679476, | ||
| "totalBlobSize": "875492278272", | ||
| "totalBlocks": 1664933, | ||
| "totalTransactions": 3121566, | ||
| "totalUniqueBlobs": 6575105, | ||
| "totalUniqueReceivers": 5361, | ||
| "totalUniqueSenders": 5941, | ||
| "updatedAt": "2025-03-25T11:45:00.590Z" | ||
| } | 
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| type BlobscanOverallStats = { | ||
| avgBlobAsCalldataFee: number | ||
| avgBlobFee: number | ||
| avgBlobGasPrice: number | ||
| avgMaxBlobGasFee: number | ||
| totalBlobGasUsed: string | ||
| totalBlobAsCalldataGasUsed: string | ||
| totalBlobFee: string | ||
| totalBlobAsCalldataFee: string | ||
| totalBlobs: number | ||
| totalBlobSize: string | ||
| totalBlocks: number | ||
| totalTransactions: number | ||
| totalUniqueBlobs: number | ||
| totalUniqueReceivers: number | ||
| totalUniqueSenders: number | ||
| updatedAt: string | ||
| } | ||
| 
     | 
||
| type BlobscanOverallStatsErr = { | ||
| message: string | ||
| code: string | ||
| issues: [message: string] | ||
| } | ||
| 
     | 
||
| /** | ||
| * Fetch the overall stats from Blobscan | ||
| * | ||
| * @see https://api.blobscan.com/#/stats/stats-getOverallStats | ||
| * | ||
| */ | ||
| export const fetchBlobscanStats = async () => { | ||
| const data = await fetch("https://api.blobscan.com/stats/overall").then( | ||
| (res) => responseHandler(res) | ||
| ) | ||
| 
     | 
||
| return data | ||
| } | ||
| 
     | 
||
| type BlobscanResponse = | ||
| | (Omit<Response, "json"> & { | ||
| json: () => BlobscanOverallStats | PromiseLike<BlobscanOverallStats> | ||
| }) | ||
| | (Omit<Response, "json"> & { | ||
| json: () => BlobscanOverallStatsErr | PromiseLike<BlobscanOverallStatsErr> | ||
| }) | ||
| 
     | 
||
| const responseHandler = async (response: Response) => { | ||
| const res = await (response as BlobscanResponse).json() | ||
| 
     | 
||
| if ("message" in res) { | ||
| throw Error(`Code ${res.code}: Failed to fetch Blobscan Overall Stats`, { | ||
| cause: res.message, | ||
| }) | ||
| } | ||
| return res | ||
| } | 
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Simplify the price formatting for
formatSmallUSD(), so that two decimal places are always shown, no matter the number of significant figures. (i.e.$xx.xxversus$x.xx)