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

# API Akun Historis Solana (Beta)

> Baca status akun Solana sebagaimana adanya pada slot atau transaksi mana pun di masa lalu dengan getHistoricalAccountInfo dan getHistoricalTokenAccountsByOwner dari Helius (beta).

> [!NOTE]
>
> Status akun historis masih dalam versi Beta. Parameter, harga, format respons, dan cakupan data dapat berubah.

## Apa itu status akun historis?

Metode RPC Solana standar seperti `getAccountInfo` dan `getTokenAccountsByOwner` hanya mengembalikan status akun saat ini. Validator hanya menyimpan versi terbaru dari setiap akun, sehingga setiap penulisan menggantikan penulisan sebelumnya. Riwayat transaksi tidak mengisi kekosongan tersebut: `getTransaction` dan `getBlock` mengembalikan instruksi, log, dan perubahan saldo, bukan data akun yang ditulis oleh program.

Metode akun historis Helius mengembalikan akun sebagaimana adanya pada slot sebelumnya, atau tepat setelah transaksi tertentu dalam slot tersebut. Karena Anda dapat membaca status di antara dua transaksi dalam slot yang sama, Anda dapat melihat secara tepat perubahan yang dibuat oleh satu transaksi, bahkan ketika akun ditulis berkali-kali dalam satu slot. Gunakan metode ini untuk:

* Memeriksa saldo token dompet pada suatu titik waktu untuk audit, akuntansi, atau pelaporan pajak
* Men-debug transaksi dengan membaca akun yang disentuhnya tepat sebelum dan sesudah transaksi dijalankan
* Membaca akun protokol, seperti pool, vault, atau oracle, pada slot sebelumnya tanpa memutar ulang ledger sendiri

Metode RPC ini eksklusif untuk Helius. Metode tersebut bukan bagian dari RPC Solana standar.

## Metode mana yang harus saya gunakan?

