跳转到主要内容

概述

LaserStream的gRPC服务基于Yellowstone接口,并通过历史重放、多节点故障转移和完全托管环境等功能加以增强。 LaserStream使用开源的gRPC协议,确保没有供应商锁定,并与现有的gRPC实现最大限度兼容。 您可以直接使用 @yellowstone-grpc 进行连接,或者使用性能优化的 Helius LaserStream SDK 来获得额外的优势,包括更高的吞吐量、自动重连、订阅管理、错误处理等。

LaserStream SDK比JavaScript Yellowstone客户端快40倍

了解我们如何使用Rust Core与零拷贝NAPI绑定来最大化JavaScript SDK的性能
性能提示:如果您在使用LaserStream连接时遇到任何延迟或性能问题,请参考故障排除部分以了解常见原因和解决方案。
压缩:我们强烈不建议使用 gZip 压缩,推荐使用 zstd。gZip 的压缩和解压速度非常慢,会成为流处理的瓶颈。zstd 提供类似的压缩比,同时提供显著更快的压缩和解压带宽。未来将不再支持 gZip。

终端节点和地区

LaserStream 在全球多个地区提供。 选择离您的应用程序最近的终端节点以获得最佳性能:

Mainnet LaserStream 终端节点

地区位置终端节点
ewr纽瓦克,新泽西(纽约附近)https://laserstream-mainnet-ewr.helius-rpc.com
pitt匹兹堡,美国(中部)https://laserstream-mainnet-pitt.helius-rpc.com
slc盐湖城,美国(西海岸)https://laserstream-mainnet-slc.helius-rpc.com
lax洛杉矶,美国(西海岸)https://laserstream-mainnet-lax.helius-rpc.com
lon伦敦,欧洲https://laserstream-mainnet-lon.helius-rpc.com
ams阿姆斯特丹,欧洲https://laserstream-mainnet-ams.helius-rpc.com
fra法兰克福,欧洲https://laserstream-mainnet-fra.helius-rpc.com
tyo东京,亚洲https://laserstream-mainnet-tyo.helius-rpc.com
sgp新加坡,亚洲https://laserstream-mainnet-sgp.helius-rpc.com

Devnet LaserStream 终端节点

网络位置终端节点
Devnet纽瓦克,新泽西(纽约附近)https://laserstream-devnet-ewr.helius-rpc.com
网络和地区选择
  • 对于 生产应用,选择最靠近服务器的 mainnet 终端节点以获得最佳性能(例如,如果在欧洲部署,请使用阿姆斯特丹 (ams) 或法兰克福 (fra))
  • 对于 测试,使用:https://laserstream-devnet-ewr.helius-rpc.com

快速入门

有兴趣尝试 LaserStream 吗?申请免费试用
1

创建新项目

mkdir laserstream-grpc-demo
cd laserstream-grpc-demo
npm init -y
2

安装依赖项

npm install helius-laserstream
npm install --save-dev typescript ts-node
npx tsc --init
3

获取您的 API 密钥

Helius Dashboard 生成密钥。此密钥将作为 LaserStream 的身份验证令牌。
计划要求:LaserStream devnet 需要开发者或商务计划。LaserStream mainnet 需要专业计划。
4

创建订阅脚本

创建 index.ts,如下所示:
import { subscribe, CommitmentLevel, LaserstreamConfig, SubscribeRequest } from 'helius-laserstream'

async function main() {
  const subscriptionRequest: SubscribeRequest = {
    transactions: {
      client: {
        accountInclude: ['TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA'],
        accountExclude: [],
        accountRequired: [],
        vote: false,
        failed: false
      }
    },
    commitment: CommitmentLevel.CONFIRMED,
    accounts: {},
    slots: {},
    transactionsStatus: {},
    blocks: {},
    blocksMeta: {},
    entry: {},
    accountsDataSlice: [],
    // Optionally, you can replay missed data by specifying a fromSlot:
    // fromSlot: '224339000'
    // Note: Currently, you can only replay data from up to 216000 slots in the past (24 hours).
  };

// Replace the values below with your actual LaserStream API key and endpoint
const config: LaserstreamConfig = {
  apiKey: 'YOUR_API_KEY', // Replace with your key from https://dashboard.helius.dev/
  endpoint: 'https://laserstream-mainnet-ewr.helius-rpc.com', // Choose your closest region
}

  await subscribe(config, subscriptionRequest, async (data) => {
    
    console.log(data);

  }, async (error) => {
    console.error(error);
  });
}

main().catch(console.error);
5

