Enhanced WebSocket
Why choose Enhanced WebSocket – fast JSON streams with
decoded accounts and transactions. No custom network stack is required.
Available on Business and higher plans.
How it works – connect to the Atlas endpoint, subscribe to Pump AMM
transactions, and listen for updates. The sample retries five times with
exponential back‑off.
Requirements
- Node.js ≥ 18 (tested with v20)
- TypeScript ≥ 5 if you plan to run the
.ts
samples with ts‑node
- A Helius Business Plan or higher
- An environment variable named
HELIUS_API_KEY
that stores your API key
Install dependencies globally: npm i -g typescript ts‑node
Implementation
Create the WebSocket Client
Create a file named enhanced-ws-pump.ts
with the following code:
// enhanced-ws-pump.ts
import WebSocket from 'ws';
// Configuration for reconnection
const MAX_RETRIES = 5;
const INITIAL_RETRY_DELAY = 1000; // 1 second
let retryCount = 0;
let retryDelay = INITIAL_RETRY_DELAY;
// Function to create a new WebSocket connection
function createWebSocket() {
return new WebSocket(`wss://atlas-mainnet.helius-rpc.com/?api-key=${process.env.HELIUS_API_KEY}`);
}
// Function to send a request to the WebSocket server
function sendRequest(ws: WebSocket) {
const request = {
jsonrpc: "2.0",
id: 420,
method: "transactionSubscribe",
params: [
{
accountInclude: ["pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA"]
},
{
commitment: "processed",
encoding: "jsonParsed",
transactionDetails: "full",
maxSupportedTransactionVersion: 0
}
]
};
ws.send(JSON.stringify(request));
}
// Function to send a ping to the WebSocket server
function startPing(ws: WebSocket) {
return setInterval(() => {
if (ws.readyState === WebSocket.OPEN) {
ws.ping();
console.log('Ping sent');
}
}, 30000); // Ping every 30 seconds
}
// Function to handle reconnection
function reconnect() {
if (retryCount >= MAX_RETRIES) {
console.error('Maximum retry attempts reached.');
return;
}
console.log(`Attempting to reconnect in ${retryDelay/1000} seconds... (Attempt ${retryCount + 1}/${MAX_RETRIES})`);
setTimeout(() => {
retryCount++;
retryDelay *= 2; // Exponential backoff
initializeWebSocket();
}, retryDelay);
}
// Function to initialize WebSocket with all event handlers
function initializeWebSocket() {
const ws = createWebSocket();
let pingInterval: NodeJS.Timeout;
ws.on('open', function open() {
console.log('WebSocket is open');
retryCount = 0; // Reset retry count on successful connection
retryDelay = INITIAL_RETRY_DELAY; // Reset retry delay
sendRequest(ws);
pingInterval = startPing(ws);
});
ws.on('message', function incoming(data: WebSocket.Data) {
const messageStr = data.toString('utf8');
try {
const messageObj = JSON.parse(messageStr);
// Check if it's a subscription confirmation
if (messageObj.result !== undefined) {
console.log('Subscription confirmed:', messageObj);
return;
}
// Check if it's transaction data
if (messageObj.params && messageObj.params.result) {
const transaction = messageObj.params.result;
console.log('Received transaction:', JSON.stringify(transaction, null, 2));
}
} catch (e) {
console.error('Failed to parse JSON:', e);
}
});
ws.on('error', function error(err: Error) {
console.error('WebSocket error:', err);
});
ws.on('close', function close() {
console.log('WebSocket is closed');
if (pingInterval) {
clearInterval(pingInterval);
}
reconnect();
});
}
// Start the WebSocket connection
initializeWebSocket();
// Handle program termination
process.on('SIGINT', () => {
console.log('Shutting down...');
process.exit(0);
});
Set Environment Variables
Add your Helius API key as an environment variable:
export HELIUS_API_KEY=your-helius-api-key
Replace your-helius-api-key
with your actual Helius API key from the dashboard.
Run the Application
Execute the script to start streaming Pump AMM data:
npx ts-node enhanced-ws-pump.ts
You will see parsed Pump AMM transactions in your terminal. The client retries automatically when the socket closes.
Key benefits
- Browser-compatible - The WebSocket protocol works in both Node.js and browser environments
- Rich data - Get fully parsed transaction objects with decoded instructions and accounts
- Simple implementation - No special libraries required beyond a standard WebSocket client
- Auto-reconnect - Built-in retry logic ensures a stable connection
Common issues and solutions
Next steps
Create a UI Dashboard
Build a web interface to visualize incoming Pump AMM transactions in real-time using React or Vue.js.
Implement Database Storage
Store transaction data in a database like MongoDB or PostgreSQL for historical analysis:
import { MongoClient } from 'mongodb';
// Setup MongoDB connection
async function setupDatabase() {
const client = new MongoClient('mongodb://localhost:27017');
await client.connect();
return client.db('pump-amm').collection('transactions');
}
// Then in your message handler:
ws.on('message', async function incoming(data: WebSocket.Data) {
const messageStr = data.toString('utf8');
try {
const messageObj = JSON.parse(messageStr);
if (messageObj.params && messageObj.params.result) {
const transaction = messageObj.params.result;
// Store in database
const collection = await setupDatabase();
await collection.insertOne({
timestamp: new Date(),
transaction: transaction
});
console.log('Transaction stored in database');
}
} catch (e) {
console.error('Failed to process message:', e);
}
});
Set Up Alerting System
Configure alerts for high-value transactions or specific patterns using a service like Discord webhooks:
import axios from 'axios';
// Send alert to Discord webhook
async function sendAlert(message: string) {
await axios.post('YOUR_DISCORD_WEBHOOK_URL', {
content: message
});
}
// Then in your message handler:
if (messageObj.params && messageObj.params.result) {
const transaction = messageObj.params.result;
// Example: Check for transactions above a certain value
const isHighValue = checkIfHighValueTransaction(transaction);
if (isHighValue) {
sendAlert(`High-value transaction detected: ${transaction.signature}`);
}
}
Implement Heartbeat Monitoring
Add a more robust heartbeat system to ensure continuous connectivity:
// Enhanced heartbeat system
function setupHeartbeat(ws: WebSocket) {
let lastPongTime = Date.now();
// Send ping regularly
const pingInterval = setInterval(() => {
if (ws.readyState === WebSocket.OPEN) {
ws.ping();
}
}, 30000);
// Track pong responses
ws.on('pong', () => {
lastPongTime = Date.now();
});
// Check connection health
const healthCheck = setInterval(() => {
const now = Date.now();
if (now - lastPongTime > 90000) { // No pong for 90 seconds
console.warn('Connection seems unresponsive, reconnecting...');
ws.terminate();
clearInterval(pingInterval);
clearInterval(healthCheck);
}
}, 30000);
return { pingInterval, healthCheck };
}