Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
6d7409e
feat: add /reports page under Research menu
konopkja May 22, 2026
0ecf73c
perf(reports): convert cover images to WebP
konopkja May 22, 2026
596990f
docs(reports): rewrite intro copy in educational voice
konopkja May 22, 2026
b217d5a
feat(reports): show PDF file size on cards linking direct PDFs
konopkja May 22, 2026
b0ca60b
feat(reports): link 4 more reports directly to their PDFs
konopkja May 22, 2026
08df5b2
feat(reports): refresh cover artwork + add Ethereum Basics card
konopkja May 25, 2026
bf33bc5
perf(reports): re-encode hero from higher-resolution source
konopkja May 25, 2026
1658afa
feat(reports): expand JSON-LD with CollectionPage + per-report ItemList
konopkja May 26, 2026
b63c00c
feat(reports): swap hero to existing what-is-ethereum-network illustr…
konopkja May 26, 2026
7509e40
seo(reports): set H1 to "Reports on Ethereum from institutions"
konopkja May 26, 2026
ac76b61
feat(reports): swap hero to books illustration
konopkja May 26, 2026
bb32cf5
chore(reports): refresh hero illustration
konopkja May 26, 2026
25aac03
perf(reports): tighten hero asset to 104 KB
konopkja May 26, 2026
134d910
Merge branch 'dev' into feat/reports-page
myelinated-wackerow May 27, 2026
12b48b2
refactor: reports page cards and layout
myelinated-wackerow May 27, 2026
969e94a
patch(ui): add text-pretty to ui/card
myelinated-wackerow May 27, 2026
9fa828d
refactor: use formatDate
myelinated-wackerow May 27, 2026
07ce1e2
refactor(intl): use number formatting for PDF byte size
myelinated-wackerow May 27, 2026
aa041ed
temp: hide report pending PDF
myelinated-wackerow May 27, 2026
f6dcdfc
refactor: use url helper utils
myelinated-wackerow May 27, 2026
b723b45
chore: remove unnecessary wraper div
myelinated-wackerow May 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
185 changes: 185 additions & 0 deletions app/[locale]/reports/data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
import type { StaticImageData } from "next/image"

import a16zCover from "@/public/images/reports/a16z-state-of-crypto-2025.webp"
import bisCover from "@/public/images/reports/bis-papers-156.webp"
import quantumCover from "@/public/images/reports/coinbase-quantum-blockchain.webp"
import consensysCover from "@/public/images/reports/consensys-trustware.webp"
// import ethereumBasicsCover from "@/public/images/reports/ethereum-basics-governments-institutions.webp"
import fidelityCoinCover from "@/public/images/reports/fidelity-coin-report-ethereum.webp"
import l2LandscapeCover from "@/public/images/reports/l2-landscape.webp"
import mckinseyCover from "@/public/images/reports/mckinsey-ripples-to-waves.webp"
import openzeppelinCover from "@/public/images/reports/openzeppelin-risk-assessment.webp"
import tdsCover from "@/public/images/reports/trillion-dollar-security-card.webp"
import twinstakeCover from "@/public/images/reports/twinstake-pectra.webp"
import whiteHouseCover from "@/public/images/reports/white-house-crypto.webp"

export type ReportCategory =
| "ef-original"
| "regulator"
| "central-bank"
| "bank-research"
| "big-four"
| "crypto-native"
| "academic"

export type Report = {
/** Stable slug used for keys and (when internal) the subpage path */
slug: string
/** Full title as published */
title: string
/** Publisher (shown as paragraph text under the title) */
publisher: string
/**
* Publication date in ISO 8601 (YYYY, YYYY-MM, or YYYY-MM-DD). Used as
* `datePublished` in the Report JSON-LD and rendered as short date on card.
*/
dateIso: string
/** Publisher category, used for grouping or filtering. */
category: ReportCategory
/** Destination link. Internal entries point to /reports/<slug>/. */
href: string
/** Internal entries open a subpage; external entries open the publisher URL in a new tab. */
internal?: boolean
/** Cover image. Publisher OG image or first-page render of the source PDF. */
imgSrc: StaticImageData
/**
* If the link points directly to a PDF, the file size in bytes (from the
* publisher's Content-Length header at the time of authoring). Surfaced in
* the card so readers know what they are about to download.
*/
fileSizeBytes?: number
}

