本文介绍了如何使用 QuickNode 和 LYS Labs 的Structured Real-Time Solana Data插件,通过 WebSocket 实时追踪 Solana 链上的事件,包括 SPL 代币的铸造以及 Pump.fun 协议上的代币迁移。通过 Node.js 脚本连接到 LYS WebSocket API,过滤并记录特定链上事件。
在 Solana 上构建实时应用程序,例如交易机器人、分析仪表板或通知服务,需要快速且可靠地访问链上事件。解码原始交易数据通常既缓慢又复杂,从而造成了显著的开发障碍。
这就是 LYS Labs 的 结构化实时 Solana 数据 插件的用武之地。它提供了一个解码后的、人类可读的 Solana 交易事件的简单 WebSocket 流,使你可以专注于应用程序的核心逻辑,而不是数据解析。本指南将向你展示如何构建一个脚本来跟踪 Solana 上的所有新代币铸造,以及来自 Pump.fun 的代币迁移,为更复杂的应用程序提供基础。
此插件可通过 QuickNode Marketplace 获得,为 Solana 区块链提供实时数据解决方案。它捕获事件的发生并立即通过 WebSocket 连接传递它们。
主要功能包括:
在本指南中,你将学习如何通过构建一个 Node.js 脚本来筛选和记录新 SPL 代币的铸造来使用这些功能。
让我们深入了解开发过程。
首先,你需要一个 API 密钥才能与 LYS Labs 通信。你可以直接从 QuickNode Marketplace 获得此密钥。
请妥善保管你的 API 密钥,因为你需要它来连接到 WebSocket API。

