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

> Gunakan preconfSubscribe untuk melakukan streaming transaksi Solana sebelum diubah menjadi shred — Preconfirmations Helius membawa status eksekusi, sedangkan Preconfirmations BAM tiba sebelum eksekusi.

Mulai langganan ke [Preconfirmations](/docs/id/pre-confirmations/overview) — transaksi yang dikirim sebelum dikumpulkan menjadi entri dan diubah menjadi shred. Ini adalah sinyal transaksi dengan latensi terendah yang ditawarkan Helius. Satu langganan melakukan streaming Preconfirmations Helius, yang dipancarkan tepat saat leader mengeksekusi transaksi dan membawa status eksekusinya, serta [Preconfirmations BAM](/docs/id/pre-confirmations/overview#prekonfirmasi-bam), yang dipancarkan saat validator berkomitmen untuk mengeksekusinya; tetapkan `includeBam: false` agar hanya menerima Preconfirmations Helius.

## Endpoint

`preconfSubscribe` disediakan dari endpoint [Gatekeeper](/docs/id/gatekeeper/overview) Helius:

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

Nama host `beta` merujuk pada peluncuran Gatekeeper, bukan tingkat kematangan Preconfirmations — ini akan menjadi endpoint standar seiring migrasi lalu lintas ke Gatekeeper.

<Note>
  Streaming tidak berlangsung terus-menerus. Cakupan meningkat sesuai proporsi stake jaringan
  yang meneruskan data ke Helius atau menjalankan BAM, jadi mungkin ada slot tanpa pesan — tangani
  celah ini dengan baik. Lihat [Cakupan](/docs/id/pre-confirmations/overview#cakupan).
</Note>

## Otorisasi

<ParamField query="api-key" type="string" required>
  Kunci API Helius Anda, yang diteruskan sebagai parameter kueri `api-key`. Memerlukan paket Professional atau yang lebih tinggi.
</ParamField>

## Isi

<ParamField body="params" type="array">
  Opsional. Hilangkan `params` untuk menerima setiap transaksi dari Helius dan BAM. Untuk mempersempit streaming, teruskan objek filter sebagai elemen pertama — pemfilteran dilakukan di sisi server, sehingga Anda hanya membayar dan menerima transaksi yang Anda perlukan.

  <Expandable title="Filter" defaultOpen>
    Setiap bidang bersifat opsional — bidang yang tidak ada berarti "tanpa batasan" untuk predikat tersebut, sehingga filter kosong cocok dengan setiap transaksi dari kedua sumber. Bidang yang ditetapkan digabungkan dengan **AND** dan dievaluasi dalam urutan `includeBam` → `failed` → `regionInclude` → `accountExclude` → `accountRequired` → `accountInclude`.

    <ParamField body="includeBam" type="boolean" default="true">
      `false` menghapus Preconfirmations BAM sehingga Anda hanya menerima Preconfirmations Helius. `true`, seperti saat bidang dihilangkan, mempertahankan kedua sumber.
    </ParamField>

    <ParamField body="failed" type="boolean">
      `true` hanya mengembalikan transaksi yang gagal (dibatalkan); `false` hanya mengembalikan transaksi yang berhasil. Kedua nilai tersebut mengecualikan transaksi Helius dengan status yang tidak diketahui. Hilangkan bidang ini untuk menerima semua status. Preconfirmations dengan status yang tidak diketahui tetap dikirim jika cocok dengan filter sumber, wilayah, dan akun.
    </ParamField>

    <ParamField body="regionInclude" type="string[]">
      Jika tidak kosong, transaksi harus berasal dari **salah satu** [wilayah](#kode-wilayah) ini. Transaksi tanpa informasi wilayah akan dihapus jika bidang ini ditetapkan.
    </ParamField>

    <ParamField body="accountInclude" type="string[]">
      Jika tidak kosong, transaksi harus merujuk pada **setidaknya satu** akun ini (kunci publik base58). Dibatasi hingga 500 entri.
    </ParamField>

    <ParamField body="accountExclude" type="string[]">
      Transaksi akan dihapus jika merujuk pada **salah satu** akun ini. Diprioritaskan daripada `accountInclude`. Dibatasi hingga 500 entri.
    </ParamField>

    <ParamField body="accountRequired" type="string[]">
      Transaksi harus merujuk pada **semua** akun ini. Dibatasi hingga 500 entri.
    </ParamField>
  </Expandable>
</ParamField>

Nilai akun yang tidak valid atau kode wilayah yang tidak dikenal akan mengembalikan kesalahan JSON-RPC `-32602` (parameter tidak valid).

Filter akun mencocokkan lebih dari sekadar kunci akun statis transaksi — Helius menyelesaikan [tabel pencarian alamat](/docs/id/glossary#address-lookup-table-alt) v0 di sisi server, sehingga `accountInclude`, `accountExclude`, dan `accountRequired` juga mencocokkan akun yang dimuat transaksi melalui ALT.

### Kode wilayah

| Kode  | Lokasi         | Kode  | Lokasi             |
| ----- | -------------- | ----- | ------------------ |
| `slc` | Salt Lake City | `tyo` | Tokyo              |
| `fra` | Frankfurt      | `ams` | Amsterdam          |
| `lon` | London         | `dal` | Dallas             |
| `pit` | Pittsburgh     | `dub` | Dublin             |
| `sgp` | Singapura      | `mia` | Miami              |
| `ewr` | Newark         | `lax` | Los Angeles        |
| `iad` | Ashburn        | `sea` | Seattle            |
| `hkg` | Hong Kong      | `sqq` | Šiauliai, Lituania |

Untuk Preconfirmations Helius, wilayah menunjukkan lokasi tempat Helius menyerap transaksi. Untuk Preconfirmations BAM, wilayah menunjukkan endpoint BAM regional yang memancarkan preconfirmation, bukan tempat Helius menyerapnya. Endpoint BAM di Singapura dan Dallas dipetakan ke `sgp` dan `dal`.

## Respons

<ResponseField name="result" type="integer">
  ID langganan (diperlukan untuk membatalkan langganan)
</ResponseField>

<RequestExample>
  ```json Request theme={"system"}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "preconfSubscribe",
    "params": [
      {
        "failed": false,
        "regionInclude": ["ewr", "fra"],
        "accountInclude": ["9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM"]
      }
    ]
  }
  ```

  ```json Helius only theme={"system"}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "preconfSubscribe",
    "params": [{ "includeBam": false }]
  }
  ```

  ```javascript 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' // Helius and BAM preconfirmations by default
      // Optional filter:
      // params: [{ failed: false, accountInclude: ['9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM'] }]
      // Helius preconfirmations only:
      // params: [{ includeBam: false }]
    }));

    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) | transaction bytes
    const buf = Buffer.from(data);
    const version = buf.readUInt8(0);
    if (version !== 1) return; // unknown schema version; update your decoder
    const slot = buf.readBigUInt64LE(1);
    const txIndex = buf.readBigUInt64LE(9); // always 0 for BAM preconfirmations
    const status = buf.readUInt8(17); // 0 = failed, 1 = success, 2 = unknown
    const txBytes = buf.subarray(18); // transaction in Solana wire format (legacy, v0, or v1)

    console.log('Preconfirmation:', { slot, txIndex, status, bytes: txBytes.length });
  });
  ```
</RequestExample>

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

  ```text Notification (binary frame) theme={"system"}
  version   u8              payload schema version, currently 1
  slot      u64 (LE)        slot the transaction is scheduled in
  tx_index  u64 (LE)        index of the transaction within the slot (always 0 for BAM)
  status    u8              0 = failed, 1 = success, 2 = unknown
  tx        bytes           transaction in Solana wire format (legacy, v0, or v1)
  ```
</ResponseExample>

## Notifikasi

Setelah konfirmasi JSON, notifikasi dikirim sebagai frame WebSocket **biner** (bukan JSON). Preconfirmations Helius dan BAM menggunakan tata letak yang sama. Setiap frame merupakan tata letak byte padat yang membawa satu transaksi:

| Byte | Bidang        | Jenis                 | Deskripsi                                                                                                                        |
| ---- | ------------- | --------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| 0    | `version`     | `u8`                  | Versi skema payload. Saat ini `1`.                                                                                               |
| 1–8  | `slot`        | `u64` (little-endian) | Slot tempat transaksi dijadwalkan.                                                                                               |
| 9–16 | `tx_index`    | `u64` (little-endian) | Indeks transaksi dalam slot. Selalu `0` untuk Preconfirmations BAM, yang membawa ID urutan dan posisi bundel, bukan indeks slot. |
| 17   | `status`      | `u8`                  | Status transaksi: `0` = gagal, `1` = berhasil, `2` = tidak diketahui.                                                            |
| 18+  | `transaction` | `bytes`               | Transaksi dalam format wire Solana. Lihat [Mendekode transaksi](#mendekode-transaksi).                                           |

Payload tidak memiliki bidang sumber. Jangan menyimpulkan bahwa transaksi berasal dari BAM berdasarkan `tx_index = 0`, karena Preconfirmations Helius dapat membawa nilai yang sama.

<Warning>
  **Selalu baca dan periksa byte `version` terlebih dahulu.** Saat ini nilainya `1`. Jika
  Helius perlu memperbarui format payload, nomor versi akan bertambah — buat percabangan
  berdasarkan versi agar dekoder Anda tetap berfungsi saat skema berubah.
</Warning>

Preconfirmation adalah sinyal awal, bukan jaminan. Transaksi belum masuk ke on-chain dan masih dapat gagal atau dihapus. Konfirmasikan bahwa transaksi telah masuk melalui pemeriksaan commitment standar sebelum menganggapnya final.

### Mendekode transaksi

Byte transaksi diteruskan persis seperti yang diserialisasi oleh validator, menggunakan enkode wire standar untuk versi transaksi tersebut. Transaksi legacy dan v0 menggunakan tata letak yang mendahulukan tanda tangan seperti yang dihasilkan oleh `bincode`. Transaksi v1 ([SIMD-0385](https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0385-transaction-v1.md)) menggunakan tata letak yang mendahulukan pesan dengan tanda tangan di bagian akhir, sehingga `bincode` gagal pada payload v1.

Gunakan dekoder yang menangani setiap versi. Di Rust, [`agave-transaction-view`](https://docs.rs/agave-transaction-view) mengurai transaksi legacy, v0, dan v1 secara langsung dan merupakan opsi yang direkomendasikan; [`wincode`](https://docs.rs/wincode) dengan `VersionedTransaction` dari SDK Solana terbaru juga dapat digunakan. Di JavaScript, pastikan versi pustaka Anda mendukung transaksi v1. Lihat [panduan](/docs/id/pre-confirmations/preconf-subscribe#mendekode-transaksi) untuk contoh Rust.

## Notifikasi duplikat

Preconfirmations Helius dan BAM dideduplikasi per sumber, bukan lintas sumber. Sebagian kecil transaksi mencapai Helius melalui keduanya, sehingga Anda dapat menerima tanda tangan yang sama dua kali, dan kedua salinan tersebut mungkin melaporkan slot yang berbeda. Lakukan deduplikasi berdasarkan tanda tangan di klien dan buat tindakan yang dipicu transaksi bersifat idempoten. Lihat [panduan](/docs/id/pre-confirmations/preconf-subscribe#notifikasi-duplikat).

## Harga

Preconfirmations memerlukan **paket Professional atau yang lebih tinggi** dan dikenai biaya **10 kredit per pesan** — satu pesan untuk setiap transaksi yang di-streaming. Lihat [Kredit](/docs/id/billing/credits) untuk detailnya.

Penagihan dihitung per pesan, bukan per tanda tangan unik. Transaksi yang dikirim oleh Helius dan BAM dihitung dua kali. Tetapkan `includeBam: false` jika Anda hanya menginginkan Preconfirmations Helius.

## Terkait

<CardGroup cols={2}>
  <Card title="Preconfirmations Overview" icon="bolt" href="/docs/id/pre-confirmations/overview">
    Penjelasan tentang Preconfirmations dan posisinya dalam pipeline validator.
  </Card>

  <Card title="preconfUnsubscribe" icon="circle-stop" href="/docs/id/api-reference/pre-confirmations/preconfunsubscribe">
    Hentikan langganan berdasarkan ID-nya.
  </Card>
</CardGroup>
