Basic Price Feed Tutorial
Example Code: The complete working example for this tutorial is available at sb-on-demand-examples/solana/feeds/basic
This tutorial walks you through the simplest way to integrate Switchboard oracle price feeds into your Solana program. You'll learn how to read verified price data using Switchboard's managed update system.
What You'll Build
A minimal Anchor program that reads price feed data from a Switchboard oracle account, plus a TypeScript client that fetches fresh oracle data and calls your program.
Prerequisites
Rust and Cargo installed
Solana CLI installed and configured
Node.js 18+ and npm/pnpm
Basic understanding of Anchor framework
A Solana keypair with SOL (devnet or mainnet)
Key Concepts
Before diving into the code, let's understand how Switchboard's managed update system works.
Managed Updates
Switchboard uses a managed update system where oracle data is stored in canonical accounts derived deterministically from feed IDs. This means:
No manual account management needed
Same feed IDs always produce the same oracle account address
Accounts are created automatically if they don't exist
The Two-Instruction Pattern
Every Switchboard oracle update requires two instructions in sequence:
Ed25519 Signature Verification - Verifies the oracle operator's signature
Quote Program Storage - Stores the verified data in the canonical oracle account
Your program then reads from this oracle account as a third instruction in the same transaction.
Feed IDs
Each price feed has a unique 32-byte hex identifier. You can find feed IDs in the Switchboard Explorer.
Example: BTC/USD feed ID:
The On-Chain Program
Here's the complete Anchor program that reads oracle data:
Code Walkthrough
Imports
SwitchboardQuote- The account type that holds oracle dataSwitchboardQuoteExt- Extension trait for accessing feed valuesdefault_queue()- Returns the default Switchboard queue for the current networkSlotHashes,Instructions- Sysvar types needed for verification
The Instruction
The read_oracle_data instruction:
Accesses feed data from
quote_account.feedsCalculates staleness by comparing the quote slot to the current slot
Iterates through feeds to extract values using
feed.hex_id()andfeed.value()
Account Validation
This constraint ensures the passed account is the legitimate canonical oracle account for the contained feeds. It prevents malicious actors from passing fake oracle data.
Sysvars
The program requires three sysvars:
Clock- For checking the current slotSlotHashes- For quote verificationInstructions- For verifying the Ed25519 instruction was included
The TypeScript Client
Here's the complete client code that fetches oracle data and calls your program:
Client Code Walkthrough
Step 1: Load Environment
This auto-detects whether you're on mainnet or devnet based on your RPC endpoint and loads the appropriate Switchboard queue.
Step 2: Derive Canonical Account
The canonical account is a PDA derived from the queue public key and feed IDs. This ensures the same inputs always produce the same account address.
Step 3: Simulate Feed (Optional)
You can simulate a feed to see what value the oracle would return before submitting a transaction.
Step 4: Create Update Instructions
This returns an array of instructions:
Ed25519 signature verification instruction
Quote program
verified_updateinstruction
Step 5-7: Build and Send Transaction
The transaction includes:
Ed25519 verification instruction
Quote program update instruction
Your program's instruction
All three must be in the same transaction for the verification to work.
Running the Example
1. Clone the Examples Repository
2. Install Dependencies
3. Configure Your Environment
Create or update your Solana CLI config to point to devnet:
Ensure your keypair has SOL:
4. Build and Deploy the Program (Optional)
If you want to deploy your own instance:
5. Run the Example
Expected Output
Adding to Your Program
To integrate Switchboard into your own program:
1. Add Dependencies
In your Cargo.toml:
2. Add the Account Struct
3. Read the Price
Next Steps
Multiple Feeds: Pass multiple feed IDs to
fetchManagedUpdateIxsto update several prices in one transactionStaleness Checks: Add maximum staleness requirements for your use case
Custom Feeds: Learn how to create custom data feeds in the Custom Feeds section
Advanced Patterns: See the Advanced Price Feed tutorial for more complex integration patterns
Last updated