Pump.fun代币迁移实时监视
本文介绍如何使用Shyft gRPC监控从Pump.fun到Raydium的代币迁移。

一键发币: SUI | SOL | BNB | ETH | BASE | ARB | OP | POLYGON | AVAX | FTM | OK
在Pumpfun完成其债券曲线活动后,代币被迁移到Raydium进行交易。使用gRPC可以更轻松地识别已迁移并正在Raydium上交易的代币。
通过本文末尾,您将学会如何使用gRPC和Shyft API流式传输从Pump.fun迁移到Raydium的代币。
1、开始之前
在开始构建之前,请注册并获取Shyft RPC/API和gRPC令牌访问权限。
gRPC服务不直接支持Web浏览器,因此您需要一个后端应用程序来处理gRPC数据。虽然此示例使用Node.js,但您可以根据自己的偏好选择多种服务器端语言,包括C#、Go、Java、Kotlin、Python或PHP。
在这篇文章中,我们将查看如何使用gRPC获取Raydium上代币的价格更新。我们将涵盖以下步骤:
- 设置gRPC连接
- 跟踪Pumpfun上已完成的债券曲线
- 反序列化我们的Pumpfun数据
- 使用Defi API获取流动性详情
- 结论
本文所有相关代码均可在我们的 GitHub 和 Replit 上找到。欢迎您克隆它并跟随操作。
2、设置gRPC连接
要开始流式传输,您需要配置gRPC URL和访问令牌。
const client = new Client(
'您的区域特定Shyft gRPC URL',
'Shyft gRPC访问令牌',
undefined,
);
现在开始流式传输!
3、跟踪Pumpfun上已完成的债券曲线
我们需要基于我们建立的逻辑最终确定Pumpfun上的债券曲线。只有已完成的债券曲线才有资格迁移到Raydium并进行交易。为了过滤相关数据,我们使用memcmp
以确保只检索已完成的债券曲线。
const req: SubscribeRequest = {
slots: {},
accounts: {
pumpfun: {
account: [],
filters: [
{
memcmp: {
offset: structure.offsetOf('complete').toString(),
bytes: Uint8Array.from([1]),
},
},
],
owner: [pumpfun], //pump-fun程序ID
},
},
transactions: {},
blocks: {},
blocksMeta: {
block: [],
},
accountsDataSlice: [],
commitment: CommitmentLevel.PROCESSED,
entry: {},
transactionsStatus: {},
};
4、gRPC请求的关键组件
让我们分解这个请求的主要部分:
- 账户过滤器:这里的关键过滤器是
memcmp
过滤器,它检查代币的“完成”状态。这有助于识别在Pump.fun上完成其债券曲线活动并准备迁移到Raydium的代币。
offset
指定账户结构中完成状态的位置。使用structure.offsetOf('complete')
确保我们基于代币的最终状态进行过滤。bytes
过滤器与Uint8Array.from([1])
一起查找值1
,表示债券曲线活动已完成。
2. 程序所有者:owner
字段指定Pumpfun
程序ID或Raydium
程序ID。这确保我们只订阅与迁移到Raydium相关的事件。
3. 提交级别:CommitmentLevel.PROCESSED
设置允许您订阅已处理块,这确保您可以实时接收交易和代币迁移的更新。
4. 交易和区块:通过订阅这些字段,您可以跟踪代币的持续活动,允许您监控与其迁移和交易相关的实时事件。
当我们console.log数据变量时,我们应该期望输出如下格式
filters: [ 'pumpfun' ],
account: {
account: {
pubkey: <Buffer fc 97 83 0f e5 17 be a3 5b b8 40 7a 09 41 30 4a 07 f0 53 8f 4b 76 8e 1c d4 31 1b ee b5 8d 1a 22>,
lamports: '85006591115',
owner: <Buffer 01 56 e0 f6 93 66 5a cf 44 db 15 68 bf 17 5b aa 51 89 cb 97 f5 d2 ff 3b 65 5d 2b b6 fd 6d 18 b0>,
executable: false,
rentEpoch: '18446744073709551615',
data: <Buffer 17 b7 f8 37 60 d8 ac 60 00 98 12 4c 91 fe 00 00 5b 84 da c6 1a 00 00 00 00 00 00 00 00 00 00 00 5b d8 b6 ca 13 00 00 00 00 80 c6 a4 7e 8d 03 00 01>,
writeVersion: '1536398957277',
txnSignature: <Buffer 3c 9f 98 aa 21 1e a5 31 fb 9c ae a8 6c 53 df 6d 4a e0 6c d5 bf 2e fa a3 56 48 be 00 b1 ef 23 c3 46 3b 76 72 af 22 28 e1 e0 b9 57 04 d8 59 9b 97 8b 38 ... 14 more bytes>
},
slot: '300981652',
isStartup: false
},
slot: undefined,
transaction: undefined,
block: undefined,
ping: undefined,
pong: undefined,
blockMeta: undefined,
entry: undefined
}
5、反序列化Pump.fun数据
我们将逐步了解如何使用提供的代码解码Pumpfun交易。交易数据是以二进制格式存在的,我们将使用模拟数据布局的结构对其进行解码。
5.1 导入所需库
我们首先导入所需的库:
import base58 from "bs58";
import { struct, bool, u64, Layout } from "@coral-xyz/borsh";
base58
用于处理常用的Solana交易的base58编码。@coral-xyz/borsh
是一个强大的二进制序列化/反序列化库,我们将使用它定义和解码交易数据的结构。
5.2 定义数据结构
我们使用borsh
中的struct
函数定义债券曲线交易的数据结构:
export const structure = struct([
u64("discriminator"),
u64("virtualTokenReserves"),
u64("virtualSolReserves"),
u64("realTokenReserves"),
u64("realSolReserves"),
u64("tokenTotalSupply"),
bool("complete"),
]);
以下是字段的分解:
- discriminator:数据结构的独特标识符。
- virtualTokenReserves:代币的虚拟储备。
- virtualSolReserves:以Solana(SOL)形式的虚拟储备。
- realTokenReserves:代币的真实储备。
- realSolReserves:以SOL形式的真实储备。
- tokenTotalSupply:代币的总供应量。
- complete:一个布尔值,指示债券曲线过程是否已完成。
每个字段都映射到特定类型,例如u64
(用于无符号64位整数)和bool
(用于布尔值)。这确保了二进制数据能够正确解释。
5.3 解码交易数据
接下来,我们定义一个名为bondingCurveData
的函数,该函数基于结构解码交易缓冲区:
export function bondingCurveData(buffer: Buffer) {
let value = structure.decode(buffer);
const discriminator = BigInt(value.discriminator);
const virtualTokenReserves = BigInt(value.virtualTokenReserves);
const virtualSolReserves = BigInt(value.virtualSolReserves);
const realTokenReserves = BigInt(value.realTokenReserves);
const realSolReserves = BigInt(value.realSolReserves);
const tokenTotalSupply = BigInt(value.tokenTotalSupply);
const complete = value.complete;
return {
discriminator,
virtualTokenReserves,
virtualSolReserves,
realTokenReserves,
realSolReserves,
tokenTotalSupply,
complete
};
}
解码的工作原理:
- 输入:该函数接受一个
Buffer
作为输入,这是原始交易数据。 - 结构解码:我们使用
structure.decode(buffer)
将原始二进制数据解码为基于我们之前定义的字段的结构化对象。 - BigInt转换:
u64
字段解析为BigInt
以处理可能不适合标准JavaScript数字类型的大型值。 - 布尔值处理:
complete
字段是一个简单的布尔值,指示债券曲线过程是否已完成。
5.4 处理编码数据(Base58解码)
在某些情况下,交易数据可能是Base58编码的。我们可以先解码此数据,然后再将其传递给bondingCurveData
函数。以下decodeTransact
函数执行此任务:
export function decodeTransact(data) {
const output = base58.encode(Buffer.from(data, 'base64'));
return output;
}
此函数接受base64编码的字符串(通常是传递交易数据的方式),将其转换为Buffer,然后将其编码为Base58。解码后,交易数据可以传递给bondingCurveData
函数进行进一步处理。
这是完整的代码:
import base58 from "bs58";
import { struct, bool, u64, Layout } from "@coral-xyz/borsh";
export const structure = struct([
u64("discriminator"),
u64("virtualTokenReserves"),
u64("virtualSolReserves"),
u64("realTokenReserves"),
u64("realSolReserves"),
u64("tokenTotalSupply"),
bool("complete"),
]);export function decodeTransact(data){
const output = base58.encode(Buffer.from(data,'base64'))
return output;
}
export function bondingCurveData(buffer: Buffer) { let value = structure.decode(buffer);
const discriminator = BigInt(value.discriminator);
const virtualTokenReserves = BigInt(value.virtualTokenReserves);
const virtualSolReserves = BigInt(value.virtualSolReserves);
const realTokenReserves = BigInt(value.realTokenReserves);
const realSolReserves = BigInt(value.realSolReserves);
const tokenTotalSupply = BigInt(value.tokenTotalSupply);
const complete = value.complete;
return {
discriminator,
virtualTokenReserves,
virtualSolReserves,
realTokenReserves,
realSolReserves,
tokenTotalSupply,
complete
};
}
我们的编码结果应如下所示
{
signature: null,
pubKey: 'DmqJvcKbiH8L1yaFwxzLJQD7z1HrCMSAoWFs3xwEhybA',
owner: '6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P',
poolstate: {
discriminator: 6966180631402821399n,
virtualTokenReserves: 0n,
virtualSolReserves: 0n,
realTokenReserves: 0n,
realSolReserves: 0n,
tokenTotalSupply: 1000000000000000n,
complete: true
}
}
6、使用DeFi API获取流动性详情
Shyft的DeFi API是一种API服务,聚合了各种去中心化交易所(DEX)的数据。通过其get_by_pair
端点,您可以获取与代币对关联的流动性池详情。
以下是JavaScript中的函数:
export async function getTokenInfo(address) {
// 构造Shyft的API URL,使用提供的代币地址和Sol作为代币B
const url = `https://defi.shyft.to/v0/pools/get_by_pair?tokenA=${address}&tokenB=sol`;
// 发出API请求以获取池数据
const response = await fetch(url, requestOptions);
const data = await response.json(); // 从响应中提取相关信息
const dexes = data?.result?.dexes;
const raydium = dexes?.raydiumAmm?.pools[0]; // 进一步提取Raydium池数据的各个属性
const pubKey = raydium?.pubkey;
const baseVault = raydium?.baseVault;
const quoteVault = raydium?.quoteVault;
const lp = raydium?.lpMint;
const owner = raydium?.owner; // 以结构化格式返回提取的数据
return {
pubKey,
baseVault,
quoteVault,
lp,
owner
};
}
7、实时监控迁移代币事件
下面的代码的主要目标是实时监控迁移的代币并提供有关流动性池和债券曲线状态的重要详细信息。具体来说,该脚本监控PumpFun
代币,并在债券曲线完成且已迁移到Pumpfun时获取更新。
stream.on("data", async (data) => {
try{
const result = await tOutPut(data);
if(!result) return;
const tokenInfo = await getTokenBalance(result.pubKey);
const poolInfo = await getTokenInfo(tokenInfo?.ca);
if(poolInfo.lp === undefined) return;
console.log(
`
PUMPFUN -- RAYDIUM
CA : ${tokenInfo?.ca}
Name : ${tokenInfo?.name} (${tokenInfo?.symbol})
POOL DETAILS : Base Vault ${poolInfo?.baseVault}
Quote Vault ${poolInfo?.quoteVault}
Public Key ${poolInfo?.pubKey}
LP Mint ${poolInfo?.lp}
BONDING CURVE STATUS : COMPLETED
`
)
我们将更新stream.on
函数以适应我们的请求
我们的结果应为以下格式
PUMPFUN -- RAYDIUM
CA : 4wFZ2by5RWPrck2TBrgpjDpA6FRuNt4Hr8zD2GWyUCVh
Name : Chichi (Chichi)
POOL DETAILS : Base Vault 9LsYe4HuGBaZMjQZiadgfgN5CWMqY7KSoZp2XoFic1Ns
Quote Vault EAS5XB5NnqSPDPcMNJTNpfYKnDbWG4RYEfebyKjYhsCk
Public Key EbEQF3PtZxE2WSm4vvsiHsBngjzLbesndXnadNBpagDg
LP Mint 2i4BM7e8uTa95fEvq5UNwPDtA2DStfVgdiB1pBwjBo1y
BONDING CURVE STATUS : COMPLETED
PUMPFUN -- RAYDIUM
CA : 9Jh1TuT4hat9DW2oJikrikn8R8dwxuFqJZgD1Xx3pump
Name : Unknown Token (Token)
POOL DETAILS : Base Vault APdNU7jtC6MDjZVhoy9uX9sWmyPiQ3fFhtFiX5vtSivy
Quote Vault 4zwqJM5RhndH3a9j9tzzjYh771KNYh4JhmEyQ3YSFuER
Public Key FEJmFht44kdSuTctSyUhkp8Mp7SuJ5zngcpyAAzH8EFf
LP Mint f3PBsht2jJ2fvt9Wn3NNEVGf7K6vYdNWGG3euFPWv9w
BONDING CURVE STATUS : COMPLETED
8、结束语
本质上,我们的方法涉及获取在Raydium去中心化交易所上交易的代币,这些代币已从Pumpfun迁移过来。我们利用了Shyft的DeFi API和功能强大的gRpc工具来访问实时区块链数据。
原文链接:How to track token transfers from Pump.fun to Raydium
DefiPlot翻译整理,转载请标明出处
免责声明:本站资源仅用于学习目的,也不应被视为投资建议,读者在采取任何行动之前应自行研究并对自己的决定承担全部责任。