替换您的API密钥并选择您的区域

index.ts中,更新config对象:
  1. 您的实际API密钥来自Helius Dashboard
  2. 离您的服务器位置最近的LaserStream端点
const config: LaserstreamConfig = {
  apiKey: 'YOUR_ACTUAL_API_KEY', // Replace with your key from Helius Dashboard
  endpoint: 'https://laserstream-mainnet-fra.helius-rpc.com', // Example: Frankfurt mainnet
  // For devnet: endpoint: 'https://laserstream-devnet-ewr.helius-rpc.com'
}
网络和区域选择示例:
  • 用于生产(Mainnet)
    • 欧洲:使用fra(法兰克福)、ams(阿姆斯特丹)或lon(伦敦)
    • 美国东部:使用ewr(纽约)
    • 美国西部:使用slc(盐湖城)或lax(洛杉矶)
    • 亚洲:使用tyo(东京)或sgp(新加坡)
  • 用于开发(Devnet)
    • 使用https://laserstream-devnet-ewr.helius-rpc.com
6

运行并查看结果

npx ts-node index.ts
每当一个confirmed令牌交易涉及TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA时,您将在控制台中看到数据。

订阅请求

在订阅请求中,您需要包含以下常规参数:
历史重播: 您可以选择在主SubscribeRequest对象中包含一个fromSlot: string字段,以便从特定槽开始重播数据。目前,支持重播过去最多216,000个槽(24小时)的数据。
const subscriptionRequest: SubscribeRequest = {
  commitment: CommitmentLevel.CONFIRMED,
  accountsDataSlice: [],
  transactions: {},
  accounts: {},
  slots: {},
  blocks: {},
  blocksMeta: {},
  entry: {},
}
接下来,您需要指定要订阅的数据过滤器,如帐户、区块、槽或交易。
为槽位更新定义过滤器。您使用的键(例如,mySlotLabel)是此特定过滤器配置的用户定义标签,这使您可以根据需要定义多个命名配置(尽管通常只需一个即可)。
slots: {
  // mySlotLabel is a user-defined name for this slot update filter configuration
  mySlotLabel: {
    // filterByCommitment: true => Only broadcast slot updates at the specified subscribeRequest commitment
    filterByCommitment: true
    // interslotUpdates: true allows receiving updates for changes occurring within a slot, not just new slots.
    interslotUpdates: true
  }
},
为账户数据更新定义过滤器。您使用的键(例如,tokenAccounts)是此特定过滤器配置的用户定义标签如果所有字段为空,则广播所有账户。否则:
  • 字段作为逻辑AND操作。
  • 数组内的值作为逻辑OR操作(除非在filters内,它们作为逻辑AND操作)。
accounts: {
  // tokenAccounts is a user-defined label for this account filter configuration
  tokenAccounts: {
    // Matches any of these public keys (logical OR)
    account: ["9SHQTA66Ekh7ZgMnKWsjxXk6DwXku8przs45E8bcEe38"],
    // Matches owners that are any of these public keys
    owner: ["TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"],
    // Filters - all must match (AND logic)
    filters: [
      { dataSize: 165 },
      {
        memcmp: {
          offset: 0,
          data: { base58: "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" }
        }
      }
    ]
  }
},
为交易更新定义过滤器。您使用的键(例如,myTxSubscription)是此特定过滤器配置的用户定义标签如果所有字段为空,则广播所有交易。否则:
  • 字段操作为逻辑AND
  • 数组内的值被视为逻辑OR(除了 accountRequired,必须全部匹配)。
transactions: {
  // myTxSubscription is a user-defined label for this transaction filter configuration
  myTxSubscription: {
    vote: false,
    failed: false,
    signature: "",
    // Transaction must include at least one of these public keys (OR)
    accountInclude: ["86xCnPeV69n6t3DnyGvkKobf9FdN2H9oiVDdaMpo2MMY"],
    // Exclude if it matches any of these
    accountExclude: [],
    // Require all accounts in this array (AND)
    accountRequired: []
  }
},
为区块更新定义过滤器。你使用的键(例如,myBlockLabel)是此特定过滤器配置的用户定义标签
blocks: {
  // myBlockLabel is a user-defined label for this block filter configuration
  myBlockLabel: {
    // Only broadcast blocks referencing these accounts
    accountInclude: ["86xCnPeV69n6t3DnyGvkKobf9FdN2H9oiVDdaMpo2MMY"],
    includeTransactions: true,
    includeAccounts: false,
    includeEntries: false
  }
},
功能类似于区块,但不包括交易、帐户和条目。您使用的键(例如,blockmetadata)是此订阅的用户定义标签。目前,区块元数据没有可用的过滤器——所有消息默认广播。
blocksMeta: {
  blockmetadata: {}
},
订阅分类帐条目。您使用的键(例如,entrySubscribe)是此订阅的用户定义标签。目前,没有可用的条目过滤器;所有条目都被广播。
entry: {
  entrySubscribe: {}
},

