如何实时捕捉 Raydium V4 新流动性池:链上监听与数据解析完整指南

·

在 Solana 的高速链上环境中,“第一时间发现新流动性池”意味着抢占早期资金入口。本文带你零部署成本监听 Raydium V4 官方程序,提取每一步关键数据,帮你把 Solana、Raydium、流动性池、监控脚本 等关键词自然贯穿全文,直接上手即用。


项目思路速览

  1. 锁定程序地址:Raydium Liquidity Pool V4 固定合约 675kPX9MHTjS2zt…
  2. 订阅日志:使用 Solana Web3.js 的 onLogs 持续捕获 initialize2 指令。
  3. 解析交易:拿到交易签名后,读取代币精度、名称、初始数量开盘时间
  4. 结果推送:可直接对接 Telegram Bot 或自建警报,实现毫秒级通知。

环境准备

npm install @solana/web3.js @solana/spl-token \
            @metaplex-foundation/mpl-token-metadata \
            bs58 @solana/buffer-layout moment-timezone
核心关键词:Solana RPC、Raydium 监听脚本、流动性池追踪

第一步:订阅 Raydium V4 实时日志

利用 Connection.onLogs 可直接订阅 程序级事件,而非逐个区块轮询。

const connection = new solanaWeb3.Connection('<YOUR_RPC>', 'confirmed');
const raydiumV4 = new solanaWeb3.PublicKey('675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8');

connection.onLogs(
  raydiumV4,
  ({ logs, err, signature }) => {
    if (err) return;
    if (logs?.some(l => l.includes('initialize2'))) {
      console.log('🆕 发现新池签名:', signature);
      parsePool(signature);        // 立即解析
    }
  },
  'confirmed'
);

如果你本地带宽不足,👉 把 RPC 切换到全球低延迟线路,立即提速


第二步:解析交易内关键账户

拿到签名后,先拼出完整交易,再按照以下索引定位:

const tx = await connection.getParsedTransaction(signature, {
  maxSupportedTransactionVersion: 0,
  commitment: 'confirmed'
});

const accounts = tx.transaction.message.instructions
  .find(ix => ix.programId.equals(raydiumV4))
  .accounts;

const [lpMint, tokenA, tokenB] = [accounts[4], accounts[8], accounts[9]];

第三步:读取代币信息与精度

利用 SPL-Token 与 Metaplex 标准,可直接拉取链上元数据:

async function fetchTokenMeta(mintStr) {
  const mintPub = new solanaWeb3.PublicKey(mintStr);
  const mintInfo = await splToken.getMint(connection, mintPub);
  const [metadataPDA] = await deprecated.Metadata.getPDA(mintPub);
  const metadata = await Metadata.fromAccountAddress(connection, metadataPDA);
  const name = metadata.data.name.replace(/\x00/g, '');
  return { name, decimals: mintInfo.decimals };
}

const metaA = await fetchTokenMeta(tokenA.toString());
const metaB = await fetchTokenMeta(tokenB.toString());

第四步:解码开盘参数

Raydium initialize2 指令后附加的 Instruction Data 固定 41 字节:

字段长度说明
discriminator1固定 0x09
nonce1用于计算权限种子
openTime8 LEUnix 时间戳或 0=立即开
initPcAmount8 LEToken B 初始数量
initCoinAmount8 LEToken A 初始数量
const data58 = bs58.decode(instructionData);
const layout = struct([
  u8('discriminator'),
  u8('nonce'),
  nu64('openTime'),
  nu64('initPc'),
  nu64('initCoin')
]);
const decoded = layout.decode(data58);

等价换算到标准单位:

const initA = decoded.initCoin / 10 ** metaA.decimals;
const initB = decoded.initPc   / 10 ** metaB.decimals;

案例输出

当系统捕获到新池时,终端会瞬间打印:

