- Use multiple Solana RPC endpoints to reduce latency and avoid single points of failure.
- A distributed setup ensures higher availability and faster data updates, especially for real-time balance monitoring.
- This sample Node.js code with a connection pool approach demonstrates how to subscribe to account balance changes across different geographic locations simultaneously.
- Environment variables keep your endpoints secure while allowing easy setup and configuration.
Main article
This guide will explore how a distributed approach to querying the Solana blockchain can reduce latency and provide a more resilient infrastructure for your DApps. Whether you’re a blockchain enthusiast or a seasoned developer looking to optimize your Solana-based projects, this tutorial is crafted to offer valuable insights and practical steps to achieve a seamless and efficient blockchain interaction experience.A brief overview of Solana’s architecture
Solana stands out in the blockchain world for its unprecedented throughput and minimal transaction costs stemming from its innovative architecture. The Proof of History (PoH) consensus mechanism is at the heart of Solana’s efficiency. This unique solution enables greater scalability by creating a historical record proving that an event has occurred at a specific time. This, coupled with the blockchain’s underlying Proof of Stake (PoS) consensus, allows Solana to process thousands of transactions per second without compromising decentralization or security.A simple project
At the heart of this tutorial lies a practical, hands-on example that will guide us through the intricacies of interacting with Solana’s network using multiple RPC endpoints. We will develop a robust piece of JavaScript code to manage a pool of Solana connections. This code establishes connections to several RPC endpoints across different geographic locations and intelligently distributes operations amongst these endpoints to achieve optimal performance and reliability. Through this example, we aim to listen to the balance changes of a specific Solana account from multiple nodes in parallel. Using multiple nodes in different regions simultaneously can improve reliability and performance, and the first node to get the updated data will win the race.The importance of multiple endpoints
The traditional approach of interacting with the blockchain through a single RPC endpoint can be a bottleneck for your application. This is where the strategy of using multiple endpoints across various geographic locations comes into play, offering several key advantages:- Redundancy: By having your application connected to multiple nodes, you mitigate the risk of a single point of failure. If one node goes down or becomes unreachable, your application can seamlessly switch to another, ensuring uninterrupted service. This is because each node is physically running on a different machine.
- Reduced Latency: Latency can vary significantly based on the geographic distance between your user and the RPC endpoint. Generally, the endpoint closer to the user will respond faster, but sometimes, another node may pick up new data sooner.
- Higher Availability: Different nodes may have varying loads or maintenance schedules. Running multiple endpoints ensures that your application always has access to at least one up-to-date and responsive node, thereby improving the reliability of your service.
Prerequisites
Before we get into the code, ensuring you have the right tools and setup is crucial. Let’s walk through everything you’ll need:Environment setup
To interact with the Solana blockchain and execute the scripts you’ll write, certain environmental setups are necessary:- Node.js: Install Node.js (version 18 or above) on your machine. Node.js is fundamental for running our scripts and managing dependencies. You can download it from the official Node.js website.
- npm (Node Package Manager): npm is the default package manager for Node.js and is indispensable for installing the libraries our project requires. It comes bundled with Node.js, so there’s no separate installation process.
Deploy a Chainstack Solana node
Deploy multiple reliable Solana RPC endpoints. Note that you need to be on a paid plan to deploy multiple nodes.Installing required packages
Our project relies on a Solana JavaScript library plusdotenv (which loads environment variables from a .env file into process.env, keeping RPC URLs out of your code). This guide shows both Solana JS libraries side by side — both are actively maintained, so use whichever fits your project:
@solana/kit— the newer, tree-shakable, functional SDK. Account subscriptions are exposed through a websocket client (createSolanaRpcSubscriptions).@solana/web3.js— the classic object-oriented API, where aConnectionobject carries both HTTP and websocket calls (onAccountChange).
- @solana/kit
- @solana/web3.js (classic)
Bash
package.json file:
Setting up environment variables
We’ll use environment variables to manage our RPC endpoints and other sensitive information. This method keeps our credentials secure and makes our application easily configurable without hardcoding sensitive data:- Create a
.envfile in the root of your project directory. - Add your Solana RPC URLs and sensitive information to the
.envfile. For instance:
Additional considerations
- Security: Always keep your private keys and sensitive information secure. Do not commit your
.envfile or any files containing sensitive data to version control. Make sure to include the.envfile in your.gitignore.
The code
Now that we are set, create a new file in your project namedindex.js and paste the following code into it.
- @solana/kit
- @solana/web3.js (classic)
Javascript
Code breakdown
Both versions do the same thing — open one client per endpoint, subscribe to a single account across all of them, and log the first node to report each new balance. They differ only in how the subscription is opened and consumed. Here are the key components:Imports and environment variables
The@solana/kit version imports createSolanaRpcSubscriptions and address; the @solana/web3.js version imports Connection and PublicKey. Both load dotenv/config to read the endpoints from .env and keep them out of the code.
The connection/subscription pool
Each pool entry holds one client per endpoint:@solana/web3.jsbuilds aConnectionper node, passing the HTTP RPC URL plus{ wsEndpoint }for its websocket.@solana/kitbuilds acreateSolanaRpcSubscriptionsclient per node. Account subscriptions are websocket-only, which is why the@solana/kitpool takes just thewssURL for each endpoint.
Shared state for balance tracking
Both keep a singlelatestLoggedBalance so the same balance isn’t logged twice when multiple nodes report the same change. In @solana/kit this value is a bigint; in @solana/web3.js it’s a number.
Listening for balance changes
This is the core API difference between the two libraries:@solana/web3.jsregisters a callback:connection.onAccountChange(publicKey, (accountInfo) => { ... }, 'confirmed'), whereaccountInfo.lamportsis anumber.@solana/kitopens an async iterable:await rpcSubscriptions.accountNotifications(account, { commitment: 'confirmed' }).subscribe({ abortSignal }), then consumes it withfor await (const notification of notifications). Eachnotification.value.lamportsis abigint. Running one subscription per endpoint underPromise.allkeeps them all listening concurrently, and the sharedabortSignaltears them all down cleanly.
Main execution flow
Both define the endpoints from environment variables, build the pool, choose a public key to watch, and start listening. The@solana/kit version additionally creates an AbortController and awaits the listeners; call abortController.abort() to stop every subscription at once.
Run the script
To run the script, make sure to place your HTTPS and WSS endpoints in the.env file, then run the start command in the console:
