> For the complete documentation index, see [llms.txt](https://docs.rome.builders/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.rome.builders/products/oracle-gateway.md).

# Oracle Gateway

The Oracle Gateway exposes Solana-native price feeds (Pyth, Switchboard V3) through Chainlink's `AggregatorV3Interface`, so Ethereum protocols porting to Rome keep their existing oracle integration code. **Oracle Gateway V2 is live on every public chain**, with a keeper guaranteeing feed freshness and a customer portal for registration. The adapters, factory, and keeper model are covered in the [rome-oracle-gateway](https://github.com/rome-protocol/rome-oracle-gateway) repo.

## The problem

Ethereum DeFi expects Chainlink's `AggregatorV3Interface`:

```solidity
(, int256 price,,,) = priceFeed.latestRoundData();
```

Solana's oracle providers (Pyth, Switchboard) have different data formats. Without adaptation, every ported protocol would need custom oracle code.

## The solution

Oracle Gateway V2 deploys lightweight adapter contracts that:

1. Read price data directly from Pyth or Switchboard accounts on Solana (cross-state reads, not CPI)
2. Parse the on-chain data
3. Normalize prices to 8 decimals
4. Expose the standard Chainlink `AggregatorV3Interface`

```solidity
import {IAggregatorV3Interface} from "@rome-protocol/rome-solidity/contracts/oracle/IAggregatorV3Interface.sol";

// Same interface as Chainlink on Ethereum
(, int256 price,,,) = IAggregatorV3Interface(ADAPTER).latestRoundData();
// price = SOL/USD at 8 decimals (e.g. 15000000000 = $150.00)
```

## Consume a feed in three steps

1. **Resolve the adapter address from the registry** — never hardcode it:

```ts
import { getOracle } from "@rome-protocol/registry";
const solUsd = getOracle(200010).feeds["SOL/USD"].address;
// Hadrian today: 0x76b92646D63FB1AFEa687C7Dac48b437bF99C1B4
```

2. **Read it** with the interface your protocol already uses — `IAggregatorV3Interface(solUsd).latestRoundData()`. A stale or uninitialized feed **reverts** rather than serving a frozen price.
3. **Several feeds at once?** `BatchReader.getLatestPrices(adapters[])` (Hadrian: `0x306d670dff7f51ae33f263f5122bd2b18d98adc7`) — and `getFeedHealth(adapters[])` before you depend on them. Cached adapters make each consumer read a plain `SLOAD`, so multi-feed transactions (a multi-collateral borrow, a portfolio view) stay cheap.

[cardo](https://github.com/rome-protocol/cardo) consumes these feeds in production today. Because the surface is exactly `AggregatorV3Interface`, Compound- and Aave-class protocols are **drop-in** — point their price-feed configuration at the adapter addresses; their oracle code needs zero changes.

## Adapter types

* **PythPullAdapter** — reads Pyth price accounts (price, confidence, EMA, publish time).
* **SwitchboardV3Adapter** — reads Switchboard aggregator accounts (price, timestamp; no EMA).
* **CachedPyth / CachedFeed adapters** — cached-track variants for CU-efficient reads.

Adapters are deployed as EIP-1167 minimal-proxy clones by the `OracleAdapterFactory` and expose an extended interface alongside `AggregatorV3Interface` (`latestPriceData`, `maxStaleness`, `oracleType`, and a `metadata()` surface used for health checks).

## Freshness — the oracle-keeper

Adapters enforce a `maxStaleness` window: if `block.timestamp - publishTime > maxStaleness`, reads revert. On Solana mainnet, Pyth runs production keepers. On Solana devnet (where the public chains live), Pyth's pushers are best-effort, so Rome runs its own **oracle-keeper** sidecar to keep the underlying Pyth accounts fresh. Freshness is monitored and alerted on.

Check feed health with `BatchReader.getFeedHealth` (which reads each adapter's `metadata()`), not just `latestRoundData` — a feed can be reachable but stale.

## Customer portal

Register feeds and configure consumers per chain through the [Oracle Gateway portal](https://oracle.testnet.romeprotocol.xyz/). See the [portal page](/apps-on-rome/oracle-gateway.md) for what it covers.

## Deployed addresses

Canonical per-chain addresses (factories, adapter implementations, and the live feeds) live in the [registry](https://github.com/rome-protocol/rome-registry/tree/main/chains). Headline factories:

| Contract             | Hadrian                                      | Martius                                      |
| -------------------- | -------------------------------------------- | -------------------------------------------- |
| OracleAdapterFactory | `0xe68e7bc697010c73f1798b356f8ae2f0ba1319db` | `0xbc06fe9603a02ff4aead265c253f5c6303ee5fbb` |
| BatchReader          | `0x306d670dff7f51ae33f263f5122bd2b18d98adc7` | `0xc5e6d932bfd2b4da27643848063905f46861fae8` |

## Constraints

* **No historical round data** — `getRoundData(roundId)` reverts; only `latestRoundData()` is supported.
* **Switchboard EMA not supported** — EMA data is Pyth-only.
* **Per-chain staleness** — `maxStaleness` is set per environment at bring-up: direct (Pyth-read) adapters default to \~60 seconds; cached adapters default to 3600 seconds (the keeper refreshes far more often — \~25s on devnet/testnet today).
* **Parser offsets** are validated against current Pyth/Switchboard layouts; layout changes require re-validation.

## What's Next

* [Oracle Gateway portal](/apps-on-rome/oracle-gateway.md) — register feeds, configure consumers
* [Contract Addresses](/reference/contract-addresses.md) — precompiles and per-chain addresses


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.rome.builders/products/oracle-gateway.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
