Skip to content

Rebuild the explorer from scratch as a portfolio-first app - #827

Closed
adamsoffer wants to merge 14 commits into
livepeer:nextfrom
adamsoffer:claude/fervent-carson-qz38nu
Closed

adamsoffer wants to merge 14 commits into
livepeer:nextfrom
adamsoffer:claude/fervent-carson-qz38nu

Conversation

@adamsoffer

@adamsoffer adamsoffer commented Sep 29, 2026 •

Copy link
Copy Markdown
Collaborator

Description

A from-scratch rebuild of the Livepeer Explorer. The portfolio is the home view, the pages use the Livepeer Design System (shared with the Console), and the old pages router, Stitches and Apollo are replaced by Next.js 16 App Router, Tailwind v4, TanStack Query and wagmi/RainbowKit.

Each commit covers one area and typechecks on its own (the first only removes the old app), so reviewing commit by commit is the easiest way through.

Type of Change

  • feat: New feature
  • build: Build system or dependency changes
  • chore: Other changes

Changes Made

  • Portfolio: track any addresses (connected wallet, cold wallet, Safe, any ENS name) with stake, rewards, fees and network share per round, plus realised APR and a Needs attention list (missed reward calls, cut changes, ready withdrawals, Safe actions, open votes). Includes an earnings CSV priced at each reward call, and a prompt to delegate unstaked LPT.
  • Orchestrators: ranked by expected yield instead of stake, so new stake isn't steered to the biggest. Yield is rewards at today's cut plus fees, leaving out fees an orchestrator paid itself; raised cuts are flagged, newcomers are grouped separately, and ties go to the smaller orchestrator.
  • Staking: one dialog for delegate, move, unstake, restake and withdraw; acting for another address prompts you to connect it. Approve and bond go out as one batch inside the Safe app.
  • Governance: proposals and LIP polls with voting, plus creating polls and treasury proposals.
  • Also: gateway pages, a network overview with scrubbable KPIs, a searchable activity feed, ⌘K search, per-page share images, and redirects from old URLs.

Testing

  • Tested locally against the offline subgraph mock (scripts/mock/), with screenshots at desktop (light and dark) and mobile
  • Added/updated tests: portfolio maths, orchestrator ranking, paging, governance thresholds, CSV, prices
  • All tests passing (78), plus lint, typecheck and production build

Before merging (needs a real wallet and live data)

  • Send each staking and governance transaction with MetaMask, Rainbow and WalletConnect, and the Safe flows inside the Safe app
  • Compare the orchestrator APRs with on-chain pendingStake / pendingFees for 5–10 orchestrators
  • Check the new queries against the published subgraph, including the self-paid tickets query

Impact / Risk

Risk level: High (full replacement of the app)

Impacted areas: UI, data fetching, wallet and transactions, config

User impact: a new home view and navigation; old URLs redirect to their new pages.

Rollback plan: revert this PR's commit on main.

