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

# Cara Mendapatkan Saldo Token Historis Dompet Solana

> Kueri saldo token apa pun atau SOL native milik dompet pada timestamp, waktu-tanggal, atau slot sebelumnya. Ideal untuk PnL, basis biaya, pelaporan pajak, dan rekonstruksi status dompet.

<Note>
  Wallet API masih dalam versi Beta. Endpoint dan format respons dapat berubah.
</Note>

## Gambaran umum

Endpoint Saldo Historis menjawab pertanyaan: **berapa saldo token tertentu (atau SOL native) yang dimiliki dompet ini pada titik waktu tertentu di masa lalu?** Sementara endpoint [Saldo](/docs/id/wallet-api/balances) melaporkan kepemilikan *saat ini*, `balance-at` melaporkan kepemilikan pada timestamp, waktu-tanggal, atau slot mana pun.

Endpoint ini menemukan **satu transaksi terbaru pada atau sebelum titik waktu yang diminta** yang melibatkan dompet dan token tersebut, lalu membaca **saldo pascatransaksi** dompet dari transaksi itu. Saldo pascatransaksi adalah saldo yang berlaku sejak transaksi tersebut hingga transaksi berikutnya. Jadi, "saldo pada waktu T" adalah saldo pascatransaksi dari transaksi relevan terakhir dengan waktu blok (atau slot) pada atau sebelum T. Untuk dompet pada umumnya, nilai ini tepat, bukan perkiraan.

* **Token (SPL / Token-2022)**: dibaca dari saldo token pascatransaksi, yang dijumlahkan dari seluruh akun token dompet untuk mint tersebut.
* **SOL native**: dibaca dari saldo lamport pascatransaksi. Gunakan pseudo-mint `So11111111111111111111111111111111111111111` untuk menyatakan SOL native.

## Kapan fitur ini digunakan

Gunakan API Saldo Historis untuk:

* **Penghitungan PnL**: menentukan kepemilikan pada awal dan akhir periode.
* **Basis biaya dan lot pajak**: merekonstruksi saldo pada peristiwa akuisisi atau pelepasan.
* **Penyelesaian sengketa**: membuktikan kepemilikan dompet pada waktu tertentu.
* **Verifikasi snapshot**: memeriksa saldo dompet saat snapshot airdrop atau tata kelola.
* **Akuntansi dan audit**: merekonstruksi status dompet pada batas periode.

## Mulai cepat

### Saldo token pada timestamp

Dapatkan saldo USDC dompet pada timestamp Unix:

