跳转到主要内容

概述

Yellowstone gRPC 提供两种相关但不同的订阅类型来追踪网络进度:
  • Slot — 轻量级更新,指示 Slot 何时达到 processedconfirmedfinalized 承诺。低带宽,适合共识监控。
  • 区块 — 完整区块数据,包括交易、账户更新和条目。较高带宽,适合索引器和分析。

Slot 订阅

过滤参数

参数类型描述
filterByCommitmentbooleantrue 时,仅发出与订阅承诺级别匹配的 Slot 更新。为 false(默认)时,发出所有承诺级别的更新。
interslotUpdatesbooleantrue 时,发出 Slot 内的状态变化,而不仅仅是 Slot 边界。适合精细的实时监控。

示例:追踪已确认 Slot

import Client, { CommitmentLevel, SubscribeRequest } from "@triton-one/yellowstone-grpc";

const client = new Client(
  "https://your-endpoint.grpc.orbitflare.com",
  "YOUR_GRPC_TOKEN",
  { "grpc.max_receive_message_length": 64 * 1024 * 1024 }
);

async function main() {
  const stream = await client.subscribe();

  const streamClosed = new Promise<void>((resolve, reject) => {
    stream.on("error", (error) => { reject(error); stream.end(); });
    stream.on("end", () => resolve());
    stream.on("close", () => resolve());
  });

  stream.on("data", (data) => {
    if (data.slot) {
      const { slot, parent, status } = data.slot;
      console.log(`Slot ${slot}(父 Slot: ${parent})— 状态: ${status}`);
    }
  });

  const request: SubscribeRequest = {
    slots: {
      slotUpdates: {
        filterByCommitment: true,
      },
    },
    commitment: CommitmentLevel.CONFIRMED,
    accounts: {},
    accountsDataSlice: [],
    transactions: {},
    transactionsStatus: {},
    blocks: {},
    blocksMeta: {},
    entry: {},
    ping: { id: 1 },
  };

  await new Promise<void>((resolve, reject) => {
    stream.write(request, (err) => {
      if (err == null) resolve(); else reject(err);
    });
  });

  await streamClosed;
}

main();

区块订阅

过滤参数

参数类型描述
accountIncludestring[]过滤区块内的交易和账户更新,仅包含这些账户。
includeTransactionsboolean在每个区块更新中包含完整交易数据。
includeAccountsboolean在每个区块更新中包含账户状态更新。
includeEntriesboolean在每个区块更新中包含条目(执行单元)。
启用 includeTransactions: true 且没有账户过滤的区块订阅会产生非常大的数据量。使用 accountInclude 将流缩小到您关心的账户,或结合专用节点以维持持续吞吐量。

示例:流式传输带交易的区块

import Client, { CommitmentLevel, SubscribeRequest } from "@triton-one/yellowstone-grpc";

const client = new Client(
  "https://your-endpoint.grpc.orbitflare.com",
  "YOUR_GRPC_TOKEN",
  { "grpc.max_receive_message_length": 1024 * 1024 * 1024 }
);

async function main() {
  const stream = await client.subscribe();

  stream.on("data", (data) => {
    if (data.block) {
      const { block } = data;
      console.log(`区块 Slot: ${block.slot}`);
      console.log(`  区块哈希: ${block.blockhash}`);
      console.log(`  交易数: ${block.transactions?.length ?? 0}`);
    }
  });

  const request: SubscribeRequest = {
    blocks: {
      blockStream: {
        accountInclude: [
          "675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8", // Raydium AMM
        ],
        includeTransactions: true,
        includeAccounts: false,
        includeEntries: false,
      },
    },
    commitment: CommitmentLevel.CONFIRMED,
    accounts: {},
    accountsDataSlice: [],
    transactions: {},
    transactionsStatus: {},
    slots: {},
    blocksMeta: {},
    entry: {},
    ping: { id: 1 },
  };

  await new Promise<void>((resolve, reject) => {
    stream.write(request, (err) => {
      if (err == null) resolve(); else reject(err);
    });
  });

  const streamClosed = new Promise<void>((resolve, reject) => {
    stream.on("error", (e) => { reject(e); stream.end(); });
    stream.on("end", () => resolve());
    stream.on("close", () => resolve());
  });

  await streamClosed;
}

main();

如何选择 Slot 与区块订阅

需求使用
检测 Slot 何时最终确定Slot 订阅(filterByCommitment: true
追踪区块高度进度Slot 订阅
索引区块中的所有交易区块订阅(includeTransactions: true
监控每个区块的账户状态变化区块订阅(includeAccounts: true
最低延迟共识信号processed 级别的 Slot 订阅
完整归档质量区块数据finalized 级别的区块订阅