メインコンテンツへスキップ

Monitor Solana Accounts Using WebSockets and Solana Kit

更新日:
2026年6月1日

読了時間:8分

🛠️ 更新のお知らせ

このガイドは、Solana Web3.js 2.0の新しい名称「Solana Kit」を反映するよう更新されました。皆様が常に最新の状態を維持できるよう、最新のベストプラクティスに従っています。Solana Kit の詳細については、こちらをご覧ください

概要

In September 2024, Solana announced Solana Web3.js 2.0 - now known as Solana Kit - a major update to their JavaScript library for interacting with the Solana blockchain. Among many other things, Solana Kit introduces a new, more robust way to handle WebSocket subscriptions for monitoring on-chain events. This guide will show you how to implement account monitoring using the new subscription system, which provides better type safety and error handling than the previous version.

主な業務内容

In this guide, you'll learn how to:

  • Set up a WebSocket connection using the new @solana/kit API
  • Create an account subscription to monitor balance changes of the Pump.fun Fee Account
  • Handle subscription cleanup and error cases
  • Format and display balance changes in a user-friendly way

Script demo

必要なもの

  • Node.js (version 20.0 or higher recommended)
  • npm or yarn package manager
  • TypeScript and ts-node installed

Key Differences from Web3.js 1.0

The new @solana/kit subscription system introduces several improvements:

  1. Type Safety: The new API uses TypeScript generics and strict typing throughout.
  2. Modern Async Iteration: Uses for await...of loops instead of callbacks, conforming to the modern async iterator protocol.
  3. Abort Controller Integration: Built-in support for subscription cleanup using AbortController. If you are unfamiliar, AbortController is a built-in JavaScript class that allows you to abort asynchronous operations, such as HTTP requests or WebSocket connections.
  4. Better Error Handling: Improved error types and handling mechanisms.

環境のセットアップ

1. Create a new project directory:

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

2. Initialize a new npm project:

npm init -y

3. Install the required dependencies:

npm install @solana/kit

And the dev dependencies if you do not have them installed globally:

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

4. Create a TypeScript configuration file (tsconfig.json):

tsc --init 

And update the configuration file with the following content:

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

Creating the Account Monitor

「」という名前の新しいファイルを作成します。 app.ts, and let's implement the account monitoring system step by step.

echo > app.ts

Open the file in your code editor, and let's get started!

1. Import the required dependencies:

Add the following imports to your app.ts file:

import {
createSolanaRpcSubscriptions,
RpcSubscriptions,
SolanaRpcSubscriptionsApi,
address,
Address
} from '@solana/kit';

2. Define constants:

Below your imports, add the following constants:

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

To build on Solana, you'll need an API endpoint to connect with the network.


See why over 50% of projects on Solana choose Quicknode and sign up for an account here. We're going to use a Solana Mainnet endpoint.

Solana Mainnet Endpoint

Copy the WSS Provider Link and update your WSS_PROVIDER_URL constant to match the link.

We are going to be monitoring the Pump.fun Fee Account (CebN5WGQ4jvEPvsVU4EoHEpgzq1VV7AbicfhtW4xC9iM)for balance changes, but feel free to use any Solana account you'd like. Note that the @solana/kit library requires that we use the Address type from the @solana/kit library--we can create an Address from a string using the 住所 function from the library.

3. Define helper functions:

Add the following helper function below your constants:

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

This function will format lamports as SOL with two decimal places and optionally include the unit (SOL) in the string.

4. Define interface:

Let's create an interface to define the arguments for our tracking function:

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

In the previous sections, we discussed Address and AbortSignal, so let's quickly touch on RpcSubscriptions and SolanaRpcSubscriptionsApi.

In the new Solana Kit API, the methods that used to be exposed through the Connection class are now exposed via two classes: Rpc and RpcSubscriptions, one for HTTP requests and one for WebSockets. The RpcSubscriptions class gives access to WebSocket methods for tracking on-chain events (e.g., account changes, program changes, logs, slots, etc). Check out our docs for more information.