<Tabs>
  <Tab title="JavaScript">
    ```javascript theme={"system"}
    const getBalanceAt = async (wallet, mint, time) => {
      const url = `https://api.helius.xyz/v1/wallet/${wallet}/balance-at?mint=${mint}&time=${time}&api-key=YOUR_API_KEY`;

      const response = await fetch(url);

      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }

      const result = await response.json();

      if (result.asOf === null) {
        console.log('Wallet had no activity for this token by that time — balance is 0');
        return result;
      }

      console.log(`Balance: ${result.balance}`);
      console.log(`Raw amount: ${result.balanceRaw} (${result.decimals} decimals)`);
      console.log(`As of slot ${result.asOf.slot}, signature ${result.asOf.signature}`);

      return result;
    };

    // USDC balance on 2025-01-10 19:20:00 UTC
    getBalanceAt(
      "5tzFkiKscXHK5ZXCGbXZxdw7gTjjD1mBwuoFbhUvuAi9",
      "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
      1736536800
    );
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={"system"}
    import requests

    def get_balance_at(wallet: str, mint: str, time: int):
        url = f"https://api.helius.xyz/v1/wallet/{wallet}/balance-at"
        headers = {"X-Api-Key": "YOUR_API_KEY"}
        params = {"mint": mint, "time": time}

        response = requests.get(url, headers=headers, params=params)
        response.raise_for_status()
        result = response.json()

        if result["asOf"] is None:
            print("Wallet had no activity for this token by that time — balance is 0")
            return result

        print(f"Balance: {result['balance']}")
        print(f"Raw amount: {result['balanceRaw']} ({result['decimals']} decimals)")
        print(f"As of slot {result['asOf']['slot']}, signature {result['asOf']['signature']}")

        return result

    # USDC balance on 2025-01-10 19:20:00 UTC
    get_balance_at(
        "5tzFkiKscXHK5ZXCGbXZxdw7gTjjD1mBwuoFbhUvuAi9",
        "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
        1736536800
    )
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={"system"}
    curl "https://api.helius.xyz/v1/wallet/5tzFkiKscXHK5ZXCGbXZxdw7gTjjD1mBwuoFbhUvuAi9/balance-at?mint=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v&time=1736536800&api-key=YOUR_API_KEY"
    ```
  </Tab>
</Tabs>

### Saldo token pada waktu-tanggal

Berikan waktu-tanggal yang mudah dibaca manusia sebagai pengganti timestamp. Ingatlah untuk mengenkode spasi dalam URL sebagai `%20`:

```bash theme={"system"}
curl "https://api.helius.xyz/v1/wallet/5tzFkiKscXHK5ZXCGbXZxdw7gTjjD1mBwuoFbhUvuAi9/balance-at?mint=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v&datetime=2025-01-10%2019:20:00&api-key=YOUR_API_KEY"
```

### Saldo SOL native pada slot

Untuk SOL native, gunakan pseudo-mint `So11111111111111111111111111111111111111111`. Kueri berbasis slot bersifat tepat dan deterministik:

```bash theme={"system"}
curl "https://api.helius.xyz/v1/wallet/5tzFkiKscXHK5ZXCGbXZxdw7gTjjD1mBwuoFbhUvuAi9/balance-at?mint=So11111111111111111111111111111111111111111&slot=313000000&api-key=YOUR_API_KEY"
```

## Parameter kueri

| Parameter  | Wajib      | Jenis  | Deskripsi                                                                                   |
| ---------- | ---------- | ------ | ------------------------------------------------------------------------------------------- |
| `mint`     | Ya         | string | Alamat mint token. Untuk SOL native, gunakan `So11111111111111111111111111111111111111111`. |
| `time`     | Salah satu | int    | Timestamp Unix dalam **detik**. Saldo pada waktu ini.                                       |
| `datetime` | Salah satu | string | String waktu-tanggal, misalnya `2025-01-10 19:20:00`. Menggunakan UTC secara default.       |
| `slot`     | Salah satu | int    | Nomor slot. Saldo pada slot ini. Tepat dan deterministik.                                   |

Anda harus memberikan tepat **satu** dari `time`, `datetime`, atau `slot`. Jika Anda tidak memberikannya atau memberikan lebih dari satu, API akan menampilkan kesalahan `400`.

### Format waktu-tanggal

Format yang diterima:

* Tanggal saja: `2025-01-10` → tengah malam UTC
* Tanggal + waktu: `2025-01-10 19:20:00` atau `2025-01-10T19:20:00` (detik bersifat opsional) → UTC
* Dengan zona waktu eksplisit: `2025-01-10T19:20:00Z`, `2025-01-10T19:20:00+02:00`, `2025-01-10T19:20:00-05:00` → digunakan sebagaimana diberikan

Format yang tidak valid atau tidak didukung (`01/10/2025`, `2025-13-10`, `2025-02-30`) akan menampilkan kesalahan `400`.

<Warning>
  Waktu-tanggal ditafsirkan sebagai UTC secara default. Waktu-tanggal tanpa zona waktu seperti `2025-01-10 19:20:00` diperlakukan sebagai UTC, bukan waktu lokal Anda. Sertakan offset zona waktu eksplisit jika Anda menginginkan zona waktu lain. Kolom `requested.time` dalam respons menampilkan detik epoch yang telah ditentukan sehingga Anda dapat memverifikasi penafsirannya.
</Warning>

## Format respons

```json theme={"system"}
{
  "wallet": "5tzFkiKscXHK5ZXCGbXZxdw7gTjjD1mBwuoFbhUvuAi9",
  "mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
  "isNative": false,
  "balance": "284961463.392936",
  "balanceRaw": "284961463392936",
  "decimals": 6,
  "requested": {
    "time": 1736536800,
    "slot": null,
    "datetime": null
  },
  "asOf": {
    "slot": 313000000,
    "blockTime": 1736536794,
    "signature": "5Cyy7Mh9nVgFq3T8wJp2sKxR4dE6bA1uZoNcLrXmYqUpon"
  }
}
```

### Catatan kolom

* **`wallet`**: salinan alamat dompet yang dikueri.
* **`mint`**: salinan mint yang dikueri (pseudo-mint SOL untuk SOL native).
* **`isNative`**: `true` jika hasilnya adalah SOL native.
* **`balance`**: jumlah yang mudah dibaca manusia sebagai **string desimal** — berupa string, bukan angka, agar saldo besar tidak kehilangan presisi. Angka nol di bagian akhir dihapus (`"1.5"`, bukan `"1.500000"`).
* **`balanceRaw`**: jumlah tepat dalam unit terkecil (lamport untuk SOL), sebagai string.
* **`decimals`**: jumlah desimal token (9 untuk SOL).
* **`requested`**: salinan kueri. Saat `datetime` digunakan, `time` juga diisi dengan detik epoch yang telah ditentukan sehingga penafsiran UTC dapat terlihat.
* **`asOf`**: transaksi yang menjadi sumber pembacaan saldo (`slot`, `blockTime`, `signature`).

`asOf: null` berarti nol, bukan kesalahan. Jika dompet tidak memiliki transaksi yang cocok pada atau sebelum titik waktu yang diminta, endpoint akan menampilkan `200` dengan `balance: "0"` dan `asOf: null` — dompet tersebut memang belum memiliki token itu pada saat tersebut.

## Kasus penggunaan

### Perubahan saldo selama suatu periode

Bandingkan kepemilikan pada dua titik waktu:

```javascript theme={"system"}
const getBalanceChange = async (wallet, mint, startTime, endTime) => {
  const fetchBalance = (time) =>
    fetch(
      `https://api.helius.xyz/v1/wallet/${wallet}/balance-at?mint=${mint}&time=${time}&api-key=YOUR_API_KEY`
    ).then(r => r.json());

  const [start, end] = await Promise.all([
    fetchBalance(startTime),
    fetchBalance(endTime)
  ]);

  // balanceRaw is an exact integer string — use BigInt for precise arithmetic
  const delta = BigInt(end.balanceRaw) - BigInt(start.balanceRaw);
  const human = Number(delta) / 10 ** end.decimals;

  console.log(`Start: ${start.balance}`);
  console.log(`End: ${end.balance}`);
  console.log(`Change: ${human > 0 ? '+' : ''}${human}`);

  return { start, end, delta };
};
```

### Pemeriksaan kelayakan snapshot

Verifikasi bahwa dompet memiliki token pada slot snapshot:

```javascript theme={"system"}
const heldAtSnapshot = async (wallet, mint, snapshotSlot, minimumRaw) => {
  const result = await fetch(
    `https://api.helius.xyz/v1/wallet/${wallet}/balance-at?mint=${mint}&slot=${snapshotSlot}&api-key=YOUR_API_KEY`
  ).then(r => r.json());

  const eligible = BigInt(result.balanceRaw) >= BigInt(minimumRaw);
  console.log(`${wallet}: ${result.balance} at slot ${snapshotSlot} — ${eligible ? 'eligible' : 'not eligible'}`);

  return eligible;
};
```

## Praktik terbaik

* **Gunakan `slot` untuk hasil yang deterministik.** `time` dan `datetime` ditentukan melalui waktu blok yang dilaporkan validator, yang dapat melenceng beberapa detik. Jika reproduksibilitas yang tepat diperlukan (snapshot, audit), lakukan kueri berdasarkan `slot`.
* **Uraikan saldo sebagai string.** `balance` dan `balanceRaw` berupa string untuk mempertahankan presisi. Gunakan `BigInt(balanceRaw)` (atau bilangan bulat presisi arbitrer dalam bahasa Anda) untuk operasi aritmetika — jangan konversikan menjadi float.
* **Perlakukan `asOf: null` sebagai nol.** `null` `asOf` adalah respons berhasil yang berarti dompet tidak memiliki aktivitas untuk token tersebut hingga titik waktu yang diminta. Jangan menanganinya sebagai kesalahan.
* **Cache hasil historis.** Saldo pada titik waktu sebelumnya tidak akan berubah. Cache hasil secara permanen untuk menghindari panggilan API berulang.

## Kesalahan umum

| Kode Kesalahan | Deskripsi                                                                                                                            | Solusi                                                          |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------- |
| 400            | `mint` tidak ada, mint tidak valid, tidak ada atau terdapat beberapa `time`/`datetime`/`slot`, atau `datetime` tidak dapat diuraikan | Berikan mint yang valid dan tepat satu parameter titik waktu    |
| 401            | Kunci API tidak ada atau tidak valid                                                                                                 | Pastikan kunci API Anda disertakan dalam permintaan             |
| 404            | Alamat dompet dalam jalur tidak valid                                                                                                | Pastikan alamat tersebut adalah alamat Solana base58 yang valid |
| 429            | Batas laju terlampaui                                                                                                                | Kurangi frekuensi permintaan atau tingkatkan paket Anda         |
| 502            | Kesalahan RPC hulu atau waktu tunggu habis                                                                                           | Coba lagi dengan backoff eksponensial                           |

## Batasan

* **Saldo dompet dengan beberapa akun token dapat terhitung kurang.** Saldo dibaca dari satu transaksi terbaru yang cocok. Kasus umum — satu akun token terkait per mint — menghasilkan nilai yang tepat. Jika dompet menyimpan mint yang sama di beberapa akun token dan transaksi terbaru hanya menyentuh sebagian akun tersebut, saldo dapat terhitung kurang.
* **Presisi SOL native untuk saldo yang sangat besar.** Untuk saldo SOL di atas \~9.007.199 SOL (2⁵³ lamport), presisi mungkin hilang di layanan hulu. Jumlah token tidak terpengaruh.
* **Presisi `time`/`datetime` bergantung pada waktu blok yang dilaporkan validator**, yang dapat melenceng beberapa detik. Gunakan `slot` untuk hasil yang tepat dan deterministik.
* **Satu token per permintaan.** Tidak ada format batch untuk beberapa mint atau "semua saldo pada waktu T".

## Langkah berikutnya

<CardGroup cols={3}>
  <Card title="Wallet Balances" icon="scale-balanced" href="/docs/id/wallet-api/balances">
    Dapatkan kepemilikan token dan NFT dompet saat ini beserta nilainya dalam USD.
  </Card>

  <Card title="Wallet API Overview" icon="wallet" href="/docs/id/wallet-api/overview">
    Semua endpoint Wallet API dan konvensi bersama.
  </Card>

  <Card title="API Reference" icon="code" href="/docs/id/api-reference/wallet-api/balance-at">
    Skema permintaan dan respons untuk saldo historis.
  </Card>
</CardGroup>
