Feed updates
Equity.US.VXV6removedCommodities.RSN7/UScwent liveCommodities.CLLX6/USDremovedCrypto.PRL/USDwent liveCommodities.LIZ6/CNYaddedCommodities.LIX6/CNYaddedCommodities.WTIZ7/USDaddedCommodities.WTIX7/USDaddedCommodities.WTIV7/USDaddedCommodities.WTIU7/USDaddedCommodities.WTIQ7/USDaddedCommodities.WTIN7/USDaddedCommodities.WTIM7/USDaddedCommodities.WTIK7/USDadded
View all
Developer Hub

Use Prices on EVM Chains

Steps to verify prices on EVM Chains

This guide covers steps to verify prices on EVM Chains. Choose a Contract explains which to use.

Pyth Pro

Integrating with Pyth Pro in smart contracts is a three-step process:

  1. Use Pyth Lazer SDK in EVM smart contracts to parse the price updates.
  2. Subscribe to Pyth Pro websocket to receive price updates on backend or frontend.
  3. Include the price updates into the smart contract transactions.

Use Pyth Lazer SDK in smart contracts

Pyth Pro provides a Solidity SDK, which allows applications to parse the price updates.

forge install pyth-network/pyth-crosschain

Add the following remappings to remappings.txt. The last two point at the OpenZeppelin libraries the SDK imports:

pyth-lazer-sdk/=lib/pyth-crosschain/lazer/contracts/evm/src/
@openzeppelin/contracts-upgradeable/=lib/pyth-crosschain/lazer/contracts/evm/lib/openzeppelin-contracts-upgradeable/contracts/
@openzeppelin/contracts/=lib/pyth-crosschain/lazer/contracts/evm/lib/openzeppelin-contracts/contracts/

Once the SDK is installed, one can import the sdk into smart contracts:

import { PythLazer } from "pyth-lazer-sdk/PythLazer.sol";
import { PythLazerLib } from "pyth-lazer-sdk/PythLazerLib.sol";
import { PythLazerStructs } from "pyth-lazer-sdk/PythLazerStructs.sol";

After importing the SDK, initialize the PythLazer contract and set up state varables to store prices and timestamps:

contract ExampleConsumer {
  // Example state.
  PythLazer pythLazer;
  int64 public price;
  uint64 public timestamp;

  //...

  constructor(address pythLazerAddress) {
    pythLazer = PythLazer(pythLazerAddress);
  }
}

Add an argument of type bytes calldata to the method which will receive the price update:

function updatePrice(bytes calldata priceUpdate) public payable {
  uint256 verification_fee = pythLazer.verification_fee();
  (bytes memory payload, ) = pythLazer.verifyUpdate{ value: verification_fee }(priceUpdate);
  //...
}

The verifyUpdate function will verify the price update and return the payload and the address of the signer. This call takes a fee which can be queried from verification_fee() function and passed to the verifyUpdate call. This fee is used to cover the cost of verifying the price update.

This SDK provides parsePayloadHeader method to retrieve the values from the payload header.

(uint64 _timestamp, PythLazerStructs.Channel channel, uint8 feedsLen, uint16 pos) = PythLazerLib.parsePayloadHeader(payload);

This method returns:

  • _timestamp: The timestamp of the price update.
  • channel: The channel of the price update.
  • feedsLen: The number of feeds in the price update.
  • pos: The cursor position of the payload.

One can iterate over all the feeds and properties present within the price update, modifying the state variables as necessary.

Here is an example of how to iterate over the feeds and properties:

for (uint8 i = 0; i < feedsLen; i++) {
    uint32 feedId;
    uint8 num_properties;
    (feedId, num_properties, pos) = PythLazerLib.parseFeedHeader(payload, pos);
    for (uint8 j = 0; j < num_properties; j++) {
        PythLazerStructs.PriceFeedProperty property;
        (property, pos) = PythLazerLib.parseFeedProperty(payload, pos);
        if (property == PythLazerStructs.PriceFeedProperty.Price) {
            int64 _price;
            (_price, pos) = PythLazerLib.parseFeedValueInt64(payload, pos);
            if (feedId == 2 && _timestamp > timestamp) {
                price = _price;
                timestamp = _timestamp;
            }
        } else if (property == PythLazerStructs.PriceFeedProperty.BestBidPrice) {
            int64 _price;
            (_price, pos) = PythLazerLib.parseFeedValueInt64(payload, pos);
        } else if (property == PythLazerStructs.PriceFeedProperty.BestAskPrice) {
            int64 _price;
            (_price, pos) = PythLazerLib.parseFeedValueInt64(payload, pos);
        } else {
            revert("unknown property");
        }
    }
}

Make sure to pass the pos variable to every parsing call and assign the returned pos value to the same variable. Failure to do so will cause incorrect parsing results.

When calling these parse functions, you must not skip price feeds or properties. Every parsing function will modify your pos variable, so skipping a call of parseFeedHeader, parseFeedProperty, or parseFeedValueInt64 will lead to incorrect parsing results. Keep in mind that you can customize the set of price feeds and properties when requesting price updates via WebSocket. This will be explained in the next step.

