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

# Dukungan Transaksi v1

> Siapkan integrasi Solana Anda untuk transaksi v1: atur maxSupportedTransactionVersion ke 1, tingkatkan ke SDK yang mendukung v1, dan baca biaya prioritas dari transactionConfig.

Agave 4.2 memperkenalkan transaksi v1 ([SIMD-0385](https://github.com/solana-foundation/solana-improvement-documents/blob/main/proposals/0385-transaction-v1.md)). Setelah gerbang fitur aktif di mainnet, dompet dan program akan mulai mengirimkan transaksi v1, dan setiap permintaan yang mengambil data transaksi lengkap harus memilih untuk menerimanya.

Halaman ini membahas perubahan yang terjadi, endpoint Helius yang terdampak, dan cara memperbarui kode Anda. Untuk daftar periksa lengkap Agave 4.2, termasuk jenis reward, semantik pembaruan akun, dan waktu slot, lihat [daftar periksa migrasi Agave 4.2](https://www.helius.dev/blog/agave-4-2-migration-checklist).

## Perubahan dalam transaksi v1

Transaksi lama dan v0 tidak berubah. Untuk sebagian besar integrasi, ada dua hal penting mengenai transaksi v1:

* **Anda harus memilih untuk menerimanya.** Permintaan data transaksi lengkap memerlukan `maxSupportedTransactionVersion: 1`, dan pustaka klien Anda harus menggunakan versi yang dapat melakukan deserialisasi v1.
* **Anggaran komputasi dipindahkan ke header pesan.** Pesan v1 membawa objek `transactionConfig` dengan `computeUnitLimit`, `heapSize`, `loadedAccountsDataSizeLimit`, dan `priorityFee`. Tidak ada instruksi program ComputeBudget dalam transaksi v1.

Format wire juga berubah (byte versi baru dan tanda tangan di akhir transaksi), tetapi hal ini hanya memengaruhi kode yang mendekode byte transaksi mentah. Lihat [Mendekode byte transaksi mentah](#dekode-byte-transaksi-mentah-dengan-parser-yang-mendukung-v1) di bawah ini.

Dalam respons JSON, transaksi v1 melaporkan `"version": 1` dan `message`-nya menyertakan `transactionConfig`:

```json theme={"system"}
{
  "version": 1,
  "transaction": {
    "signatures": ["..."],
    "message": {
      "accountKeys": ["..."],
      "instructions": [
        { "programIdIndex": 3, "accounts": [0, 1], "data": "3Bxs4..." }
      ],
      "recentBlockhash": "...",
      "transactionConfig": {
        "computeUnitLimit": 200000,
        "heapSize": null,
        "loadedAccountsDataSizeLimit": 200000,
        "priorityFee": 50000
      }
    }
  }
}
```

`"priorityFee": 50000` berarti transaksi ini membayar total 50.000 lamport. Kolom `null` berarti pengirim tidak menetapkannya. Pesan lama dan v0 sepenuhnya menghilangkan `transactionConfig`.

## Atur maxSupportedTransactionVersion ke 1

Setiap permintaan yang mengembalikan data transaksi lengkap harus mendeklarasikan versi transaksi tertinggi yang dapat ditanganinya. Atur `maxSupportedTransactionVersion: 1` pada:

* [`getTransaction`](/docs/id/rpc/guides/gettransaction)
* [`getBlock`](/docs/id/rpc/guides/getblock)
* [`getTransactionsForAddress`](/docs/id/rpc/gettransactionsforaddress) dengan `transactionDetails: "full"`
* [`transactionSubscribe`](/docs/id/rpc/websocket/transaction-subscribe) dengan `transactionDetails: "accounts"` atau `"full"`
* [`blockSubscribe`](/docs/id/api-reference/rpc/websocket/blocksubscribe)

Permintaan yang menghilangkan parameter tersebut, atau mengaturnya ke `0`, akan gagal dengan kesalahan JSON-RPC `-32015` begitu permintaan tersebut menemukan transaksi v1:

```json theme={"system"}
{
  "jsonrpc": "2.0",
  "error": {
    "code": -32015,
    "message": "Transaction version (1) is not supported by the requesting client. Please use \"maxSupportedTransactionVersion\" in your request."
  },
  "id": 1
}
```

Untuk `getBlock`, satu transaksi v1 di bagian mana pun dalam blok akan menyebabkan seluruh permintaan gagal. Jika Anda melihat `-32015` dalam log, berarti proyek tersebut sudah mengalami kegagalan pada transaksi berversi.

<CodeGroup>
  ```json getTransaction theme={"system"}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "getTransaction",
    "params": [
      "2id3YC2jK9G5Wo2phDx4gJVAew8DcY5NAojnVuao8rkxwPYPe8cSwE5GzhEgJA2y8fVjDEo6iR6ykBvDxrTQrtpb",
      {
        "encoding": "jsonParsed",
        "commitment": "confirmed",
        "maxSupportedTransactionVersion": 1
      }
    ]
  }
  ```

  ```json getBlock theme={"system"}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "getBlock",
    "params": [
      341197053,
      {
        "encoding": "jsonParsed",
        "transactionDetails": "full",
        "maxSupportedTransactionVersion": 1
      }
    ]
  }
  ```

  ```json getTransactionsForAddress theme={"system"}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "getTransactionsForAddress",
    "params": [
      "86xCnPeV69n6t3DnyGvkKobf9FdN2H9oiVDdaMpo2MMY",
      {
        "transactionDetails": "full",
        "encoding": "jsonParsed",
        "limit": 100,
        "maxSupportedTransactionVersion": 1
      }
    ]
  }
  ```

  ```json transactionSubscribe theme={"system"}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "transactionSubscribe",
    "params": [
      { "accountInclude": ["86xCnPeV69n6t3DnyGvkKobf9FdN2H9oiVDdaMpo2MMY"] },
      {
        "commitment": "confirmed",
        "encoding": "jsonParsed",
        "transactionDetails": "full",
        "maxSupportedTransactionVersion": 1
      }
    ]
  }
  ```
</CodeGroup>

## Tingkatkan SDK Anda sebelum menaikkan nilainya

Mengatur `maxSupportedTransactionVersion: 1` memberi tahu node agar mengembalikan transaksi v1. Pustaka klien Anda tetap harus dapat melakukan deserialisasi transaksi tersebut. Lakukan peningkatan terlebih dahulu, lalu ubah parameternya:

| Klien                                           | Versi minimum yang mendukung transaksi v1 |
| ----------------------------------------------- | ----------------------------------------- |
| `@solana/kit`                                   | 8.0                                       |
| `@solana/web3.js`                               | v3                                        |
| Rust `solana-sdk` / `solana-transaction-status` | Rilis yang dibuat dengan crate Agave 4.2  |
| `yellowstone-grpc-client`                       | 13.3.0                                    |
| `yellowstone-grpc-proto`                        | 12.6.0                                    |
| `helius-laserstream` (JavaScript)               | 0.8.4                                     |
| `helius-laserstream` (Rust)                     | 0.6.3                                     |
| `helius-laserstream` (Go)                       | 0.2.0                                     |

Implementasi `VersionedTransaction.deserialize` lama dalam JavaScript hanya menangani transaksi lama dan v0 serta memunculkan kesalahan pada byte `0x81` di awal. Proto Yellowstone lama dibuat sebelum kolom pesan v1 tersedia, sehingga pengguna gRPC pada versi tersebut tidak pernah melihat `transactionConfig`. Untuk klien gRPC Go, buat ulang dari proto Yellowstone terbaru dan `solana-storage-proto`.

## Baca biaya prioritas dari transactionConfig

Kode yang memperkirakan biaya prioritas transaksi dengan memindai instruksi program ComputeBudget (`ComputeBudget111111111111111111111111111111`, `setComputeUnitPrice`, `setComputeUnitLimit`) akan membaca setiap transaksi v1 seolah-olah membayar nol. Pada v1, nilainya berada di `message.transactionConfig`, dan satuannya berbeda:

| Format   | Lokasi biaya                    | Satuan                           |
| -------- | ------------------------------- | -------------------------------- |
| Lama, v0 | Instruksi `setComputeUnitPrice` | Mikro-lamport per unit komputasi |
| v1       | `transactionConfig.priorityFee` | Total lamport untuk transaksi    |

Jangan terapkan perhitungan `price × computeUnitLimit ÷ 1e6` lama ke `priorityFee`. Nilai tersebut sudah merupakan total.

```typescript priority-fee.ts theme={"system"}
import bs58 from "bs58";

const COMPUTE_BUDGET = "ComputeBudget111111111111111111111111111111";

/** Total priority fee in lamports for a `json`-encoded transaction. */
function priorityFeeLamports(tx: any): number {
  const message = tx.transaction.message;

  // v1: the header carries the total directly.
  if (message.transactionConfig) {
    return message.transactionConfig.priorityFee ?? 0;
  }

  // Legacy and v0: derive it from ComputeBudget instructions.
  let microLamportsPerCu = 0n;
  let computeUnitLimit: bigint | null = null;
  let otherInstructions = 0;

  for (const ix of message.instructions) {
    if (message.accountKeys[ix.programIdIndex] !== COMPUTE_BUDGET) {
      otherInstructions++;
      continue;
    }
    const data = bs58.decode(ix.data);
    const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
    if (data[0] === 2) computeUnitLimit = BigInt(view.getUint32(1, true));
    if (data[0] === 3) microLamportsPerCu = view.getBigUint64(1, true);
  }

  // Without an explicit limit, the runtime grants 200,000 CU per non-ComputeBudget instruction, capped at 1,400,000.
  const limit = computeUnitLimit ?? BigInt(Math.min(otherInstructions * 200_000, 1_400_000));
  return Number((microLamportsPerCu * limit) / 1_000_000n);
}
```

Buat percabangan berdasarkan `transactionConfig` (atau `version === 1`), bukan berdasarkan keberadaan instruksi ComputeBudget, karena transaksi lama tanpa biaya prioritas juga tidak memilikinya.

## Dekode byte transaksi mentah dengan parser yang mendukung v1

Bagian ini hanya berlaku jika Anda menggunakan byte transaksi mentah, misalnya dari [preconfSubscribe](/docs/id/pre-confirmations/preconf-subscribe), [preprocessedSubscribe](/docs/id/preprocessed-transactions/preprocessed-subscribe), atau respons RPC yang dikodekan dengan `base64`. Jika Anda menggunakan respons `json` atau `jsonParsed`, lewati bagian ini.

Transaksi v1 mengubah tata letak wire dalam dua hal:

* **Byte versi.** Transaksi v1 dimulai dengan `0x81` (desimal 129). Transaksi v0 dimulai dengan `0x80`.
* **Tanda tangan dipindahkan ke akhir.** Transaksi lama dan v0 menempatkan tanda tangan terlebih dahulu, lalu pesan. Transaksi v1 menempatkan pesan terlebih dahulu dan tanda tangan di akhir, sehingga dekoder bergaya `bincode` yang mengharapkan array tanda tangan di awal akan gagal pada byte v1.

<Frame caption="Byte layout of a transaction v1 with three addresses and one instruction. The signature sits at the end, after the message.">
  <img src="https://mintcdn.com/helius/VV8h76d8Pisjh8RU/images/solana-transaction-v1-byte-layout.png?fit=max&auto=format&n=VV8h76d8Pisjh8RU&q=85&s=75b76003a7c6a506f6ff24dfc47cb677" alt="Byte-by-byte layout of a Solana transaction v1: version byte, header, config mask, lifetime specifier, address and instruction counts, three 32-byte addresses, compute unit config, instruction header, indices, discriminators, lamports, and a 64-byte signature at the end" width="1280" height="720" data-path="images/solana-transaction-v1-byte-layout.png" />
</Frame>

Untuk panduan setiap kolom dalam format wire v1, lihat [Transaksi v1 dalam artikel versi transaksi Solana](https://www.helius.dev/blog/solana-transaction-versions#transaction-v1).

Gunakan dekoder yang memahami tata letak v1:

* **Rust:** [`agave-transaction-view`](https://docs.rs/agave-transaction-view) mengurai transaksi lama, v0, dan v1 secara langsung. [`wincode`](https://docs.rs/wincode), serializer kompatibel bincode yang digunakan oleh SDK Solana saat ini, juga mendekode v1 menjadi `VersionedTransaction`.
* **JavaScript / TypeScript:** `@solana/kit` 8.0+ atau `@solana/web3.js` v3.

Dekoder khusus perlu memeriksa byte pertama: `0x81` berarti v1 dan tanda tangan ditempatkan setelah pesan, bukan sebelumnya.

## Daftar periksa

1. Cari dengan grep `getBlock`, `getTransaction`, `getTransactionsForAddress`, `transactionSubscribe`, dan `blockSubscribe`, termasuk isi JSON-RPC mentah dan wrapper SDK seperti `connection.getParsedTransaction`.
2. Tingkatkan ke SDK yang mendukung v1.
3. Atur `maxSupportedTransactionVersion: 1` pada setiap pemanggilan yang ditemukan pada langkah 1.
4. Ganti pemindaian instruksi ComputeBudget dengan pemeriksaan `transactionConfig`, dan perlakukan `priorityFee` sebagai total lamport.
5. Ganti dekoder mentah bergaya `bincode` dengan `agave-transaction-view` atau SDK yang telah ditingkatkan.
6. Tingkatkan dependensi streaming ke versi dalam tabel di atas.
7. Cari `-32015` dalam log dengan grep setelah perubahan untuk memastikan tidak ada yang masih gagal.

Untuk pembahasan teknis mendalam mengenai spesifikasi versi transaksi Solana, format wire, dan contoh, baca artikel kami, [Pembuatan Versi Transaksi Solana: Lama, v0, dan v1](https://www.helius.dev/blog/solana-transaction-versions).

## Terkait

<CardGroup cols={2}>
  <Card title="getTransaction guide" icon="magnifying-glass" href="/docs/id/rpc/guides/gettransaction">
    Parameter, bentuk respons, dan contoh untuk mengambil satu transaksi.
  </Card>

  <Card title="getBlock guide" icon="cube" href="/docs/id/rpc/guides/getblock">
    Ambil blok lengkap, termasuk setiap transaksi di dalamnya.
  </Card>

  <Card title="getTransactionsForAddress" icon="list" href="/docs/id/rpc/gettransactionsforaddress">
    Riwayat transaksi yang difilter dan diberi paginasi untuk alamat apa pun dalam satu pemanggilan.
  </Card>

  <Card title="Agave 4.2 migration checklist" icon="clipboard-check" href="https://www.helius.dev/blog/agave-4-2-migration-checklist">
    Setiap perubahan besar Agave 4.2, beserta langkah-langkah perbaikannya.
  </Card>
</CardGroup>
