# Using Data Feeds Onchain (Solana)
Source: https://docs.chain.link/data-feeds/solana/using-data-feeds-solana

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

> **NOTE: SDK v2 is now available**
>
> The Chainlink [Solana SDK v2 is now available](https://crates.io/crates/chainlink_solana/), offering improved performance with lower compute unit usage through direct account reads instead of Cross-Program Invocation (CPI). This guide demonstrates the v2 SDK pattern. If you're using the v1 SDK, see the [migration guide below](#migrating-from-v1-to-v2) to upgrade.

Chainlink Data Feeds are the quickest way to connect your smart contracts to the real-world market prices of assets. This guide demonstrates how to deploy a program to the Solana Devnet cluster and access Data Feeds onchain using the [Chainlink Solana Starter Kit](https://github.com/smartcontractkit/solana-starter-kit). To learn how to read price feed data using offchain applications, see the [Using Data Feeds Offchain](/solana/using-data-feeds-off-chain) guide.

To get the full list of available Chainlink Data Feeds on Solana, see the [Solana Feeds](/data-feeds/price-feeds/addresses?network=solana) page. View the program that owns the Chainlink Data Feeds in the [Solana Devnet Explorer](https://solscan.io/account/HEvSKofvBgfaexv23kMabbYqxasxU3mQ4ibBMEmJWHny?cluster=devnet), or the [Solana Mainnet Explorer](https://solscan.io/account/HEvSKofvBgfaexv23kMabbYqxasxU3mQ4ibBMEmJWHny).

> **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).

## The Chainlink Data Feeds OCR2 program

The program that owns the data feeds on both Devnet and Mainnet is [HEvSKofvBgfaexv23kMabbYqxasxU3mQ4ibBMEmJWHny](https://solscan.io/account/HEvSKofvBgfaexv23kMabbYqxasxU3mQ4ibBMEmJWHny?cluster=devnet). This is the program ID that you use to retrieve Chainlink Price Data onchain in your program. The source code for this program is available in the [smartcontractkit/chainlink-solana](https://github.com/smartcontractkit/chainlink-solana/tree/develop/contracts/programs/ocr_2) repository on GitHub.

You can [add data feeds to an existing project](#adding-data-feeds-onchain-in-an-existing-project) or [use the Solana Starter Kit](#using-the-solana-starter-kit).

## Adding Data Feeds onchain in an existing project

You can read Chainlink Data Feed data onchain in your existing project using the [Chainlink Solana Crate](https://crates.io/crates/chainlink_solana). SDK v2 uses direct account reads for improved performance and lower compute unit usage compared to the deprecated v1 SDK which used Cross-Program Invocation (CPI).

> \*\*CAUTION: Reading feed data\*\*
>
>
>
> Although you can directly query the data feed accounts, you should not rely on the memory layout always being the same as it currently is. Based on this, the recommendation is to always use the consumer library queries below.

Import the Chainlink Solana Crate into your project and use the code sample to make function calls.

1. Add the Chainlink Solana Crate as an entry in your `Cargo.toml` file dependencies section, as shown in the [starter kit Cargo.toml example](https://github.com/smartcontractkit/solana-starter-kit/blob/main/programs/chainlink_solana_demo/Cargo.toml).

   ```toml
   [dependencies]
   chainlink_solana = "2.0.8"
   ```

   If you're using [Anchor](https://www.anchor-lang.com/docs), also add:

   ```toml
   [dependencies]
   anchor-lang = "0.31.1"
   chainlink_solana = "2.0.8"
   ```

2. Choose the code sample that matches your project setup:

   - **Rust (Anchor)**
   - **Rust (Vanilla)**

   Both samples demonstrate SDK v2, which reads data directly from the feed account. The code samples have the following components:

   - `read_feed_v2`: Reads feed data directly from the account data with the feed owner verification
   - `latest_round_data`: Returns the latest round information for the specified price pair including the latest price
   - `description`: Returns a price pair description such as SOL/USD
   - `decimals`: Returns the precision of the price, as in how many numbers the price is padded out to
   - `Display`: A helper function that formats the padded out price data into a human-readable price

<Tabs client:visible>
  <Fragment slot="tab.anchor">Rust (Anchor)</Fragment>
  <Fragment slot="tab.rust">Rust (Vanilla)</Fragment>

  <Fragment slot="panel.anchor">
    <CodeSample src="samples/Solana/PriceFeeds/on-chain-read-anchor.rs" />
  </Fragment>

  <Fragment slot="panel.rust">
    <CodeSample src="samples/Solana/PriceFeeds/on-chain-read.rs" />
  </Fragment>
</Tabs>

Program Transaction logs:

<Tabs client:visible>
  <Fragment slot="tab.anchor">Rust (Anchor)</Fragment>
  <Fragment slot="tab.rust">Rust (Vanilla)</Fragment>

  <Fragment slot="panel.anchor">
    ```shell Rust with Anchor
    Fetching transaction logs... [ 'Program HEvSKofvBgfaexv23kMabbYqxasxU3mQ4ibBMEmJWHny
    consumed 1826 of 1306895 compute units', 'Program return: HEvSKofvBgfaexv23kMabbYqxasxU3mQ4ibBMEmJWHny CA==',
    'Program HEvSKofvBgfaexv23kMabbYqxasxU3mQ4ibBMEmJWHny success', 'Program log: SOL / USD price is 93.76988029', ]
    ```
  </Fragment>

  <Fragment slot="panel.rust">
    ```shell Rust
    > Program logged: "Chainlink Price Feed Consumer entrypoint" > Program logged: "SOL / USD price is
    83.99000000"
    > Program consumed: 95953 of 1400000 compute units > Program return:
    HNYSbr77Jc9LhHeb9tx53SrWbWfNBnQzQrM4b3BB3PCR CA==
    ```
  </Fragment>
</Tabs>

To learn more about Solana and Anchor, see the [Solana Documentation](https://docs.solana.com/) and the [Anchor Documentation](https://www.anchor-lang.com/).

## Using the Solana starter kit

This guide demonstrates the following tasks:

- Write and deploy programs to the [Solana Devnet](https://solscan.io/?cluster=devnet) cluster using Anchor.
- Retrieve price data data using the [Solana Web3 JavaScript API](https://www.npmjs.com/package/@solana/web3.js) with Node.js.

This example shows a full end to end example of using Chainlink Price Feeds on Solana. It includes an onchain program written in rust, as well as an offchain client written in JavaScript. The client passes in an account to the program, the program then looks up the latest price of the specified price feed account, and then stores the result in the passed in account. The offchain client then reads the value stored in the account.

### Install the required tools

Before you begin, set up your environment for development on Solana:

1. Install [Git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) if it is not already configured on your system.

2. Install [Node.js 14 or higher](https://nodejs.org/en/download/). Run `node --version` to verify which version you have installed:

   ```shell
   node --version
   ```

3. Install [Yarn](https://classic.yarnpkg.com/lang/en/docs/install/) to simplify package management and run code samples.

4. Install a C compiler such as the one included in [GCC](https://gcc.gnu.org/install/). Some of the dependencies require a C compiler.

5. Install [Rust](https://www.rust-lang.org/tools/install):

   ```shell
   curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh &&
   source $HOME/.cargo/env
   ```

6. Install the latest Mainnet version of [the Solana CLI](https://github.com/solana-labs/solana/releases) and export the path to the CLI:

   ```shell
   sh -c "$(curl -sSfL https://release.solana.com/v1.13.6/install)" &&
   export PATH="~/.local/share/solana/install/active_release/bin:$PATH"
   ```

   Run `solana --version` to make sure the Solana CLI is installed correctly.

   ```shell
   solana --version
   ```

7. [Install Anchor](https://www.anchor-lang.com/docs/installation). On some operating systems, you might need to build and install Anchor locally. See the [Anchor documentation](https://www.anchor-lang.com/docs) for instructions.

After you install the required tools, build and deploy the example program from the [solana-starter-kit](https://github.com/smartcontractkit/solana-starter-kit) repository.

### Deploy the example program

This example includes a contract written in Rust. Deploy the contract to the Solana Devnet cluster.

1. In a terminal, clone the [solana-starter-kit](https://github.com/smartcontractkit/solana-starter-kit) repository and change to the `solana-starter-kit` directory:

   ```shell
   git clone https://github.com/smartcontractkit/solana-starter-kit &&
   cd ./solana-starter-kit
   ```

   You can see the complete code for the example on [GitHub](https://github.com/smartcontractkit/solana-starter-kit/).

2. In the `./solana-starter-kit` directory, install Node.js dependencies defined in the `package.json` file:

   ```shell
   yarn install
   ```

3. Create a temporary Solana wallet to use for this example. Use a temporary wallet to isolate development from your other wallets and prevent you from unintentionally using lamports on the Solana Mainnet. Alternatively, if you have an existing wallet that you want to use, locate the path to your keypair file and use it as the keypair for the rest of this guide.

   ```shell
   solana-keygen new --outfile ./id.json
   ```

   When you build your production applications and deploy Solana programs to the Mainnet cluster, always follow the security best practices in the [Solana Wallet Guide](https://docs.solana.com/wallet-guide) for managing your wallets and keypairs.

4. Fund your Solana wallet. On Devnet, use `solana airdrop` to add tokens to your account. The contract requires at least 4 SOL to deploy and the faucet limits each request to 2 SOL, so you must make two requests to get a total of 4 SOL on your wallet:

   ```shell
   solana airdrop 2 --keypair ./id.json --url devnet &&
   solana airdrop 2 --keypair ./id.json --url devnet
   ```

   - If the command line faucet does not work, run `solana address` on the temporary wallet to print the public key value for the wallet and request tokens from [SolFaucet](https://solfaucet.com/):

     ```shell
     solana address -k ./id.json
     ```

5. Run `anchor build` to build the example program. If you receive the `no such subcommand: 'build-bpf'` error, restart your terminal session and run `anchor build` again:

   ```shell
   anchor build
   ```

6. The build process generates keypairs for your program accounts. Before you deploy your programs, you must add these public keys to the respective `lib.rs` files. The starter kit contains two programs that both need their IDs updated:
   1. **For the `chainlink_solana_demo` program:**

      Get the keypair from the `./target/deploy/chainlink_solana_demo-keypair.json` file that Anchor generated:

      ```shell
      solana address -k ./target/deploy/chainlink_solana_demo-keypair.json
      ```

      Edit the `./programs/chainlink_solana_demo/src/lib.rs` file and replace the keypair in the `declare_id!()` definition with the output from the previous command:

      ```shell
      vi ./programs/chainlink_solana_demo/src/lib.rs
      ```

      Example (replace with your actual program ID):

      ```rust
      declare_id!("JC16qi56dgcLoaTVe4BvnCoDL6FhH5NtahA7jmWZFdqm");
      ```

   2. **For the `ccip_basic_receiver` program:**

      Get the keypair from the `./target/deploy/ccip_basic_receiver-keypair.json` file:

      ```shell
      solana address -k ./target/deploy/ccip_basic_receiver-keypair.json
      ```

      Edit the `./programs/ccip-basic-receiver/src/lib.rs` file and replace the keypair in the `declare_id!()` definition with the output from the previous command:

      ```shell
      vi ./programs/ccip-basic-receiver/src/lib.rs
      ```

      Example (replace with your actual program ID):

      ```rust
      declare_id!("ANvQpnDMhuuKmSWYV2ET7A78UZeU2bWbGjRpn4z27nv2");
      ```

7. With the new program IDs added to both files, run `anchor build` again. This recreates the necessary program files with the correct program IDs:

   ```shell
   anchor build
   ```

8. Run `anchor deploy` to deploy the program to the Solana Devnet. Remember to specify the keypair file for your wallet and override the default. This wallet is the account owner (authority) for the program:

   ```shell
   anchor deploy --provider.wallet ./id.json --provider.cluster devnet
   ```

9. To confirm that the program deployed correctly, run `solana program show --programs` to get a list of deployed programs that your wallet owns. For this example, check the list of deployed programs for the `id.json` wallet on the Solana Devnet:

   ```shell
   solana program show --programs --keypair ./id.json --url devnet
   ```

   The command prints information for both deployed programs, including the program ID, slot number, the wallet address that owns each program, and the program balance:

   ```shell
   Program Id                                   | Slot      | Authority                                    | Balance
   ANvQpnDMhuuKmSWYV2ET7A78UZeU2bWbGjRpn4z27nv2 | 110801571 | FsQPnANKDhqpoayxCL3oDHFCBmrhP34NrfbDR34qbQUt | 2.23 SOL
   JC16qi56dgcLoaTVe4BvnCoDL6FhH5NtahA7jmWZFdqm | 110801572 | FsQPnANKDhqpoayxCL3oDHFCBmrhP34NrfbDR34qbQUt | 1.47 SOL
   ```

   To see additional details of your deployed programs, copy a program ID and look it up in the [Solana Devnet Explorer](https://solscan.io/?cluster=devnet).

Now that the program is onchain, you can call it.

### Call the deployed program

Use your deployed program to retrieve price data from a Chainlink data feed on Solana Devnet. For this example, call your deployed program using the [`client.js` example](https://github.com/smartcontractkit/solana-starter-kit/blob/main/client.js) code.

1. Set the [Anchor environment variables](https://www.twilio.com/en-us/blog/how-to-set-environment-variables-html). Anchor uses these to determine which wallet to use and Solana cluster to use.

   ```shell
   export ANCHOR_PROVIDER_URL=https://api.devnet.solana.com &&
   export ANCHOR_WALLET=./id.json
   ```

2. Run the `client.js` example and pass the program address in using the `--program` flag:

   ```shell
   node client.js --program $(solana address -k ./target/deploy/chainlink_solana_demo-keypair.json)
   ```

   If the script executes correctly, you will see output with the current price of SOL / USD.

   ```shell
   ⋮
   Price Is: 96.79778375
   Success
   ⋮
   ```

3. Each request costs an amount of SOL that is subtracted from the `id.json` wallet. Run `solana balance` to check the remaining balance for your temporary wallet on Devnet.

   ```shell
   solana balance --keypair ./id.json --url devnet
   ```

4. To get prices for a different asset pair, run `client.js` again and add the `--feed` flag with one of the available [Chainlink data feeds](/data-feeds/price-feeds/addresses?network=solana). For example, to get the price of BTC / USD on Devnet, use the following command:

   ```shell
   node client.js \
   --program $(solana address -k ./target/deploy/chainlink_solana_demo-keypair.json) \
   --feed 6PxBx93S8x3tno1TsFZwT5VqP8drrRCbCXygEXYNkFJe
   ```

   ```shell
   Price Is: 111198.0536333
   Success
   ```

The program that owns the data feeds is [HEvSKofvBgfaexv23kMabbYqxasxU3mQ4ibBMEmJWHny](https://solscan.io/account/HEvSKofvBgfaexv23kMabbYqxasxU3mQ4ibBMEmJWHny?cluster=devnet), which you can see defined for `const CHAINLINK_PROGRAM_ID` in the `client.js` file.

### Clean up

After you are done with your deployed contract and no longer need it, it is nice to close the program and withdraw the Devnet SOL tokens for future use. In a production environment, you will want to withdraw unused SOL tokens from any Solana program that you no longer plan to use, so it is good to practice the process when you are done with programs on Devnet.

1. Run `solana program show` to see the list of deployed programs that your wallet owns and the balances for each of those programs:

   ```shell
   solana program show --programs --keypair ./id.json --url devnet
   ```

   ```shell
   Program Id                                   | Slot      | Authority                                    | Balance
   GRt21UnJFHZvcaWLbcUrXaTCFMREewDrm1DweDYBak3Z | 110801571 | FsQPnANKDhqpoayxCL3oDHFCBmrhP34NrfbDR34qbQUt | 3.07874904 SOL
   ```

2. Run `solana program close` and specify the program that you want to close:

   ```shell
   solana program close [YOUR_PROGRAM_ID] --keypair ./id.json --url devnet
   ```

   The program closes and the remaining SOL is transferred to your temporary wallet.

3. If you have deployments that failed, they might still be in the buffer holding SOL tokens. Run `solana program show` again with the `--buffers` flag:

   ```shell
   solana program show --buffers --keypair ./id.json --url devnet
   ```

   If you have open buffers, they will appear in the list.

   ```shell
   Buffer Address                               | Authority                                    | Balance
   CSc9hnBqYJoYtBgsryJAmrjAE6vZ918qaFhL6N6BdEmB | FsQPnANKDhqpoayxCL3oDHFCBmrhP34NrfbDR34qbQUt | 1.28936088 SOL
   ```

4. If you have any buffers that you do not plan to finish deploying, run the same `solana program close` command to close them and retrieve the unused SOL tokens:

   ```shell
   solana program close [YOUR_PROGRAM_ID] --keypair ./id.json --url devnet
   ```

5. Check the balance on your temporary wallet.

   ```shell
   solana balance --keypair ./id.json --url devnet
   ```

6. If you are done using this wallet for examples and testing, you can use [`solana transfer`](https://docs.solana.com/cli/transfer-tokens) to send the remaining SOL tokens to your default wallet or another Solana wallet that you use. For example, if your default wallet keypair is at `~/.config/solana/id.json`, you can send `ALL` of the temporary wallet's balance with the following command:

   ```shell
   solana transfer ~/.config/solana/id.json ALL --keypair ./id.json --url devnet
   ```

   Alternatively, you can send the remaining balance to a web wallet. Specify the public key for your wallet instead of the path the default wallet keypair. Now you can use those Devnet funds for other examples and development.

To learn more about Solana and Anchor, see the [Solana Documentation](https://docs.solana.com/) and the [Anchor Documentation](https://www.anchor-lang.com/).

## Migrating from v1 to v2

SDK v2 uses direct account reads instead of Cross-Program Invocation (CPI), resulting in better performance, lower compute units, and simpler code.

### Key changes

1. Update dependency in `Cargo.toml`:

   ```toml
   chainlink_solana = "2.0.8"  # was "1.0.0"
   ```

2. Update imports:

   ```rust
   use chainlink_solana::v2::read_feed_v2;  // was: use chainlink_solana as chainlink;
   ```

3. Remove `chainlink_program` from account context - only `chainlink_feed` is needed

4. Replace multiple CPI calls with a single read:

   <Tabs client:visible>
     <Fragment slot="tab.v1">v1 Pattern</Fragment>
     <Fragment slot="tab.v2">v2 Pattern</Fragment>

     <Fragment slot="panel.v1">
       ```rust
       // Multiple CPI calls
       let round = chainlink::latest_round_data(
          ctx.accounts.chainlink_program.to_account_info(),
          ctx.accounts.chainlink_feed.to_account_info(),
       )?;
       let description = chainlink::description(/* ... */)?;
       let decimals = chainlink::decimals(/* ... */)?;
       ```
     </Fragment>

     <Fragment slot="panel.v2">
       ```rust
       // Single read operation
       let feed = &ctx.accounts.chainlink_feed;
       let result = read_feed_v2(
          feed.try_borrow_data()?,
          feed.owner.to_bytes(),
       ).map_err(|_| MyError::ReadError)?;

          let round = result.latest_round_data()
             .ok_or(MyError::RoundDataMissing)?;
          let description = result.description();
          let decimals = result.decimals();
       ```
     </Fragment>
   </Tabs>

5. Add error types (v2 requires explicit error handling):

   ```rust
   #[error_code]
   pub enum MyError {
       #[msg("read error")]
       ReadError,
       #[msg("no round data")]
       RoundDataMissing,
   }
   ```

6. Update client code - remove `chainlinkProgram` from transaction accounts:
   ```typescript
   await program.methods
     .execute()
     .accounts({ chainlinkFeed: CHAINLINK_FEED }) // Remove chainlinkProgram
     .rpc()
   ```

### Complete example