本文介绍了如何使用 gRPC 实时追踪 Pump.fun 上新发行的 Token。通过 Shyft 提供的 API 获取 gRPC URL 和 Token,设置 gRPC 连接,订阅与 Pumpfun 程序 ID 相关的交易流,解码交易数据,并通过过滤日志消息来识别新 Token 的发行。最后,利用 Shyft API 获取 Token 的基本信息,如名称、符号、描述等,并实时输出。
在 Pumpfun 上流式传输新发行的 Token 需要实时数据跟踪。不幸的是,Pumpfun 目前缺乏流式传输所需的工具和资源。在这篇博客中,你将学习如何利用 gRPC 实时流式传输 Pump.fun 上新发行的 Token 的数据。
注册并在 Shyft 仪表板 中获取以上所有详细信息
前端不支持 gRPC 流式传输,因此你需要一个后端应用程序来接收 gRPC 数据。在这个例子中,我们使用了 NodeJS,但也可以使用其他后端语言,如 C#、Go、Java、Kotlin、Python 或 PHP。
在本文中,我们将探讨如何使用 gRPC 来流式传输 Pump.fun 上新添加的 Token。
要开始流式传输,我们需要建立客户端服务。这需要:gRPC URL 和 gRPC 访问 Token。
const client = new Client(
'Your Region specific Shyft gRPC URL',
'Shyft gRPC Access Token',
undefined,
);
现在,让我们深入研究并从区块链中获取数据!
以下代码演示了如何建立从 gRPC 服务到实时数据流的订阅。具体来说,我们订阅与 pumpfun
程序 ID(6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P
)相关的交易。
const req = {
accounts: {},
slots: {},
transactions: {
bondingCurve: {
vote: false,
failed: false,
signature: undefined,
accountInclude: ['6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P'], //Address 6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P
accountExclude: [],
accountRequired: [],
},
},
transactionsStatus: {},
entry: {},
blocks: {},
blocksMeta: {},
accountsDataSlice: [],
ping: undefined,
commitment: CommitmentLevel.CONFIRMED, //for receiving confirmed txn updates
};
subscribeCommand(client, req);
输出将如下所示:
filters: [ 'Pumpfun' ],
account: undefined,
slot: undefined,
transaction: {
transaction: {
signature: <Buffer 48 e8 a9 27 ba af 8d a7 34 10 83 b8 57 6f 9c d0 e2 31 67 fe 33 c7 94 44 64 de 88 67 d1 9a ff 69 77 e6 6b f4 0b ec e0 48 19 5d a0 0f ef 7e aa b9 c4 af ... 14 more bytes>,
isVote: false,
transaction: [Object],
meta: [Object],
index: '1690'
},
slot: '288764368'
},
block: undefined,
ping: undefined,
pong: undefined,
blockMeta: undefined,
entry: undefined
}
要获取新的 Token 发行 Tx,我们需要解码并简化我们的流输出。在 utils
文件夹中,你将找到 transactionOutput.ts
文件。以下代码说明了如何修改输出以满足我们的需求:
import { decodeTransact } from "./decodeTransaction";
export function tOutPut(data){
const dataTx = data?.transaction?.transaction
const signature = data != undefined?decodeTransact(dataTx?.signature):"";
const message = dataTx?.transaction?.message
const header = message?.header;
const accountKeys = data != undefined?message?.accountKeys?.map((t)=>{
return decodeTransact(t)
}):"";
const recentBlockhash = decodeTransact(message?.recentBlockhash);
const instructions = message?.instructions
const meta = dataTx?.meta
const logs : any[] = meta?.logMessages;
const logFilter = logs?.some(instruction =>
instruction.match(instruction.match(/MintTo/i)));
return {
signature,
message:{
header,
accountKeys,
recentBlockhash,
instructions
},
meta,
logFilter
}
}
输出将如下所示:
{
signature: '2mHnosZrcuDPB7PoB5CLS69qW4AA5SfZWkrn4ZPyGpQyQjQG2fZPGAnb28RmTwLeAW4wq4ZMj4oLgrgsWvW4zQbc',
message: {
header: {
numRequiredSignatures: 2,
numReadonlySignedAccounts: 0,
numReadonlyUnsignedAccounts: 10
},
accountKeys: [\
'89qbZTVyGqpfeu5btKubFqYjV9mh4w3zWDGacKkFpMPj',\
'8MqEGUhijWXbDuzoJR4Zax37HLTpJQZXNfcH81CWpump',\
'HFqU5x63VTqvQss8hp11i4wVV8bD44PvwucfZ2bU7gRe',\
],
recentBlockhash: '5upunMbFnmYLm2dq8tEDgHoW3yMBqsLQg7UwTBjWFysa',
instructions: [ [Object], [Object], [Object], [Object], [Object], [Object] ]
},
meta: {
err: undefined,
fee: '90719',
preBalances: [\
'6868763480', '0',\
'1432215', '0',\
'0', '0',\
'0', '320032236232075',\
'1', '1',\
'1141440', '323296939',\
'5530000', '1141440',\
'934087680', '731913600',\
'1009200', '0'\
],
postBalances: [\
'5832283961', '1461600',\
'5432215', '1001231920',\
'2039280', '15616720',\
'2039280', '320032246232075',\
'1', '1',\
'1141440', '323296939',\
'5530000', '1141440',\
'934087680', '731913600',\
'1009200', '0'\
],
innerInstructions: [ [Object], [Object], [Object] ],
innerInstructionsNone: false,
logMessages: [\
'Program ComputeBudget111111111111111111111111111111 invoke [1]',\
'Program ComputeBudget111111111111111111111111111111 success',\
'Program 11111111111111111111111111111111 invoke [1]',\
'Program 11111111111111111111111111111111 success',\
'Program ComputeBudget111111111111111111111111111111 invoke [1]',\
'Program ComputeBudget111111111111111111111111111111 success',\
'Program 6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P invoke [1]',\
'Program log: Instruction: Create',\
'Program 11111111111111111111111111111111 invoke [2]',\
'Program 11111111111111111111111111111111 success',\
'Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]',\
'Program log: Instruction: InitializeMint2',\
'Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 2780 of 238053 compute units',\
'Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success',\
'Program 11111111111111111111111111111111 invoke [2]',\
'Program 11111111111111111111111111111111 success',\
'Program ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL invoke [2]',\
\
],
logMessagesNone: false,
preTokenBalances: [],
postTokenBalances: [ [Object], [Object] ],
rewards: [],
loadedWritableAddresses: [],
loadedReadonlyAddresses: [],
returnData: undefined,
returnDataNone: true,
computeUnitsConsumed: '173923'
},
logFilter: true
}
要获取新 Token 发行,我们过滤日志消息以查找在其日志中包含术语 "MintTo"
的交易。 这有助于我们识别并仅返回与 Token 铸造相关的交易。
在获得结果之前,我们需要关于 Token 的基本信息,如名称、符号、描述、小数位数和供应量。下面的代码展示了如何使用 Shyft 的 getInfo
API 获取这些信息。
var myHeaders = new Headers();
const api = 'Your api key'
myHeaders.append("x-api-key", api);
var requestOptions:any = {
method: 'GET',
headers: myHeaders,
redirect: 'follow'
};
export async function getTokenInfo(token){
const info = await fetch(`https://api.shyft.to/sol/v1/token/get_info?network=mainnet-beta&token_address=${token}`, requestOptions)
const infoJson = await info.json();
const name = infoJson.result.name;
const symbol = infoJson.result.symbol;
const desc = infoJson.result.description;
const decimal = infoJson.result.decimals;
const supply = infoJson.result.current_supply;
return{
name,
symbol,
desc,
supply,
decimal
}
}
我们将 Token 信息作为对象返回,然后导出我们的函数,以便可以被其他函数调用。
const result = await tOutPut(data);
: 将传入的 data
传递给 tOutPut
函数,该函数处理数据并返回一个 promise。此 promise 的结果被等待并存储在 result
变量中。result?.logFilter == true
: 检查 result
是否不是 null
或 undefined
,并且其 logFilter
属性是否为 true
。这表明日志消息符合标准(例如,包含 "MintTo"
)。const tokenStream = result?.meta?.postTokenBalances[0];
: 从 result
的 meta
属性中的 postTokenBalances
数组中检索第一个 Token 余额条目。const mint = tokenStream?.mint;
: 从 tokenStream
中提取 Token 的 mint 地址。const tokenInfo = await getTokenInfo(mint);
: 使用 mint 地址调用 getTokenInfo
函数以获取有关 Token 的详细信息。此函数返回一个 promise,该 promise 被等待,并将生成的 Token 信息存储在 tokenInfo
中。stream.on("data", async (data) => {
try{
const result = await tOutPut(data);
if(result?.logFilter == true){
const tokenStream = result?.meta?.postTokenBalances[0];
const mint = tokenStream?.mint
const tokenInfo = await getTokenInfo(mint);
console.log(`
CA| ${mint}
Name| ${tokenInfo?.name}
Symbol| ${tokenInfo?.symbol}
Desc| ${tokenInfo?.desc}
Decimal| ${tokenInfo?.decimal}
Supply| ${tokenInfo?.supply}
<https://solscan/tx/${result.signature}>
`)
}
}catch(error){
if(error){
console.log(error)
}
}
CA
: Token 的 mint 地址。Name
: Token 的名称。Symbol
: Token 的符号。Desc
: Token 的描述。Decimal
: Token 支持的小数位数。Supply
: Token 的当前供应量。Transaction Link
: 用于在 Solscan 上查看交易的 URL,其中包含交易签名。console.log(`
CA| ${mint}
Name| ${tokenInfo?.name}
Symbol| ${tokenInfo?.symbol}
Desc| ${tokenInfo?.desc}
Decimal| ${tokenInfo?.decimal}
Supply| ${tokenInfo?.supply}
<https://solscan/tx/${result.signature}>
`);
我们的结果应该如下所示
CA| 4hhRRFQ4MS8jmzjeVdvAk66zxKU3ARTaherKwYfkpump
Name| FLOSS
Symbol| FLOSS
Desc| Don't forget to FLOSS.
Decimal| 6
Supply| 1000000000
https://solscan/tx/2pbXSouh76bS4aAwXfrCSYtGdDuKcCTcRmuvKDJWrR9UkibUNjRooSFE9qS1jvtpHxpp3EZj8itK9G59VTMjgGUT
CA| CEfDZRT4X7sX5Q1BqeK7KeqvLtCZc1Jmr1GdTQ6Kpump
Name| Bro said he knew a spot
Symbol| SPOT
Desc| Bro said he knew a spot
Decimal| 6
Supply| 1000000000
https://solscan/tx/3ncnJNsApRX21hbT9rSN7qtty5bj3czBj63bFkJsCg1Wa4Bu7wJ4PUryZREFvqvPPD1PXGboHyRFXNvUz4tzttF2
在本文中,你学习了如何设置一个实时流,用于使用 gRPC 跟踪 Pumpfun 上新发行的 Token。通过利用 gRPC,你已经克服了链上数据跟踪的限制,现在可以接收具有毫秒级延迟的实时交易数据。
此设置允许你掌握 Token 发行的最新信息,并使用 Shyft 的 gRPC 访问详细的 Token 信息。
如需其他支持,请加入我们的 Discord 服务器 或在 Twitter 上关注我们以获取最新更新。我们的团队随时为你提供帮助,以利用这项创新技术。
你可以在我们的 GitHub 存储库 中找到与本文相关的所有代码。你可以克隆它并使用它来构建创新解决方案。
有关数据流式传输的更多教程,请浏览我们的其他文章:
如何使用 Shyft 的 gRPC 服务流式传输实时 Solana 交易 使用 gRPC 进行实时数据流式传输:账户、交易、区块 如何在 Solana 上流式传输实时 Pump.fun 更新,
如何在 Pumpfun 上流式传输 Bonding Curve 交易
如何使用 gRPC 实时流式传输 Solana Moonshot 交易
- 原文链接: blogs.shyft.to/how-to-st...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!