5. Create account tracking function:

以下の内容をあなたの app.ts file. We will walk through it step by step below:

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(` Account change detected at slot ${slot.toLocaleString()}. New Balance: ${lamportsToSolString(currentLamports)} (${sign}${lamportsToSolString(Math.abs(delta))})`);
lastLamports = currentLamports;
}
} catch (error) {
throw error;
}
} catch (error) {
throw error;
}
}

これを詳しく見ていきましょう:

  1. First, we define a variable called lastLamports and set it to null. This variable will be used to store the last known balance of the account so we can calculate the delta each time we receive a new notification.
  2. Next, we create a try/catch block to handle errors when creating our subscription.
  3. 内部の try block, we call the accountNotifications method (similar to the onAccountChange method in the v1 library) on the rpcSubscriptions object, passing in the accountAddress そして commitment options. We also pass in the abortSignal to cancel the subscription if needed.
  4. Next, we create a try/catch block to handle errors when processing the notifications.
  5. 内部の try block, we use a for await...of loop to iterate over the notifications received from the subscription. We get the スロット from the 文脈 そして、その ラムポート from the of each notification, and we do some light processing to log the balance change to the console.

6. Create Entry Point:

以下の内容をあなたの app.ts file to execute your tracking function:

async function main() {
console.log(`💊 Tracking Pump.fun Fee Account: ${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('Subscription error', e);
} finally {
abortController.abort();
}
}

main();

We are effectively creating an entry point for our script, which will be executed when we run our script using ts-node. We will call the メイン function at the bottom of the file. The メイン function will use our WSS_PROVIDER_URL to create a new instance of the RpcSubscriptions class, which we will use to create our subscription. We will then call the trackAccount function, passing in the RpcSubscriptions instance, the PUMP_FUN_FEE_ACCOUNT address, and the abortController.signal.

Now, let's run our script.

モニターの実行

When you are ready, run your script using ts-node:

ts-node app.ts

The monitor will start tracking changes to the specified account and display balance changes in this format:

Account change detected at slot 301,428,932. New Balance: 265,598.16 SOL (+0.14 SOL)

Nice job! 🚀 🚀 🚀

課金と最適化

Billing credits for WebSocket methods are based on the number of responses received, not the number of subscriptions created. For example, if you open an accountNotifications subscription and receive 100 responses, your account will be billed 2,000 credits (20 credits per response X 100 responses). Check the API credits page for updated billing rates.

購読内容を最適化し、不要な購読や関係のない返信による課金を防ぐためには、以下の点をご検討ください:

  • use AbortController or other subscription logic to cancel subscriptions when they are no longer needed.
  • 該当するメソッドのフィルターを活用し、関連するデータのみを受け取るようにします。

代替案

Quicknodeでは、Solanaからリアルタイムデータを取得するためのいくつかのソリューションを提供しています。以下のオプションを確認し、ご自身のユースケースに適したツールを見つけてください:

  • WebSockets: As discussed in this guide, WebSockets offer direct connections to Solana nodes for real-time updates--these are ideal for simple applications and rapid development.
  • Solana gRPC(Yellowstone互換のGeyser gRPC):Solana gRPCは、Solanaデータのストリーミングを行うための強力なgRPCインターフェースを提供し、フィルタリング機能や履歴データのサポートが組み込まれています。
  • Streams:Solanaデータの処理および複数の宛先へのルーティングを行うマネージドソリューション。フィルタリング機能と履歴データのサポートが組み込まれています。

詳細については、当社のブログ記事をご覧ください。

結論

Solana Kit provides a more robust, type-safe way to handle Solana WebSocket subscriptions. The new API makes it easier to manage subscriptions, handle errors, and clean up resources properly. When building applications that need to monitor Solana blockchain events, these new features help create more reliable and maintainable code.

皆様からのフィードバックを心よりお待ちしております!❤️

ご意見や新しいトピックに関するご要望などがありましたら、ぜひお知らせください。皆様からのご連絡を心よりお待ちしております。

For more information, check out:

このガイドをシェアする