mcpField
S
switchboard

switchboard

github.com/sendaifunデータ・データベース130189 回インストール13 週間前に更新
リポジトリ

switchboard について

switchboard は、Switchboard の Solana 向けオラクルプロトコルの統合スキルです。SDK を使った価格フィード、オラクルクオート、ストリーミングデータ、検証可能な乱数の利用方法を開発者向けに案内します。

主な機能

  1. 01Solana オラクル統合ガイド
  2. 02プル型価格フィード更新
  3. 03オラクルクオート統合
  4. 04Surge WebSocket ストリーミング
  5. 05VRF 乱数統合

活用シーン

  1. 01Solana プログラムへの価格データ追加
  2. 02低レイテンシ価格ストリームの利用
  3. 03フィード保存なしでのオラクルデータ取得
  4. 04検証可能なオンチェーン乱数の要求

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/sendaifun/skills --skill switchboard

インストール後、Claude Code で/switchboardを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

docs/
troubleshooting.md
examples/feeds/
oracle-quote.ts
pull-feed.ts
read-feed.ts
examples/randomness/
vrf-example.ts
examples/setup/
example.ts
examples/surge/
streaming.ts
resources/
github-repos.md
program-ids.md
rust-reference.md
sdk-reference.md
templates/
setup.ts

詳細

Switchboard Oracle Protocol - 完全統合ガイド

Switchboard を統合するための決定版ガイドです。Switchboard は、Solana 上で最速かつ最もカスタマイズ性に優れた、唯一のパーミッションレスなオラクルプロトコルです。

Switchboard とは?

Switchboard は、業界をリードするパフォーマンスで、開発者が独自のデータをオンチェーンに取り込めるようにする、パーミッションレスなオラクルプロトコルです。

  • 価格フィード - プル型の効率性を備えたリアルタイムの資産価格
  • オラクルクォート - オンチェーンストレージを使わず、1 秒未満のレイテンシを実現(コストを 90% 削減)
  • Surge - 100 ミリ秒未満のレイテンシを実現する WebSocket ストリーミング
  • VRF ランダム性 - 暗号学的に安全で検証可能なランダム関数
  • 予測市場 - 市場ベースの予測データ
主な統計情報
  • オンチェーン取引高 10 億ドル以上 を保護
  • Kamino、Jito、MarginFi、Drift Protocol で利用
  • Surge の価格フィードで 2〜5 ミリ秒のレイテンシ
  • 従来型のオラクルと比較して コストを 90% 削減

基本原則

原則説明
速度Surge では 2〜5 ミリ秒、標準では 400 ミリ秒。DeFi 業界をリードする速度です
コスト効率プル型フィードにより、継続的なストリーミングコストを削減します
パーミッションレス承認を受けずに、フィードをすぐにデプロイできます
セキュリティTEE(信頼実行環境)により、データの改ざんを防ぎます

統合方法

1. オラクルクォート(推奨)

オンチェーンストレージを介さず、オラクルからプログラムにデータを直接渡します。

  • 1 秒未満のレイテンシ
  • コストを 90% 削減
  • 書き込みロックなし(並列読み取り)
  • ステートレス設計
2. 従来型フィード

従来のプル型フィード更新方式です。

  • フィードアカウントの維持
  • クランキング処理
  • シンプルなユースケースに適しています
3. Surge(リアルタイム)

高頻度アプリケーション向けの WebSocket ストリーミングです。

  • 100 ミリ秒未満のレイテンシ
  • 永続的な接続
  • トレーディングインターフェースに最適

プログラム ID

プログラムMainnetDevnet
オラクルプログラムSW1TCH7qEPTdLsDHRgPuMQjbQxKdH2aBStViMFnt64fAio4gaXjXzJNVLtzwtNVmSqGKpANtXhybbkhtAC94ji2
クォートプログラムorac1eFjzWL5R3RbbdMV68K9H6TaCVVcL6LjvQQWAbz-
デフォルトキュー
ネットワークキューアドレス
MainnetA43DyUGA7s8eXPxqEjJY6EBu1KKbNgfxF8h17VAHn13w
DevnetEYiAmGSdsQTuCw413V5BzaruWuCCSDgTPtBGvLkXHbe7

クイックスタート

インストール
# TypeScript SDK
npm install @switchboard-xyz/on-demand @switchboard-xyz/common

# Rust (Cargo.toml)
# switchboard-on-demand = "0.8.0"
基本設定
import { 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");

価格フィード

フィードの取得と更新
import { 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);
フィード値の読み取り
// 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}`);

オラクルクォート(推奨)

オラクルクォートは、オラクルデータを利用する最も効率的な方法です。

import { 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: {},
});
Rust 統合(オラクルクォート)
use 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>,
}

Surge(リアルタイムストリーミング)

リアルタイムの価格更新が必要なアプリケーション向けです。

import { 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");
});

VRF ランダム性

暗号学的に安全なオンチェーンのランダム性です。

TypeScript クライアント
import { 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);
Rust 統合
use 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(())
}

カスタムフィードの作成

フィードビルダー UI の使用
  1. ondemand.switchboard.xyz にアクセスします
  2. 「Create Feed」をクリックします
  3. データソースと集約方法を設定します
  4. Mainnet/devnet にデプロイします
  5. 統合用にフィードハッシュをコピーします
TypeScript SDK の使用
import { 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();

フレームワークの比較

項目Anchor(基本)Pinocchio(上級)
学習曲線初心者向け上級者向け
コンピュートユニット約 2,000 CU約 190 CU
安全性モデル完全な検証信頼されたクランカー
ユースケース標準的な DeFiオラクル AMM、HFT

ベストプラクティス

1. 古さのチェック

フィードが最新であることを必ず確認します。

let staleness = current_slot.saturating_sub(feed_slot);
require!(staleness < MAX_STALENESS_SLOTS, ErrorCode::StaleFeed);
2. 複数の署名

重要な処理では、複数のオラクル署名をリクエストします。

const { pullIx } = await feedAccount.fetchUpdateIx({
  numSignatures: 3, // Increase for higher security
});
3. エラー処理
try {
  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;
}
4. コンピュートバジェット

複雑な処理では、コンピュートバジェットを増やします。

import { ComputeBudgetProgram } from "@solana/web3.js";

const modifyComputeUnits = ComputeBudgetProgram.setComputeUnitLimit({
  units: 400_000,
});

const tx = new Transaction()
  .add(modifyComputeUnits)
  .add(pullIx)
  .add(yourInstruction);

リソース

公式リンク
GitHub リポジトリ
リポジトリ説明
switchboard-sdkSwitchboard SDK の公開ミラー
sb-on-demand-examples統合例
solana-sdkRust SDK
on-demandTypeScript 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

コメント