使用 WebSocket 和 Solana Web3.js 2.0 监控 Solana 账户

  • QuickNode
  • 发布于 2025-01-30 23:18
  • 阅读 17

本文介绍了Solana Web3.js 2.0的主要更新,并详细讲解了如何使用其新的WebSocket订阅系统来监控Solana区块链上的账户余额变化。通过具体的代码示例,指南展示了项目的设置、环境配置和具体实现步骤,特别强调了新API的类型安全性、现代异步迭代和更好的错误处理机制,适合开发者学习及应用于Solana开发。

概述

Solana 最近宣布 Solana Web3.js 2.0,这是他们用于与 Solana 区块链互动的 JavaScript 库的重大更新。在众多新功能中,Solana Web3.js 2.0 引入了一种新的、更强大的方式来处理 WebSocket 订阅,以监控链上事件。这个指南将向你展示如何使用新的订阅系统实现账户监控,该系统提供了比以前版本更好的类型安全性和错误处理。

你将要做的事情

在本指南中,你将学习如何:

  • 使用新的 Web3.js 2.0 API 设置 WebSocket 连接
  • 创建一个账户订阅,以监控 Pump.fun 费用账户的余额变动
  • 处理订阅清理和错误情况
  • 以用户友好的方式格式化和显示余额变动

脚本演示

你将需要的东西

  • Node.js(建议使用版本 20.0 或更高)
  • npm 或 yarn 包管理器
  • 安装 TypeScript 和 ts-node

与 Web3.js 1.0 的主要区别

新的 Web3.js 2.0 订阅系统引入了几个改进:

  1. 类型安全:新的 API 在整个系统中使用 TypeScript 泛型和严格类型。
  2. 现代异步迭代:使用 for await...of 循环而不是回调,符合现代 异步迭代器协议
  3. Abort Controller 集成:提供内置支持的订阅清理,使用 AbortController。如果你不熟悉,AbortController 是一个内置的 JavaScript 类,允许你中止异步操作,如 HTTP 请求或 WebSocket 连接。
  4. 更好的错误处理:改进的错误类型和处理机制。

设置你的环境

1. 创建一个新的项目目录:

mkdir solana-subscriptions-v2 && cd solana-subscriptions-v2

2. 初始化一个新的 npm 项目:

npm init -y

3. 安装所需的依赖:

npm install @solana/web3.js@2

如果你没有全局安装开发依赖,也请安装开发依赖:

npm install --save-dev typescript ts-node @types/node

4. 创建一个 TypeScript 配置文件 (tsconfig.json):

tsc --init

并用以下内容更新配置文件:

{
  "compilerOptions": {
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "noEmit": true,
    "target": "ESNext"
  },
}

创建账户监控器

创建一个名为 app.ts 的新文件,让我们逐步实现账户监控系统。

echo > app.ts

在你的代码编辑器中打开该文件,让我们开始吧!

1. 导入所需的依赖:

app.ts 文件中添加以下导入:

import {
    createSolanaRpcSubscriptions,
    RpcSubscriptions,
    SolanaRpcSubscriptionsApi,
    address,
    Address
} from '@solana/web3.js';

2. 定义常量:

在你的导入下方添加以下常量:

const WSS_PROVIDER_URL = 'wss://your-quicknode-endpoint.example';
const LAMPORTS_PER_SOL = 1_000_000_000;
const PUMP_FUN_FEE_ACCOUNT = address("CebN5WGQ4jvEPvsVU4EoHEpgzq1VV7AbicfhtW4xC9iM");

要在 Solana 上进行开发,你需要一个 API 端点来连接网络。

查看为什么超过 50% 的 Solana 项目选择 QuickNode,并在 这里 注册一个免费帐户。我们将使用 Solana 主网端点。

Solana 主网端点

复制 WSS 提供者链接并更新你的 WSS_PROVIDER_URL 常量以匹配该链接。

我们将监控 Pump.fun 费用账户 ( CebN5WGQ4jvEPvsVU4EoHEpgzq1VV7AbicfhtW4xC9iM ) 的余额变动,但你可以自由使用任何你喜欢的 Solana 账户。请注意 Solana Web3.js 2.0 库要求我们使用来自 @solana/web3.js 库的 Address 类型,我们可以使用库中的 address 函数从字符串创建一个 Address

3. 定义辅助函数:

在你的常量下方添加以下辅助函数:

const lamportsToSolString = (lamports: number, includeUnit = true): string => {
    const solAmount = lamports / LAMPORTS_PER_SOL;
    return `${solAmount.toLocaleString('en-US', {
        minimumFractionDigits: 2,
        maximumFractionDigits: 2
    })} ${includeUnit ? 'SOL' : ''}`;
};

此函数将以两位小数的形式将 lamports 格式化为 SOL,并可选择在字符串中包含单位(SOL)。

4. 定义接口:

让我们创建一个接口来定义我们的跟踪函数的参数:

interface TrackAccountArgs {
    rpcSubscriptions: RpcSubscriptions<SolanaRpcSubscriptionsApi>;
    accountAddress: Address;
    abortSignal: AbortSignal;
}

在前面的部分,我们讨论过 AddressAbortSignal,现在快速了解一下 RpcSubscriptionsSolanaRpcSubscriptionsApi

在新的 Web3.js 2.0 API 中,曾经通过 Connection 类暴露的方法现在通过两个类暴露:RpcRpcSubscriptions,一个用于 HTTP 请求,一个用于 WebSocket。RpcSubscriptions 类提供访问用于追踪链上事件(例如,账户变化、程序变化、日志、插槽等)的 WebSocket 方法。有关更多信息,请查看我们的 文档

5. 创建账户跟踪函数:

在你的 app.ts 文件中添加以下内容。我们将分步讲解它:

async function trackAccount({ rpcSubscriptions, accountAddress, abortSignal }: TrackAccountArgs) {
    let lastLamports: number | null = null;

    try {
        const accountNotifications = await rpcSubscriptions
            .accountNotifications(accountAddress, { commitment: 'confirmed' })
            .subscribe({ abortSignal });

        try {
            for await (const notification of accountNotifications) {
                const { slot } = notification.context;
                const currentLamports = Number(notification.value.lamports);
                const delta = lastLamports !== null ? currentLamports - lastLamports : 0;
                const sign = delta > 0 ? '+' : delta < 0 ? '-' : ' ';
                console.log(`   在插槽 ${slot.toLocaleString()} 检测到账户变化。新余额:${lamportsToSolString(currentLamports)} (${sign}${lamportsToSolString(Math.abs(delta))})`);
                lastLamports = currentLamports;
            }
        } catch (error) {
            throw error;
        }
    } catch (error) {
        throw error;
    }
}

让我们逐步解析它:

  1. 首先,我们定义一个名为 lastLamports 的变量并将其设置为 null。该变量将用于存储账户的最后已知余额,以便我们在每次接收到新通知时计算增量。
  2. 接下来,我们创建一个 try/catch 块来处理创建订阅时的错误。
  3. try 块内,我们调用 accountNotifications 方法(类似于 v1 库中的 onAccountChange 方法),在 rpcSubscriptions 对象上,传入 accountAddresscommitment 选项。我们还传入 abortSignal,以在需要时取消订阅。
  4. 接下来,我们创建一个 try/catch 块来处理处理通知时的错误。
  5. try 块内,我们使用 for await...of 循环来迭代从订阅中接收到的通知。我们从 context 中获取 slot,从每个通知的 value 中获取 lamports,并轻松处理以将余额变化记录到控制台中。

6. 创建入口点:

在你的 app.ts 文件中添加以下内容以执行你的跟踪函数:

async function main() {
    console.log(`💊 正在跟踪 Pump.fun 费用账户: ${PUMP_FUN_FEE_ACCOUNT} 💊`);
    const rpcSubscriptions = createSolanaRpcSubscriptions(WSS_PROVIDER_URL);
    const abortController = new AbortController();
    try {
        await trackAccount({
            rpcSubscriptions,
            accountAddress: PUMP_FUN_FEE_ACCOUNT,
            abortSignal: abortController.signal
        });
    } catch (e) {
        console.log('订阅错误', e);
    } finally {
        abortController.abort();
    }
}

main();

我们实际上为我们的脚本创建了一个入口点,当我们使用 ts-node 运行脚本时会执行该脚本。我们将在文件底部调用 main 函数。main 函数将使用我们的 WSS_PROVIDER_URL 创建一个新的 RpcSubscriptions 类实例,我们将使用它创建我们的订阅。然后我们将调用 trackAccount 函数,传入 RpcSubscriptions 实例、PUMP_FUN_FEE_ACCOUNT 地址和 abortController.signal

现在,让我们运行我们的脚本。

运行监控器

准备好后,使用 ts-node 运行你的脚本:

ts-node app.ts

监控器将开始跟踪指定账户的变化,并以以下格式显示余额变化:

在插槽 301,428,932 检测到账户变化。新余额:265,598.16 SOL (+0.14 SOL)

干得不错! 🚀 🚀 🚀

计费和优化

WebSocket 方法的计费积分基于收到的响应次数,而不是创建的订阅次数。例如,如果你打开一个 accountNotifications 订阅并收到 100 个响应,你的账户将被收取 2,000 积分( 每个响应 20 积分 X 100 个响应)。查看 API 积分页面 以获取更新的计费费率。

为了优化你的订阅并确保不会因不必要的订阅或无关响应而产生费用,你应该考虑以下几点:

  • 使用 AbortController 或其他订阅逻辑,在不再需要时取消订阅。
  • 利用适用方法的过滤器,只接收相关数据。

替代方案

QuickNode 提供 多种解决方案以获取 Solana 的实时数据。查看以下选项,找到适合你用例的合适工具:

  • WebSockets:正如本指南中讨论的,WebSockets 提供直接连接到 Solana 节点以获取实时更新,适合简单应用和快速开发。
  • Yellowstone gRPC Geyser 插件:Yellowstone gRPC Geyser 插件提供强大的 gRPC 接口,用于流式 Solana 数据,内置过滤和历史数据支持。
  • Streams:管理解决方案,可将 Solana 数据处理并路由到多个目的地,内置过滤和历史数据支持。

欲了解更多信息,请查看我们的 博客文章

结论

Web3.js 2.0 提供了一种更强大、类型安全的方式来处理 Solana WebSocket 订阅。新的 API 使管理订阅、处理错误和正确清理资源变得更容易。当构建需要监控 Solana 区块链事件的应用程序时,这些新功能有助于创建更可靠和可维护的代码。

我们 ❤️ 反馈!

告诉我们 如果你有任何反馈或对新主题的请求。我们很想听听你的想法。

欲了解更多信息,请查看:

  • 原文链接: quicknode.com/guides/sol...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
QuickNode
QuickNode
江湖只有他的大名,没有他的介绍。