Using Data Feeds Offchain (Stellar)

Chainlink Data Feeds are the quickest way to access market prices for real-world assets. This guide demonstrates how to read Chainlink Data Feeds on the Stellar Testnet offchain using a Soroban RPC simulation with the Stellar CLI and the Stellar JavaScript SDK. To learn how to use Data Feeds in your onchain Soroban contracts, see the Using Data Feeds Onchain guide.

To get the full list of Chainlink Data Feeds on Stellar, see the Price Feed Contract Addresses page with Stellar selected.

Available data feeds on Stellar

The following table shows all available data feeds on Stellar. Each feed is identified by its data_id (the Feed ID), which you pass to the proxy contract to read that feed's data.

Networks

Stellar Mainnet

Unlike EVM chains, Stellar uses a single proxy contract for all feeds. Instead of a per-feed contract address, you select a feed by its feed ID (data_id) shown below. See the Using Data Feeds on Stellar guide to learn how to read these feeds.

Prerequisites

Before you begin, you should have:

Requirements

To complete this guide, you'll need:

  • Stellar CLI: Install the Stellar CLI. Run stellar --version to verify your installation.

  • Node.js 18 or higher: Install Node.js. Run node --version to verify your installation.

Read a feed with the Stellar CLI

You can read a Chainlink Data Feed offchain without deploying a contract by simulating a call to the proxy contract using the stellar contract invoke command with the --send=no flag. This does not submit a transaction and requires no XLM.

The proxy contract exposes a latest_round function that takes a data_id and returns the most recent round for that feed. You pass the data_id as raw hex (without the 0x prefix).

  1. Run the following command, replacing <SOURCE_ACCOUNT> with any Stellar account public key. The proxy contract on Stellar Testnet is CBUF6IADAWPWIDWRTHJNINKXHG2UTIQ6TU2F2HRAXWAI7OT3KJPKK6O4, and the BTC/USD data_id is 01a0b4d920000332000000000000000000000000000000000000000000000000:

    stellar contract invoke \
    --id CBUF6IADAWPWIDWRTHJNINKXHG2UTIQ6TU2F2HRAXWAI7OT3KJPKK6O4 \
    --source-account <SOURCE_ACCOUNT> \
    --network testnet \
    --send=no \
    -- latest_round \
    --data_id "01a0b4d920000332000000000000000000000000000000000000000000000000"
    

    Expect an output similar to the following:

    {"answer":"86352425538914820000000","round_id":59,"timestamp":1790089710}
    

    Where:

    • answer is the latest BTC/USD price with 18 decimal places (86352425538914820000000 = 86352.43).
    • round_id is the unique identifier of the round.
    • timestamp is the Unix timestamp in seconds when the round was recorded.

    You can find the data_id for each feed on the Price Feed Contract Addresses page with Stellar selected.

Read a feed with the Stellar JavaScript SDK

You can also read a Chainlink Data Feed offchain using the Stellar JavaScript SDK with a Soroban RPC query. This example uses the contract.Client API available in SDK v17 and later.

  1. Create a new directory for your project and initialize it:

    mkdir stellar-offchain && cd stellar-offchain && npm init -y
    
  2. Install the Stellar JavaScript SDK:

    npm install @stellar/stellar-sdk
    
  3. Create a read-feed.js file with the following contents. This script queries the proxy contract's latest_round function for a given data_id:

    const { contract } = require("@stellar/stellar-sdk")
    
    const proxy = "CBUF6IADAWPWIDWRTHJNINKXHG2UTIQ6TU2F2HRAXWAI7OT3KJPKK6O4"
    const dataId = "01a0b4d920000332000000000000000000000000000000000000000000000000"
    
    async function readLatestRound() {
      const client = await contract.Client.from({
        contractId: proxy,
        rpcUrl: "https://soroban-testnet.stellar.org",
        networkPassphrase: "Test SDF Network ; September 2015",
      })
      const result = await client.latest_round({ data_id: Buffer.from(dataId, "hex"), decimals: 18 })
      const round = result.result
      console.log("Latest round:", {
        round_id: round.round_id.toString(),
        answer: round.answer.toString(),
        timestamp: round.timestamp.toString(),
      })
    }
    
    readLatestRound().catch(console.error)
    

    The data_id argument is a 32-byte value, passed as a Buffer object. The decimals argument requests the precision at which the answer is returned; 18 is the default.

  4. Run the script:

    node read-feed.js
    

    Expect an output similar to the following:

    Latest round: {
      round_id: '59',
      answer: '86352425538914820000000',
      timestamp: '1790089710'
    }
    

    Where answer is the latest BTC/USD price with 18 decimal places (86352425538914820000000 = 86352.43).

What's next

Get the latest Chainlink content straight to your inbox.