用TypeScript实时监控Solana账户:Solana Web3.js 2.0 & WebSocket完全指南

·

本文手把手教你用新版 Solana Web3.js 2.0WebSocket 订阅实时监控任意 Solana 账户余额变动,附完整 TypeScript 示例与环境配置。

概述:为什么升级 Solana Web3.js 2.0

最新的 Solana Web3.js 2.0 带来了更健壮的 WebSocket 订阅系统,显著提升:

你将在本指南完成:

  1. 建立稳定 WebSocket 连接。
  2. 订阅关注账户并格式化余额变化。
  3. 优雅中断连接,避免额外 API 积分消耗。
  4. 提取可复用的监控模板。

你将需要

👉 立即体验一键比特币购入,轻松做链上开发燃料!


新旧差异对比:1.0 vs 2.0

维度v1.xv2.0
API 风格回调地狱AsyncIterable
错误处理单一 throw多粒度 Error 类型
资源清理手动 close内置 AbortSignal
类型任意 any严格 Address, Commitment

五步部署实战

以下示例以 Pump.fun 费用账户 为例,亦可替换为你想追踪的任意地址。

1. 初始化项目

mkdir solana-sub-v2 && cd solana-sub-v2
npm init -y
npm install @solana/web3.js@2
npm install -D typescript ts-node @types/node
tsc --init

在生成的 tsconfig.json 中确认:

"module": "NodeNext",
"target": "ESNext"

2. 写入关键常量

新建 app.ts,头部声明:

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

const WSS_PROVIDER_URL = 'wss://your-node-endpoint.example';   // 替换成你的 WebSocket RPC
const LAMPORTS_PER_SOL = 1_000_000_000;
const PUMP_FUN_FEE_ACCOUNT = address("CebN5WGQ4jvEPvsVU4EoHEpgzq1VV7AbicfhtW4xC9iM");

3. helper 函数:Lamports → SOL 输出

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

4. 核心监控函数

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

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

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

  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)} SOL (${sign}${lamportsToSolString(Math.abs(delta))})`);
    lastLamports = currentLamports;
  }
}

5. 启动入口

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.error('订阅异常:', e);
  } finally {
    abortController.abort();
    console.log('✅ 清理完成');
  }
}
main();

一键运行:

ts-node app.ts

计费与优化技巧


常见疑问解答 FAQ

Q1:我的 WebSocket 经常断开怎么办?
A:请检查节点稳定性,或考虑配置 Yellowstone gRPC Geyser 插件 获取更强健流式结构。

Q2:能一次订阅多个地址吗?
A:目前需各自调用 accountNotifications,但可并行运行多个 AbortSignal 实现秒级取消。

Q3:是否一定要 TypeScript?
A:JS 亦可运行,只是会失去 类型安全IDE 智能提示 优势。

Q4:LAMPORTS 与 SOL 单位总是混淆?
A:牢记 1 SOL = 1,000,000,000 Lamports,可用 export const LAMPORTS_PER_SOL = 1_000_000_000 作为常量以防手滑。

Q5:如何排除垃圾推送?
A:使用 filters 参数或升级到 gRPC 高级过滤算子,如只接收 >100 Lamports 变化。

Q6:代码能否部署到浏览器?
A:Solana Web3.js 2.0 完全支持浏览器,可配合 Vite/webpack 打包。


进阶替代方案

若流量大或需要 历史回滚,可研究:


下一步:让监控更懂你

本文模板高度通用,替换 PUMP_FUN_FEE_ACCOUNT 即可追踪你的 DAO 金库、NFT 铸造账户或节点奖励地址。

保持关注更新
👉 深入探索黄色石 gRPC 的 5 个灰度实战技巧