Additional Notes

  • New env vars (see .env.example): NEXT_PUBLIC_SUBGRAPH_API_KEY (restrict it to your domains), optional NEXT_PUBLIC_SUBGRAPH_DEPLOYMENT, SITE_URL, NEXT_PUBLIC_WALLET_CONNECT_PROJECT_ID, PINATA_JWT (poll creation), optional GITHUB_ACCESS_TOKEN.
  • Not ported: the Vercel Web Analytics delegation funnel (feat: instrument the delegation funnel with Vercel Web Analytics #809).
  • Build workaround: RainbowKit's Base Account wallet pulls in optional @x402/* modules, which Turbopack aliases to an empty stub.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Dh52qRhBrfkLKKAAGqPxYN


Generated by Claude Code

Deletes the pages-router app: Stitches styles, Apollo and its codegen,
and the hand-written components, hooks and layouts. Repository tooling
(CI, templates, husky, license, contributing docs) stays. The contract
ABIs are kept and move to lib/abis.

This commit doesn't build on its own; the next ones put the new app in
place.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dh52qRhBrfkLKKAAGqPxYN
New package.json and lockfile, TypeScript, ESLint, Jest and PostCSS
config, and the Dockerfile. Old URLs such as /accounts/:a/delegating
and /transcoders redirect to their new pages. RainbowKit's Base Account wallet lazily pulls
in optional @x402/* modules, so Turbopack aliases them to an empty stub.
AGENTS.md and CLAUDE.md hold the Next.js notes for coding agents.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dh52qRhBrfkLKKAAGqPxYN
Theme tokens for light, dark and system, the brand mark, buttons,
dialogs, tooltips, badges, sortable headers, page scaffolding and the
time-series chart, plus number and token formatting. Icons and the web
manifest are refreshed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dh52qRhBrfkLKKAAGqPxYN
A plain GraphQL client over The Graph's gateway (Studio URL without a
key), cursor paging that handles events sharing a timestamp, active-set
status from activation rounds, and queries for the network, orchestrators,
gateways, votes and accounts, wrapped in TanStack Query hooks.

lib/portfolio/compute.ts rebuilds stake, rewards and fees per round from
the cumulative reward and fee factors, so bonding and moving stake never
count as earnings. Orchestrator stats include realised APR, the yield at
today's cut and reward-call reliability. Tests cover the maths, paging,
activity status and search.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dh52qRhBrfkLKKAAGqPxYN
The portfolio is a list of addresses kept in the browser; connecting a
wallet adds its address, and any address or ENS name can be added and
renamed. Acting for an address that isn't connected is one "Connect
<name>" step, and the action resumes once that account connects.

One staking dialog handles delegate, stake more, move, unstake, restake
and withdrawals, including approval. Inside the Safe app, approve and bond
go out as one batch (EIP-5792), queued transactions show as sent to the
Safe, and a Safe's queued Livepeer actions are decoded locally.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dh52qRhBrfkLKKAAGqPxYN
A vertical sidebar with navigation, the wallet menu, theme switcher and
a round clock that celebrates when a new round starts; a top bar with a
drawer on phones; ⌘K search across orchestrators (by ENS name or
address), gateways, addresses, pages and theme; and error and not-found
pages.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dh52qRhBrfkLKKAAGqPxYN
Treasury proposals and LIP polls with quorum and quota thresholds, vote
tallies and voting. Creating a poll lists LIPs that are "Proposed" and
have no poll yet; the server pins the official LIP text to IPFS before
calling PollCreator.createPoll. A treasury proposal takes a markdown
description, a receiver (address or ENS) and an LPT amount checked
against the treasury and your voting power. Open votes feed the
portfolio's Needs attention.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dh52qRhBrfkLKKAAGqPxYN
The home view charts stake, rewards, fees and network share across your
addresses, with realised APR, projected earnings and pending
withdrawals. Delegations adapt to the width they get, withdrawing fees
says what it will withdraw, and unstaked LPT gets a prompt that opens
the delegate flow pre-filled. Needs attention flags missed reward calls,
cut changes, inactive orchestrators, ready withdrawals, Safe actions and
open votes.

The earnings CSV has one row per wallet per round, valued in USD at the
hour of the reward call from Coinbase's hourly candles, served through a
cached route.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dh52qRhBrfkLKKAAGqPxYN
The list defaults to what a delegator joining now can expect, rather
than stake, so new stake isn't steered to whoever already has the most:
rewards over the last 30 rounds (lowered to today's cut when it was
raised, and flagged) plus 90 days of fees at today's fee share, valued at
today's ETH/LPT price, leaving out fees an orchestrator paid itself.
Newcomers get their own group and near-ties go to the smaller
orchestrator. Profiles show yield, stake and fee charts, the last 90
reward calls, cut history and delegators.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dh52qRhBrfkLKKAAGqPxYN
Fees paid, deposit and reserve, deposit runway, and payouts by
orchestrator, flagging a gateway that pays its own orchestrator.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dh52qRhBrfkLKKAAGqPxYN
A round card with reward calls, LPT minted and fees; KPI tiles with
30-day sparklines you can scrub; history charts; and a paginated,
filterable activity feed searchable by address, ENS or transaction hash.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dh52qRhBrfkLKKAAGqPxYN
Orchestrator, gateway, poll and proposal pages draw their own share card
and title, e.g. "titan-node · 32% APR · 30/30 reward calls"; the rest of
the site uses a static image.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dh52qRhBrfkLKKAAGqPxYN
scripts/mock serves the queries from generated fixtures, with a
screenshot script for visual review. The README and .env.example cover
the new setup: the Graph API key, optional deployment pin, WalletConnect
and Pinata.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dh52qRhBrfkLKKAAGqPxYN
Copilot AI balanced review requested due to automatic review settings September 29, 2026 03:27
@vercel

vercel Bot commented Sep 29, 2026

Copy link
Copy Markdown
Contributor

@adamsoffer is attempting to deploy a commit to the Livepeer Foundation Team on Vercel.

A member of the Team first needs to authorize it.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

It is a high-risk full application replacement with pending live-wallet validation and unresolved subgraph configuration and ranking correctness issues.

Review effort: Balanced
Findings: 2 Medium severity

Open (2)
What changed in this PR

Rebuilds Livepeer Explorer around a portfolio-first Next.js App Router architecture, replacing the legacy Pages Router, Apollo, and Stitches stack.

Changes:

  • Adds portfolio, governance, staking, activity, and share-card infrastructure.
  • Introduces TanStack Query subgraph access, Tailwind UI primitives, and Safe support.
  • Removes legacy routes, APIs, GraphQL documents, components, and assets.
File Description
app/​** Adds App Router pages, APIs, metadata, and error handling.
components/​** Replaces legacy UI with portfolio, governance, staking, and shared components.
lib/​** Adds subgraph, governance, staking, search, and utility logic.
scripts/​mock/​README.md Documents the mock and screenshot harness.
Dockerfile Updates container build configuration.
.env.example Documents the new runtime configuration.
tsconfig.json Updates Next.js and import-path settings.
next-env.d.ts Updates generated App Router types.
postcss.config.mjs Enables Tailwind PostCSS processing.
eslint.config.mjs Removes obsolete exclusions.
public/​manifest.json Updates application metadata.
public/​icon.svg, app/​icon.svg Add the new application icon.
AGENTS.md, CLAUDE.md Add Next.js agent guidance.
pages/​**, queries/​**, apollo/​** Remove the legacy router and Apollo layer.
utils/​**, hooks/​** Remove superseded utilities and hooks.
public/​img/​**, styles/​globals.css Remove obsolete visual assets and styles.
lib/​api/​**, components/​legacy paths Remove replaced APIs, types, and UI components.
codegen.yml, @types/​custom.d.ts Remove obsolete GraphQL and asset typing configuration.
.prettierignore Removes exclusions for deleted generated content.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread Dockerfile
ARG NEXT_PUBLIC_NETWORK=ARBITRUM_ONE
ARG NEXT_PUBLIC_SUBGRAPH_ENDPOINT
ARG NEXT_PUBLIC_SUBGRAPH_API_KEY
ARG NEXT_PUBLIC_SUBGRAPH_ID
Comment thread lib/subgraph/network.ts
ids: transcoders.map((t) => t.id),
since: Math.floor(Date.now() / 1000) - 90 * 86400,
},
{ max: 10_000 }
@adamsoffer
adamsoffer changed the base branch from main to next September 29, 2026 03:33
@adamsoffer
adamsoffer force-pushed the claude/fervent-carson-qz38nu branch 2 times, most recently from 1723dbd to 107e352 Compare September 29, 2026 03:51
Replaces the Conventional Commits guidance with an area-prefix style:
the area of the app, then a short imperative summary. PR titles follow
it too, since PRs are squash-merged and the title becomes the commit
on main.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@vercel

vercel Bot commented Sep 29, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
explorer-arbitrum-one Canceled Canceled Sep 29, 2026 2:52pm UTC

Request Review

@adamsoffer

Copy link
Copy Markdown
Collaborator Author

Superseded by #828, which is the same 14 commits pushed to a branch in this repo so Vercel previews deploy without per-commit fork authorization.

This branch was successfully deployed

1 active deployment
Preview — c7ef0ea3 Deployed Sep 29, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants