feat: add minor details in how it works#3739
Conversation
Adds /price-feeds/migration — a guide for existing Pyth Core integrators to upgrade to Pyth Pro before the July 31, 2026 merge. Covers the three required updates (API key, contract address, Hermes endpoint), chain and feed support, and FAQ for common questions including auto-migration behavior. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Surfaces the Pyth Core → Pyth Pro merge (July 31, 2026) on every page via the fumadocs `<Banner>` component, mounted inside FumadocsRootProvider in the Root layout. Clicking navigates to /price-feeds/migration; the dismiss state persists across sessions in localStorage under the banner id `pyth-core-pro-migration-2026-07-31`. Styled with `bg-violet-950` to coordinate with the link/primary purple without competing with the violet CTAs on content pages. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds /price-feeds/migration/contracts — the page Step 2 of the migration hub links to. Sources its data live from the contract_manager workspace package, filtering EvmPriceFeedContracts.json for entries tagged `deploymentType: "lazer-prod"` (the Pyth Pro–compatible Pyth Core deployments). Mirrors the existing LazerTable pattern for Pyth Pro contracts: - Async server component, joins contract entries with EvmChains.json for mainnet/networkId, augments with chainid.network for pretty names and block explorer URLs, falls back to a humanized chain id when upstream has no entry. - Per-chain name/explorer overrides in `deployments-config.ts` for chains the upstream registry doesn't cover well (Tempo, MegaETH, Sonic Blaze Testnet). - Two tables on the page (Mainnets / Testnets); the same component is reused with the `isMainnet` prop. Also exposes `evmPriceFeedContracts` and `EvmPriceFeedContractEntry` from `@pythnetwork/contract-manager/utils/utils` so the docs (and any other consumer) can iterate the price-feed contracts array directly. Previously the file was imported only for the `getEvmPriceFeedContractAddress(chainId)` lookup helper. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…perEVM chainid.network has a legacy "Wanchain Testnet" entry occupying network ID 999, which is now Hyperliquid EVM Mainnet. Without an override the mainnets table rendered our Hyperliquid contract as "Wanchain Testnet". Override 999 → "HyperEVM" with the hyperevmscan.io explorer. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
A subtle Callout at the bottom of /price-feeds/migration/contracts that routes unsupported-chain users to contact@pyth.network — matches the "unsupported chain" intercept pattern from the migration hub's chain support section. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ions Reframes the migration narrative to focus on Pyth Core being upgraded (its underlying data infrastructure is replaced with an improved version), rather than "becoming Pyth Pro." Pyth Pro stays as a separate product elsewhere in the site, but the upgrade story is told purely as a Pyth Core change. Migration page (`/price-feeds/migration`): - Page title: "Upgrading to Pyth Pro" → "Upgrading Pyth Core" - Section 1 rewritten to describe the upgrade without naming Pyth Pro; the infrastructure is described as "improved," with the new features surfaced directly (higher-frequency updates, customizable channels, Pyth Terminal access). - Step 1 "Get your Pyth Pro API key" → "Get your Pyth API Key" - Step 3 "Pyth Pro endpoint" → "upgraded Hermes endpoint"; env var example `PYTH_PRO_KEY` → `PYTH_API_KEY` - Comparison table intro: "Both paths land on Pyth Pro" → "Both paths reach the upgraded Pyth Core" - Chain support intro: "Pyth Pro is live on these chains" → "Pyth Core will be supported on these chains after the upgrade" - Feed support: drops "Pyth Pro feed explorer" naming; the link goes to the same explorer but is described as "the feed explorer" - FAQ rewrites: every "Pyth Pro" mention removed; "automatic migration" → "automatic upgrade" in user-facing copy Contracts page (`/price-feeds/migration/contracts`): - Description and intro reworded to drop "Pyth Pro" — talks about upgrading the Pyth Core integration instead. Site-wide banner (`Root/index.tsx`): - Copy: "Pyth Core is upgrading to Pyth Pro on July 31, 2026..." → "Pyth Core is upgrading on July 31, 2026..." API key naming locked in as "Pyth API Key" (capitalized). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Restructures the upgrade path so the decision point (upgrade early vs wait for automatic) sits after the one universal step instead of being treated as a parallel comparison at the bottom of the page. New flow: - Step 1 (everyone who calls Hermes): get a Pyth API Key and add a Bearer header. Hermes base URL stays `hermes.pyth.network` — no URL change needed since the upgraded backend auto-redirects on July 31. - Decision section with a slim 4-row comparison table: Timing, Downtime, Contract address, Action. "Upgrade now (recommended)" is preserved; "Wait for automatic" gets equal prose treatment. - Steps 2 + 3 (early upgraders only): swap contract to the Pyth Classic Contract; point Hermes at the upgraded endpoint (`pyth.dourolabs.app/hermes`). The URL change now only appears in the early-upgrade section. Other adjustments: - "Does this apply to you?" explicitly branches into Hermes users, on-chain Pyth Core contract users, and downstream-protocol consumers. - New FAQ entry for push-feed-only integrators clarifying they don't need an API key. - Step 1's code example switched from a diff to plain `curl` / TS so it doesn't imply a URL swap. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Previously the banner was mounted in the global Root layout and shipped on every page, including Pyth Pro, Entropy, Express Relay, and other docs sections where the migration narrative doesn't apply (and confuses Pyth Pro users). Move the banner out of Root and into the same conditional mount points the Entropy banner uses, following the established pattern: - `(homepage)/layout.tsx` — mounted on the landing page. - `(docs)/[section]/layout.tsx` — mounted when `section === "price-feeds"`, next to the existing `section === "entropy"` rainbow banner. Because `section === "price-feeds"` matches Pyth Core, Pyth Pro, and the migration pages, the banner component itself runs a client-side `usePathname` filter so it only renders on: - `/` - `/price-feeds/core/*` - `/price-feeds/migration/*` …and returns null on `/price-feeds/pro/*`. Banner copy and styling are unchanged. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drops the "Pyth Classic Contract" name in favor of "upgraded Pyth Core Contract" — clearer that this is the same Pyth Core, post-upgrade, not a separate product. Updates contracts page title/body and the contracts table column header. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds a lightweight, progressive-enhancement walkthrough to the upgrade page instead of a step-gated wizard: - BranchToggle: two cards select "upgrade now" vs "wait" and persist the choice in ?path= via nuqs (shareable/bookmarkable). - BranchSection: wraps content so the non-selected branch fades to 0.55 opacity but stays in DOM (preserves SEO/indexing and lets readers still scan both paths). - ActiveStepHighlighter: reads ?step= on mount, scrolls the target into view, and applies a violet halo for ~4s via the .migration-step-active rule in global.css. Also adds a reassurance Callout near the top with the page's terminology dictionary (Pyth API Key, upgraded Pyth Core Contract, upgraded Hermes endpoint), and trims the "Chain support" section to point at the contracts page rather than hardcoding chain lists. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The migration is a Pyth Core upgrade — keeping it at /price-feeds/migration (sibling to core/ and pro/) read as "the bridge between the two products," which is exactly the confusion the recently-scoped banner aimed to avoid. - File move: content/docs/price-feeds/migration/* → content/docs/price-feeds/core/migration/* - meta.json: drop "migration" from price-feeds, add to core right after "getting-started" (high-priority, time-sensitive) - MigrationBanner: drop the now-defunct /price-feeds/migration route check; update the CTA href to /price-feeds/core/migration - Homepage feature card: update CTA href - Internal cross-links updated (the upgrade page <-> contracts page) No redirects — not published yet. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Updated curated content based on documentation changes.
URL rename matches the page's framing ("Upgrading Pyth Core") and
reads better than "migration" in the sidebar.
- File move: content/docs/price-feeds/core/migration/* ->
content/docs/price-feeds/core/upgrade/*
- meta.json: "migration" -> "upgrade" in core/
- Internal links updated (upgrade page <-> contracts page)
- MigrationBanner CTA + homepage feature-card CTA updated
Sidebar visibility:
- icon: RocketLaunch on the upgrade page frontmatter (already
registered in src/lib/source.ts)
- Persistent violet accent via global.css targeting
a[data-active="false"][href="/price-feeds/core/upgrade"].
Drops when the user is on the upgrade page itself (fumadocs
already highlights active entries in primary).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Sidebar: solid violet ribbon for the Pyth Core upgrade entry
via global.css. Targets a[data-active="false"][href="..."] so
it only applies on non-active pages (fumadocs already styles
the active state). White text + currentColor icon.
- MDX polish on the upgrade page:
* Drop the "What you should know going in" reassurance Callout
in favor of a tighter top-of-page.
* Convert "Does this apply to you?" to a bullet list.
* Promote inline ### Step 1 / ### Step 2 headings instead of
fumadocs <Steps> wrapper for the universal first step.
* Tighten comparison table wording and branch sections; add
inline contract-page link in the Wait path.
- BranchToggle: trim the "Wait for automatic" caption.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Updated curated content based on documentation changes.
….mdx Co-authored-by: guibescos <59208140+guibescos@users.noreply.github.com>
Updated curated content based on documentation changes.
Co-authored-by: guibescos <59208140+guibescos@users.noreply.github.com>
Per PR review feedback (#3712): Pyth Core is being upgraded by the Pyth DAO, not by the reader, so "Preparing for the Pyth Core upgrade" is a more accurate framing for the upgrade-hub landing page. Also updates the site-wide migration banner CTA from "see what changes" to "see how to prepare" so the banner reads as an action prompt rather than a passive announcement. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Updated curated content based on documentation changes.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
5 Skipped Deployments
|
|
|
||
| ### Routers | ||
|
|
||
| Routers are the same routers in Pyth Pro. To learn more visit [insert link here]. |
There was a problem hiding this comment.
🔴 Placeholder text "[insert link here]" shipped in production documentation
Line 33 contains the literal placeholder [insert link here] which would be rendered as-is to users visiting the documentation site. This is clearly an unfinished TODO that should either be replaced with an actual link (e.g., to a Pyth Pro routers page) or the sentence should be removed until a proper link is available.
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
Pull request overview
This PR updates the Developer Hub documentation for the Pyth Core upgrade by adding a brief note about routers and clarifying upgraded Hermes endpoint requirements.
Changes:
- Adds a new sentence in the “Routers” section intended to link to more information (currently a placeholder).
- Splits the upgraded Hermes description into shorter lines and notes that an API key is required.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
|
||
| ### Routers | ||
|
|
||
| Routers are the same routers in Pyth Pro. To learn more visit [insert link here]. |
| The upgraded Hermes endpoint exposes the same API as traditional Hermes — the same endpoints and the same response shapes — at a different URL. It collects signed roots and price messages from all five routers and serves the latest update with the signed root and per-price Merkle proofs. Existing Hermes clients work unchanged when pointed at the upgraded endpoint. | ||
| The upgraded Hermes endpoint exposes the same API as traditional Hermes — the same endpoints and the same response shapes — at a different URL. It collects signed roots and price messages from all five routers and serves the latest update with the signed root and per-price Merkle proofs. | ||
| Existing Hermes clients work unchanged when pointed at the upgraded endpoint. | ||
| Having an API key is required for upgraded Hermes. |
8248348 to
74dcb26
Compare
There was a problem hiding this comment.
🚩 Missing meta.json for upgrade subdirectory
The new content/docs/price-feeds/core/upgrade/ directory has three pages (index.mdx, contracts.mdx, how-it-works.mdx) but no meta.json file. Other sibling subdirectories under core/ (e.g., how-pyth-works/, use-real-time-data/, troubleshoot/) all have meta.json files that define page ordering in the sidebar. Without one, fumadocs will auto-sort the upgrade sub-pages alphabetically, which may produce an unexpected sidebar order (contracts → how-it-works → index) rather than the likely intended (index → how-it-works → contracts). This isn't a breaking issue — fumadocs handles missing meta.json gracefully — but it's inconsistent with established patterns per the AGENTS.md guidance.
Was this helpful? React with 👍 or 👎 to provide feedback.
| const CONTENT = `\` | ||
| function () { return (\`# Pyth Core — Quick Start |
There was a problem hiding this comment.
🔴 LLM endpoint content corrupted with JavaScript wrapper text
The CONTENT template literal in apps/developer-hub/src/app/llms-price-feeds-core.txt/route.ts was modified to wrap the entire markdown content in spurious JavaScript syntax. The string now starts with a backtick + newline + function () { return (\`` and ends with `) };. When the GET` handler serves this content, LLM consumers will receive literal garbage text:
What the endpoint now returns
`
function () { return (`# Pyth Core — Quick Start
...
`) };
The previous version cleanly started with # Pyth Core — Quick Start.
This completely breaks the /llms-price-feeds-core.txt endpoint for any LLM or AI agent that consumes it, as it will parse the JavaScript wrapper as part of the content.
| const CONTENT = `\` | |
| function () { return (\`# Pyth Core — Quick Start | |
| const CONTENT = `# Pyth Core — Quick Start | |
Was this helpful? React with 👍 or 👎 to provide feedback.
| - https://docs.pyth.network/price-feeds/core/price-feed-ids.mdx — Complete feed catalog | ||
| - https://docs.pyth.network/price-feeds/core/create-your-first-pyth-app/index.mdx — Step-by-step EVM tutorial | ||
| - https://docs.pyth.network/price-feeds/core/migrate-an-app-to-pyth/chainlink.mdx — Chainlink migration guide | ||
| \`) }; |
There was a problem hiding this comment.
🔴 Closing JavaScript wrapper text appended to LLM endpoint content
The closing counterpart to BUG-0001: the end of the CONTENT string at apps/developer-hub/src/app/llms-price-feeds-core.txt/route.ts:205 appends literal \) };` text to the LLM-facing output. This must be removed along with the opening wrapper (lines 5-6) to restore the clean markdown output.
| \`) }; |
Was this helpful? React with 👍 or 👎 to provide feedback.
|
|
||
| ### EVM Mainnet | ||
| - Ethereum: 0x4305FB66699C3B2702D4d05CF36551390A4c69C6 | ||
| - Ethereum: **New Address Here** |
There was a problem hiding this comment.
🔴 Placeholder "New Address Here" shipped in LLM-facing content
The Ethereum contract address was replaced with the placeholder **New Address Here** at apps/developer-hub/src/app/llms-price-feeds-core.txt/route.ts:104. This is clearly unfinished — LLM consumers and AI agents relying on this endpoint for Ethereum's Pyth contract address will receive a non-functional placeholder instead of an actual address. The previous value was 0x4305FB66699C3B2702D4d05CF36551390A4c69C6.
Prompt for agents
The Ethereum contract address on line 104 of apps/developer-hub/src/app/llms-price-feeds-core.txt/route.ts was replaced with the placeholder string "**New Address Here**". This needs to be replaced with the actual upgraded Pyth Core contract address for Ethereum mainnet. If the upgraded address is not yet known, revert to the previous address (0x4305FB66699C3B2702D4d05CF36551390A4c69C6) with a TODO comment, or remove the Ethereum entry until the address is finalized.
Was this helpful? React with 👍 or 👎 to provide feedback.
|
|
||
| { | ||
| source: String.raw`/price-feeds/:path((?!core(?:/|$|\.mdx?$)|pro(?:/|$|\.mdx?$)|hip-3-service(?:/|$|\.mdx?$)).*)`, | ||
| source: String.raw`/price-feeds/:path((?!core(?:/|$|\.mdx?$)|pro(?:/|$|\.mdx?$)|hip-3-service(?:/|$|\.mdx?$)|migration(?:/|$|\.mdx?$)).*)`, |
There was a problem hiding this comment.
🟡 Redirect exclusion uses migration but the route is upgrade
The catch-all redirect regex in apps/developer-hub/next.config.js:261 was updated to exclude migration from being redirected to /price-feeds/core/, but the actual new route is /price-feeds/core/upgrade (not /price-feeds/migration). The migration exclusion is dead code — it protects a non-existent path. While the /price-feeds/core/upgrade route works correctly because core is already excluded, the unnecessary migration exclusion suggests a naming mistake and adds confusion for future maintainers.
| source: String.raw`/price-feeds/:path((?!core(?:/|$|\.mdx?$)|pro(?:/|$|\.mdx?$)|hip-3-service(?:/|$|\.mdx?$)|migration(?:/|$|\.mdx?$)).*)`, | |
| source: String.raw`/price-feeds/:path((?!core(?:/|$|\.mdx?$)|pro(?:/|$|\.mdx?$)|hip-3-service(?:/|$|\.mdx?$)).*)`, | |
Was this helpful? React with 👍 or 👎 to provide feedback.
| if ( | ||
| !("deploymentType" in contract) || | ||
| contract.deploymentType !== "lazer-prod" | ||
| ) { | ||
| continue; |
There was a problem hiding this comment.
🚩 MigrationContractsTable filters by "lazer-prod" which has no matching entries
The buildDeployments function at apps/developer-hub/src/components/MigrationContractsTable/index.tsx:54-58 filters evmPriceFeedContracts for entries with deploymentType === "lazer-prod". However, the current contract_manager/src/store/contracts/EvmPriceFeedContracts.json contains only "pro-compatible-production" as deployment types — no entries with "lazer-prod" exist. This means both the mainnet and testnet tables will always render "No contracts published yet for this network type." This may be intentional staging (the contracts page is ready before data is populated), but it could also indicate a naming mismatch between the expected deployment type and the actual data. Worth confirming with the author whether "lazer-prod" is the intended future value or if "pro-compatible-production" should be used instead.
Was this helpful? React with 👍 or 👎 to provide feedback.
Summary
Rationale
How has this been tested?