Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
9ae571c
docs: add migration hub for Pyth Core to Pyth Pro upgrade
aditya520 May 18, 2026
2dba99c
feat(developer-hub): add site-wide migration banner
aditya520 May 18, 2026
b41d706
feat(developer-hub): data-driven Pyth Classic contract addresses page
aditya520 May 18, 2026
feed414
fix(migration-contracts): override stale chainid.network entry for Hy…
aditya520 May 18, 2026
f5442ef
feat(migration-contracts): add "don't see your chain" footer
aditya520 May 19, 2026
b473a9a
docs(migration): reframe as "Upgrading Pyth Core", drop Pyth Pro ment…
aditya520 May 20, 2026
a08c7d5
docs(migration): restructure flow around the API key decision
aditya520 May 20, 2026
620e56d
docs(migration) Core to Pro wordings update
aditya520 May 20, 2026
cfcfbc4
feat(docs) Fix the comparison table
aditya520 May 20, 2026
e0404f6
feat(developer-hub): scope migration banner to homepage + Pyth Core only
aditya520 May 20, 2026
9f6cf3f
docs(migration): rename to "upgraded Pyth Core Contract"
aditya520 May 20, 2026
4ee0254
feat(migration): branch-toggle wizard + reassurance opener
aditya520 May 20, 2026
db27d01
docs(migration): move under /price-feeds/core/
aditya520 May 20, 2026
41198bb
chore(developer-hub): auto-update llms.txt curated content
github-actions[bot] May 20, 2026
f1da19d
docs(upgrade): rename /core/migration -> /core/upgrade + sidebar accent
aditya520 May 20, 2026
7e9aeac
feat(upgrade): sidebar ribbon + MDX content polish
aditya520 May 20, 2026
0b4a122
feat(docs) Add How upgrade works
aditya520 May 20, 2026
3068140
chore(developer-hub): auto-update llms.txt curated content
github-actions[bot] May 20, 2026
8731acf
Update apps/developer-hub/content/docs/price-feeds/core/upgrade/index…
aditya520 May 20, 2026
3a824f6
chore(developer-hub): auto-update llms.txt curated content
github-actions[bot] May 20, 2026
6706e10
Apply suggestions from code review
aditya520 May 20, 2026
89f2c14
docs(upgrade): retitle to "Preparing for the Pyth Core upgrade"
aditya520 May 20, 2026
b9c6c3c
chore(developer-hub): auto-update llms.txt curated content
github-actions[bot] May 20, 2026
f913bc2
feat: add minor details in how it works
keyvankhademi May 20, 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
1 change: 1 addition & 0 deletions apps/developer-hub/content/docs/price-feeds/core/meta.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"pages": [
"getting-started",
"upgrade",
"---Tutorials---",
"create-your-first-pyth-app",
"---How-To Guides---",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
title: "Upgraded Pyth Core Contract Addresses"
description: "Per-chain addresses for the upgraded Pyth Core Contract."
full: true
---

import { Callout } from "fumadocs-ui/components/callout";
import MigrationContractsTable from "../../../../../src/components/MigrationContractsTable";

These are the **upgraded Pyth Core Contract** addresses on each chain. To upgrade your Pyth Core integration, swap your existing Pyth contract address for the one listed below for your chain. The interface is unchanged — no other code changes are needed.

See the [upgrade guide](/price-feeds/core/upgrade) for the full upgrade path.

## Mainnets

<MigrationContractsTable isMainnet={true} />

## Testnets

<MigrationContractsTable isMainnet={false} />

<Callout type="info">
**Don't see your chain?** We're adding chains regularly and can discuss
custom arrangements. [Contact the team →](mailto:contact@pyth.network)
</Callout>
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
---
title: How the Pyth Core upgrade works
description: A technical look at the signers, data flow, and contracts behind the upgrade.
full: true
---

The Pyth Core upgrade preserves the existing contract interface and Hermes API surface, so existing integrations work without code changes.
Only the signers and the source of the data change. This page explains the new architecture and how it works.

## Architecture

```mermaid
flowchart LR
R1[Router 1] --> H[Upgraded Hermes endpoint]
R2[Router 2] --> H
R3[Router 3] --> H
R4[Router 4] --> H
R5[Router 5] --> H
H --> C[Consumer]
C --> P[Upgraded Pyth Core Contract]
```

## Data flow

Each tick, routers take the latest aggregated prices from Pyth Pro and construct a Merkle tree using the same leaf format Pythnet uses for Pyth Core. Each router signs the Merkle root independently. The upgraded Hermes endpoint collects roots and price messages from all routers and serves the latest update — the signed root plus per-price Merkle proofs. It does this through the same HTTP and streaming endpoints as Hermes. Consumers fetch the update and submit it to the upgraded Pyth Core Contract, which verifies the router signatures meet quorum and then verifies each price against the root using its Merkle proof.

The shape of this flow mirrors Pyth Core. The difference is where the Merkle root comes from and who signs it: on the existing system, Pythnet produces the root and Wormhole guardians sign it; in the upgrade, the routers do both.

## Components

### Routers

Routers are the same routers in Pyth Pro. To learn more visit [insert link here].
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.

🔴 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.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.


Routers build a Merkle tree over the upgraded price aggregate each tick and sign the root. The leaf format matches Pythnet's exactly, which is what makes the resulting update payload byte-compatible with Pyth Core. Five routers, operated independently, each sign the root using the same signature scheme Wormhole guardians use on the existing system.

On the existing Pyth Core, Wormhole guardians observe a Merkle root produced on Pythnet and sign it. With the upgrade, the routers both produce and sign the root.

### Upgraded Hermes 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.

### Upgraded Pyth Core Contract

New contracts are deployed at new addresses on the same chains as the existing Pyth Core contracts. They expose the same ABI, so existing integrations work without code changes. The contracts are configured to accept signatures from the five routers with a **3/5** quorum, compared to the existing system's **13/19** Wormhole guardian quorum.

## What this means for consumers

Upgrading your Pyth Core integration requires two changes: point the client at the upgraded Hermes endpoint, and use the upgraded Pyth Core Contract address in place of the existing Pyth Core contract address. SDK code, payload parsing, and update submission all stay the same.

See the [upgrade guide](/price-feeds/core/upgrade) for the full upgrade path, or the [upgraded Pyth Core Contract addresses](/price-feeds/core/upgrade/contracts) for per-chain addresses.
238 changes: 238 additions & 0 deletions apps/developer-hub/content/docs/price-feeds/core/upgrade/index.mdx
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.

🚩 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.

Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
---
title: "Preparing for the Pyth Core upgrade"
description: "Everything you need to upgrade your Pyth Core integration before July 31, 2026."
icon: RocketLaunch
full: true
---

import { Button } from "@pythnetwork/component-library/Button";
import { Accordion, Accordions } from "fumadocs-ui/components/accordion";
import { Callout } from "fumadocs-ui/components/callout";
import { Card, Cards } from "fumadocs-ui/components/card";
import { Step, Steps } from "fumadocs-ui/components/steps";
import { Tab, Tabs } from "fumadocs-ui/components/tabs";
import {
ActiveStepHighlighter,
BranchSection,
BranchToggle,
} from "../../../../../src/components/MigrationFlow";

<ActiveStepHighlighter />

## What's changing

Pyth Network is upgrading [Pyth Core](/price-feeds/core) on **July 31, 2026**.
This upgrade replaces Pyth Core's underlying data infrastructure with an improved version, enabling new features:

- Higher-frequency updates
- Customizable channels
- Access to Pyth Terminal

Your existing integration keeps working: the on-chain Pyth contract is upgraded by the Pyth DAO on July 31, and [Hermes](/api-reference/pyth-core/hermes) requests are redirected to the upgraded backend automatically.
The one new requirement is authentication on Hermes — every Hermes user needs a Pyth API Key by **July 31**.

For a walkthrough of the signers, data flow, and contracts behind the upgrade, see [How the Pyth Core upgrade works](/price-feeds/core/upgrade/how-it-works).

<Callout type="warn">
**All Hermes users need a Pyth API Key by July 31, 2026** — the upgraded
Hermes endpoint requires authentication, even for users who wait for the
automatic upgrade. [Register at Pyth Terminal →](https://pythdata.app/signup)
</Callout>

## Does this apply to you?

- **Your app calls [`hermes.pyth.network`](https://hermes.pyth.network/docs/)?**
Get a Pyth API Key in Step 1.
- **You use [Pyth Core contracts](/price-feeds/core/contract-addresses) on-chain?**
Choose: swap addresses now, or wait for the automatic upgrade (see the decision section below).
- **You only use a protocol that already integrates Pyth?**
No action needed from your side.

## Your upgrade path



### Step 1: Get a Pyth API Key

Required for everyone who calls Hermes.
Sign up at Pyth Terminal: a free trial is included, paid plans cover ongoing use.

<Button
href="https://pythdata.app/signup"
rel="noopener noreferrer"
size="md"
target="_blank"
variant="primary"
>
Sign up at Pyth Terminal
</Button>

### Step 2: Upgrade now or wait for automatic?

After Step 1, choose how and when to move to the upgraded infrastructure. Your choice is saved in the URL so you can share or bookmark a specific path.

<BranchToggle />

| | Upgrade now (recommended) | Wait for automatic |
| ---------------- | ------------------------------------------ | -------------------------------------------------------------------- |
| Timing | You choose | July 31, 2026 |
| Downtime | Up to you | Brief, during the switch |
| Hermes endpoint | Switch to the upgraded URL now | Start using `hermes.pyth.network` with an API key before the cutover |
| Contract address | You swap to the upgraded Pyth Core Contract | DAO upgrades the current Pyth Core Contract for you |

<BranchSection path="now">
**Upgrade now (recommended)**: Continue with Steps 2 and 3 below. You move to the [upgraded Hermes endpoint](https://pyth.dourolabs.app/hermes) and the [upgraded Pyth Core Contract](/price-feeds/core/upgrade/contracts) today, on your own schedule, with zero downtime.
</BranchSection>

<BranchSection path="wait">
**Wait for automatic**: You're done after Step 1. On July 31, the Pyth DAO upgrades your contract and `hermes.pyth.network` starts requiring authentication. You'll need to push a code change adding the `Authorization: Bearer $PYTH_API_KEY` header at that point. For a safer rollout, start using the authenticated Hermes API (`https://pyth.dourolabs.app/hermes`) before cutover as a fallback path. Plan a deploy around the cutover.
</BranchSection>

<BranchSection path="now">

## If you're upgrading early

<Steps>
<Step>

### Move your Hermes calls to the upgraded endpoint

Switch your Hermes base URL from `hermes.pyth.network` to `pyth.dourolabs.app/hermes` and add your API key as a bearer token. The two URLs serve the same data today. The upgraded endpoint requires authentication.

<Tabs items={["curl", "TypeScript SDK"]}>
<Tab value="curl">

```diff
- url: "https://hermes.pyth.network"
+ url: "https://pyth.dourolabs.app/hermes"
+ Authorization: "Bearer $PYTH_API_KEY"
```

</Tab>
<Tab value="TypeScript SDK">

```ts
import { HermesClient } from "@pythnetwork/hermes-client";

const client = new HermesClient("https://pyth.dourolabs.app/hermes", {
headers: {
Authorization: `Bearer ${process.env.PYTH_API_KEY}`,
},
});
```

</Tab>
</Tabs>

<Callout type="info">
**Most resilient: use both URLs as primary + fallback.** Keeps you live
through the July 31 cutover regardless of which endpoint is reachable at
any moment.

```ts
const primary = new HermesClient("https://pyth.dourolabs.app/hermes", {
headers: { Authorization: `Bearer ${process.env.PYTH_API_KEY}` },
});
const fallback = new HermesClient("https://hermes.pyth.network");

async function getLatestPriceUpdates(ids: string[]) {
try {
return await primary.getLatestPriceUpdates(ids);
} catch {
return await fallback.getLatestPriceUpdates(ids);
}
}
```
</Callout>

Routes and response shapes are unchanged.
The upgraded endpoint is a drop-in replacement. See the [Hermes API reference](https://pyth.dourolabs.app/docs/?urls.primaryName=Hermes+API#/) for the full surface.

</Step>
<Step>

### Swap your contract address

Swap your existing Pyth contract address for the [upgraded Pyth Core Contract](/price-feeds/core/upgrade/contracts) on your chain. The upgraded Pyth Core Contract preserves the Pyth Core interface. No other code changes are needed.

View all upgraded [Pyth Core Contract addresses](/price-feeds/core/upgrade/contracts).

</Step>
</Steps>

</BranchSection>

## Chain support

Pyth Core will be supported on the chains listed on the [upgraded Pyth Core Contract addresses page](/price-feeds/core/upgrade/contracts). If your chain isn't listed, [contact the team](#get-help) — additional support is available by custom arrangement.

### Feed support

Nearly all current Pyth Core feeds remain available after the upgrade, with new ones added. Look up your specific feeds on the [feed explorer](https://pythdata.app/explore). If a feed you depend on isn't listed, [contact the team](#get-help).

## FAQ

<Accordions type="single">
<Accordion title="What happens if I do nothing?">
On July 31, 2026, the Pyth DAO upgrades your contract for you and `hermes.pyth.network` starts requiring authentication. Two things you still have to do:

1. Have a Pyth API Key (Step 1) by that date.
2. Push a code change adding `Authorization: Bearer $PYTH_API_KEY` to your Hermes requests, around the cutover. Until that deploy lands, Hermes calls will fail.

Most users avoid this risk by upgrading early (see Steps 2 and 3) and switching to the upgraded Hermes endpoint, which already accepts the bearer header today.
</Accordion>
<Accordion title="Will my existing code break?">
On-chain code is fine: the upgrade is fully backward-compatible with the existing Pyth Core interface via the upgraded Pyth Core Contract.

Hermes code breaks at the cutover *if* your client is still pointed at `hermes.pyth.network` without a bearer header. Either upgrade early (Step 2) or plan a deploy around July 31 to add the header.
</Accordion>
<Accordion title="When exactly does Hermes redirect?">
On July 31, 2026. Exact switch timing is announced closer to the date. From that point, `hermes.pyth.network` serves the upgraded data and requires bearer authentication — unauthenticated requests will be rejected.
</Accordion>
<Accordion title="Can I test before upgrading?">
Yes. The upgraded endpoint (`pyth.dourolabs.app/hermes`) and the upgraded Pyth Core Contract are both available on testnets today. See the chain support section above for testnet contract addresses.
</Accordion>
<Accordion title="Will it cost me more?">
Yes. The upgrade introduces a subscription-based plan for ongoing Hermes access. A free trial is included on signup; paid plans cover continued use. Custom plans are available — [contact the team](#get-help). This is the most significant change for many Pyth Core users.
</Accordion>
<Accordion title="What if my chain isn't supported?">
Contact the team. Several chains are in active discussion and may be supported by July 31. For others, custom arrangements are possible.
</Accordion>
<Accordion title="Are all my feeds available after the upgrade?">
Nearly all current Pyth Core feeds remain available after the upgrade, with new ones added. Look up your specific feeds on the [feed explorer](https://pythdata.app/explore). If a feed you depend on isn't listed, [contact the team](#get-help).
</Accordion>
<Accordion title="I read prices on-chain only (push feeds, no Hermes) — do I need an API key?">
No. The API key is only required for Hermes (REST/SSE) requests. If your integration reads prices directly from the Pyth contract on-chain and never calls Hermes, you don't need to register. Your contract will be upgraded automatically on July 31, or you can swap it early (Step 3).
</Accordion>
<Accordion title="My code uses the Hermes REST/SSE API directly — what changes for me?">
Routes and response shapes are unchanged — the upgraded endpoint is a drop-in replacement. The differences are *which URL* you call and *whether you send a bearer header*:

- **Upgrade early (recommended):** switch your base URL to `pyth.dourolabs.app/hermes` and add `Authorization: Bearer $PYTH_API_KEY` today. The data is identical; only auth changes.
- **Wait:** stay on `hermes.pyth.network` today (unauthenticated). On July 31, push a deploy that adds the bearer header on the same URL.

See the [Hermes API reference](https://pyth.dourolabs.app/docs/?urls.primaryName=Hermes+API#/) for the full surface.
</Accordion>
</Accordions>

## Get help

<Cards>
<Card
title="Technical questions"
description="Public dev Telegram. Answers get reused — fastest path to engineers."
href="https://t.me/Pyth_Network"
external
/>
<Card
title="Sales contact"
description="Plans, chain support, custom arrangements."
href="mailto:contact@pyth.network"
external
/>
<Card
title="Production incidents"
description="Existing escalation path for paying customers."
href="mailto:contact@pyth.network"
external
/>
</Cards>
2 changes: 1 addition & 1 deletion apps/developer-hub/next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ const config = {
},

{
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?$)).*)`,
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.

🟡 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.

Suggested change
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?$)).*)`,
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

destination: "/price-feeds/core/:path",
permanent: true,
},
Expand Down
2 changes: 2 additions & 0 deletions apps/developer-hub/src/app/(docs)/[section]/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import Link from "next/link";
import type { ReactNode } from "react";

import { docsOptions } from "../../../config/layout.config";
import { MigrationBanner } from "../../../components/MigrationBanner";

export default async function Layout({
children,
Expand Down Expand Up @@ -36,6 +37,7 @@ export default async function Layout({
</span>
</Banner>
)}
{section === "price-feeds" && <MigrationBanner />}
<DocsLayout {...docsOptions}>{children}</DocsLayout>
</>
);
Expand Down
8 changes: 7 additions & 1 deletion apps/developer-hub/src/app/(homepage)/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import { HomeLayout } from "fumadocs-ui/layouts/home";
import type { ReactNode } from "react";

import { MigrationBanner } from "../../components/MigrationBanner";
import { baseOptions } from "../../config/layout.config";

export default function Layout({ children }: { children: ReactNode }) {
return <HomeLayout {...baseOptions}>{children}</HomeLayout>;
return (
<>
<MigrationBanner />
<HomeLayout {...baseOptions}>{children}</HomeLayout>
</>
);
}
Loading