跳转到主要内容

使用标准 WebSockets

标准 Solana WebSockets 提供简单的集成,适用于所有 Helius 计划,使其成为开发者的便捷选择。标准 WSS 也使用 Solana PubSub logsSubscribe,因此您只能接收日志消息。

标准 WebSockets 现在由 LaserStream 支持,响应速度比传统基于 RPC 的 WebSockets 快最多 200 毫秒。

工作原理

连接到标准 WebSocket 终端,订阅提到Pump AMM 程序的日志,并处理传入的日志数据。 下面的示例包括带有指数退避的自动重连逻辑。

要求

  • Node.js ≥ 18(使用 v20 测试)
  • 如果您计划使用 ts‑node 运行 .ts 示例,TypeScript ≥ 5
  • 任何Helius 计划—适用于所有计划层级
  • 一个名为 HELIUS_API_KEY环境变量,用于存储您的 API 密钥
全局安装依赖项:npm i -g typescript ts‑node

实施

1

安装依赖项

npm install ws
2

创建 WebSocket 客户端

创建一个名为 standard-ws-pump.ts 的文件,并包含以下代码:
// standard-ws-pump.ts
import WebSocket from 'ws';

// Configuration
const MAX_RETRIES = 5;
const INITIAL_RETRY_DELAY = 1000; // 1 second
let retryCount = 0;
let retryTimeout: NodeJS.Timeout | null = null;
let subscriptionId: number | null = null;

// Create a WebSocket connection
let ws: WebSocket;

function connect() {
  ws = new WebSocket(`wss://mainnet.helius-rpc.com/?api-key=${process.env.HELIUS_API_KEY}`);

  // Function to send a request to the WebSocket server
  function sendRequest(ws: WebSocket): void {
    const request = {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "logsSubscribe",
      "params": [
        {
          "mentions": ["pAMMBay6oceH9fJKBRHGP5D4bD4sWpmSwMn52FMfXEA"]
        }
      ]
    };
    console.log('Sending subscription request:', JSON.stringify(request, null, 2));
    ws.send(JSON.stringify(request));
  }

  // Function to send a ping to the WebSocket server
  function startPing(ws: WebSocket): void {
    setInterval(() => {
      if (ws.readyState === WebSocket.OPEN) {
        ws.ping();
        console.log('Ping sent');
      }
    }, 30000); // Ping every 30 seconds
  }

  // Define WebSocket event handlers
  ws.on('open', function open() {
    console.log('WebSocket is open');
    retryCount = 0; // Reset retry count on successful connection
    sendRequest(ws); // Send a request once the WebSocket is open
    startPing(ws); // Start sending pings
  });

  ws.on('message', function incoming(data: WebSocket.Data) {
    const messageStr = data.toString('utf8');
    try {
      const messageObj = JSON.parse(messageStr);

      // Handle subscription confirmation
      if (messageObj.result && typeof messageObj.result === 'number') {
        subscriptionId = messageObj.result;
        console.log('Successfully subscribed with ID:', subscriptionId);
        return;
      }

      // Handle actual log data
      if (messageObj.params && messageObj.params.result) {
        const logData = messageObj.params.result;
        console.log('Received log data:', JSON.stringify(logData, null, 2));
        
        // Extract the transaction signature if available
        if (logData.signature) {
          console.log('Transaction signature:', logData.signature);
          // You can call getTransaction with this signature to get the full transaction details
        }
      } else {
        console.log('Received message:', JSON.stringify(messageObj, 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 (subscriptionId) {
      console.log('Last subscription ID was:', subscriptionId);
    }
    reconnect();
  });
}

function reconnect() {
  if (retryCount >= MAX_RETRIES) {
    console.error('Max retry attempts reached. Please check your connection and try again.');
    return;
  }

  const delay = INITIAL_RETRY_DELAY * Math.pow(2, retryCount);
  console.log(`Attempting to reconnect in ${delay/1000} seconds... (Attempt ${retryCount + 1}/${MAX_RETRIES})`);

  retryTimeout = setTimeout(() => {
    retryCount++;
    connect();
  }, delay);
}

// Start the initial connection
connect();

// Cleanup function
process.on('SIGINT', () => {
  if (retryTimeout) {
    clearTimeout(retryTimeout);
  }
  if (ws) {
    ws.close();
  }
  process.exit();
});
3

设置环境变量

将您的 Helius API 密钥添加为环境变量:
export HELIUS_API_KEY=your-helius-api-key
用从控制台获取的实际 Helius API 密钥替换 your-helius-api-key如果您没有 API 密钥,请注册或让您的代理通过 Helius CLI 程序化地创建一个。
4

运行应用程序

执行脚本以开始流式传输 Pump AMM 数据:
npx ts-node standard-ws-pump.ts
您将收到提到 Pump AMM 程序的日志消息。要获取完整交易,请使用日志条目中的签名调用 getTransaction

主要优势

  • 普遍访问 - 可用于所有 Helius 计划,包括免费套餐
  • 轻量级 - 仅流式传输日志,没有完整交易,因此数据传输量最小
  • 易于实现 - 使用标准 Solana RPC WebSocket 协议
  • 低门槛 - 适合原型制作和初步监控

获取完整交易详情

由于标准 WebSocket 仅提供日志消息,您需要一个额外步骤来获取完整交易数据:
// Example of how to fetch a full transaction from a log entry
async function fetchFullTransaction(signature: string) {
  const response = await fetch(`https://mainnet.helius-rpc.com/?api-key=${process.env.HELIUS_API_KEY}`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      jsonrpc: '2.0',
      id: 'my-id',
      method: 'getTransaction',
      params: [
        signature,
        {
          encoding: 'jsonParsed',
          maxSupportedTransactionVersion: 0
        }
      ]
    })
  });
  
  const data = await response.json();
  return data.result;
}

常见问题和解决方案

验证您的 HELIUS_API_KEY 是否正确。
确保 Pump AMM 程序地址正确,并且程序上有活动。
实施更强大的重连逻辑或检查网络稳定性。