> ## Documentation Index
> Fetch the complete documentation index at: https://docs.near.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Oracles

> Learn about blockchain oracles on NEAR Protocol, including price feeds, data integration, and using oracle services like Outlayer Price Oracle and Pyth Network.

export const Github = ({url, start, end, fname, withSourceLink = true}) => {
  const [code, setCode] = useState(null);
  function toRaw(ref) {
    const fullUrl = ref.slice(ref.indexOf('https'));
    const [url] = fullUrl.split('#');
    const [org, repo, , branch, ...pathSeg] = new URL(url).pathname.split('/').slice(1);
    return `https://raw.githubusercontent.com/${org}/${repo}/${branch}/${pathSeg.join('/')}`;
  }
  async function fetchCode(url, fromLine, toLine) {
    let res;
    if (typeof window !== 'undefined') {
      const validUntil = localStorage.getItem(`${url}-until`);
      if (validUntil && Number(validUntil) > Date.now()) {
        res = localStorage.getItem(url);
      }
    }
    if (!res) {
      try {
        res = await (await fetch(url)).text();
        if (typeof window !== 'undefined') {
          localStorage.setItem(url, res);
          localStorage.setItem(`${url}-until`, String(Date.now() + 60000));
        }
      } catch {
        return 'Error fetching code, please try reloading';
      }
    }
    let body = res.split('\n');
    const from = fromLine ? Number(fromLine) - 1 : 0;
    const to = toLine ? Number(toLine) : body.length;
    body = body.slice(from, to);
    const precedingSpace = body.reduce((prev, line) => {
      if (line.length === 0) return prev;
      const spaces = line.match(/^\s+/);
      if (spaces) return Math.min(prev, spaces[0].length);
      return 0;
    }, Infinity);
    return body.map(line => line.slice(precedingSpace === Infinity ? 0 : precedingSpace)).join('\n');
  }
  function buildSourceUrl(url, start, end) {
    const base = url.split('#')[0];
    if (start && end) return `${base}#L${start}-L${end}`;
    if (start) return `${base}#L${start}`;
    return base;
  }
  useEffect(() => {
    const rawUrl = toRaw(url);
    fetchCode(rawUrl, start, end).then(res => setCode(res));
  }, [url, start, end]);
  const sourceUrl = buildSourceUrl(url, start, end);
  const startLine = start ? Number(start) : 1;
  const fileName = fname ?? sourceUrl.split('/').pop();
  return <div className="rounded-[0.625rem] border border-[#d0d7de] dark:border-[#30363d] overflow-hidden my-5 text-[0.8125rem] font-mono shadow-sm dark:shadow-[0_4px_24px_rgba(0,0,0,0.18)]">

      {}
      <div className="flex items-center justify-between py-2 px-[0.875rem] bg-[#f6f8fa] dark:bg-[#161b22] border-b border-[#d0d7de] dark:border-[#30363d]">
        <div className="flex items-center gap-2 text-[#656d76] dark:text-[#8b949e]">
          <svg width="15" height="15" viewBox="0 0 24 24" fill="currentColor">
            <path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0 0 24 12c0-6.63-5.37-12-12-12z" />
          </svg>
          <span className="text-xs font-medium text-[#1f2328] dark:text-[#e6edf3]">
            {fileName}
          </span>
        </div>
        {start && end && <span className="text-[0.6875rem] text-[#656d76] dark:text-[#8b949e] bg-[#eaeef2] dark:bg-[#21262d] border border-[#d0d7de] dark:border-[#30363d] rounded-full py-0.5 px-2">
            Lines {start}–{end}
          </span>}
      </div>

      {}
      <div className="overflow-auto max-h-[480px] bg-white dark:bg-[#0d1117] [&_tr]:border-b-0 [&_td]:border-b-0">
        {code === null ? <div className="py-5 px-4 text-xs text-[#656d76] dark:text-[#6e7681]">
            Loading...
          </div> : <table className="w-full border-collapse leading-[1.6]">
            <tbody>
              {code.split('\n').map((line, i) => <tr key={i} className="align-top border-0">
                  <td style={{
    minWidth: '60px'
  }} className="select-none pl-2 pr-3 text-right text-[0.7rem] text-[#8c959f] dark:text-[#3d444d] w-[1%] whitespace-nowrap border-r border-0 border-r-[#d0d7de] dark:border-r-[#21262d]">
                    {startLine + i}
                  </td>
                  <td className="pl-4 pr-6 text-[0.8125rem] text-[#1f2328] dark:text-[#e6edf3] whitespace-pre">
                    {line || ' '}
                  </td>
                </tr>)}
            </tbody>
          </table>}
      </div>

      {}
      {withSourceLink && <div className="flex justify-end py-1.5 px-[0.875rem] bg-[#f6f8fa] dark:bg-[#161b22] border-t border-[#d0d7de] dark:border-[#21262d]">
          <a href={sourceUrl} target="_blank" rel="noreferrer noopener" className="text-[0.6875rem] font-medium text-[#656d76] dark:text-[#8b949e] no-underline flex items-center gap-[0.3rem] hover:text-[#1f2328] dark:hover:text-[#e6edf3] transition-colors">
            View on GitHub
            <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
              <path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" />
              <polyline points="15 3 21 3 21 9" />
              <line x1="10" y1="14" x2="21" y2="3" />
            </svg>
          </a>
        </div>}
    </div>;
};

