Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Complete Switchboard Oracle Protocol SDK for Solana - the permissionless oracle solution for price feeds, on-demand data, VRF randomness, and real-time streaming via Surge. Covers TypeScript SDK, Rust integration, Oracle Quotes, and all Switchboard tools.
.claude/skills/internet-court-switchboard/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-05 | ✗→✓ | ▲ Improved | 78% | 0% |
| case-01 | ✗→✓ | ▲ Improved | 68% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 71% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 43% | 0% |
| case-07 | ✗→✓ | ▲ Improved | -43% | 0% |
The definitive guide for integrating Switchboard - the fastest, most customizable, and only permissionless oracle protocol on Solana.
Switchboard is a permissionless oracle protocol enabling developers to bring custom data on-chain with industry-leading performance:
| Principle | Description | |-----------|-------------| | Speed | 2-5ms with Surge, 400ms standard - industry-leading for DeFi | | Cost Efficiency | Pull-based feeds eliminate constant streaming costs | | Permissionless | Deploy feeds instantly without approvals | | Security | TEE (Trusted Execution Environments) prevent data manipulation |
Direct oracle-to-program data flow without on-chain storage:
Classic pull-based feed updates:
WebSocket streaming for high-frequency applications:
| Program | Mainnet | Devnet | |---------|---------|--------| | Oracle Program | SW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64f | Aio4gaXjXzJNVLtzwtNVmSqGKpANtXhybbkhtAC94ji2 | | Quote Program | orac1eFjzWL5R3RbbdMV68K9H6TaCVVcL6LjvQQWAbz | - |
| Network | Queue Address | |---------|---------------| | Mainnet | A43DyUGA7s8eXPxqEjJY6EBu1KKbNgfxF8h17VAHn13w | | Devnet | EYiAmGSdsQTuCw413V5BzaruWuCCSDgTPtBGvLkXHbe7 |
bash# TypeScript SDK npm install @switchboard-xyz/on-demand @switchboard-xyz/common # Rust (Cargo.toml) # switchboard-on-demand = "0.8.0"
typescriptimport { web3, AnchorProvider, Program } from "@coral-xyz/anchor"; import { PullFeed, CrossbarClient, ON_DEMAND_MAINNET_PID, ON_DEMAND_DEVNET_PID } from "@switchboard-xyz/on-demand"; // Setup connection and provider const connection = new web3.Connection("https://api.mainnet-beta.solana.com"); const wallet = useWallet(); // or Keypair const provider = new AnchorProvider(connection, wallet); // Load Switchboard program const sbProgram = await Program.at(ON_DEMAND_MAINNET_PID, provider); // Initialize Crossbar client for oracle communication const crossbar = new CrossbarClient("https://crossbar.switchboard.xyz");
typescriptimport { PullFeed, asV0Tx } from "@switchboard-xyz/on-demand"; // Create feed account reference const feedPubkey = new web3.PublicKey("YOUR_FEED_PUBKEY"); const feedAccount = new PullFeed(sbProgram, feedPubkey); // Fetch update instruction with oracle signatures const { pullIx, responses, numSuccess, luts } = await feedAccount.fetchUpdateIx({ crossbarClient: crossbar, chain: "solana", network: "mainnet", // or "devnet" }); // Build and send transaction const tx = await asV0Tx({ connection, ixs: [pullIx], signers: [payer], computeUnitPrice: 200_000, computeUnitLimitMultiple: 1.3, lookupTables: luts, }); const signature = await connection.sendTransaction(tx); console.log("Feed updated:", signature);
typescript// Get current feed value const feedData = await feedAccount.loadData(); const value = feedData.value.toNumber(); const lastUpdated = feedData.lastUpdatedSlot; console.log(`Price: ${value}, Last Updated: ${lastUpdated}`);
Oracle Quotes provide the most efficient way to consume oracle data:
typescriptimport { OracleQuote } from "@switchboard-xyz/on-demand"; // Feed hashes (64-char hex strings) const feedHashes = [ "0x...", // SOL/USD "0x...", // BTC/USD ]; // Derive canonical quote account const queueKey = new web3.PublicKey("A43DyUGA7s8eXPxqEjJY6EBu1KKbNgfxF8h17VAHn13w"); const quotePubkey = OracleQuote.getCanonicalPubkey(queueKey, feedHashes); // Fetch quote instruction const sigVerifyIx = await queue.fetchQuoteIx(crossbar, feedHashes, { numSignatures: 1, variableOverrides: {}, });
rustuse anchor_lang::prelude::*; use switchboard_on_demand::{default_queue, SwitchboardQuoteExt, SwitchboardQuote}; #[program] pub mod my_program { use super::*; pub fn read_oracle_data(ctx: Context<ReadOracleData>) -> Result<()> { let feeds = &ctx.accounts.quote_account.feeds; let current_slot = ctx.accounts.sysvars.clock.slot; let quote_slot = ctx.accounts.quote_account.slot; // Check staleness let staleness = current_slot.saturating_sub(quote_slot); require!(staleness < 100, ErrorCode::StaleFeed); for feed in feeds.iter() { msg!("Feed {}: Value = {}", feed.hex_id(), feed.value()); } Ok(()) } } #[derive(Accounts)] pub struct ReadOracleData<'info> { #[account(address = quote_account.canonical_key(&default_queue()))] pub quote_account: Box<Account<'info, SwitchboardQuote>>, pub sysvars: Sysvars<'info>, } #[derive(Accounts)] pub struct Sysvars<'info> { pub clock: Sysvar<'info, Clock>, }
For applications requiring real-time price updates:
typescriptimport { SwitchboardSurge } from "@switchboard-xyz/on-demand"; // Initialize Surge client const surge = new SwitchboardSurge({ apiKey: "YOUR_API_KEY", // Optional gatewayUrl: "wss://surge.switchboard.xyz", autoReconnect: true, maxReconnectAttempts: 5, reconnectDelay: 1000, }); // Subscribe to feeds surge.subscribe(["SOL/USD", "BTC/USD"]); // Handle events surge.on("connected", () => { console.log("Connected to Surge"); }); surge.on("data", (data) => { console.log(`${data.symbol}: ${data.price}`); }); surge.on("error", (error) => { console.error("Surge error:", error); }); surge.on("disconnected", () => { console.log("Disconnected from Surge"); });
Cryptographically secure on-chain randomness:
typescriptimport { RandomnessService } from "@switchboard-xyz/on-demand"; // Request randomness const randomnessAccount = await RandomnessService.create(sbProgram, { queue: queuePubkey, callback: { programId: myProgramId, accounts: [...], ixData: Buffer.from([...]), }, }); // Reveal randomness (after oracle fulfillment) const randomValue = await randomnessAccount.reveal(); console.log("Random value:", randomValue);
rustuse switchboard_on_demand::RandomnessAccountData; pub fn consume_randomness(ctx: Context<ConsumeRandomness>) -> Result<()> { let randomness_data = RandomnessAccountData::parse( ctx.accounts.randomness_account.to_account_info() )?; // Use the random value let random_value = randomness_data.get_value(&ctx.accounts.clock)?; // Example: coin flip let is_heads = random_value[0] % 2 == 0; Ok(()) }
typescriptimport { FeedBuilder } from "@switchboard-xyz/on-demand"; const feedConfig = new FeedBuilder() .addJob({ tasks: [ { httpTask: { url: "https://api.example.com/price", }, }, { jsonParseTask: { path: "$.price", }, }, ], }) .setMinResponses(3) .setMaxVariance(0.1); const feedHash = await feedConfig.build();
| Aspect | Anchor (Basic) | Pinocchio (Advanced) | |--------|----------------|----------------------| | Learning Curve | Beginner-friendly | Advanced only | | Compute Units | ~2,000 CU | ~190 CU | | Safety Model | Full validation | Trusted cranker | | Use Cases | Standard DeFi | Oracle AMMs, HFT |
Always verify feed freshness:
rustlet staleness = current_slot.saturating_sub(feed_slot); require!(staleness < MAX_STALENESS_SLOTS, ErrorCode::StaleFeed);
Request multiple oracle signatures for critical operations:
typescriptconst { pullIx } = await feedAccount.fetchUpdateIx({ numSignatures: 3, // Increase for higher security });
typescripttry { const { pullIx, numSuccess } = await feedAccount.fetchUpdateIx({...}); if (numSuccess < minRequired) { throw new Error(`Insufficient oracle responses: ${numSuccess}`); } } catch (error) { if (error.message.includes("timeout")) { // Retry with different oracles } throw error; }
For complex operations, increase compute budget:
typescriptimport { ComputeBudgetProgram } from "@solana/web3.js"; const modifyComputeUnits = ComputeBudgetProgram.setComputeUnitLimit({ units: 400_000, }); const tx = new Transaction() .add(modifyComputeUnits) .add(pullIx) .add(yourInstruction);
-- Feed Builder: https://ondemand.switchboard.xyz
| Repository | Description | |------------|-------------| | switchboard-sdk | Public mirror of Switchboard SDKs | | sb-on-demand-examples | Integration examples | | solana-sdk | Rust SDK | | on-demand | TypeScript SDK |
switchboard/
├── SKILL.md # This file
├── resources/
│ ├── program-ids.md # All program addresses and queues
│ ├── sdk-reference.md # TypeScript SDK API reference
│ ├── rust-reference.md # Rust SDK reference
│ └── github-repos.md # Repository links
├── examples/
│ ├── setup/
│ │ └── example.ts # Basic setup
│ ├── feeds/
│ │ ├── pull-feed.ts # Pull feed updates
│ │ ├── oracle-quote.ts # Oracle quote integration
│ │ └── read-feed.ts # Read feed values
│ ├── randomness/
│ │ └── vrf-example.ts # VRF randomness
│ └── surge/
│ └── streaming.ts # Real-time streaming
├── templates/
│ └── setup.ts # Complete starter template
└── docs/
└── troubleshooting.md # Common issues| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-05 | fail→pass | 23,815 | 20,248 | -15% | 1 | 1 | 0% | 3,568 | 6,346 | +78% | 0 | 0 | — |
case-01 | fail→pass | 21,764 | 14,495 | -33% | 1 | 1 | 0% | 3,014 | 5,059 | +68% | 0 | 0 | — |
case-02 | fail→pass | 21,891 | 14,586 | -33% | 1 | 1 | 0% | 3,060 | 5,229 | +71% | 0 | 0 | — |
case-03 | fail→pass | 25,402 | 16,605 | -35% | 1 | 1 | 0% | 3,890 | 5,575 | +43% | 0 | 0 | — |
case-04 | pass→fail | 18,923 | 17,664 | -7% | 1 | 1 | 0% | 2,754 | 5,804 | +111% | 0 | 0 | — |
case-06 | fail→fail | 18,839 | 14,151 | -25% | 1 | 1 | 0% | 3,178 | 5,001 | +57% | 0 | 0 | — |
case-07 | fail→pass | 65,296 | 10,880 | -83% | 1 | 1 | 0% | 7,915 | 4,516 | -43% | 0 | 0 | — |
case-08 | pass→pass | 17,107 | 9,972 | -42% | 1 | 1 | 0% | 2,112 | 4,270 | +102% | 0 | 0 | — |
case-09 | fail→fail | 23,740 | 23,261 | -2% | 1 | 1 | 0% | 3,483 | 6,595 | +89% | 0 | 0 | — |
case-10 | pass→pass | 14,271 | 11,951 | -16% | 1 | 1 | 0% | 1,718 | 4,679 | +172% | 0 | 0 | — |
case-11 | fail→pass | 18,211 | 20,571 | +13% | 1 | 1 | 0% | 2,486 | 6,332 | +155% | 0 | 0 | — |
case-12 | fail→pass | 13,726 | 8,464 | -38% | 1 | 1 | 0% | 1,608 | 3,940 | +145% | 0 | 0 | — |
case-13 | pass→pass | 21,401 | 14,434 | -33% | 1 | 1 | 0% | 3,038 | 5,142 | +69% | 0 | 0 | — |
case-14 | fail→fail | 19,281 | 20,072 | +4% | 1 | 1 | 0% | 2,468 | 6,250 | +153% | 0 | 0 | — |
case-15 | fail→pass | 25,132 | 16,589 | -34% | 1 | 1 | 0% | 3,462 | 5,560 | +61% | 0 | 0 | — |
case-16 | fail→pass | 25,584 | 20,667 | -19% | 1 | 1 | 0% | 3,377 | 5,830 | +73% | 0 | 0 | — |
case-17 | fail→pass | 19,150 | 14,994 | -22% | 1 | 1 | 0% | 2,438 | 5,189 | +113% | 0 | 0 | — |
case-18 | fail→pass | 40,893 | 7,679 | -81% | 1 | 1 | 0% | 8,214 | 3,754 | -54% | 0 | 0 | — |
case-19 | pass→pass | 16,526 | 10,559 | -36% | 1 | 1 | 0% | 2,290 | 4,390 | +92% | 0 | 0 | — |
case-20 | fail→pass | 18,662 | 9,753 | -48% | 1 | 1 | 0% | 2,269 | 4,176 | +84% | 0 | 0 | — |
case-21 | fail→pass | 15,366 | 8,394 | -45% | 1 | 1 | 0% | 1,825 | 3,903 | +114% | 0 | 0 | — |
case-22 | fail→pass | 35,975 | 7,125 | -80% | 1 | 1 | 0% | 5,798 | 3,596 | -38% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 21 counted toward the lift figure. The other 1 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +59 percentage points is the difference between those two pass rates over the 21 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.