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

# 如何使用 preconfSubscribe

> 通过 preconfSubscribe WebSocket 方法以最低的延迟流式传输计划的 Solana 交易。订阅、解码负载，并在交易落地之前做出反应。

<Tip>
  **使用 [Sender Max](/zh/sending-transactions/sender-max)（最低提示：0.001 SOL）来进行预确认。** 只有在您的交易先到达时，预确认才有意义——Sender Max 是实现这一点的最快方法。从一开始就构建 Sender Max 以充分利用预确认。
</Tip>

## 什么是`preconfSubscribe`？

`preconfSubscribe` 是 Helius 的一个 WebSocket 方法，用于流式传输[预确认](/zh/pre-confirmations/overview)——在交易被分片之前传递在计划交易阶段的交易。这是 Helius 提供的最低延迟交易信号。

<Note>
  流不是连续的。覆盖范围随着转发到 Helius 的权益份额而波动，因此请预料到会有没有消息的插槽——请优雅地处理这些间隙。参见[覆盖范围](/zh/pre-confirmations/overview#coverage)。
</Note>

`preconfSubscribe` 从 `wss://beta.helius-rpc.com` 提供服务 —— Helius [Gatekeeper](/zh/gatekeeper/overview) 端点 —— 而不是 `mainnet.helius-rpc.com`。使用您的 API 密钥作为查询参数进行认证。

```
wss://beta.helius-rpc.com/?api-key=<API_KEY>
```

<Note>
  `beta` 主机名指的是 [Gatekeeper](/zh/gatekeeper/overview) 发布，而不是预确认的成熟度。预确认首先在 Gatekeeper 端点启动；随着 Helius 将流量迁移到 Gatekeeper，它将成为标准端点。
</Note>

## 订阅

使用 `preconfSubscribe` 方法发送 JSON-RPC 请求。服务器响应一个订阅 ID，然后为每个计划的交易流式传输通知。传递一个可选的[过滤器](#filtering)作为第一个 `params` 元素以仅接收匹配的交易；省略 `params` 以接收完整的流。

```json theme={"system"}
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "preconfSubscribe"
}
```

### 订阅响应

```json theme={"system"}
{
  "jsonrpc": "2.0",
  "result": 24040,
  "id": 1
}
```

存储 `result` — 这是你用来[取消订阅](#unsubscribing)的订阅ID。在此确认后，通知以二进制帧形式流动（见下文）。

## 过滤

默认情况下，`preconfSubscribe` 会流动每个计划的交易。要缩小流，请将过滤对象作为 `params` 的第一个元素传递。过滤在服务器端进行，因此您只需支付并接收您关心的交易。

```json theme={"system"}
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "preconfSubscribe",
  "params": [
    {
      "failed": false,
      "regionInclude": ["ewr", "fra"],
      "accountInclude": ["9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM"],
      "accountExclude": ["TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"],
      "accountRequired": ["11111111111111111111111111111111"]
    }
  ]
}
```

每个字段都是可选的——缺失的字段意味着该谓词没有“约束”，因此一个空的过滤器（或没有 `params`）匹配每个交易。

| 字段                | 类型         | 语义                                                             |
| ----------------- | ---------- | -------------------------------------------------------------- |
| `failed`          | `boolean`  | `false` 丢弃失败（回滚）的交易；成功和未知状态的交易仍会通过。`true` — 类似于省略该字段 — 保留每个状态。 |
| `regionInclude`   | `string[]` | 如果非空，则交易必须来自这些[地区](#location-filtering)中的**一个**。               |
| `accountInclude`  | `string[]` | 如果非空，则交易必须引用这些账户中的**至少一个**。                                    |
| `accountExclude`  | `string[]` | 如果交易引用了这些账户中的**任何一个**，则将其丢弃。优先于 `accountInclude`。              |
| `accountRequired` | `string[]` | 交易必须引用所有这些账户。                                                  |

<Note>
  今天只匹配交易的**静态**账户键。从v0地址查找表（ALTs）加载的账户尚未解析，因此在ALT账户上的过滤将不匹配。ALT支持即将推出。
</Note>

过滤规则：

* 所有谓词都通过 AND 结合在一起，评估顺序为 `regionInclude` → `accountExclude` → `accountRequired` → `accountInclude`。
* 账户是base58编码的公钥。无效值返回 JSON-RPC 错误 `-32602`（无效参数）。
* 每个账户列表的上限为 **500** 项。

### 位置过滤

使用 `regionInclude` 仅接收来自特定 Helius 区域的交易。传递一个或多个区域代码；当交易的起始区域与其中任何一个匹配时，它将通过。

```json theme={"system"}
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "preconfSubscribe",
  "params": [{ "regionInclude": ["ewr", "fra"] }]
}
```

有效的区域代码：

| Code  | Location |
| ----- | -------- |
| `slc` | 盐湖城      |
| `fra` | 法兰克福     |
| `lon` | 伦敦       |
| `pit` | 匹兹堡      |
| `sgp` | 新加坡      |
| `ewr` | 纽瓦克      |
| `tyo` | 东京       |
| `ams` | 阿姆斯特丹    |
| `dal` | 达拉斯      |
| `dub` | 都柏林      |
| `mia` | 迈阿密      |
| `lax` | 洛杉矶      |
| `iad` | 阿什本      |
| `sea` | 西雅图      |

<Note>
  当设置 `regionInclude` 时，不携带区域信息的交易将被丢弃。未识别的区域代码返回 JSON-RPC 错误 `-32602`（无效参数）。
</Note>

## 通知有效负载

通知作为**二进制** WebSocket 帧传递（不是 JSON）。每个帧是一个打包的字节布局，携带一个单独的计划交易：

| Bytes | Field         | Type                            | Description                                                    |
| ----- | ------------- | ------------------------------- | -------------------------------------------------------------- |
| 0     | `version`     | `u8`                            | 负载模式版本。目前为 `1`。                                                |
| 1–8   | `slot`        | `u64` （小端序）                     | 交易计划所在的槽位。                                                     |
| 9–16  | `tx_index`    | `u64` （小端序）                     | 槽位内交易的索引。                                                      |
| 17    | `status`      | `u8`                            | 交易状态：`0` = 失败，`1` = 成功，`2` = 未知。执行状态由验证者在尽力的基础上报告——当不可用时为 `2`。 |
| 18+   | `transaction` | `bincode(VersionedTransaction)` | 计划的交易，bincode-序列化。                                             |

按顺序读取字段，然后[`bincode`](https://docs.rs/bincode)将剩余字节反序列化为`VersionedTransaction`以读取指令、账户和签名。

<Warning>
  **始终先读取并检查`version`字节。** 当前为`1`。如果Helius需要更新负载格式，版本将递增——基于此进行分支，以确保您的解码器在模式更改时保持工作。
</Warning>

<Note>
  预确认是一个早期信号，而不是保证。交易尚未上链，可能仍会失败或被丢弃。通过标准承诺检查确认上链后再将其视为最终结果。
</Note>

## 示例

```javascript theme={"system"}
const WebSocket = require('ws');

const ws = new WebSocket('wss://beta.helius-rpc.com/?api-key=<API_KEY>');

ws.on('open', () => {
  ws.send(JSON.stringify({
    jsonrpc: '2.0',
    id: 1,
    method: 'preconfSubscribe'
    // Optional: only successful txs from EWR/FRA touching a given account
    // params: [{ failed: false, regionInclude: ['ewr', 'fra'], accountInclude: ['9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM'] }]
  }));

  // Keep the connection alive
  setInterval(() => ws.ping(), 30_000);
});

ws.on('message', (data, isBinary) => {
  // The subscribe acknowledgement arrives as a JSON text frame
  if (!isBinary) {
    const msg = JSON.parse(data.toString());
    if (msg.id === 1) console.log('Subscribed, ID:', msg.result);
    return;
  }

  // Notifications arrive as binary frames:
  // version (u8) | slot (u64 LE) | tx_index (u64 LE) | status (u8) | bincode(VersionedTransaction)
  const buf = Buffer.from(data);
  const version = buf.readUInt8(0); // currently 1 — branch on this if it changes
  if (version !== 1) return; // unknown schema version; update your decoder
  const slot = buf.readBigUInt64LE(1);
  const txIndex = buf.readBigUInt64LE(9);
  const status = buf.readUInt8(17); // 0 = failed, 1 = success, 2 = unknown
  const txBytes = buf.subarray(18); // bincode-serialized VersionedTransaction

  console.log('Scheduled transaction:', { version, slot, txIndex, status, bytes: txBytes.length });
  // Deserialize txBytes (bincode) into a VersionedTransaction with your Solana tooling
});

ws.on('error', console.error);
ws.on('close', () => process.exit(1));
```

## 取消订阅

要停止接收通知，请调用`preconfUnsubscribe`，并使用`preconfSubscribe`返回的订阅ID。

```json theme={"system"}
{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "preconfUnsubscribe",
  "params": [24040]
}
```

```json theme={"system"}
{
  "jsonrpc": "2.0",
  "result": true,
  "id": 2
}
```

## 定价

预确认需要**专业计划或更高级别**，每条消息花费**10个积分**——每个流式交易一条消息——从您的计划中扣费。详情参见[积分](/zh/billing/credits)。

<Note>
  预确认是一个新产品，定价可能会有变动。
</Note>

## 相关

<CardGroup cols={2}>
  <Card title="预确认概述" icon="bolt" href="/zh/pre-confirmations/overview">
    预确认是什么以及它们在验证器流水线中的位置。
  </Card>

  <Card title="transactionSubscribe" icon="tower-broadcast" href="/zh/rpc/websocket/transaction-subscribe">
    流式传输已确认承诺的交易，并提供丰富的过滤功能。
  </Card>
</CardGroup>
