Tutorial : How to Listen to Live Account Changes with Websockets on Solana
A in-depth tutorials that will guide you through the process of building on Solana
Solana is a fast, scalable, and low-cost blockchain that supports various applications and use cases. One of the features that makes Solana unique is its websocket API, which allows developers to subscribe to real-time events and notifications on the network. This can be very useful for building applications that require fast and continuous data exchange, such as chat, gaming, or streaming.
In this tutorial, we will show you how to use the Solana web3.js library to connect to a Solana websocket endpoint and listen to live account changes. This means that you will be able to monitor and react to any changes in the state of any account on the Solana blockchain, such as its data, lamports (the smallest unit of SOL), or token balance. This can be very helpful for tracking your own wallet balance, monitoring the activity of other accounts, or implementing custom logic based on account updates.
To follow along, you will need:
- Node.js and npm installed on your machine
- A Solana wallet with some SOL and SPL tokens
- A text editor and a terminal
You can also find the complete code for this tutorial in this GitHub repository.
Let's get started!
Step 1: Create a project folder and install dependencies
First, create a new folder for your project and navigate to it in your terminal. Then, run the following commands to initialize a Node.js project and install the required libraries:
npm init -y
npm install @solana/web3.js @solana/spl-token
This will create a package.json file and a node_modules folder in your project directory.
We will use the @solana/web3.js library to interact with the Solana network and the websocket API. We will also use the @solana/spl-token library to decode and display the token balance of SPL token accounts.
Step 2: Create an index.js file and import the libraries
Next, create an index.js file in your project folder and open it in your text editor. Then, add the following lines of code to import the libraries we installed
const web3 = require('@solana/web3.js');
const splToken = require('@solana/spl-token')
These are the modules we will use to communicate with the Solana network and the SPL token program.
Step 3: Connect to a Solana cluster and get an account address
Now, we need to connect to a Solana cluster and get an account address that we want to monitor. For this tutorial, we will use the devnet cluster, which is a public test network that anyone can use for development purposes. You can also use other clusters, such as mainnet-beta or testnet, by changing the cluster URL.
To connect to a cluster, we need to create a web3.Connection object and pass it the cluster URL. We can use the web3.clusterApiUrl function to get the URL for a given cluster name.
For example:
const connection = new web3.Connection(web3.clusterApiUrl('devnet'));
This will create a connection object that we can use to communicate with the devnet cluster.
Next, we need to get an account address that we want to subscribe to. For this tutorial, we will use our own wallet address, but you can use any valid Solana address.
To get our wallet address, we need to create a web3.Keypair object from our private key. You can use any Solana wallet software to generate a keypair and export your private key as a JSON file.
Once you have your private key file, you can load it into your code using the fs module from Node.js.
For example:
const fs = require('fs');
const keypair = web3.Keypair.fromSecretKey(
new Uint8Array(JSON.parse(fs.readFileSync('keypair.json', 'utf-8')))
);
This will create a keypair object that contains your public key and private key. You can access your public key using the keypair.publicKey property. This is the address that we will use to subscribe to account changes.
For example:
const address = keypair.publicKey;
console.log('Address:', address.toBase58())
This will print your address in base58 encoding, which is the standard format for Solana addresses.
Step 4: Subscribe to account changes using websockets
Now that we have our connection object and our address, we can subscribe to account changes using websockets.
To do this, we need to use the connection.onAccountChange method and pass it our address and a callback function. The callback function will be invoked whenever there is a change in the account data or lamports.
The callback function will receive two arguments: an accountInfo object and a context object.
The accountInfo object contains information about the account state, such as its data, lamports, owner, and executable flag.
The context object contains information about the event, such as its slot and commitment level.
For example, we can write the following code to subscribe to account changes and print the accountInfo and context objects:
connection.onAccountChange(address, (accountInfo, context) => {
console.log('Account info:', accountInfo);
console.log('Context:', context);
});
This will register a listener for account changes and print the account info and context whenever there is an update.
Step 5: Decode and display the token balance of the account
If the account we are monitoring is an SPL token account, we can also decode and display its token balance using the @solana/spl-token library. To do this, we need to create a splToken.Token object and pass it the connection object, the token account address, the SPL token program ID, and the owner address.
The SPL token program ID is a fixed address that identifies the SPL token program on the Solana network.
You can use the splToken.TOKEN_PROGRAM_ID constant to get this address.
The owner address is the address that owns and controls the token account. For example:
const token = new splToken.Token(
connection,
address,
splToken.TOKEN_PROGRAM_ID,
keypair
);
This will create a token object that we can use to interact with the token account.
Next, we can use the token.getAccountInfo method to get the token account info, which contains information such as the mint address, the amount, the delegate address, and the state.
The mint address is the address that identifies the type of token.
The amount is the number of tokens in the account, in raw form.
To convert it to a human-readable form, we need to divide it by 10^decimals, where decimals is the number of decimal places for the token.
We can use the token.getMintInfo method to get the mint info, which contains information such as the decimals, the supply, and the freeze authority.
For example:
token.getAccountInfo(address).then((tokenAccountInfo) => {
console.log('Token account info:', tokenAccountInfo);
const mintAddress = tokenAccountInfo.mint;
const amount = tokenAccountInfo.amount.toNumber();
token.getMintInfo(mintAddress).then((mintInfo) => {
console.log('Mint info:', mintInfo);
const decimals = mintInfo.decimals;
const balance = amount / Math.pow(10, decimals);
console.log('Balance:', balance);
});
});
This will print the token account info, the mint info, and the balance of the account.
Conclusion
In this tutorial, we have learned how to listen to live account changes with websockets on Solana. We have used the Solana web3.js library to connect to a Solana cluster and subscribe to account updates. We have also used the @solana/spl-token library to decode and display the token balance of an SPL token account. We hope this tutorial has been helpful and informative for you. If you have any questions or feedback, please feel free to contact us or leave a comment below. Happy coding!