UNPKG

@unruggable/gateways

Version:

Trustless Ethereum Multichain CCIP-Read Gateway

39 lines (38 loc) 1.45 kB
import { isHexString } from 'ethers/utils'; import { sha256 } from 'ethers/crypto'; export async function fetchBeaconData(url) { try { const res = await fetch(url); if (!res.ok) throw `HTTP ${res.status}`; const { data } = await res.json(); if (!data) throw 'expected "data"'; return data; } catch (err) { throw new Error(`${url}: ${err}`); } } // https://ethereum.github.io/beacon-APIs/#/Beacon/getBlobSidecars function isSidecar(sidecar) { return (sidecar instanceof Object && 'blob' in sidecar && 'kzg_commitment' in sidecar && isHexString(sidecar.blob) && sidecar.blob.length == 262146 && isHexString(sidecar.kzg_commitment) && sidecar.kzg_commitment.length == 98); } // https://github.com/ethereum/go-ethereum/blob/c1ff2d8ba973f9f7ebfbf45e3c36f8d3299846ba/crypto/kzg4844/kzg4844.go#L154 function blobVersionHashFromKzgCommitment(kzgCommitment) { return '0x01' + sha256(kzgCommitment).slice(4); } export async function fetchSidecars(beaconAPI, blockId) { const sidecars = await fetchBeaconData(`${beaconAPI}/eth/v1/beacon/blob_sidecars/${blockId}`); if (!Array.isArray(sidecars)) throw new Error(`expected blob sidecars: ${blockId}`); return Object.fromEntries(sidecars .filter(isSidecar) .map((x) => [blobVersionHashFromKzgCommitment(x.kzg_commitment), x])); }