> ## 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.

# Solana Pump AMM 数据流与 LaserStream

> 可复制粘贴的 LaserStream 脚本，实时流传 Pump.fun 账户和交易活动，附带滚动统计和签名解码功能。

使用 [LaserStream SDK](/zh/laserstream/clients) 实时流传每一个 Pump.fun 账户更新和交易。本页面提供一个完整的 TypeScript 脚本，您可以从头到尾运行：它在每笔交易到达时打印信息，每分钟报告滚动统计（吞吐量、唯一费用支付者、Sol 中的总费用），并在重连时自动保持连接。

这是对任何需要持续 Pump.fun 可见性项目的有用起点——交易机器人、分析仪表板、警报管道，或者只是探索数据形态以便您在其基础上构建更专业的东西。

<Info>
  **先决条件：** 一 个 [Helius API 密钥](https://dashboard.helius.dev/)（用于 Mainnet LaserStream 的商务或专业计划）和 Node.js 18+。熟悉 [账户订阅](/zh/laserstream/guides/account-subscription) 和 [交易监控](/zh/laserstream/guides/transaction-monitoring) 有帮助但不是必须的。
</Info>

***

## 设置

创建一个新项目，安装 SDK + `bs58`（用于解码交易签名），并设置您的 API 密钥：

```bash theme={"system"}
mkdir pump-monitor && cd pump-monitor
npm init -y
npm install helius-laserstream bs58
npm install --save-dev typescript ts-node @types/node
npx tsc --init
export HELIUS_API_KEY=your-key-here
```

选择离此脚本运行位置最近的端点——参见 [LaserStream 区域](/zh/laserstream/grpc#mainnet-endpoints)。

***

## 脚本

将其另存为 `index.ts`，然后运行 `npx ts-node index.ts`：

```typescript [expandable] theme={"system"}
import { subscribe, CommitmentLevel, LaserstreamConfig, SubscribeRequest } from 'helius-laserstream';
import bs58 from 'bs58';

const PUMP_PROGRAM_ID = '6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P';

// Rolling stats across the session.
const stats = {
  startedAt: Date.now(),
  transactions: 0,
  successes: 0,
  failures: 0,
  uniquePayers: new Set<string>(),
  totalFeesLamports: 0,
  accountUpdates: 0,
};

async function handleUpdate(data: any) {
  if (data.transaction) {
    const tx = data.transaction.transaction;
    if (!tx) return;

    stats.transactions++;
    const failed = !!tx.meta?.err;
    failed ? stats.failures++ : stats.successes++;

    // tx.meta.fee is a u64 string — coerce before adding.
    stats.totalFeesLamports += Number(tx.meta?.fee ?? 0);

    // Fee payer is the first account in the message.
    const firstKey = tx.transaction?.message?.accountKeys?.[0];
    if (firstKey) {
      const payer = typeof firstKey === 'string' ? firstKey : bs58.encode(firstKey);
      stats.uniquePayers.add(payer);
    }

    // tx.signature is a Buffer in the SDK.
    const sig = bs58.encode(tx.signature);
    const slot = data.transaction.slot;
    const flag = failed ? '❌' : '✅';
    console.log(`${flag}  ${sig.slice(0, 12)}…  slot ${slot}  fee ${tx.meta?.fee} lamports`);
  }

  if (data.account) {
    stats.accountUpdates++;
    const acct = data.account.account;
    const pubkey = typeof acct.pubkey === 'string' ? acct.pubkey : bs58.encode(acct.pubkey);
    console.log(`📋  account ${pubkey}  ${acct.data?.length ?? 0} bytes`);
  }
}

function printReport() {
  const minutes = (Date.now() - stats.startedAt) / 60_000;
  console.log('\n📊  Pump.fun activity report');
  console.log(`   Runtime:           ${minutes.toFixed(1)} min`);
  console.log(`   Transactions:      ${stats.transactions} (${stats.successes} ok, ${stats.failures} failed)`);
  console.log(`   Throughput:        ${(stats.transactions / Math.max(minutes, 0.0001)).toFixed(1)} tx/min`);
  console.log(`   Unique fee payers: ${stats.uniquePayers.size}`);
  console.log(`   Total fees:        ${(stats.totalFeesLamports / 1e9).toFixed(4)} SOL`);
  console.log(`   Account updates:   ${stats.accountUpdates}\n`);
}

async function main() {
  const config: LaserstreamConfig = {
    apiKey: process.env.HELIUS_API_KEY ?? 'YOUR_API_KEY',
    endpoint: 'https://laserstream-mainnet-ewr.helius-rpc.com', // pick the region closest to you
  };

  const subscriptionRequest: SubscribeRequest = {
    accounts: {
      'pump-accounts': {
        account: [],
        owner: [PUMP_PROGRAM_ID],
        filters: [],
      },
    },
    transactions: {
      'pump-transactions': {
        accountInclude: [PUMP_PROGRAM_ID],
        accountExclude: [],
        accountRequired: [],
        vote: false,
        failed: false,
      },
    },
    commitment: CommitmentLevel.CONFIRMED,
    slots: {},
    transactionsStatus: {},
    blocks: {},
    blocksMeta: {},
    entry: {},
    accountsDataSlice: [],
  };

  console.log('🚀  Streaming Pump.fun activity. Press Ctrl+C to stop.\n');

  const reportTimer = setInterval(printReport, 60_000);
  process.on('SIGINT', () => {
    clearInterval(reportTimer);
    printReport();
    process.exit(0);
  });

  await subscribe(config, subscriptionRequest, handleUpdate, async (error) => {
    console.error('Stream error:', error);
  });
}

main().catch(console.error);
```

***

## 脚本的功能

### 一个订阅，两个过滤块

一个 `subscribe(...)` 调用包含两个命名的过滤组：

* **`accounts`** 过滤接收每当数据变化时 Pump.fun 程序拥有的每个账户（债券曲线、铸造状态等）。
* **`transactions`** 过滤接收每个与 Pump.fun 程序交互的交易。 `vote: false, failed: false` 标记在到达您的处理程序之前删除投票和失败的交易。

两者通过单个 gRPC 流到达，因此 SDK 只需管理一个连接。如果连接断开，SDK 会自动重新连接，您将继续从两个过滤器接收更新。

### 读取原始字段

负载中的几个值需要进行小的转换，以便于使用：

* **`tx.signature`** 是一个 [`Buffer`](https://nodejs.org/api/buffer.html)。通过 `bs58.encode(...)` 运行它，以获得在资源管理器或 `getTransaction` 响应中看到的 base58 签名。
* **`tx.meta.fee`** 是一个以字符串存储的 u64，以确保在 JavaScript 中不会丢失 `Number.MAX_SAFE_INTEGER` 以上的精度。在进行算术运算之前，将其包裹在 `Number(...)` 中。同样的 u64 字符串约定也适用于多个区块级字段 — 请参阅 [Slot & Block Monitoring](/zh/laserstream/guides/slot-and-block-monitoring) 以了解完整的数据结构。

### 滚动统计

`setInterval` 每 60 秒打印一次快照：总交易数、成功与失败、吞吐量、唯一费用支付者和 SOL 中的总费用。在脚本退出之前按下 `Ctrl+C` 可获得最后一次快照。

***

## 扩展脚本

一些进一步发展的方向：

* **解码指令判别码**，将交易标记为 `buy` / `sell` / `create` — 请参阅 [Decoding Transaction Data](/zh/laserstream/guides/decoding-transaction-data) 以获取解析模式。
* **持久化** 滚动统计数据到数据库（Postgres，Redis，ClickHouse），而不是在内存中 `Set` / 计数器。
* **警报** 阈值 — 大型费用支付者、突然的交易量飙升、新的债券曲线账户。
* **重放** 启动时错过的活动，通过设置 `fromSlot` 在 `SubscribeRequest` 上（最多 24 小时 — 请参阅 [Historical Replay](/zh/laserstream/historical-replay)）。
* **组合** 使用 [Slot & Block Monitoring](/zh/laserstream/guides/slot-and-block-monitoring) 以获取区块级上下文。

***

## 后续步骤

<CardGroup cols={2}>
  <Card title="交易监控" icon="receipt" href="/zh/laserstream/guides/transaction-monitoring">
    此脚本使用的一般交易过滤模式。
  </Card>

  <Card title="解码交易数据" icon="binary" href="/zh/laserstream/guides/decoding-transaction-data">
    将二进制交易负载解析为可读的Solana交易。
  </Card>

  <Card title="账户订阅" icon="user" href="/zh/laserstream/guides/account-subscription">
    使用过滤器监控特定账户状态更改。
  </Card>

  <Card title="历史重放" icon="clock-rotate-left" href="/zh/laserstream/historical-replay">
    从起始槽重放过去最多24小时的Pump.fun活动。
  </Card>
</CardGroup>