export const TryOutOnLantstool = ({path, user = 'lantstool', repo = 'examples.near-protocol', branch = 'main'}) => {
  const lantstoolUrl = `https://app.lantstool.dev/import/gh/${user}/${repo}/${branch}/${path}`;
  const githubUrl = `https://github.com/${user}/${repo}/blob/${branch}/${path}`;
  const [code, setCode] = useState(null);
  function toRaw(ref) {
    const [org, repoName, , branchName, ...pathSeg] = new URL(ref).pathname.split('/').slice(1);
    return `https://raw.githubusercontent.com/${org}/${repoName}/${branchName}/${pathSeg.join('/')}`;
  }
  useEffect(() => {
    const rawUrl = toRaw(githubUrl);
    (async () => {
      try {
        let res;
        const validUntil = typeof window !== 'undefined' && localStorage.getItem(`${rawUrl}-until`);
        if (validUntil && Number(validUntil) > Date.now()) {
          res = localStorage.getItem(rawUrl);
        }
        if (!res) {
          res = await (await fetch(rawUrl)).text();
          if (typeof window !== 'undefined') {
            localStorage.setItem(rawUrl, res);
            localStorage.setItem(`${rawUrl}-until`, String(Date.now() + 60000));
          }
        }
        setCode(res);
      } catch {
        setCode('Error fetching code, please try reloading');
      }
    })();
  }, [githubUrl]);
  return <div>
      <p>
        Try it out on{' '}
        <a href={lantstoolUrl} target="_blank" rel="noopener noreferrer">
          Lantstool
        </a>
      </p>
      <div className="rounded-[0.625rem] border border-[#d0d7de] dark:border-[#30363d] overflow-hidden my-3 text-[0.8125rem] font-mono shadow-sm dark:shadow-[0_4px_24px_rgba(0,0,0,0.18)]">
        <div className="flex items-center gap-2 py-2 px-[0.875rem] bg-[#f6f8fa] dark:bg-[#161b22] border-b border-[#d0d7de] dark:border-[#30363d]">
          <svg width="15" height="15" viewBox="0 0 24 24" fill="currentColor" className="text-[#656d76] dark:text-[#8b949e]">
            <path d="M12 0C5.37 0 0 5.37 0 12c0 5.31 3.435 9.795 8.205 11.385.6.105.825-.255.825-.57 0-.285-.015-1.23-.015-2.235-3.015.555-3.795-.735-4.035-1.41-.135-.345-.72-1.41-1.23-1.695-.42-.225-1.02-.78-.015-.795.945-.015 1.62.87 1.845 1.23 1.08 1.815 2.805 1.305 3.495.99.105-.78.42-1.305.765-1.605-2.67-.3-5.46-1.335-5.46-5.925 0-1.305.465-2.385 1.23-3.225-.12-.3-.54-1.53.12-3.18 0 0 1.005-.315 3.3 1.23.96-.27 1.98-.405 3-.405s2.04.135 3 .405c2.295-1.56 3.3-1.23 3.3-1.23.66 1.65.24 2.88.12 3.18.765.84 1.23 1.905 1.23 3.225 0 4.605-2.805 5.625-5.475 5.925.435.375.81 1.095.81 2.22 0 1.605-.015 2.895-.015 3.3 0 .315.225.69.825.57A12.02 12.02 0 0 0 24 12c0-6.63-5.37-12-12-12z" />
          </svg>
          <span className="text-xs font-medium text-[#1f2328] dark:text-[#e6edf3]">
            {githubUrl.split('/').pop()}
          </span>
        </div>
        <div className="overflow-auto max-h-[480px] bg-white dark:bg-[#0d1117] [&_tr]:border-b-0 [&_td]:border-b-0">
          {code === null ? <div className="py-5 px-4 text-xs text-[#656d76] dark:text-[#6e7681]">Loading...</div> : <table className="w-full border-collapse leading-[1.6]">
              <tbody>
                {code.split('\n').map((line, i) => <tr key={i} className="align-top border-0">
                    <td style={{
    minWidth: '60px'
  }} className="select-none pl-2 pr-3 text-right text-[0.7rem] text-[#8c959f] dark:text-[#3d444d] w-[1%] whitespace-nowrap border-r border-0 border-r-[#d0d7de] dark:border-r-[#21262d]">
                      {i + 1}
                    </td>
                    <td className="pl-4 pr-6 text-[0.8125rem] text-[#1f2328] dark:text-[#e6edf3] whitespace-pre">
                      {line || ' '}
                    </td>
                  </tr>)}
              </tbody>
            </table>}
        </div>
      </div>
    </div>;
};

