Skip to main content
The Oracle Precompile is not yet available. In the meantime, you can query prices using one of the approaches described below.
Injective offers multiple ways to access oracle price data depending on your architecture and requirements. The following approaches range from integrating with Pyth off-chain, to reading Pyth prices on-chain through Injective’s EVM.

Approach 1: Off-chain price feeds with Pyth

If your application fetches prices off-chain (for example, in a backend service or bot), you can query Pyth’s HTTP API directly without any on-chain interaction. Refer to the Pyth documentation on fetching price updates for details on available endpoints, request formats, and response schemas. This approach is ideal for off-chain trading systems, analytics dashboards, or any service that requires price data without submitting transactions.

Approach 2: On-chain price feeds with Pyth (EVM)

For smart contracts that need to read prices on-chain, you can interact with the Pyth contract deployed on Injective’s EVM. This uses Pyth’s pull-based oracle model, where price updates are fetched off-chain and submitted on-chain before reading.

Contract addresses

To obtain the Pyth contract address for Injective EVM, refer to the Pyth contract addresses page and locate the Injective EVM entry: Currently, Pyth is deployed at 0x36825bf3Fbdf5a29E2d5148bfe7Dcf7B5639e320 on Injective’s EVM mainnet.
Always consult the official documentation to obtain up-to-date addresses.

Price feed IDs

Each asset pair has a unique price feed ID. You can look up feed IDs on the Pyth price feed IDs page. For example, search for INJ/USD.

Supported feeds

AssetPrice Feed ID
INJ/USD0x7a5bc1d2b56ad029048cd63964b3ad2776eadf812edc1a43a31406cb54bff592
BTC/USD0xe62df6c8b4a85fe1a67db44dc12de5db330f7ac66b72dc658afedf0f4a415b43
ETH/USD0xff61491a931112ddf1bd8147cd1b641375f79f5825126d665480874634fd0ace
XRP/USD0xec5d399846a9209f3fe5881d70aae9268c94339ff9817e8d18ff19fa05eea1c8
USDT/USD0x2b89b9dc8fdf9f34709a5b106b472f0f39bb6ca9ce04b0fd7f2e971688e2e53b
USDC/USD0xeaa020c61cc479712813461ce153894a96a6c00b21ed0cfc2798d1f9a9e9c94a
Always consult the official documentation to obtain up-to-date addresses.

Integration guide

For a complete walkthrough of integrating Pyth price feeds into your Solidity contracts using the pull model, follow the Pyth EVM pull integration tutorial.

Example

The following example demonstrates how to read the INJ/USD price from the Pyth contract on Injective’s EVM:
import { ethers } from "ethers";
import { toHumanReadable } from "@injectivelabs/utils";

const provider = new ethers.JsonRpcProvider(
  "https://sentry.evm-rpc.injective.network",
);

const IPythABI = [
  {
    inputs: [{ internalType: "bytes[]", name: "updateData", type: "bytes[]" }],
    name: "getUpdateFee",
    outputs: [{ internalType: "uint256", name: "feeAmount", type: "uint256" }],
    stateMutability: "view",
    type: "function",
  },
  {
    inputs: [{ internalType: "bytes[]", name: "updateData", type: "bytes[]" }],
    name: "updatePriceFeeds",
    outputs: [],
    stateMutability: "payable",
    type: "function",
  },
  {
    inputs: [
      { internalType: "bytes32", name: "id", type: "bytes32" },
      { internalType: "uint256", name: "age", type: "uint256" },
    ],
    name: "getPriceNoOlderThan",
    outputs: [
      {
        components: [
          { internalType: "int64", name: "price", type: "int64" },
          { internalType: "uint64", name: "conf", type: "uint64" },
          { internalType: "int32", name: "expo", type: "int32" },
          { internalType: "uint256", name: "publishTime", type: "uint256" },
        ],
        internalType: "struct PythStructs.Price",
        name: "price",
        type: "tuple",
      },
    ],
    stateMutability: "view",
    type: "function",
  },
  {
    inputs: [{ internalType: "bytes32", name: "id", type: "bytes32" }],
    name: "getPriceUnsafe",
    outputs: [
      {
        components: [
          { internalType: "int64", name: "price", type: "int64" },
          { internalType: "uint64", name: "conf", type: "uint64" },
          { internalType: "int32", name: "expo", type: "int32" },
          { internalType: "uint256", name: "publishTime", type: "uint256" },
        ],
        internalType: "struct PythStructs.Price",
        name: "price",
        type: "tuple",
      },
    ],
    stateMutability: "view",
    type: "function",
  },
] as const;

const pyth = new ethers.Contract(
  "0x36825bf3Fbdf5a29E2d5148bfe7Dcf7B5639e320",
  IPythABI,
  provider,
);

async function main() {
  try {
    const priceFeedId =
      "0x7a5bc1d2b56ad029048cd63964b3ad2776eadf812edc1a43a31406cb54bff592"; // INJ/USD

    // const price = await pyth.getPriceUnsafe(priceFeedId);
    const maxAge = 60; // 60s
    const price = await pyth.getPriceNoOlderThan(priceFeedId, maxAge);

    console.log(
      "Human readable price:",
      price.expo > 0
        ? toHumanReadable(price.price.toString(), price.expo.toString()).toFixed(2)
        : toHumanReadable(price.price.toString(), (-price.expo).toString()).toFixed(4),
    );
  } catch (error) {
    console.error(error);
  } finally {
    await provider.destroy();
  }
}

main().catch(console.error);
getPriceUnsafe returns the last pushed price without a staleness check. For production use, prefer getPriceNoOlderThan(priceFeedId, maxAge) — but note this requires the price to have been pushed on-chain recently, otherwise the call will revert. See the Pyth documentation for more details on the pull model.