yellowstone-grpc について
Yellowstone gRPCでSolanaのデータを利用するためのスキルです。フィルター付き購読、更新データの解析、取引・監視システム向けの接続管理を解説します。
主な機能
- 01トランザクション、アカウント、スロット、ブロックのストリーム受信
- 02データ種別やアドレスによる購読フィルター
- 03トランザクション更新の解析
- 04再接続とストリーム再開
活用シーン
- 01DEXスワップやウォレット活動の監視
- 02アカウント変更に応じたプール準備金の追跡
- 03低遅延が求められるSolana取引システムの構築
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ agiprolabs/ claude-trading-skills --skill yellowstone-grpcインストール後、Claude Code で/yellowstone-grpcを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/performance.mdproto_reference.mdproviders.mdsubscription_filters.mdscripts/monitor_wallets.pysubscribe_transactions.py詳細
Yellowstone gRPC — Solana のリアルタイムストリーミング
Yellowstone gRPC を使用して、Solana 上のすべてのトランザクション、アカウント更新、スロット、ブロックをリアルタイムでストリーミングします。これは、レイテンシに敏感な Solana 取引システムの基盤です。REST ポーリングをプッシュ型ストリーミングに置き換えることで、スロットレイテンシを約 5ms に抑えます。
Yellowstone gRPC を選ぶ理由
| 方法 | スロットレイテンシ(p90) | 用途 |
|---|---|---|
REST ポーリング(getTransaction) | 約 150ms 以上 | 履歴の検索 |
WebSocket(onLogs) | 約 10ms | シンプルな通知 |
| Yellowstone gRPC | 約 5ms | 本番環境の取引システム |
Yellowstone は、Solana バリデーターのデータを gRPC 経由で公開する Geyser プラグインです。主要な RPC プロバイダーはすべてこれを稼働させています。トランザクション、アカウント変更、スロット、ブロック、エントリーのフィルター済みストリームをサブスクライブすると、データがプッシュ配信されます。
クイックスタート
1. アクセス権を取得する
gRPC 対応の RPC プロバイダーが必要です。比較の詳細は references/providers.md を参照してください。
| プロバイダー | gRPC の開始価格 | 備考 |
|---|---|---|
| Shyft | $199/mo | コストパフォーマンスに優れ、7 つのリージョン、帯域幅無制限 |
| Helius | $999/mo | LaserStream、DAS API を含む |
| Triton One | 約 $2,900/mo | Yellowstone を開発、最低レイテンシ |
| QuickNode | プランによって異なる | マーケットプレイスのアドオン |
| Chainstack | $49/mo(1 ストリーム) | 低価格の選択肢、フィルターに制限あり |
| Alchemy | 無料プランあり | コンピュートユニット従量制 |
2. 依存関係をインストールする
# Python
uv pip install grpcio grpcio-tools protobuf base58 solders python-dotenv
# Generate Python stubs from proto files
git clone https://github.com/rpcpool/yellowstone-grpc.git
python -m grpc_tools.protoc \
-I./yellowstone-grpc/yellowstone-grpc-proto/proto/ \
--python_out=./generated \
--pyi_out=./generated \
--grpc_python_out=./generated \
./yellowstone-grpc/yellowstone-grpc-proto/proto/*.proto
# Rust — Cargo.toml
[dependencies]
yellowstone-grpc-client = "6.0.0"
yellowstone-grpc-proto = "6.0.0"
tokio = { version = "1", features = ["rt-multi-thread", "macros"] }
futures = "0.3"
bs58 = "0.5"
# TypeScript
npm install @triton-one/yellowstone-grpc @solana/web3.js
3. 環境を設定する
export GRPC_ENDPOINT="https://grpc.ny.shyft.to" # your provider endpoint
export GRPC_TOKEN="your-x-token-here" # from provider dashboard
4. 接続してサブスクライブする
import grpc
import os
from generated import geyser_pb2, geyser_pb2_grpc
endpoint = os.environ["GRPC_ENDPOINT"].replace("https://", "")
token = os.environ["GRPC_TOKEN"]
# Authenticated TLS channel
auth_creds = grpc.metadata_call_credentials(
lambda ctx, cb: cb((("x-token", token),), None)
)
channel = grpc.secure_channel(
endpoint,
grpc.composite_channel_credentials(
grpc.ssl_channel_credentials(), auth_creds
),
options=[("grpc.max_receive_message_length", 64 * 1024 * 1024)],
)
stub = geyser_pb2_grpc.GeyserStub(channel)
基本概念
サブスクリプションの種類
| 種類 | 取得できるデータ | 用途 |
|---|---|---|
transactions | メタデータ付きの完全なトランザクション | DEX スワップの監視、コピートレード |
accounts | 変更時のアカウントデータ | プールの準備金の追跡、トークン供給量 |
slots | スロット進行イベント | ブロックのタイミング、確認状況の追跡 |
blocks | ブロックの全内容 | ブロック単位の分析 |
blocks_meta | ブロックのメタデータのみ | 軽量なブロック追跡 |
entry | ブロックエントリー(シュレッドグループ) | 低レベルのバリデータデータ |
transactions_status | 完全なデータを含まない Tx ステータス | 軽量な確認 |
フィルターのロジック
- 複数のフィルター種別(transactions + accounts)= AND — いずれかの種別に一致する更新を取得します
- 配列内の複数の値(
account_includeに含まれる複数のアドレス)= OR - 名前付きフィルターを使うと、レスポンスでどのフィルターに一致したかを判別できます
- 新しい
SubscribeRequestを送信すると、以前のフィルターはすべて置き換えられます
コミットメントレベル
| レベル | 速度 | 安全性 | 用途 |
|---|---|---|---|
PROCESSED | 最速 | ロールバックされる可能性あり | 時間が重要なシグナル |
CONFIRMED | 約 400ms 遅い | 超多数の投票済み | ほとんどの取引用途 |
FINALIZED | 約 6~12 秒遅い | 不可逆 | 決済の検証 |
よく使われるサブスクリプションパターン
DEX プログラム上のすべてのスワップを監視する
# Filter: all non-vote, non-failed transactions involving PumpFun
request = geyser_pb2.SubscribeRequest(
transactions={
"pumpfun": geyser_pb2.SubscribeRequestFilterTransactions(
account_include=["6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"],
vote=False,
failed=False,
)
},
commitment=geyser_pb2.CommitmentLevel.PROCESSED,
)
特定のウォレットを追跡する
request = geyser_pb2.SubscribeRequest(
transactions={
"whales": geyser_pb2.SubscribeRequestFilterTransactions(
account_include=[
"WalletAddress1...",
"WalletAddress2...",
],
vote=False,
failed=False,
)
},
commitment=geyser_pb2.CommitmentLevel.CONFIRMED,
)
プールの準備金を監視する(アカウントのサブスクリプション)
request = geyser_pb2.SubscribeRequest(
accounts={
"raydium_pools": geyser_pb2.SubscribeRequestFilterAccounts(
account=["PoolAddress1...", "PoolAddress2..."],
)
},
commitment=geyser_pb2.CommitmentLevel.PROCESSED,
)
データスライスで帯域幅を削減する
# Only get the first 40 bytes of account data (e.g., just the discriminator + key fields)
request = geyser_pb2.SubscribeRequest(
accounts={
"token_accounts": geyser_pb2.SubscribeRequestFilterAccounts(
owner=["TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"],
filters=[
geyser_pb2.SubscribeRequestFilterAccountsFilter(
token_account_state=True
)
],
)
},
accounts_data_slice=[
geyser_pb2.SubscribeRequestAccountsDataSlice(offset=0, length=40)
],
)
トランザクション更新の解析
SubscribeUpdateTransaction を受信したら、以下を抽出します。
for update in stream:
if update.HasField("transaction"):
tx = update.transaction
info = tx.transaction
sig = base58.b58encode(info.signature).decode()
slot = tx.slot
msg = info.transaction.message
account_keys = [base58.b58encode(k).decode() for k in msg.account_keys]
# Instructions
for ix in msg.instructions:
program = account_keys[ix.program_id_index]
accounts = [account_keys[i] for i in ix.accounts]
data = ix.data # bytes — decode per program IDL
# Token balance changes (post-execution)
meta = info.meta
for tb in meta.post_token_balances:
mint = tb.mint
owner = tb.owner
amount = tb.ui_token_amount.ui_amount
フィールドの詳細なドキュメントは references/proto_reference.md を参照してください。
本番環境のアーキテクチャ
[gRPC Stream] → [Bounded Channel] → [Processing Workers]
(1K-100K cap) ├─ Parse instructions
├─ Update state / DB
└─ Trigger actions
重要なパターン:
- I/O と処理を分離し、gRPC ストリームを決してブロックしないでください
- 指数バックオフで再接続します(100ms → 上限 60s)
- 切断後の再開には
from_slotを使用します(リオーグへの安全対策として約 32 スロット戻します) - 接続を維持するため、15~30 秒ごとに Ping を送信します
vote: falseで常にフィルターしてください — 投票トランザクションは全トラフィックの約 70% を占めますmax_receive_message_lengthは 64MB 以上に設定してください(デフォルトの 4MB では小さすぎます)
本番環境向けチェックリストの詳細は references/performance.md を参照してください。
取引で使用する主なプログラム ID
| プログラム | アドレス | 機能 |
|---|---|---|
| PumpFun | 6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P | トークンのローンチ、ボンディングカーブ取引 |
| PumpSwap | PSwapMdSai8tjrEXcxFeQth87xC4rRsa4VA5mhGhXkP | PumpFun でローンチを終えたトークンのスワップ |
| Raydium AMM | 675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8 | 従来型 AMM のスワップ |
| Raydium CLMM | CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK | 集中流動性 |
| Raydium CPMM | CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C | 定積型マーケットメイキング |
| Orca Whirlpool | whirLbMiicVdio4qvUfM5KAg6Ct8VwpYzGff3uctyCc | 集中流動性 |
| Meteora DLMM | LBUZKhRxPF3XUpBCjp4YzTKgLccjZhTSDM9YuVaPwxo | ダイナミック流動性マーケットメイキング |
| Jupiter V6 | JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4 | スワップアグリゲーター |
| Token Program | TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA | SPL トークン操作 |
ファイル
リファレンス
references/providers.md— プロバイダーの比較:エンドポイント、料金、認証、機能references/subscription_filters.md— すべてのフィルタータイプの例を含む、完全なフィルターリファレンスreferences/proto_reference.md— 主な protobuf メッセージ定義とフィールドのドキュメントreferences/performance.md— 接続管理、再接続、バックプレッシャー、本番環境向けチェックリスト
スクリプト
scripts/subscribe_transactions.py— プログラム ID でフィルターしたトランザクションをストリーミングして解析scripts/monitor_wallets.py— 特定のウォレットのオンチェーンアクティビティを監視