# Somnia Price Feeds

> A push-based crypto price feed on Somnia. Agent subcommittees price every tracked pair across exchanges about once a second and write the median onchain, as a spot and a mark price that any contract reads for free.

**Spot and mark prices onchain, about once a second, free to read.**

Somnia Price Feeds is a push-based crypto price feed. A self-re-arming onchain schedule ticks roughly once a second. Each tick sends a request to a [Somnia Agents](/agents/somnia-agents) subcommittee that prices every tracked pair across exchanges, and the median is written back into contract storage. Consumers read those cells: there is no subscription to buy, no fee per read and no callback.

Two prices are published for each pair:

| | What it is | Use it for |
| --- | --- | --- |
| **spot** | The median index price across venues, recomputed every tick | Settlement, display |
| **mark** | An EMA over the spot series, which damps single-tick spikes | Liquidation, margin |

The onchain feed is the supported surface. An [indexer](/data/price-feeds/reference#historical-data) also serves the history for charts and monitoring, but nothing that moves value should read from it.

## Addresses

`PriceFeedScheduler` is a UUPS proxy. Its address stays fixed across upgrades, so bind to the proxy, never to an implementation.

| Network | Chain ID | `PriceFeedScheduler` |
| --- | --- | --- |
| Somnia Mainnet | `5031` | `0x1998C88D54a240b8C671493f27f58eC416b81D7F` |
| Somnia Testnet | `50312` | `0x7ccAE31E45693475be1e4BAa2360D6997eB2D32B` |

## Conventions

- **Prices** are unsigned and scaled by `10 ** decimals()`, which is `18` on both networks today. Read `decimals()` once rather than hardcoding it.
- **Timestamps** are Unix **milliseconds**, not seconds. A cell's timestamp is `block.timestamp * 1000`, so it is second-granular and shared by every pair written in the same tick. `sourceUpdatedAtMs` carries millisecond precision.
- **Cadence.** Ticks fire on a fixed grid, just after each whole second. A tick delivered very late skips one grid point rather than firing twice back to back.
- **Pairs** are ccxt-style strings, such as `"BTC/USDC"`.
- **Reads never revert on stale or missing data.** A pair that is untracked, removed or not yet written returns zero. You decide what is too old: the feed never invents a value. The `*OrRevert` helpers revert on **your** bound, not the feed's.

## Read a price safely

`latest()` returns `(price, updatedAtMs)` and never reverts, so a consumer that forgets to check both fields will trade on a zero or an hour-old price. Use the one-call safe form instead:

```solidity
// Copy IQualifiedPriceFeed into your project, or declare just the functions you call:
// the feed publishes no ABI package today.
import {IQualifiedPriceFeed} from "./IQualifiedPriceFeed.sol";

contract Consumer {
    IQualifiedPriceFeed constant FEED =
        IQualifiedPriceFeed(0x1998C88D54a240b8C671493f27f58eC416b81D7F);

    uint256 constant MAX_AGE_MS = 5_000; // 5 missed ticks tolerated

    function settle() external view returns (uint256 btc) {
        // Reverts NoPrice() if never written, StalePrice(ageMs, maxAgeMs) if too old.
        btc = FEED.latestOrRevert("BTC/USDC", MAX_AGE_MS);
    }
}
```

Set `maxAgeMs` by what a stale price would cost you. Settlement and liquidation want single-digit seconds at a one-second cadence; display can be generous. A bound below the tick cadence means nothing, because cell timestamps are second-granular.

## Next steps

- [Reading prices](/data/price-feeds/reading-prices): the four read interfaces, the quality fields and the mark hazard.
- [Feed liveness](/data/price-feeds/liveness): tell a dead feed from one unpriced pair.
- [Pairs and events](/data/price-feeds/pairs-and-events): the tracked pairs, the events and how to request a new pair.
- [Reference](/data/price-feeds/reference): every call and what it returns, and the historical-data indexer.

Somnia Price Feeds is built on [Somnia Agents](/agents/somnia-agents) and [Somnia Reactivity](/developer/reactivity), the same pieces as the [Somnia Oracle](/data/somnia-oracle). Third-party feeds from Stork, DIA and Protofire also run on Somnia Mainnet: see [Oracles](/developer/deployment-and-production/ecosystem/ecosystem-tools/oracles).

---

Every page is also Markdown: append `.md` to its URL, or ask for `text/markdown`. Found something wrong, missing or confusing in these docs? Tell us: `POST /api/feedback` on this site with JSON `{"message": "…", "context": "what you were doing and what happened", "page": "…"}`, or a plain-text body. `GET /api/feedback` gives the JSON Schema. The team reads every one.