| Yang Anda perlukan | Gunakan ini | Hasil |
| - | - | - |
| Satu akun pada posisi sebelumnya | [`getHistoricalAccountInfo`](https://www.helius.dev/docs/id/api-reference/rpc/http/gethistoricalaccountinfo) | Akun tersebut, atau `null` jika tidak ada |
| Akun token dompet pada posisi sebelumnya | [`getHistoricalTokenAccountsByOwner`](https://www.helius.dev/docs/id/api-reference/rpc/http/gethistoricaltokenaccountsbyowner) | Satu halaman akun SPL Token dan Token-2022, secara opsional untuk satu mint |

Keduanya menerima tiga parameter yang sama: alamat, objek kueri yang memilih posisi dalam riwayat, dan objek konfigurasi.

## Ketersediaan dan harga

* **Paket**: [Paket](https://www.helius.dev/docs/id/billing/plans.md) Business dan yang lebih tinggi.
* **Biaya**: 0 kredit per panggilan selama beta (harga dapat berubah).
* **Batas laju**: `getHistoricalAccountInfo` mengizinkan 100 permintaan per detik, dengan burst maksimum 100. `getHistoricalTokenAccountsByOwner` mengizinkan 10 permintaan per detik, dengan burst maksimum 10. Batas ini terpisah dari batas laju RPC paket Anda, dan permintaan yang melampauinya akan menghasilkan HTTP `429`. Lihat [batas laju](https://www.helius.dev/docs/id/billing/rate-limits.md).
* **Jaringan**: Hanya Mainnet. Panggil metode tersebut pada endpoint mainnet standar, `https://mainnet.helius-rpc.com`, atau endpoint [Gatekeeper](https://www.helius.dev/docs/id/gatekeeper/overview.md), `https://beta.helius-rpc.com`. Devnet menghasilkan galat `-32601`.

## Cakupan data

Riwayat tersedia mulai dari slot 444,959,999 (7 September 2026). Itu adalah slot terakhir epoch 1029, sehingga slot tersebut menyimpan status pada awal epoch 1030. Permintaan untuk slot sebelumnya menghasilkan galat `-32018` ("Riwayat akun tidak tersedia").

## Memilih posisi dalam riwayat

Parameter kedua adalah objek kueri dengan dua kolom opsional, `slot` dan `transactionIndex`:

| Kueri | Mengembalikan status |
| - | - |
| Dihilangkan atau `{}` | Pada slot terbaru yang telah diindeks, dibatasi pada komitmen yang diminta |
| `{ "slot": 445000000 }` | Pada akhir slot 445,000,000, setelah setiap transaksi dan penulisan nontransaksi apa pun seperti reward epoch |
| `{ "slot": 445000000, "transactionIndex": 10 }` | Tepat setelah transaksi pada indeks 10 di slot 445,000,000 dijalankan |

`transactionIndex` memerlukan `slot`.

Penulisan nontransaksi, seperti reward epoch, diterapkan pada akhir slot. Kueri dengan `transactionIndex` tidak pernah menyertakannya, bahkan untuk transaksi terakhir dalam slot. Untuk menyertakannya, kueri `slot` tanpa `transactionIndex`.

### Membaca status sebelum dan sesudah transaksi

Untuk memeriksa perubahan yang dibuat transaksi, baca akun dua kali:

* **Setelah transaksi**: kueri `slot` dan `transactionIndex` milik transaksi tersebut.
* **Sebelum transaksi**: kueri `slot` yang sama dengan `transactionIndex` dikurangi 1. Jika transaksi tersebut merupakan transaksi pertama dalam slotnya (indeks 0), kueri slot sebelumnya tanpa `transactionIndex`.

[`getTransactionsForAddress`](https://www.helius.dev/docs/id/rpc/gettransactionsforaddress) mengembalikan `slot` dan `transactionIndex` untuk setiap transaksi, sehingga Anda dapat menemukan posisi transaksi di sana dan meneruskannya langsung ke metode ini.

```bash theme={"system"}
# State of the account right after the transaction at index 10 in slot 445000000
curl https://mainnet.helius-rpc.com/?api-key=YOUR_API_KEY \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": "1",
    "method": "getHistoricalAccountInfo",
    "params": [
      "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
      { "slot": 445000000, "transactionIndex": 10 },
      { "encoding": "jsonParsed" }
    ]
  }'
```

## Memahami lastUpdatedAt

Setiap akun yang dikembalikan menyertakan `lastUpdatedAt`, yaitu posisi penulisan yang menghasilkan status yang Anda terima:

```json theme={"system"}
"lastUpdatedAt": { "slot": 444999837, "transactionIndex": 700 }
```

* **`slot` dan `transactionIndex`** menunjuk ke penulisan terakhir pada atau sebelum posisi yang Anda kueri. Dalam contoh di atas, kueri untuk slot 445,000,000 mengembalikan status yang terakhir ditulis oleh transaksi pada indeks 700 di slot 444,999,837.
* **`transactionIndex: null`** berarti penulisan terjadi di luar transaksi, seperti reward epoch.
* **`slot: 444959999` dengan `transactionIndex: null`** berarti akun belum berubah sejak awal cakupan riwayat. Ini tidak berarti akun ditulis dalam slot tersebut.

## Arti nilai null

`value` bernilai `null` ketika akun tidak ada pada posisi yang Anda kueri. Akun tersebut mungkin belum dibuat atau sudah ditutup.

* **Respons `null` tidak memiliki `lastUpdatedAt`**, sehingga respons tersebut tidak memberi tahu kapan akun dibuat atau ditutup. Untuk menemukan transaksi tersebut, gunakan [`getTransactionsForAddress`](https://www.helius.dev/docs/id/rpc/gettransactionsforaddress).
* **Alamat yang tidak pernah ada** juga mengembalikan `null`, bukan galat.
* **Slot sebelum cakupan riwayat** menghasilkan galat `-32018` untuk setiap alamat, baik akun tersebut pernah ada maupun tidak.

## Menelusuri mundur riwayat akun

Gunakan `lastUpdatedAt` sebagai kursor untuk mencantumkan setiap status yang pernah dimiliki akun, dimulai dari yang terbaru. Setelah setiap pembacaan, kueri posisi tepat sebelum penulisan yang Anda terima:

| `lastUpdatedAt` yang Anda terima | Kueri berikutnya |
| - | - |
| `{ "slot": S, "transactionIndex": N }`, dengan N lebih besar dari 0 | `{ "slot": S, "transactionIndex": N - 1 }` |
| `{ "slot": S, "transactionIndex": 0 }` | `{ "slot": S - 1 }` |
| `{ "slot": S, "transactionIndex": null }` | `{ "slot": S - 1 }` |

Berhenti ketika `value` bernilai `null`, yang berarti penulisan yang baru saja Anda lewati telah membuat akun tersebut. Berhenti juga ketika `lastUpdatedAt.slot` mencapai 444,959,999, yaitu awal cakupan riwayat.

```typescript theme={"system"}
const url = `https://mainnet.helius-rpc.com/?api-key=${process.env.HELIUS_API_KEY}`;
const COVERAGE_START_SLOT = 444959999;

type Position = { slot?: number; transactionIndex?: number };

async function getAccountHistory(address: string, start: Position = {}, maxStates = 100) {
  const states = [];
  let position = start;

  while (states.length < maxStates) {
    const response = await fetch(url, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        jsonrpc: "2.0",
        id: "1",
        method: "getHistoricalAccountInfo",
        params: [address, position, { encoding: "base64" }],
      }),
    });
    const { result, error } = await response.json();
    if (error) throw new Error(`${error.code}: ${error.message}`);

    const account = result.value;
    if (!account) break; // The account didn't exist before this write

    states.push(account);
    const { slot, transactionIndex } = account.lastUpdatedAt;
    if (slot <= COVERAGE_START_SLOT) break; // Reached the start of history coverage

    // Step to the position just before this write
    position = transactionIndex ? { slot, transactionIndex: transactionIndex - 1 } : { slot: slot - 1 };
  }

  return states; // Newest first
}
```

* **Akun yang sekarang sudah ditutup** mengembalikan `null` pada slot terbaru. Berikan posisi `start` dari saat akun masih ada.
* **Penulisan nontransaksi** mundur ke slot sebelumnya. Jika akun yang sama juga ditulis oleh transaksi pada awal slot tersebut, penelusuran akan melewati status itu.
* **Untuk menelusuri maju dalam waktu**, cantumkan transaksi akun dari yang paling lama terlebih dahulu dengan [`getTransactionsForAddress`](https://www.helius.dev/docs/id/rpc/gettransactionsforaddress) dan `sortOrder: "asc"`. Kemudian baca status pada `slot` dan `transactionIndex` setiap transaksi.

## Konteks respons

`context.slot` dalam setiap respons adalah slot terbaru yang telah diindeks Helius saat melayani permintaan. Itu bukan slot yang Anda kueri. Gunakan `slot` dalam permintaan Anda, atau `lastUpdatedAt`, untuk memahami data yang Anda terima.

## Melakukan paginasi secara konsisten

`getHistoricalTokenAccountsByOwner` mengembalikan hasil satu halaman pada satu waktu. Setiap respons menyertakan `value.accounts` dan `value.paginationKey`.

* **Kirim kembali `paginationKey`** dalam objek konfigurasi untuk mengambil halaman berikutnya.
* **Berhenti hanya ketika `paginationKey` bernilai `null`.** Sebuah halaman dapat memiliki sedikit hasil, atau kosong, tetapi masih memiliki hasil lainnya setelah halaman tersebut.
* **Tetapkan `slot` yang sama di setiap halaman.** Jika Anda menghilangkan `slot`, setiap halaman akan membaca slot terbaru yang telah diindeks, dan halaman Anda dapat berasal dari titik waktu yang berbeda.
* **Atur `limit`** antara 1 dan 5.000. Nilai default-nya adalah 5.000.

## Enkode dan data yang diurai

* **Enkode yang didukung** adalah `base64` (default), `base64+zstd`, dan `jsonParsed`. `base58` dan `binary` tidak didukung.
* **Akun token `jsonParsed`** menggunakan jumlah desimal mint pada posisi yang dikueri, sehingga jumlahnya tetap benar meskipun mint telah berubah sejak saat itu. Jika mint tidak dapat dibaca pada posisi tersebut, akun akan kembali menggunakan base64.
* **`dataSlice`** berfungsi dengan cara yang sama seperti dalam `getAccountInfo`.

## Komitmen

`commitment` menerima `finalized` (default) dan `confirmed`. `processed` tidak didukung. `slot` yang lebih baru daripada yang diizinkan oleh komitmen yang diminta menghasilkan galat `-32004`.

## Galat

| Kode | Arti | Tindakan |
| - | - | - |
| `-32018` | Slot berada sebelum awal cakupan riwayat | Kueri slot 444,959,999 atau yang lebih baru |
| `-32004` | Slot lebih baru daripada yang diizinkan oleh komitmen yang diminta | Gunakan `confirmed`, atau kueri slot yang lebih lama |
| `-32602` | Parameter tidak valid | Periksa pesan galat untuk kolom tertentu |
| `-32601` | Metode tidak ditemukan | Panggil endpoint mainnet Helius atau Gatekeeper Anda. Metode akun historis tidak tersedia di devnet |

## Pertanyaan umum

### Bagaimana cara mendapatkan status akun Solana pada slot tertentu?

Panggil `getHistoricalAccountInfo` dengan alamat dan `{ "slot": S }`. Metode ini mengembalikan akun sebagaimana adanya pada akhir slot S, dalam format yang sama seperti `getAccountInfo`.

### Dapatkah saya membaca akun di antara dua transaksi dalam slot yang sama?

Ya. Tambahkan `transactionIndex` ke kueri untuk mendapatkan status akun tepat setelah transaksi tersebut dijalankan. Lihat [Membaca status sebelum dan sesudah transaksi](#membaca-status-sebelum-dan-sesudah-transaksi).

### Seberapa jauh ke belakang saya dapat melakukan kueri?

Riwayat dimulai pada slot 444,959,999, tanggal 7 September 2026. Slot sebelumnya menghasilkan galat `-32018`.

### Paket mana yang menyertakan metode akun historis?

Paket Business dan yang lebih tinggi. Panggilan dikenai biaya 0 kredit selama periode beta; harga dapat berubah. Metode ini hanya tersedia di mainnet.

### Berapa batas lajunya?

`getHistoricalAccountInfo` mengizinkan 100 permintaan per detik, dan `getHistoricalTokenAccountsByOwner` mengizinkan 10 permintaan per detik. Kedua batas tersebut terpisah dari batas laju RPC paket Anda. Lihat [Ketersediaan dan harga](#ketersediaan-dan-harga).

### Bagaimana cara mendapatkan setiap status akun sebelumnya?

Mundur dari satu penulisan ke penulisan sebelumnya menggunakan `lastUpdatedAt`. Lihat [Menelusuri mundur riwayat akun](#menelusuri-mundur-riwayat-akun).

### Apakah saya memerlukan SDK baru?

Tidak. Ini adalah metode JSON-RPC, sehingga klien HTTP apa pun dapat digunakan. Pustaka klien Solana standar tidak menyertakannya, jadi kirim permintaan secara langsung, seperti dalam contoh di atas.

## Langkah berikutnya

> [card] [getHistoricalAccountInfo](https://www.helius.dev/docs/id/api-reference/rpc/http/gethistoricalaccountinfo.md)
>
> Baca satu akun pada slot atau transaksi sebelumnya

> [card] [getHistoricalTokenAccountsByOwner](https://www.helius.dev/docs/id/api-reference/rpc/http/gethistoricaltokenaccountsbyowner.md)
>
> Cantumkan akun token dompet pada slot sebelumnya

> [card] [getTransactionsForAddress](https://www.helius.dev/docs/id/rpc/gettransactionsforaddress.md)
>
> Temukan slot dan transactionIndex dari transaksi yang ingin Anda periksa

> [card] [Historical data overview](https://www.helius.dev/docs/id/rpc/historical-data.md)
>
> Riwayat transaksi, transfer, dan metode arsip lainnya


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.