# Using Data Feeds on Stellar
Source: https://docs.chain.link/data-feeds/stellar

> For the complete documentation index, see [llms.txt](/llms.txt).

[Stellar](https://stellar.org/) is a Layer 1 blockchain that uses [Soroban](https://soroban.stellar.org/) smart contracts written in [Rust](https://www.rust-lang.org/). Chainlink Data Feeds on Stellar are delivered through [Chainlink Runtime Environment (CRE)](/cre), which publishes data onchain using a decentralized oracle network.

Chainlink Data Feeds on Stellar follow the same pattern as [Data Feeds on Aptos](/data-feeds/aptos): a single proxy contract serves every feed, and consumers select a feed by its 32-byte `data_id` rather than by a per-feed contract address. This contrasts with Chainlink's integration on EVM blockchains, where each price feed has a separate contract address.

## How Stellar Data Feeds work

Data Feeds on Stellar use a proxy and cache model:

- **Proxy contract**: A single proxy contract is the only contract that consumers interact with. The proxy address stays stable across cache replacements, so your application does not need to change when the underlying data is upgraded.
- **Cache contract**: The proxy delegates reads to a cache contract that the Chainlink oracle network writes into. When the cache is replaced, the proxy continues to point to the new cache, and the proxy address remains unchanged.

Consumers select a feed by passing its 32-byte `data_id` to the proxy. You can find the `data_id` for each feed on the [Price Feed Contract Addresses](/data-feeds/price-feeds/addresses?network=stellar) page with Stellar selected.

## Supported networks

Chainlink Data Feeds are available on the following Stellar networks:

- [Stellar Testnet](https://stellar.org/developers/guides/concepts/networks#testnet)
- [Stellar Mainnet (Pubnet)](https://stellar.org/developers/guides/concepts/networks#public-network)

## Proxy contract addresses

The proxy contract address is the same for every feed on a given network. You only ever interact with the proxy.

- **Stellar Testnet**: \<TESTNET\_PROXY\_ADDRESS>
- **Stellar Mainnet (Pubnet)**: \<MAINNET\_PROXY\_ADDRESS>

## Reader interface

Consumers call the following functions on the proxy contract. The interface is defined in the [chainlink-stellar](https://github.com/smartcontractkit/chainlink-stellar/tree/main/contracts/common/interfaces/src/data_feeds_proxy.rs) repository.

| Function                                 | Returns                                                                 |
| ---------------------------------------- | ----------------------------------------------------------------------- |
| `latest_round(data_id, decimals)`        | The most recent round for that feed, scaled to the requested `decimals` |
| `get_round(data_id, round_id, decimals)` | A specific historical round, scaled to the requested `decimals`         |
| `decimals(data_id)`                      | The storage precision of the feed, currently always `18`                |
| `description(data_id)`                   | Human-readable pair name                                                |

### Round structure

A round returned by the proxy carries the following fields:

| Field       | Description                                               |
| ----------- | --------------------------------------------------------- |
| `round_id`  | The unique identifier of the round                        |
| `answer`    | The answer for the feed, represented as an `I256`         |
| `timestamp` | The Unix timestamp in seconds when the round was recorded |

## Error handling

When you call the proxy, the contract can return a `ProxyReadError`. The following cases describe what each error means for a consumer:

| Error             | Meaning                                                                                                                                         |
| ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `NoDataPresent`   | No round is available for the requested `data_id` or `round_id`. This can happen if the feed has not been written yet or the round has expired. |
| `InvalidDecimals` | The `decimals` you requested is outside the supported range for the feed. The valid range is `[min_decimals(feed), 18]`.                        |
| `RoundsToZero`    | A non-zero answer would truncate to zero at the requested `decimals`. Request fewer decimal places.                                             |

## How long a round is available

A round is stored in the cache contract's temporary storage with a retention period of `3,110,400` ledgers. After this period, a round can no longer be read from the proxy.

## Getting started

You can read Chainlink Data Feeds on Stellar either onchain or offchain:

- **Onchain**: Deploy a [Soroban contract in Rust](/data-feeds/stellar/using-data-feeds-on-chain) that calls the proxy and reads a price, deployed with `stellar-cli` to the Stellar Testnet.
- **Offchain**: Read a feed via [Soroban RPC simulation](/data-feeds/stellar/using-data-feeds-off-chain) using `stellar-cli` and the [Stellar JavaScript SDK](https://github.com/stellar/js-stellar-sdk).

## Answer precision

The cache stores every answer at a fixed `18` decimal places (`DECIMALS`). Feeds sourced at a lower precision, such as `8` decimals, are scaled up to `18` on write, so the stored value is always `18`-decimal regardless of the feed's native precision. As a result, `decimals(data_id)` on the proxy currently always returns `18`; it describes the storage precision, not the originating feed.

Decimal conversion is applied at the proxy level. When you call `latest_round` or `get_round`, you pass the precision you want the answer returned at. The valid range is `[min_decimals(feed), 18]`:

- A feed's minimum precision is owner-configurable and defaults to `18`, which locks the feed to full precision unless the owner explicitly opens it up.
- Downscaling truncates toward zero, matching the behavior of Solidity integer division that EVM consumers already use.
- A non-zero answer that would truncate to zero at the requested precision fails with a distinct error rather than silently returning zero. An answer that is genuinely zero returns zero at any precision.

> **DANGER: Select quality data feeds**
>
> Be aware of the quality of the data that you use. [Learn more about making responsible data quality decisions](/data-feeds/selecting-data-feeds).