如何使用 Shyft gRPC 追踪 Raydium 上的新流动性池

  • Shyft_to
  • 发布于 2024-09-24 10:20
  • 阅读 13

本文介绍了如何使用 Shyft 的 gRPC 服务实时追踪 Raydium 上新建的流动性池。通过构建交易流管道,并利用特定的编码值和空字节数组进行过滤,可以高效地获取新池创建事件。该方法还可应用于其他 DEX,只需替换程序 ID 和使用相应的交易解析器。

实时 Raydium 池跟踪:再也不会错过新的池启动

如何跟踪新的 Raydium 池

Raydium 是 Solana 区块链上的一个自动化做市商(AMM),它通过利用流动性池来促进去中心化的代币交换。这些池充当虚拟存储库,用户可以在其中直接交换代币,而无需中央订单簿。对于积极交换和交易代币的用户,或者对于交易机器人或在 Raydium 上构建实时应用程序的人来说,及时了解平台事件(例如创建新池、池的当前状态或交换的代币)至关重要。Shyft 的 gRPC 服务可以通过提供实时流式传输功能来满足此需求,确保用户立即了解 Raydium 上任何池的任何变化或更新,从而更有效地监控和有策略地安排交换时间。

在本文中,我们将探讨如何使用 Shyft 的 gRPC 服务实时跟踪 Raydium 上新创建的池。

正在寻找一个完整的可用的示例来配合学习吗?请参考我们创建的这个 replit 项目这里 请务必从 Shyft Discord 这里 获取你的 gRPC URL访问Token,并在执行之前将其添加到 Secrets 部分。

开始之前

要开始,我们需要准备一些东西。

身份验证:你的 Shyft API 密钥、gRPC 端点和 gRPC Token

你可以从 Shyft 网站获取你自己的 Shyft API 密钥(Shyft 使用的身份验证参数)。你也可以在你的 Shyft 仪表板上找到你特定区域的 gRPC 端点和访问Token。

服务端后端(如 NodeJS)来接收 gRPC 数据

由于 Web 浏览器不支持 gRPC 服务,因此你需要一个后端应用程序来接收 gRPC 数据。在本例中,我们使用了 NodeJS,但任何其他后端服务器端语言,如 C#、Go、Java、Kotlin、Python 或 PHP 也可以使用

介绍

Shyft 的由 Geyser 驱动的 gRPC 提供流式传输服务,用于帐户更新、交易、区块和槽更新,一旦它们在链上发生。我们的计划包括集成 Shyft 的 gRPC 服务,以建立 Raydium 流动性池 v4 的交易流式传输管道

一旦我们在后端获得这些数据,我们就可以快速分析它以识别在 Raydium 上创建新池的交易。通过使用特定的编码值和空字节数组进行过滤,我们可以高效地检索我们需要的重要的数据。这样,我们就可以专注于与 SOL 和 Serum 市场相关的流动性池,同时仍然捕获活跃的交易事件。

初始化 — gRPC 访问和客户端

Shyft 的 gRPC 访问Token可在其 Discord 服务器中找到。请参阅“开始之前”部分了解更多详细信息。

一旦我们获得访问Token和 gRPC URL,我们将从 Yellow Stone 服务导入客户端类。初始化一个新客户端需要两个参数gRPC URL访问Token。客户端可以按如下方式初始化:

Shyft 提供 Dragonmouth gRPC 节点,最初由 Triton One 作为其 Yellowstone 项目的一部分开发。这些节点可以从 Solana 网络进行实时数据流式传输。

要使用 Node.js 连接到这些节点,你需要 @triton-one/yellowstone-grpc SDK。安装后,你可以初始化一个客户端对象。这包括:

  1. 导入客户端类:@triton-one/yellowstone-grpc SDK 导入 Client 类。
  2. 获取凭据: 从 Shyft 获取你的访问Token和 gRPC URL。
  3. 初始化客户端: 使用 Client 类创建一个新的客户端对象。在初始化期间提供访问Token和 gRPC URL 作为参数。

客户端可以按以下方式初始化。

import Client from "@triton-one/yellowstone-grpc";

const client = new Client(
  "https://grpc.us.shyft.to", //你的区域特定的 Shyft gRPC URL
  "hbdj-asjnf-access-token-asdh", //Shyft gRPC 访问Token
  undefined,
);

有关如何使用 gRPC 设置客户端和流式传输交易的更详细的指南,请随时查看这篇关于 流式传输实时 Solana 交易 的文章。

启用实时更新 — 请求和接收流

