在代币完成其在 Pumpfun 上的绑定曲线(bonding curve)活动后,它将迁移到 Raydium 进行交易。使用 gRPC 可以更容易地识别已迁移并在 Raydium 上积极交易的代币。

通过本文,你将学习如何使用 gRPC 和 Shyft APIs 从 Pump.fun 代币迁移到 Raydium。
入门
在你开始构建之前,注册并获取 Shyft RPC/API 和 gRPC 代币访问。
gRPC 服务不直接在 Web 浏览器中支持,因此你需要一个后端应用程序来处理 gRPC 数据。虽然本示例使用 Node.js,你可以根据自己的喜好选择各种服务器端语言,包括 C#、Go、Java、Kotlin、Python 或 PHP。
在本文中,我们将看看如何使用 gRPC 获取 Raydium 上一个代币的价格更新。我们将涵盖以下步骤
设置 gRPC 连接
跟踪 Pumpfun 上已完成的绑定曲线
反序列化我们的 pumpfun 数据
使用 Defi Api 获取流动性详情
结论
设置 gRPC 连接
要开始,你需要克隆 Git 仓库。按照以下步骤操作:
打开终端。
转到要克隆的目录。
执行以下 git clone 命令:
$ git clone https://github.com/Shyft-to/solana-defi.git
安装
在终端中,导航到包含代码的文件夹,使用 cd grpc-defiapi-liquidityDetails
,然后执行 npm install
安装所有依赖项。
cd grpc-pumpfun_migration npm install
建立 gRPC 连接
要开始流式传输,你需要配置 gRPC URL 和 访问令牌。
const client = new Client( '你所在地区的 Shyft gRPC URL', 'Shyft gRPC 访问令牌', undefined, );
是时候开始流式传输了!
跟踪 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: {}, };
gRPC 请求的关键组件
让我们逐步分析请求的主要部分:
账户过滤器: 这里的关键过滤器是
memcmp
过滤器,它检查代币的complete
状态。这有助于识别已经完成其绑定曲线活动的代币,准备好迁移。
offset
指定了账户结构中完成状态的位置。使用structure.offsetOf('complete')
确保我们根据代币的最终状态进行过滤。使用
Uint8Array.from([1])
的bytes
过滤器查找值为1
,表示绑定曲线活动已经完成。
2. 程序拥有者: owner 字段指定了 Pumpfun 程序 ID 或 Raydium 程序 ID。这确保我们只订阅与迁移到 Raydium 的代币相关的事件。
3. 承诺级别: CommitmentLevel.PROCESSED
设置允许你订阅 已处理的块,确保你在交易和代币迁移发生时获得近实时更新。
4. 交易和块: 通过订阅这些字段,你可以跟踪代币的持续活动,监控与其迁移和交易相关的实时事件。
在我们的 stream.on
功能中,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 }
反序列化 Pump.fun 数据
我们将逐步介绍如何使用提供的代码解码 Pumpfun 交易。交易数据是二进制格式,我们将使用模仿数据布局的结构解码它。
第 1 步:导入所需库
我们首先导入所需的库:
import base58 from "bs58"; import { struct, bool, u64, Layout } from "@coral-xyz/borsh";
base58
用于处理 base58 编码,常用于 Solana 交易。@coral-xyz/borsh
是一个强大的二进制定序/反序列化库,我们将用于定义和解码交易数据的结构。
第 2 步:定义数据结构
我们使用 borsh
的 struct
函数定义绑定曲线交易的数据结构:
export const structure = struct([ u64("discriminator"), u64("virtualTokenReserves"), u64("virtualSolReserves"), u64("realTokenReserves"), u64("realSolReserves"), u64("tokenTotalSupply"), bool("complete"), ]);
以下是字段的 breakdown:
discriminator: 数据结构的唯一标识符。
virtualTokenReserves: 代币的虚拟储备。
virtualSolReserves: Solana (SOL) 中的虚拟储备。
realTokenReserves: 代币的真实储备。
realSolReserves: SOL 中的真实储备。
tokenTotalSupply: 代币的总供应量。
complete: 一个布尔值,指示绑定曲线过程是否完成。
每个字段都映射到一个特定的类型,例如 u64
(用于无符号 64 位整数)和 bool
(用于布尔值)。这确保了二进制数据被正确解释。
第 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
字段是一个简单的布尔值,指示绑定曲线过程是否已完成。
第 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 }; }
我们的编码结果应如下所示:
cd grpc-pumpfun_migration npm install0
附加:使用 DeFi API 获取流动性详情
Shyft 的 DeFi API 是一个聚合来自各种去中心化交易所(DEX)的数据的 API 服务。通过其 get_by_pair
端点,你可以获取与代币对相关的流动性池的详细信息。
以下是 JavaScript 中的函数:
cd grpc-pumpfun_migration npm install1
实时流式传输 Pumpfun 的已迁移代币事件在 Raydium 上
以下代码的主要目标是 实时监控迁移的代币 并提供有关 流动性池 和 绑定曲线 状态的重要细节。具体来说,正在监控 PumpFun
代币,当绑定曲线完成并已迁移到 pumpfun 时,脚本获取更新。
cd grpc-pumpfun_migration npm install2
我们更新我们的 stream.on
函数以符合我们期望的请求格式
我们的结果应为此格式:
cd grpc-pumpfun_migration npm install3
结论
本质上,我们的方法涉及在 Raydium 去中心化交易所上获取已迁移的 Pumpfun 交易代币。我们利用了 Shyft 的 DeFi API 和 gRpc,这是一个强大的工具,可用于访问实时区块链数据。