代码示例(LaserStream SDK)

import { subscribe, CommitmentLevel, LaserstreamConfig, SubscribeRequest } from 'helius-laserstream'

async function main() {
    const subscriptionRequest: SubscribeRequest = {
        transactions: {},
        commitment: CommitmentLevel.CONFIRMED,
        accounts: {},
        slots: {
            slot: { filterByCommitment: true },
        },
        transactionsStatus: {},
        blocks: {},
        blocksMeta: {},
        entry: {},
        accountsDataSlice: [],
    };

    const config: LaserstreamConfig = {
        apiKey: 'YOUR_API_KEY', // Replace with your key
        endpoint: 'https://laserstream-mainnet-ewr.helius-rpc.com', // Choose your closest region
    }

    await subscribe(config, subscriptionRequest, async (data) => {
        console.log(data);
    }, async (error) => {
        console.error(error);
    });
}

main().catch(console.error);

SDK 选项

我们为多种编程语言提供官方 SDK: 对于其他语言或自定义实现,您可以直接使用 Yellowstone gRPC proto 文件 来生成您偏好的语言的 gRPC 客户端。

疑难解答 / 常见问题

答: LaserStream 连接的性能问题通常由以下原因造成:
  • JavaScript 客户端缓慢:JavaScript 客户端可能因为处理过多的消息或消耗过多的带宽而滞后。考虑更精准地过滤您的订阅以减少消息量,切换到 LaserStream JavaScript SDK,或尝试使用其他语言。
  • 本地带宽有限:大量订阅可能会使带宽有限的客户端负担过重。监控您的网络使用情况,考虑升级您的连接或减少订阅范围。
  • 地理距离:较长的网络路径增加了延迟和数据包丢失。使用靠近您服务器的端点。对于高延迟连接,增加网络读取缓冲区大小(可以提高 5 倍以上的带宽):
    sudo sysctl -w net.core.rmem_max=67108864 net.ipv4.tcp_rmem="4096 87380 67108864"
    
    要在重启后保持生效,添加到 /etc/sysctl.conf
    net.core.rmem_max=67108864
    net.ipv4.tcp_rmem=4096 87380 67108864
    
    增加 HTTP/2 流窗口大小到 64MB 以防止流控瓶颈:
    // Rust (tonic)
    Channel::from_static("https://laserstream-mainnet-ewr.helius-rpc.com")
        .initial_stream_window_size(1024 * 1024 * 64)  // 64MB window
        .connect()
        .await?;
    
  • 客户端处理瓶颈:确保您的消息处理逻辑经过优化,不会长时间阻塞主线程。
调试客户端延迟:为帮助您调试客户端,我们构建了一个工具来测试从您的节点到 Laserstream gRPC 服务器的最大带宽。要使用它运行:
cargo install helius-laserstream-bandwidth
helius-laserstream-bandwidth --laserstream-url $LASERSTREAM_URL --api-key $API_KEY
输出返回您的服务器与Laserstream服务器之间的最大网络容量。最低需要10MB/s来订阅所有交易数据,80MB/s来订阅所有账户数据。我们建议至少具备要求容量的2倍以获得最佳性能。
A: 请确认您的API密钥和端点是正确的,并且您的网络允许到指定端点的出站gRPC连接。检查Helius状态页面是否有任何正在进行的事件。
A: 请仔细检查过滤器部分描述的逻辑运算符(AND/OR)。确保公钥是正确的。检查您请求中指定的承诺级别。
A: 可以,您可以在同一个SubscribeRequest对象中,在多个键下定义过滤器配置(例如,accounts, transactions)。
A: 我们不实现消费者组。相反,LaserStream提供团队所需的相同结果:恢复、重放和多节点可靠性,而无需协调层(以及随之而来的延迟/开销)。我们认为对于大多数工作负载来说,消费者组是不必要的,并且它们增加了延迟和操作开销。例如,单个LaserStream gRPC连接可以发出高达10倍Solana的交易+账户数据,大多数客户端订阅一个小的、经过过滤的片段。在这种情况下使用消费者组会消耗性能余地并引入另一个故障点。