[Blockchain Oracles](https://en.wikipedia.org/wiki/Blockchain_oracle) serve as intermediaries that connect smart contracts with external (off-chain) data.

`Example:`

* **Price Feeds:** Real-time pricing for cryptocurrencies, stocks, or commodities.
* **Event Information:** Updates on real-world events like sports results or weather conditions.
* **API Access:** Connections to external web services and systems.

<Info>
  Oracles, being external third-party services, require careful consideration of their reliability, security, and decentralization to avoid risks such as incorrect data, manipulation, or single points of failure.
</Info>

***

## Deployed Oracles on NEAR

Here is a directory of third-party oracle services deployed on the NEAR blockchain:

| Name                                                                                         | Creator                                           | Description                                        |
| -------------------------------------------------------------------------------------------- | ------------------------------------------------- | -------------------------------------------------- |
| [Outlayer Price Oracle](#price-oracle-by-outlayer)                                           | [Outlayer](https://github.com/zavodil/oracle-ark) | TEE-Secured Price Oracle based on Outlayer         |
| [Pyth Network Oracle](#pyth-network-oracle)                                                  | [Pyth Network](https://pyth.network/)             | High-frequency, low-latency oracle for price feeds |
| **[\[Your Project Here\]](https://github.com/near/docs/edit/master/primitives/oracles.mdx)** | -                                                 | -                                                  |

***

## Price Oracle by Outlayer

* **Creator:** [Outlayer](https://github.com/fastnear/near-outlayer)
* **Official Documentation:** [Price Oracle Outlayer](https://price-oracle.outlayer.ai/docs/)
* **Codebase Repository:** [zavodil/oracle-ark](https://github.com/zavodil/oracle-ark)
* **Deployed Addresses:**
  * **Mainnet:** [price-oracle.near](https://nearblocks.io/address/price-oracle.near)
  * **Testnet:** [price-oracle.testnet](https://testnet.nearblocks.io/address/price-oracle.testnet)

### How to use / integrate

The `price-oracle.near` implements Pyth-compatible view methods natively (see [Pyth Network Oracle](#pyth-network-oracle) below). DeFi contracts using `pyth-oracle.near` can migrate by changing one contract address — no code changes needed.

<Tip>
  This price oracle is one of several services built on OutLayer, a general-purpose verifiable off-chain compute platform. See [OutLayer](/primitives/off-chain-compute/outlayer) for VRF, AI calls, cross-chain reads, and other off-chain primitives.
</Tip>

***

## Pyth Network Oracle

* **Creator:** [Pyth Network](https://pyth.network)
* **Official Documentation:** [Pyth NEAR Docs](https://docs.pyth.network/price-feeds/use-real-time-data/near)
* **Codebase Repository:** [pyth-network/pyth-crosschain](https://github.com/pyth-network/pyth-crosschain/tree/main/target_chains/near)
* **Deployed Addresses:**
  * **Mainnet:** [pyth-oracle.near](https://nearblocks.io/address/pyth-oracle.near)
  * **Testnet:** [pyth-oracle.testnet](https://testnet.nearblocks.io/address/pyth-oracle.testnet)

***

## Using Pyth Network Oracle

> Pyth Network's NEAR smart contract has two core methods to update & get price feeds of your choice.

1. [`update_price_feeds`](#update_price_feeds)
   *(updates Pyth smart contract with the price feed you provide)*
   * args: `data`
   * type: `object`
   * example: `{ "data": "504e41...' }`
2. [`get_price`](#get_price) (fetches the most recent price stored in the contract)\_
   * args: `price_identifier`
   * type: `object`
   * example: `{ price_identifier: 'f9c0172ba10dfa8...' }`

<Info>
  For a complete list of endpoints to interact with, see [Pyth's `receiver` contract](https://github.com/pyth-network/pyth-crosschain/blob/main/target_chains/near/receiver/src/ext.rs).
</Info>

### Getting Started

To get started with Pyth oracle you will need to gather the following information which differ between networks:

* Price ID(s)
* HermesAPI Endpoint
* Smart contract address

| Network   | Price Feed IDs                                                                                   | Hermes API Address         | Contract Address                                                                 |
| --------- | ------------------------------------------------------------------------------------------------ | -------------------------- | -------------------------------------------------------------------------------- |
| `testnet` | [NEAR `testnet` Price Feed IDs](https://www.pyth.network/developers/price-feed-ids#near-testnet) | `hermes-beta.pyth.network` | [pyth-oracle.testnet](https://testnet.nearblocks.io/address/pyth-oracle.testnet) |
| `mainnet` | [NEAR `mainnet` Price Feed IDs](https://www.pyth.network/developers/price-feed-ids#near-mainnet) | `hermes.pyth.network`      | [pyth-oracle.near](https://nearblocks.io/address/pyth-oracle.near)               |

<Info>
  When using Price Feed IDs, you will need to remove the `0x` prefix.

  `Price Feed ID Example (testnet):`

  <Github language="typescript" url="https://github.com/near-examples/near-js/blob/main/node-js/oracle-example/pyth-oracle-update.js" start="14" end="15" />
</Info>

***

### `update_price_feeds`

> Updates the Pyth Oracle contract data with the price feed you provide.

* args: `data` *(off-chain hex-encoded price feed)*
* type: `object`
* example: `{ "data": "504e41...' }`

Update the Pyth Oracle contract with new price feed data in two main steps:

1. [Fetch off-chain price feed](#1-fetching-off-chain-price-feed)
2. [Update Pyth Oracle contract with off-chain price feed](#2-update-pyth-oracle-contract-price-feed)

#### 1) Fetching off-chain price feed

You can obtain an off-chain price feed using Pyth's [Hermes API](https://hermes-beta.pyth.network/docs/).

To use these endpoints, you will need to provide a Price Feed ID and ensure you are targeting the correct network. See [Getting Started](#getting-started) for more information.

Here is a node.js example of fetching the latest price feed using `/v2/updates/price/latest` endpoint:

<Github url="https://github.com/near-examples/near-js/blob/main/node-js/utils/fetch-hermes-price-data.js" />

#### 2) Update Pyth Oracle Contract Price Feed

After [fetching an off-chain price feed](#1-fetching-off-chain-price-feed), you can now perform a contract call to the Pyth Oracle to update the price feed on-chain.

Call `update_price_feeds` on the Pyth Oracle contract with `data` as your arguments.

`example args:`

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "data": "504e41550100000000a00100000000010070b0ee3a00d1a3c07ee440887eb34a5a35860e6f4b9230fd62f0593fe35c8a3561735a6a37d269c5f166b84ead8918f710dc1be2ee6b51db5b22340ea2c173fc01673d544b00000000001ae101faedac5851e32b9b23b5f9411a8c2bac4aae3ed4dd7b811dd1a72ea4aa7100000000061bc18c014155575600000000000ab0f04600002710f41bc8c224ed983c68dbf5dab7dd34c9129fecfa03005500ca80ba6dc32e08d06f1aa886011eed1d77c77be9eb761cc10d72b7d0a2fd57a600000047e2eb4ef0000000000692480ffffffff800000000673d544b00000000673d544b00000048200e66a00000000005e495a60bb9370c458dd50558b34699b5b179f45e56be22f0a1a0feb1db8469adc8c5efeb53988495bac07bf9efed07f5eee43818150c55055882f6872a228e8e9bc78459ed3ea7fe0b86f3048f6bf0aad34befc46063ab7d200beb8bc9fe5839844d2233546f0742bb665f1e610370fcf8ce5be83d0f47e584b685af87cf3ebcb79e714827dcb99dba579e1a03785052ab3c7c7147d3f7bba822b04dbda159670e9a8d29e7ccf68474b2ca85e00224d29bf65b06b09f95e91703313e053b697b48ac1e4d1c57605a71ab77e7ef276bfe8a369c268333b9a37461bf2b7cb7fd4c005500ecf553770d9b10965f8fb64771e93f5690a182edc32be4a3236e0caaa6e0581a0000000e2ba8cd280000000001b40517fffffff800000000673d544b00000000673d544b0000000e3ea44c6800000000016aee120b47b853f55949284cb8ba0b63824ff9b48cd1da8417f45421b79ee3195fc8d107540a0bbb95c2445b66065754f135cb842db09a7e7ab33f79c546a48db872bd7197b04e3d7b52fbb55b3b9f51707c5a55fac3707cb563dbcde4aadeecc3649c237454cecf519dc567c0da03d81808523aa4fa71815eab25ce7da61b48647bac645d403208135002aab5fde2d7ab3c7c7147d3f7bba822b04dbda159670e9a8d29e7ccf68474b2ca85e00224d29bf65b06b09f95e91703313e053b697b48ac1e4d1c57605a71ab77e7ef276bfe8a369c268333b9a37461bf2b7cb7fd4c"
}
```

Example of updating the Pyth Oracle contract's price feed using `near-js/client` and node.js:

<Github fname="updatePythContract" url="https://github.com/near-examples/near-js/blob/main/node-js/oracle-example/pyth-oracle-update.js" />

<Github fname="getHermesPriceData" url="https://github.com/near-examples/near-js/blob/main/node-js/utils/fetch-hermes-price-data.js" />

<Github fname="nearConnect" url="https://github.com/near-examples/near-js/blob/main/node-js/utils/connect.js" />

<Info>
  Although unused deposit will be refunded, you can calculate an estimate by calling the `get_update_fee_estimate` method against the Pyth contract.
</Info>

***

### `get_price`

> Fetches the most recent price feed stored in the Pyth Oracle contract. Is a view method, so does not require a signature or payment.

* args: `price_identifier` *(unique price feed identifier)*
* type: `object`
* example: `{ price_identifier: 'f9c0172ba10dfa8...' }`

After [updating the price feed](#update_price_feeds), you can view the feed on-chain by calling `get_price` on the Pyth Oracle contract. Note that this is a view method and does not require a signature or deposit.

`Example:`

<Github url="https://github.com/near-examples/near-js/blob/main/node-js/oracle-example/pyth-oracle-view.js" />