/**
* Initial curated set of reports surfaced on /reports.
*
* Ordering: internal EF reports first, then external by date desc.
*
* Every external entry has been independently verified. URL fetched, title,
* author, and date confirmed on the publisher site, Ethereum content
* confirmed substantive. See PR description for the full audit.
*/
export const reports: Report[] = [
// TODO: PDF to be uploaded to /public/reports/ — confirm filename + add fileSizeBytes.
// {
// slug: "ethereum-basics-governments-institutions",
// title: "Ethereum Basics for Governments and Institutions",
// publisher: "Ethereum Foundation",
// dateIso: "2026",
// category: "ef-original",
// href: "/reports/ethereum-basics-for-governments-and-institutions.pdf",
// imgSrc: ethereumBasicsCover,
// },
{
slug: "trillion-dollar-security",
title: "Trillion Dollar Security",
publisher: "Ethereum Foundation",
dateIso: "2025-05",
category: "ef-original",
href: "/reports/trillion-dollar-security/",
internal: true,
imgSrc: tdsCover,
},
{
slug: "openzeppelin-blockchain-network-risk-assessment",
title: "Technical Risk Assessment on Blockchain Networks",
publisher: "OpenZeppelin",
dateIso: "2026-04-30",
category: "crypto-native",
href: "https://openzeppelin.com/hubfs/OpenZeppelin%20%7C%20Technical%20Risk%20Assessment%20on%20Blockchain%20Networks.pdf",
imgSrc: openzeppelinCover,
fileSizeBytes: 841405,
},
{
slug: "coinbase-iab-quantum-computing-blockchain",
title: "Quantum Computing & Blockchain",
publisher:
"Coinbase Independent Advisory Board on Quantum Computing and Blockchain",
dateIso: "2026-04-21",
category: "academic",
href: "https://assets.ctfassets.net/sygt3q11s4a9/6EjYavuGdtJDYCqaJrASj9/9f464a8bf26f44bd6c85710fe7e4a29f/Quantum_Computing_and_Blockchain_v10.3_15April2026.pdf",
imgSrc: quantumCover,
fileSizeBytes: 434102,
},
{
slug: "a16z-state-of-crypto-2025",
title: "State of Crypto Report 2025",
publisher: "a16z crypto",
dateIso: "2025-10-22",
category: "crypto-native",
href: "https://dwt2zme5yrom6.cloudfront.net/uploads/2025/10/State-of-Crypto-2025-a16z-crypto.pdf",
imgSrc: a16zCover,
fileSizeBytes: 17291230,
},
{
slug: "etherealize-nethermind-l2beat-l2-landscape",
title:
"The Future of Financial Infrastructure: Ethereum's Layer 2 Landscape",
publisher: "Etherealize, Nethermind and L2BEAT",
dateIso: "2025-12-04",
category: "crypto-native",
href: "https://cdn.prod.website-files.com/6728e9076a3b5a8ca8ec4816/6931c20f55129e498a8da223_%5BCompressed%5D%20L2s%20Report.pdf",
imgSrc: l2LandscapeCover,
fileSizeBytes: 6953384,
},
{
slug: "fidelity-coin-report-ethereum",
title: "Coin Report: Ethereum (ETH)",
publisher: "Fidelity Digital Assets",
dateIso: "2025-08-21",
category: "bank-research",
href: "https://www.fidelitydigitalassets.com/research-and-insights/coin-report-ethereum-eth",
imgSrc: fidelityCoinCover,
},
{
slug: "consensys-ethereum-is-trustware",
title: "Ethereum is Trustware: core trust infrastructure for the world",
publisher: "Consensys",
dateIso: "2025-08-04",
category: "crypto-native",
href: "https://consensys.io/ethereum/trust",
imgSrc: consensysCover,
},
{
slug: "twinstake-ethereum-pectra-institutional-staking",
title: "Ethereum Pectra Upgrade: The Impact on Institutional Staking",
publisher: "Twinstake",
dateIso: "2025",
category: "crypto-native",
href: "https://cdn.prod.website-files.com/658498cb3744de71ad789ca8/67cee06a2f54159204b600ea_Pectra%20Report.pdf",
imgSrc: twinstakeCover,
fileSizeBytes: 1258985,
},
{
slug: "white-house-pwg-crypto",
title: "Strengthening American Leadership in Digital Financial Technology",
publisher:
"The White House (President's Working Group on Digital Asset Markets)",
dateIso: "2025-07-30",
category: "regulator",
href: "https://www.whitehouse.gov/wp-content/uploads/2025/07/Digital-Assets-Report-EO14178.pdf",
imgSrc: whiteHouseCover,
fileSizeBytes: 5864568,
},
{
slug: "bis-papers-156-defi-functions-stability",
title:
"Cryptocurrencies and decentralised finance: functions and financial stability implications",
publisher: "Bank for International Settlements",
dateIso: "2025-04-15",
category: "central-bank",
href: "https://www.bis.org/publ/bppdf/bispap156.pdf",
imgSrc: bisCover,
fileSizeBytes: 751136,
},
{
slug: "mckinsey-from-ripples-to-waves",
title:
"From ripples to waves: The transformational power of tokenizing assets",
publisher: "McKinsey & Company",
dateIso: "2024-06-20",
category: "big-four",
href: "https://www.mckinsey.com/industries/financial-services/our-insights/from-ripples-to-waves-the-transformational-power-of-tokenizing-assets",
imgSrc: mckinseyCover,
},
]
122 changes: 122 additions & 0 deletions app/[locale]/reports/page-jsonld.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import { getTranslations } from "next-intl/server"