Shyft 的 gRPC 服务利用订阅流来促进来自 Solana 区块链的实时更新。这些流充当持久连接,允许你的应用程序在链上发生事件时持续接收更新。要在上一步中创建的客户端上设置新的订阅流,请使用 client.subscribe() 方法。

const stream = await client.subscribe();

建立订阅流后,就可以指定你要接收哪些数据了。Shyft 的 gRPC 接口提供各种更新,包括帐户更改交易新区块,甚至更新。为避免信息过载,你可以通过订阅请求指定你实际需要的内容。

这些订阅请求有不同的格式,每种格式都有自己的一组参数,它们看起来有点像这样

import { CommitmentLevel } from "@triton-one/yellowstone-grpc";

const req: SubscribeRequest = {
  accounts: {},
  slots: {},
  transactions: {},
  transactionsStatus: {},
  entry: {},
  blocks: {},
  blocksMeta: {},
  accountsDataSlice: [],
  ping: undefined,
  commitment: CommitmentLevel.CONFIRMED,
};

大多数请求参数是不言自明的,与它们的名称完全一致,

  • “accounts” 你可以通过指定此参数来订阅特定帐户(例如,SOL-USDC OpenBook),并根据提交级别(已处理、已确认、已完成)接收更新。
  • “accountDataSlice”:此字段可帮助你过滤 gRPC 流,以便你仅接收流式传输数据的相关部分。例如,你正在流式传输数据大小为 200 字节的帐户,但你只需要某个偏移量后的 40 字节。此字段可以帮助你过滤流中每次更新的这 40 字节。
  • “transactions”&“transactionsStatus”:你可以接收所有交易的更新,或根据特定标准(投票/失败的交易,包括/排除帐户)进行过滤。也可以使用此方法监视程序。
  • “slots”,“blocks”&“blocksMeta” 随时了解区块链上生成的新区块和槽。
  • “commitment”:这指定任何更新的提交级别,已处理已确认已完成

在本教程中,我们将使用 AccountDataSlice。以下是接收 Raydium 交易的示例订阅请求:

const request: SubscribeRequest = {
  "slots": {},
  "accounts": {
    "raydium": {
      "account": [],
      "filters": [\
        {\
          "memcmp": {\
            "offset": LIQUIDITY_STATE_LAYOUT_V4.offsetOf('quoteMint').toString(), // 仅过滤与 SOL 配对的代币\
            "base58": "So11111111111111111111111111111111111111112"\
          }\
        },\
        {\
          "memcmp": {\
            "offset": LIQUIDITY_STATE_LAYOUT_V4.offsetOf('marketProgramId').toString(), // 仅过滤包含 Serum 引用的 Raydium 市场\
            "base58": "srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX"\
          }\
        },\
        {\
          "memcmp": {\
            "offset": LIQUIDITY_STATE_LAYOUT_V4.offsetOf('swapQuoteInAmount').toString(), // 用于过滤新代币的黑客。可能有一种更好的方法\
            "bytes": Uint8Array.from([0])\
          }\
         },\
        {\
          "memcmp": {\
            "offset": LIQUIDITY_STATE_LAYOUT_V4.offsetOf('swapBaseOutAmount').toString(), // 用于过滤新代币的黑客。可能有一种更好的方法\
            "bytes": Uint8Array.from([0])\
          }\
        }\
      ],
      "owner": ["675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8"] // 要订阅的 raydium 程序 ID
    }
  },
  "transactions": {},
  "blocks": {},
  "blocksMeta": {
    "block": []
  },
  "accountsDataSlice": [],
  "commitment": CommitmentLevel.PROCESSED, // 订阅处理的区块以获得最快的更新
  entry: {},
  transactionsStatus: {}
}

在此代码段中,我们正在配置对 Solana 账户的订阅,以监视具有特定过滤器的 Raydium 流动性池。以下是对配置的详细分解:

  1. slots:此参数是一个空对象,表示未订阅任何特定的槽数据。
  2. accounts:此部分配置对特定 Solana 帐户的订阅。在本例中,我们关注的是 Raydium 程序:

I. raydium:这是我们为其设置过滤器的帐户类别的名称。

a. account:一个空数组,表示没有直接订阅任何特定帐户。

b. filters:这是一组缩小我们感兴趣的帐户的标准:

b.i. : memcmp:此过滤器用于匹配帐户数据中特定字节偏移量处的数据。offset 指定要检查的字节位置,而 base58bytes 指定要匹配的数据,它告诉系统在二进制结构中的哪个位置查找特定信息。即 "offset":LIQUIDITY_STATE_LAYOUT_V4.offsetOf('quoteMint').toString();