Subscribe to Pyth Pro to receive Price Updates

Pyth Pro provides a websocket endpoint to receive price updates. Moreover, Pyth Pro also provides a Typescript SDK to subscribe to the websocket endpoint.

Consult How to subscribe to prices for a complete step-by-step guide.

Include the price updates into smart contract transactions

Now that you have the price updates, and your smart contract is able to parse the price updates, you can include the price updates into the smart contract transactions by passing the price updates received from the previous step as an argument to the updatePrice method of your smart contract.

Pyth Core contracts

This section explains how EVM contracts read Pyth prices from the Pyth Core contracts.

All Pyth Core contracts were upgraded on August 26, 2026 and kept their interface. Their price updates come from the upgraded Hermes, which collects prices signed by the Pyth Pro routers. How the upgraded Pyth Core works has the details.

For an interactive playground to explore the methods supported by the Pyth contract, see the EVM API reference.

Read Sponsored Prices

For a feed in the Sponsored Feeds list, read the sponsored price without submitting an update:

PythStructs.Price memory price = pyth.getPriceNoOlderThan(priceFeedId, 60);

Install Pyth SDK

Pyth provides a Solidity SDK to fetch prices from Pyth contracts. The SDK exposes IPyth interface to interact with Pyth price feeds.

Truffle/Hardhat

If you are using Truffle or Hardhat, simply install the NPM package:

npm install @pythnetwork/pyth-sdk-solidity

Foundry

If you are using Foundry, you will need to create an NPM project if you don't already have one. From the root directory of your project, run:

npm init -y
npm install @pythnetwork/pyth-sdk-solidity

Then add the following line to your remappings.txt file:

@pythnetwork/pyth-sdk-solidity/=node_modules/@pythnetwork/pyth-sdk-solidity

Update Prices First

Update the on-chain price before reading it. getPriceNoOlderThan() reverts with StalePrice (0x19abf40e) when the stored price exceeds the staleness threshold. See Price Updates for the Pyth Core Contracts.

Write Contract Code

The code snippet below provides a general template for what your contract code should look like:

pragma solidity ^0.8.0;

import "@pythnetwork/pyth-sdk-solidity/IPyth.sol";
import "@pythnetwork/pyth-sdk-solidity/PythStructs.sol";

contract SomeContract {
  IPyth pyth;

  /**
   * @param pythContract The address of the Pyth contract
   */
  constructor(address pythContract) {
    // The IPyth interface from pyth-sdk-solidity provides the methods to interact with the Pyth contract.
    // Instantiate it with the Pyth contract address from https://docs.pyth.network/price-feeds/core/contract-addresses/evm
    pyth = IPyth(pythContract);
  }

  /**
     * This method is an example of how to interact with the Pyth contract.
     * Fetch the priceUpdate from Hermes and pass it to the Pyth contract to update the prices.
     * Add the priceUpdate argument to any method on your contract that needs to read the Pyth price.
     * See https://docs.pyth.network/price-feeds/pro/api/rest#price-updates-for-the-pyth-core-contracts for more information on how to fetch the priceUpdate.

     * @param priceUpdate The encoded data to update the contract with the latest price
     */
  function exampleMethod(bytes[] calldata priceUpdate) public payable {
    // Submit a priceUpdate to the Pyth contract to update the on-chain price.
    // Updating the price requires paying the fee returned by getUpdateFee.
    // WARNING: These lines are required to ensure the getPriceNoOlderThan call below succeeds. If you remove them, transactions may fail with "0x19abf40e" error.
    uint fee = pyth.getUpdateFee(priceUpdate);
    pyth.updatePriceFeeds{ value: fee }(priceUpdate);

    // Read the current price from a price feed if it is less than 60 seconds old.
    // Each price feed (e.g., ETH/USD) is identified by a price feed ID.
    // The complete list of feed IDs is available at https://docs.pyth.network/price-feeds/price-feeds
    bytes32 priceFeedId = 0xff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace; // ETH/USD
    PythStructs.Price memory price = pyth.getPriceNoOlderThan(priceFeedId, 60);
  }
}

The code snippet above does the following things:

  1. Instantiate the IPyth interface from the Solidity SDK using the price feeds contract address.
  2. Select Price Feed IDs for the required assets.
  3. Call IPyth.getUpdateFee to calculate the fee charged by Pyth to update the price.
  4. Call IPyth.updatePriceFeeds to update the price, paying the fee calculated in the previous step.
  5. Call IPyth.getPriceNoOlderThan with the price feed ID and an acceptable staleness threshold to read the current price.

Additional Resources

For the Pyth Pro contracts:

For the Pyth Core contracts:

  • Price Feed IDs: Price Feed IDs lists every Pyth Core price feed and its ID.
  • API Reference: the EVM API reference lets developers explore the complete API of the Pyth contract interactively.
  • Example Application: Oracle Swap is an AMM that swaps two assets at the Pyth price. It includes the contract and a frontend.

On this page