import { FileContributor } from "@/lib/types"

import PageJsonLD from "@/components/PageJsonLD"

import { isExternal, isPdf, normalizeUrlForJsonLd } from "@/lib/utils/url"

import { SITE_URL } from "@/lib/constants"

import type { Report } from "./data"

import { BASE_GRAPH_NODES } from "@/lib/jsonld/constants"
import { REFERENCE } from "@/lib/jsonld/references"

const reportSchema = (
report: Report,
index: number,
locale: string,
pageUrl: string
) => {
const itemUrl = isExternal(report.href)
? report.href
: normalizeUrlForJsonLd(locale, report.href)
const imageUrl = `${SITE_URL}${report.imgSrc.src}`

return {
"@type": "ListItem",
position: index + 1,
item: {
"@type": "Report",
"@id": `${pageUrl}#${report.slug}`,
name: report.title,
url: itemUrl,
image: imageUrl,
datePublished: report.dateIso,
inLanguage: "en",
publisher: {
"@type": "Organization",
name: report.publisher,
},
...(isPdf(report.href) && {
encodingFormat: "application/pdf",
}),
...(typeof report.fileSizeBytes === "number" && {
contentSize: `${(report.fileSizeBytes / 1048576).toFixed(1)} MB`,
}),
},
}
}

export default async function ReportsPageJsonLD({
locale,
contributors,
reports,
}: {
locale: string
contributors: FileContributor[]
reports: Report[]
}) {
const t = await getTranslations("page-reports")

const url = normalizeUrlForJsonLd(locale, "/reports/")
const itemListId = `${url}#reports-list`

const contributorList = contributors.map((contributor) => ({
"@type": "Person",
name: contributor.login,
url: contributor.html_url,
}))

const jsonLd = {
"@context": "https://schema.org",
"@graph": [
...BASE_GRAPH_NODES,
{
"@type": "CollectionPage",
"@id": url,
name: t("page-reports-metadata-title"),
description: t("page-reports-metadata-description"),
url,
inLanguage: locale,
contributor: contributorList,
author: [REFERENCE.ETHEREUM_COMMUNITY],
isPartOf: REFERENCE.ETHEREUM_ORG_WEBSITE,
breadcrumb: {
"@type": "BreadcrumbList",
itemListElement: [
{
"@type": "ListItem",
position: 1,
name: "Home",
item: normalizeUrlForJsonLd(locale, "/"),
},
{
"@type": "ListItem",
position: 2,
name: t("page-reports-metadata-title"),
item: normalizeUrlForJsonLd(locale, "/reports/"),
},
],
},
publisher: REFERENCE.ETHEREUM_FOUNDATION,
reviewedBy: REFERENCE.ETHEREUM_FOUNDATION,
mainEntity: { "@id": itemListId },
},
{
"@type": "ItemList",
"@id": itemListId,
name: t("page-reports-metadata-title"),
description: t("page-reports-metadata-description"),
numberOfItems: reports.length,
itemListOrder: "https://schema.org/ItemListOrderDescending",
itemListElement: reports.map((report, index) =>
reportSchema(report, index, locale, url)
),
},
],
}

return <PageJsonLD structuredData={jsonLd} />
}
Loading
Loading