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

1

Install Dependencies

npm install ws
2

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);
});
3

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.

4

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

1

Create a UI Dashboard

Build a web interface to visualize incoming Pump AMM transactions in real-time using React or Vue.js.

2

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);
  }
});
3

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}`);
  }
}
4

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 };
}