有了 API 密钥,你现在可以开始构建你的监控脚本。
打开你的终端并运行以下命令以创建一个项目文件夹并初始化一个 Node.js 项目:
mkdir lys-solana-tracker && cd lys-solana-tracker npm init -y 接下来,打开新创建的 package.json 文件并添加 "type": "module" 以启用 ES Module 语法。这使得处理导入和导出更加简洁。我们还将添加一个 dev 脚本以轻松运行我们的 TypeScript 文件。
{ // ...existing package.json content "type": "module", "scripts": { "dev": "tsx index.ts" } } 现在,安装必要的依赖项。我们将使用 ws 进行 WebSocket 连接,使用 dotenv 安全地管理我们的 API 密钥,并使用 tsx 直接运行 TypeScript 代码。
npm install ws dotenv npm install --save-dev typescript tsx @types/node @types/ws 最后,在你的项目目录中创建两个新文件:.env 用于存储你的 API 密钥,index.ts 用于你的应用程序代码。
touch .env index.ts 在 .env 文件中,像这样添加你的 API 密钥:
LYS_API_KEY=your_api_key_here 安全提示
始终将你的 .env 文件添加到 .gitignore 文件,以防止意外将你的秘密 API 密钥提交到公共存储库。
设置好项目后,你现在可以编写代码以连接到 LYS WebSocket 节点。
打开你的 index.ts 文件并添加以下代码。此代码段导入所需的库,从 .env 文件加载你的 API 密钥,并建立与 LYS WebSocket 服务器的连接。
import WebSocket from 'ws' import 'dotenv/config' // 1. Load the API key from the .env file // 1. 从 .env 文件加载 API 密钥 const API_KEY = process.env.LYS_API_KEY || null if (!API_KEY) { throw new Error('LYS_API_KEY is not defined in the .env file') //抛出一个错误:LYS_API_KEY 未在 .env 文件中定义 } // 2. Define the WebSocket URL and create a new WebSocket instance // 2. 定义 WebSocket URL 并创建一个新的 WebSocket 实例 const url = `wss://solana-mainnet-api-vip.lyslabs.ai/v1/?apiKey=${API_KEY}` const ws = new WebSocket(url) // 3. Once the connection is open, log a success message and subscribe to events // 3. 连接打开后,记录一条成功消息并订阅事件 ws.on('open', () => { console.log('✅ Successfully connected to LYS Labs!') // The 'subscribe' action tells the API to start sending all transaction events // “subscribe” 操作告诉 API 开始发送所有交易事件 ws.send(JSON.stringify({ action: 'subscribe' })) }) // We'll add the message handler in the next step // 我们将在下一步中添加消息处理程序 ws.on('message', data => { // Code to process incoming messages will go here // 处理传入消息的代码将放在这里 }) ws.on('error', error => { console.error('WebSocket Error:', error) //websocket 错误:错误 }) ws.on('close', () => { console.log('WebSocket connection closed.') //websocket 连接已关闭 }) 现在你已经建立了 WebSocket 连接,你可以开始监听不同的事件。在此示例中,我们将为新的代币铸造添加一个过滤器,并将它们记录到控制台。
LYS API 将数据作为单个 transaction 对象或一批 transactions 发送。为了简化处理,我们将数据规范化为一个数组,然后循环遍历它。
使用以下代码更新 ws.on("message", ...) 处理程序在你的 index.ts 文件中。此代码检查类型为 MINT 的 SPL_TOKEN 程序事件,并记录相关详细信息,例如铸造地址、金额和目标帐户。
ws.on('message', data => { const msg = JSON.parse(data.toString()) // Check if the message contains transaction data // 检查消息是否包含交易数据 if (msg.type === 'transaction' || msg.type === 'transactions') { // Normalize the data into an array, whether it's a single object or an array // 将数据规范化为一个数组,无论它是单个对象还是一个数组 const transactions = Array.isArray(msg.data) ? msg.data : [msg.data] for (const tx of transactions) { // Filter for SPL_TOKEN program events of type MINT // 筛选类型为 MINT 的 SPL_TOKEN 程序事件 if (tx.decoderType === 'SPL_TOKEN' && tx.eventType === 'MINT') { // Extract the amount, handling potential variations in the data structure // 提取金额,处理数据结构中潜在的变化 const amount = tx.uiAmount?.value ?? tx.amount ?? 'N/A' console.log('🎉 New Token Mint Detected!') //检测到新的代币铸造 console.log(` Signature: ${tx.txSignature}`) // 签名 console.log(` Mint Address: ${tx.mint}`) // 铸币地址 console.log(` Amount: ${amount}`) // 数量 console.log(` Destination: ${tx.destinationAccount}`) // 目的地 console.log('------------------------------------') } } } }) 事件数据结构
事件数据的结构可能因 eventType 而异。 LYS Labs 在 他们的官方文档 中提供了不同事件的详细示例,这是跟踪其他事件类型时的一个很好的参考资源。
代码就绪后,你现在可以运行脚本并开始实时跟踪新的代币铸造。
在你的终端中运行以下命令以启动脚本:
npm run dev 你应该看到“成功连接”消息,然后是网络上发生的新的代币铸造流,如下所示:
✅ Successfully connected to LYS Labs! //成功连接到 LYS Labs! 🎉 New Token Mint Detected! // 检测到新的代币铸造! Signature: 4h4cVhXPANAtYrw33sACEFmE35dSHGXV8baisG2qvgqdFF3QMoYa2sP8PuANy7fkCjZYVZsXLr6T8JBxzEpG6X5K Mint Address: FZN7QZ8ZUUAxMPfxYEYkH3cXUASzH8EqA6B4tyCL8f1j Amount: 857353 Destination: 3tt29ZvzMrzEW841n8H2V3AaKpevGf947Ryr4kzpXVH6 ------------------------------------ 🎉 New Token Mint Detected! // 检测到新的代币铸造! Signature: 4h4cVhXPANAtYrw33sACEFmE35dSHGXV8baisG2qvgqdFF3QMoYa2sP8PuANy7fkCjZYVZsXLr6T8JBxzEpG6X5K Mint Address: 6cGACr5TqEoFm6UiromxCeHfA5UstEMnn1eLkMskAjuh Amount: 964960861 Destination: HsVCHzkVzZfYbqM4gFWkAA153oVLLmgmLaJ4mkuRCqi2 ------------------------------------ 🎉 New Token Mint Detected! // 检测到新的代币铸造! Signature: 3DAVXZJJMwY9b7QdxwdAEzTSaHAk46G9rZ33XiHQJ91q6qkrqhj4MYLt9iSEehbQvGJuTpxHeGb5hfBSbiADQMJj Mint Address: 3RpEekjLE5cdcG15YcXJUpxSepemvq2FpmMcgo342BwC Amount: 7411092 Destination: CHtAbgouK9Sqf7hVBnhr7F5tkhJkHhCtkqbUHszymJL9 ------------------------------------ 现在你已经基本了解如何使用该插件,让我们更进一步并跟踪 Pump.fun 协议上的代币迁移。“代币迁移”是指代币获得足够的吸引力,通过将其流动性从 Pump.fun 的初始定价模型转移到主要的 DEX(如 Raydium)来“毕业”。对于交易者来说,这是一个关键事件,因为它使代币可以进入更广泛的市场。
为此,你只需要更改消息处理逻辑。设置和 WebSocket 连接保持不变。
将 ws.on("message", ...) 处理程序替换为以下代码:
// Define a type for the decoded transaction data relevant to this example // 定义与此示例相关的解码交易数据的类型 type PumpFunTransaction = { decoderType: string eventType: string txSignature: string mint?: string // This property is part of the MIGRATE event // 此属性是 MIGRATE 事件的一部分 pool?: string // This property is part of the CREATE_POOL event // 此属性是 CREATE_POOL 事件的一部分 lpMint?: string // This property is part of the CREATE_POOL event // 此属性是 CREATE_POOL 事件的一部分 } // A map to temporarily store migration events until the corresponding pool is created // 一个用于临时存储迁移事件的映射,直到创建相应的池 const pendingMigrations: Map<string, PumpFunTransaction> = new Map() ws.on('message', data => { const msg = JSON.parse(data.toString()) if (msg.type === 'transaction' || msg.type === 'transactions') { const transactions = ( Array.isArray(msg.data) ? msg.data : [msg.data] ) as PumpFunTransaction[] for (const tx of transactions) { // Watch for the MIGRATE event from Pump.fun // 关注来自 Pump.fun 的 MIGRATE 事件 if (tx.decoderType === 'PUMP_FUN' && tx.eventType === 'MIGRATE') { pendingMigrations.set(tx.txSignature, tx) } // Watch for the CREATE_POOL event from the Pump.fun AMM // 关注来自 Pump.fun AMM 的 CREATE_POOL 事件 if (tx.decoderType === 'PUMP_FUN_AMM' && tx.eventType === 'CREATE_POOL') { // Check if we saw the matching migration event for this transaction // 检查我们是否看到了此交易的匹配迁移事件 const migrateTx = pendingMigrations.get(tx.txSignature) if (migrateTx) { console.log('🚀 Token Graduated from Pump.fun!') // 代币从 Pump.fun 毕业! console.log(` Tx Signature: ${tx.txSignature}`) //交易签名: console.log(` Token Mint: ${migrateTx.mint}`) //Token铸造: console.log(` AMM Pool Address: ${tx.pool}`) //AMM 池地址: console.log(` LP Mint: ${tx.lpMint}`) //LP 铸币: console.log('------------------------------------') // Clean up the map to prevent memory leaks // 清理映射以防止内存泄漏 pendingMigrations.delete(tx.txSignature) } } } } }) 此逻辑使用交易签名将初始 MIGRATE 事件与随后的 CREATE_POOL 事件连接起来,从而让你全面了解代币的毕业情况。
这是用于跟踪新的代币铸造和 Pump.fun 代币迁移的完整代码。
查看用于跟踪新代币铸造的代码
import WebSocket from 'ws' import 'dotenv/config' // 1. Load the API key from the .env file // 1. 从 .env 文件加载 API 密钥 const API_KEY = process.env.LYS_API_KEY || null if (!API_KEY) { throw new Error('LYS_API_KEY is not defined in the .env file') // 抛出一个错误:LYS_API_KEY 未在 .env 文件中定义 } // 2. Define the WebSocket URL and create a new WebSocket instance // 2. 定义 WebSocket URL 并创建一个新的 WebSocket 实例 const url = `wss://solana-mainnet-api-vip.lyslabs.ai/v1/?apiKey=${API_KEY}` const ws = new WebSocket(url) // 3. Once the connection is open, log a success message and subscribe to events // 3. 连接打开后,记录一条成功消息并订阅事件 ws.on('open', () => { console.log('✅ Successfully connected to LYS Labs!') // Successfully connected to LYS Labs! // The 'subscribe' action tells the API to start sending all transaction events // “subscribe” 操作告诉 API 开始发送所有交易事件 ws.send(JSON.stringify({ action: 'subscribe' })) }) ws.on('message', data => { const msg = JSON.parse(data.toString()) // Check if the message contains transaction data // 检查消息是否包含交易数据 if (msg.type === 'transaction' || msg.type === 'transactions') { // Normalize the data into an array, whether it's a single object or an array // 将数据规范化为一个数组,无论它是单个对象还是一个数组 const transactions = Array.isArray(msg.data) ? msg.data : [msg.data] for (const tx of transactions) { // Filter for SPL_TOKEN program events of type MINT // 筛选类型为 MINT 的 SPL_TOKEN 程序事件 if (tx.decoderType === 'SPL_TOKEN' && tx.eventType === 'MINT') { // Extract the amount, handling potential variations in the data structure // 提取金额,处理数据结构中潜在的变化 const amount = tx.uiAmount?.value ?? tx.amount ?? 'N/A' console.log('🎉 New Token Mint Detected!') // 检测到新的代币铸造! console.log(` Signature: ${tx.txSignature}`) // 签名: console.log(` Mint Address: ${tx.mint}`) // 铸币地址: console.log(` Amount: ${amount}`) // 金额: console.log(` Destination: ${tx.destinationAccount}`) // 目的地: console.log('------------------------------------') } } } }) ws.on('error', error => { console.error('WebSocket Error:', error) // WebSocket 错误:错误 }) ws.on('close', () => { console.log('WebSocket connection closed.') // WebSocket 连接已关闭。 }) 查看用于跟踪 Pump.fun 代币迁移的代码
import WebSocket from 'ws' import 'dotenv/config' // 1. Load the API key from the .env file // 1. 从 .env 文件加载 API 密钥 const API_KEY = process.env.LYS_API_KEY || null if (!API_KEY) { throw new Error('LYS_API_KEY is not defined in the .env file') //抛出一个错误:LYS_API_KEY 未在 .env 文件中定义 } // 2. Define the WebSocket URL and create a new WebSocket instance // 2. 定义 WebSocket URL 并创建一个新的 WebSocket 实例 const url = `wss://solana-mainnet-api-vip.lyslabs.ai/v1/?apiKey=${API_KEY}` const ws = new WebSocket(url) // 3. Once the connection is open, log a success message and subscribe to events // 3. 连接打开后,记录一条成功消息并订阅事件 ws.on('open', () => { console.log('✅ Successfully connected to LYS Labs!') // 成功连接到 LYS Labs! // The 'subscribe' action tells the API to start sending all transaction events //“subscribe” 操作告诉 API 开始发送所有交易事件 ws.send(JSON.stringify({ action: 'subscribe' })) }) // Define a type for the decoded transaction data relevant to this example // 定义与此示例相关的解码交易数据的类型 type PumpFunTransaction = { decoderType: string eventType: string txSignature: string mint?: string // This property is part of the MIGRATE event //此属性是 MIGRATE 事件的一部分 pool?: string // This property is part of the CREATE_POOL event //此属性是 CREATE_POOL 事件的一部分 lpMint?: string // This property is part of the CREATE_POOL event //此属性是 CREATE_POOL 事件的一部分 } // A map to temporarily store migration events until the corresponding pool is created // 一个用于临时存储迁移事件的映射,直到创建相应的池 const pendingMigrations: Map<string, PumpFunTransaction> = new Map() ws.on('message', data => { const msg = JSON.parse(data.toString()) if (msg.type === 'transaction' || msg.type === 'transactions') { const transactions = ( Array.isArray(msg.data) ? msg.data : [msg.data] ) as PumpFunTransaction[] for (const tx of transactions) { // Watch for the MIGRATE event from Pump.fun // 关注来自 Pump.fun 的 MIGRATE 事件 if (tx.decoderType === 'PUMP_FUN' && tx.eventType === 'MIGRATE') { pendingMigrations.set(tx.txSignature, tx) } // Watch for the CREATE_POOL event from the Pump.fun AMM // 关注来自 Pump.fun AMM 的 CREATE_POOL 事件 if (tx.decoderType === 'PUMP_FUN_AMM' && tx.eventType === 'CREATE_POOL') { // Check if we saw the matching migration event for this transaction // 检查我们是否看到了此交易的匹配迁移事件 const migrateTx = pendingMigrations.get(tx.txSignature) if (migrateTx) { console.log('🚀 Token Graduated from Pump.fun!') //🚀 代币从 Pump.fun 毕业! console.log(` Tx Signature: ${tx.txSignature}`) //交易签名: console.log(` Token Mint: ${migrateTx.mint}`) //代币铸币: console.log(` AMM Pool Address: ${tx.pool}`) //AMM 池地址: console.log(` LP Mint: ${tx.lpMint}`) //LP 铸造: console.log('------------------------------------') // Clean up the map to prevent memory leaks // 清理映射以防止内存泄漏 pendingMigrations.delete(tx.txSignature) } } } } }) ws.on('error', error => { console.error('WebSocket Error:', error) //WebSocket 错误:错误 }) ws.on('close', () => { console.log('WebSocket connection closed.') //WebSocket 连接已关闭。 }) 恭喜!你已经成功构建了一个实时 Solana 事件跟踪器,该跟踪器使用由 LYS Labs 的 结构化实时数据插件 提供支持的 QuickNode Solana 节点。你现在拥有监听任何链上事件的基础知识,从而为构建响应迅速且数据驱动的 Web3 应用程序开辟了无限可能。
特别感谢 LYS Labs 团队在创建本指南中的密切合作。
如果你遇到问题或有疑问,请将它们放在我们的 Discord 中。通过在 X(以前的 Twitter) (@QuickNode) 或我们的 Telegram 公告频道 上关注我们来了解最新信息。
如果你对新主题有任何反馈或要求,请 告诉我们。我们很乐意听取你的意见。
- 原文链接: quicknode.com/guides/mar...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!