c. quoteMint:过滤 quoteMint 字段与特定 base58 编码的 mint 地址(So11111111111111111111111111111111111111112)匹配的帐户。这用于专注于与 SOL 配对的代币。通过将其与 base58 编码的值(如 "So11111111111111111111111111111111111111112") 匹配,你可以过滤掉专门与 SOL 配对的流动性池。这确保你只收到与涉及 SOL 的交易或流动性相关的数据,从而使你的分析更加集中和高效。

d. marketProgramId:过滤 marketProgramId 字段与 base58 编码的 Serum 程序 ID(srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX)匹配的帐户。base58 值(例如 "srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX") 对应于 Serum 市场程序。通过过滤此值,你可以确保你只监视与 Serum 去中心化交易所交互的流动性池,这对于跟踪相关的交易活动和价格变动至关重要。

e. swapQuoteInAmount swapBaseOutAmount:这些字段用作粗略的过滤器,通过检查这些值为零的帐户来识别新代币。此方法是一种解决方法,可能不是过滤新代币的最有效方法。

f. owner:指定我们感兴趣的帐户的所有者。在本例中,我们的目标是 Raydium 程序 ID(675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8)拥有的帐户。

3. transactions blocks blocksMeta accountsDataSlice entry transactionsStatus:这些设置为空对象或数组,表示此请求中没有交易数据、区块或其他参数的特定配置或订阅。

4. commitment:此字段定义订阅数据的确认级别:

I. CommitmentLevel.PROCESSED:此级别确保你在 Solana 网络处理更新后立即收到更新,提供最快的更新,但确认程度可能较低。

成功设置流后,必须有一个函数来处理收到的交易以进行进一步操作。stream.on('data', callbackFunc()) 方法处理流,如下所示。

//处理流的回调函数
 stream.on("data", async (data) => {
    try{
      if (data.account != undefined) {
       const info = await tOutPut(data);
       console.log(
        new Date(),
        ":",
        `New transaction https://translator.shyft.to/tx/${info.signature} \n`,
        JSON.stringify(info, null, 2) + "\n",
      );
    }
}catch(error){
  if(error){
    console.log(error)
  }
}
});

预防措施 — 重新连接机制

虽然 gRPC 流式传输提供了一种可靠的接收实时数据的方式,但意外的网络问题仍然会中断连接。为确保无缝体验,你可以在应用程序中实施重新连接机制。以下示例机制将在 gRPC 流断开连接时自动尝试重新建立连接。

async function subscribeCommand(client: Client, args: SubscribeRequest) {
  while (true) {
    try {
      await handleStream(client, args); //处理流的函数
    } catch (error) {
        //如果流由于任何错误而断开连接,这将等待一秒钟并重新启动流
      console.error("Stream error, restarting in 1 second...", error);
      await new Promise((resolve) => setTimeout(resolve, 1000));
    }
  }
}

接收交易和识别新池

因此,我们已经看到了 Shyft 的 gRPC 服务,你可以轻松地实时流式传输 Solana 交易。以下是从 gRPC 接收的原始交易:

2024-09-07T08:04:52.816Z : New transaction https://translator.shyft.to/tx/2y9VYJ944mZM2LUms5TSNH6cfSjqQMH1sde62bb2KCG6s7xXEDYV6wgCoQAa8ZSUF8AAdM19rvJ6UAnmsqYxPttM
 {
  "filters": [\
    "raydium"\
  ],
  "account": {
    "account": {
      "pubkey": {
        "type": "Buffer",
        "data": [\
          127,\
          210,\
          158,\
          190,\
          141,\
          181,\
          87,\
          182,\
          122,\
          33,\
          191,\
          96,\
          181,\
          133,\
          115,\
          87,\
          254,\
          58,\
          71,\
          41,\
          63,\
          49,\
          147,\
          127,\
          94,\
          42,\
          248,\
          21,\
          104,\
          234,\
          112,\
          121...\
        ]
      },
      "lamports": "6124800",
      "owner": {
        "type": "Buffer",
        "data": [\
          75,\
          217,\
          73,\
          196,\
          54,\
          2,\
          195,\
          63,\
          32,\
          119,\
          144,\
          237,\
          22,\
          163,\
          82,\
          76,\
          161,\
          185,\
          151,\
          92,\
          241,\
          33,\
          162,\
          169,\
          12,\
          255,\
          236,\
          125,\
          248,\
          182,\
          138,\
          205\
        ]
      },
      "executable": false,
      "rentEpoch": "18446744073709551615",
      "data": {
        "type": "Buffer",
        "data": [\
          6,\
          0,\
          0,\
          0,\
          0,\
          0,\
          0,\
          0,\
          254,\
          0,\
          0,\
          0,\
          0,\
          0,\
          0,\
          0,\
          0,\
          0,\
          0,\
          0,\
          0,\
          0..\
        ]
      },
      "writeVersion": "1420851011205",
      "txnSignature": {
        "type": "Buffer",
        "data": [\
          98,\
          111,\
          127,\
          61,\
          204,\
          178,\
          57,\
          89,\
          191,\
          6,\
          80,\
          208,\
          11,\
          5,\
          56,\
          145,\
          243,\
          41,\
          76,\
          253,\
          154,\
          116,\
          203,\
          15,\
          189,\
          83,\
          136,\
          227,\
          86,\
          200,\
          119,\
          38,\
          210,\
          69,\
          229,\
          210,\
          238,\
          115,\
          14...\
        ]
      }
    },
    "slot": "288313982",
    "isStartup": false
  }
}