🆕 发现新池签名: 4AwNAxTe...
TX: https://solscan.io/tx/4AwNAxTe...
┌-------------┬----------------------------------┬----------┐
│ Token       │ Public Key                       │ Amount   │
├-------------┼----------------------------------┼----------┤
│ INKY        │ 6ucJr...                         │ 1000000  │
│ USDC        │ EPjFWd...                        │ 5000     │
└-------------┴----------------------------------┴----------┘
开盘 UTC 时间:2024-09-18 16:30:00
LP Mint: HR1n3d... (准备注入流动性)

FAQ:高频疑问秒答

Q1 订阅日志会不会漏报?
A:使用 confirmed 已足够防重组,如发现漏报,可把 RPC 改成订阅 finalized 节点,延迟会略高。

Q2 免费 RPC 经常被限流怎么办?
A:把节点放到同地域云服务器,或使用带 WebSocket 通道的 专业加速端点。👉 点此获取低延迟 Solana WebSocket 地址

Q3 可以同时监控 Orca、Meteora 吗?
A:方法完全一样,只要把 raydiumV4 替换成对应程序 ID,并匹配相应指令名即可。

Q4 指令 data 偶尔报错?
A:检查交易是否经过 Compute Budget Program,先过滤掉扩展指令再解析数据即可。

Q5 Token Metadata 有时取不到?
A:部分新币暂未上传到链上元数据,可降级用「TICKER」或 fallback 到「Unknown」。

Q6 如何把结果推到微信/Telegram?
A:把解析结果格式化成 Markdown 发送到 Bot API 即可,Web3 后处理就是 http 请求。


完整源码(可直接跑)

import solanaWeb3 from '@solana/web3.js';
import splToken from '@solana/spl-token';
import { Metadata, deprecated } from '@metaplex-foundation/mpl-token-metadata';
import bs58 from 'bs58';
import { struct, u8, nu64 } from '@solana/buffer-layout';

const conn = new solanaWeb3.Connection('<YOUR_RPC>', 'confirmed');
const RAYDIUM = new solanaWeb3.PublicKey('675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8');

conn.onLogs(RAYDIUM, ({ logs, signature }) => {
  if (logs?.some(l => l.includes('initialize2'))) parsePool(signature);
}, 'confirmed');

async function parsePool(sig) {
  const tx = await conn.getParsedTransaction(sig, { maxSupportedTransactionVersion: 0 });
  const ix = tx.transaction.message.instructions.find(i => i.programId.equals(RAYDIUM));
  const accounts = ix.accounts;

  const [metaA, metaB] = await Promise.all([
    fetchTokenInfo(accounts[8]),
    fetchTokenInfo(accounts[9])
  ]);

  const decoded = struct([
    u8(), u8(),
    nu64('openTime'), nu64('initPc'), nu64('initCoin')
  ]).decode(bs58.decode(ix.data));

  const obj = {
    tokenA: { name: metaA.name, amount: decoded.initCoin / 10 ** metaA.decimals },
    tokenB: { name: metaB.name, amount: decoded.initPc   / 10 ** metaB.decimals },
    lpMint: accounts[4],
    tx: sig,
    openTime: decoded.openTime !== 0n ? new Date(Number(decoded.openTime) * 1000) : '立即开盘'
  };
  console.table(obj);
}

async function fetchTokenInfo(mint) {
  const mintObj = new solanaWeb3.PublicKey(mint);
  const mintInfo = await splToken.getMint(conn, mintObj);
  const [pda] = await deprecated.Metadata.getPDA(mintObj);
  const meta = await Metadata.fromAccountAddress(conn, pda);
  return { name: meta.data.name.replace(/\x00/g, ''), decimals: mintInfo.decimals };
}

写在最后

只要 30 行代码,就能把 Solana 新币首发收入囊中。掌握 initialize2 日志捕获、数据解码和元数据拼装的核心技巧后,你还可以继续拓展:

👉 想同步更多链上新玩法,关注最新频道无需翻墙。祝你在 Raydium V4 的浪潮里,快人一步、稳健盈利。