> ## Documentation Index
> Fetch the complete documentation index at: https://www.helius.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# 通过解析事件获取 Pump.fun 代币铸造

> 分页浏览地址的历史记录，通过解析事件提取 Pump.fun 的 create 和 create_v2 指令，记录每个代币铸造及其创建者、名称、符号和 URI。

本指南获取**钱包在 Pump.fun 上部署的每个代币**。它通过钱包的解析历史记录，直到历史记录耗尽，筛选出 Pump.fun 用于启动代币的两个指令。

这是解析 Streams 指南 [跟踪 Pump.fun 铸造](/docs/zh/parsed-streams/guides/track-pumpfun-mints) 的历史对应版本：相同的程序、相同的指令名称和相同的解码字段——按需获取，而不是实时推送。

<Steps>
  <Step title="查看程序">
    Pump.fun 通过两个指令根据版本来启动代币：`create` 和 `create_v2`。解析事件通过与解析 Streams 相同的 IDL 目录解码指令，因此在匹配之前，通过其 [`describeProgram`](/docs/zh/parsed-streams/quickstart#discovery) 方法确认确切的解码名称和账户角色：

    ```json Request theme={"system"}
    { "jsonrpc": "2.0", "id": 1, "method": "describeProgram", "params": [{ "program": "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P" }] }
    ```

    检查响应的 `instructions` 列表中是否有 `create` 和 `create_v2`，以及在其 `roles` 列表中查找所需账户——通常是新的 **mint** 地址，和 `creator` 账户角色或 `creator` 字段在 `args` 中。两个指令版本不一定共享一个形状，这就是为什么下面的代码检查参数和几个角色名称而不是假设一个的原因。
  </Step>

  <Step title="构建请求">
    分页获取创建者钱包的历史记录：

    ```json theme={"system"}
    {
      "address": "<CREATOR_WALLET>",
      "limit": 100,
      "sortOrder": "desc",
      "commitment": "confirmed"
    }
    ```

    值得提前了解三个与流过滤器的区别：

    * `address` 是必须的——不支持程序范围的扫描，所以您获取的是一个钱包的部署，而不是 Pump.fun 上的每个部署。对于信息流，使用 [解析 Streams](/docs/zh/parsed-streams/guides/track-pumpfun-mints)。
    * 请求没有服务器端指令过滤器。历史记录返回地址触及的所有内容，下一步是在客户端筛选出 Pump.fun 指令。
    * 没有 `includeFailed` 开关。历史记录返回成功和失败的交易，因此在客户端检查 `parsed.transactionStatus` ——失败的部署永远不会产生活跃的铸造。
  </Step>

  <Step title="分页浏览历史记录">
    每个结果都携带交易的**每个**指令。扫描 `parsed.instructions` 以查找 `create`/`create_v2` 命中，并继续传递 `paginationToken`，直到它消失：

    ```javascript pumpfun-mint-history.js theme={"system"}
    const API_KEY = process.env.HELIUS_API_KEY;

    if (!API_KEY) {
      console.error("Missing HELIUS_API_KEY.");
      process.exit(1);
    }

    const URL = `https://<ENDPOINT>/transaction-history?api-key=${API_KEY}`;
    const PUMP_PROGRAM = "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P";
    const CREATE_INSTRUCTIONS = ["create", "create_v2"];
    const CREATOR = process.argv[2];

    if (!CREATOR) {
      console.error("Usage: node pumpfun-mint-history.js <CREATOR_WALLET>");
      process.exit(1);
    }

    async function fetchPage(paginationToken) {
      const body = {
        address: CREATOR,
        limit: 100,
        sortOrder: "desc",
        commitment: "confirmed",
      };
      if (paginationToken) body.paginationToken = paginationToken;

      const response = await fetch(URL, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(body),
      });
      if (!response.ok) {
        throw new Error(`HTTP ${response.status}: ${await response.text()}`);
      }
      return response.json();
    }

    async function main() {
      let paginationToken;
      let deployCount = 0;

      do {
        const page = await fetchPage(paginationToken);

        for (const result of page.data) {
          if (result.parserStatus !== "OK") continue;
          // Failed deploys never produce a live mint.
          if (result.parsed.transactionStatus !== "OK") continue;

          for (const ix of result.parsed.instructions) {
            if (ix.programId !== PUMP_PROGRAM) continue;
            if (!CREATE_INSTRUCTIONS.includes(ix.instructionName)) continue;
            deployCount += 1;
            handleDeploy(result, ix, deployCount);
          }
        }

        paginationToken = page.paginationToken;
      } while (paginationToken);

      console.log(`${deployCount} pump deploys found for ${CREATOR}`);
    }

    main();
    ```
  </Step>

  <Step title="提取每个部署">
    从解码指令中提取 mint、创建者和元数据，正如流监听器所做的那样：

    ```javascript theme={"system"}
    // Pull an account pubkey out of a decoded instruction by its role name.
    function accountByRole(decoded, role) {
      return decoded?.accounts?.find((a) => a.name === role)?.pubkey ?? null;
    }

    function handleDeploy(result, ix, deployCount) {
      const args = ix.decoded?.args ?? {};
      const mint = accountByRole(ix.decoded, "mint");
      const creator =
        args.creator ??
        accountByRole(ix.decoded, "creator") ??
        accountByRole(ix.decoded, "user");

      console.log(`pump deploy #${deployCount} (${ix.instructionName})`);
      console.log(`    mint:    ${mint}`);
      console.log(`    creator: ${creator}`);
      console.log(`    name:    ${args.name ?? "?"}`);
      console.log(`    symbol:  ${args.symbol ?? "?"}`);
      console.log(`    uri:     ${args.uri ?? "?"}`);
      console.log(`    slot=${result.parsed.slot} sig=${result.signature}`);
    }
    ```

    检查 `ix.decoded` 是否存在，然后才能信任 `args` 和 `accounts` ——否则，Pump.fun 程序的未识别构建将显示为 `mint: null`，仅能使用 `rawData` 和 `rawAccounts`。
  </Step>
</Steps>

## 下一步

<CardGroup cols={2}>
  <Card title="跟踪 Pump.fun 铸造" icon="rocket" href="/docs/zh/parsed-streams/guides/track-pumpfun-mints">
    实时版本：一个重新连接安全的监听器，记录每个新部署着陆时的情况。
  </Card>
</CardGroup>