与传统的 RPC 响应相比,gRPC 交易流提供类似的数据,但有一些额外的字段。一些 相关的额外字段 包括 加粗isVote加粗,用于识别投票交易,加粗message headers加粗,详细说明签名者信息。响应还表示它是否是 加粗版本化的交易加粗,并且它还为 加粗区块加粗加粗ping加粗加粗条目加粗 提供了规定。

要将从 gRPC 接收到的此交易转换为像交易一样的传统 RPC,我们使用 Shyft 创建的以下实用程序函数。

import { TransactionFormatter } from "./utils/transaction-formatter";

const TXN_FORMATTER = new TransactionFormatter();
const txn = TXN_FORMATTER.formTransactionFromJson(
    data.transaction,
    Date.now(),
);

此函数通过返回 slotversionblocktimemetatransactions 来镜像传统的 Solana 的 getTransaction,从而 加粗易于与现有 Solana 应用程序集成。

后续步骤 — 发现新的 Raydium 池

下一步涉及识别创建 Raydium 上新池的交易。每当在 Raydium 中创建新池时,都会在区块链上执行包含 memcmp 指令的特定交易。由于我们已经在实时流式传输与 Raydium 相关的交易,因此我们可以访问与 Raydium 协议相关的所有交易。

但是,我们需要分析从 gRPC 流接收到的这些原始交易,以识别包含 memcmp 指令的交易,并且只有在 解析交易后才有可能。我们使用 Shyft 的交易解析器来解析从 gRPC 接收到的原始 Raydium 交易。

Raydium 输出

已解析的 Raydium 更新

在我们分解交易(解析)后,我们会得到一个“过滤器”列表,这些过滤器本质上是在执行交易时执行的操作。每个过滤器都有详细信息,例如交换中使用的金额(设置为零值)、它连接到的程序(如 Raydium)以及涉及的帐户(quoteMintbaseMint)。我们的工作是加粗利用 accountDataSlice 并查看是否有具有 memcmp 对象的特定帐户。加粗 如果我们找到其中一个,那么该交易正在创建一个新池!

适用于其他 DEX — 适用于与 Raydium 类似的程序

此池检测方法的妙处在于其适应性!它可以应用于其他去中心化交易所 (DEX),这些交易所使用类似的创建池(初始化)指令来创建池。一些示例包括 Meteora、Orca 和 Jupiter。

核心步骤基本保持不变,但有两个关键调整:

  • 程序 ID 替换: 在设置订阅请求期间,你需要将 Raydium 程序 ID 替换为目标 DEX 的特定程序 ID(例如,Meteora、Orca、Jupiter)。这确保你订阅与该特定 DEX 关联的交易。

  • 各自的交易解析器: 你需要利用专为你感兴趣的特定 DEX 设计的专用交易解析器,而不是依赖 Shyft 的 Raydium 解析器。这些解析器本质上是“代码翻译器”,经过优化以理解该 DEX 交易中的结构和指令,并且它们都可以在 Shyft 上使用。

通过实施这些调整,你可以有效地识别 Solana 区块链上各种 DEX 的新池创建事件。这使你能够保持领先地位并探索 DeFi 生态系统中的各种池机会。

这就是关于本文的全部内容。如果你想了解更多关于 gRPC 的信息,请随时查看 如何在 Solana 上设置 gRPC 流式传输,或者 使用 Shyft 构建交易机器人。非常感谢你的阅读时间,请继续关注更多 Defi 开发见解!

如果你想要完整的可用示例,这里是 git 存储库,我们已创建供你试用。请确保在试用之前将你的特定区域的 gRPC url访问Token 添加到“Secrets”部分。

资源

  • 原文链接: blogs.shyft.to/how-to-tr...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
Shyft_to
Shyft_to
在 Solana上更快更智能地构建,使用Shyft的SuperIndexer、gRPC、RPC、API和SDK