> ## 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 Mengambil Riwayat Transaksi Dompet Solana

> Dapatkan riwayat transaksi lengkap untuk dompet Solana apa pun beserta perubahan saldo untuk setiap transaksi — dibuat untuk pelacak portofolio, akuntansi, dan analitik.

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

## Gambaran umum

Endpoint Transaction History mengambil riwayat transaksi lengkap untuk dompet Solana menggunakan Enhanced Transactions API. Endpoint ini mengembalikan transaksi yang telah diuraikan dan mudah dibaca beserta perubahan saldo untuk setiap transaksi, dalam urutan kronologis terbalik (terbaru lebih dahulu).

Endpoint ini mengembalikan hingga 100 transaksi per permintaan, sehingga paginasi harus dilakukan secara manual. Gunakan parameter `before` dengan `pagination.nextCursor` untuk mengambil halaman berikutnya, lalu baca `pagination.hasMore` untuk mengetahui apakah masih ada hasil lainnya. Setiap permintaan merupakan satu panggilan API dan dikenai biaya 100 kredit.

Parameter `tokenAccounts` mengatur apakah transaksi yang melibatkan akun token milik dompet akan disertakan:

* `balanceChanged` (direkomendasikan): menyertakan transaksi yang mengubah saldo akun token sekaligus menyaring spam.
* `none`: hanya interaksi langsung dengan dompet.
* `all`: semua transaksi akun token, termasuk spam.

<Warning>
  Filter `tokenAccounts` bergantung pada bidang `owner` dalam metadata saldo token, yang belum tersedia sebelum slot 111.491.819 (\~Desember 2022). Transaksi yang melibatkan akun token yang aktif sebelum slot ini mungkin tidak tersedia. Lihat [tutorial getTransactionsForAddress](/docs/id/rpc/gettransactionsforaddress#batasan-dan-kasus-khusus) untuk solusi alternatif.
</Warning>

## Kapan harus menggunakannya

Gunakan Transaction History API saat Anda perlu:

* **Menampilkan umpan transaksi**: tampilkan riwayat transaksi lengkap kepada pengguna.
* **Menghitung PnL**: lacak keuntungan dan kerugian dari semua transaksi.
* **Pajak dan akuntansi**: buat laporan transaksi lengkap untuk pelaporan pajak.
* **Analitik portofolio**: analisis pola dan aktivitas perdagangan.
* **Jejak audit**: simpan catatan lengkap aktivitas dompet.
* **Rekonstruksi saldo**: susun ulang saldo saat ini dari data historis.

## Mulai cepat

### Kueri riwayat dasar

Dapatkan transaksi terbaru beserta perubahan saldonya:

<Tabs>
  <Tab title="JavaScript">
    ```javascript theme={"system"}
    const getTransactionHistory = async (address) => {
      const url = `https://api.helius.xyz/v1/wallet/${address}/history?api-key=YOUR_API_KEY`;

      const response = await fetch(url);
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }

      const data = await response.json();

      console.log(`Found ${data.data.length} transactions`);

      // Display recent transactions
      data.data.forEach(tx => {
        const date = new Date(tx.timestamp * 1000).toLocaleString();
        const status = tx.error ? 'Failed' : 'Success';

        console.log(`\n${status} - ${date}`);
        console.log(`Signature: ${tx.signature.slice(0, 20)}...`);
        console.log(`Fee: ${tx.fee} SOL`);

        // Show balance changes
        tx.balanceChanges.forEach(change => {
          const sign = change.amount > 0 ? '+' : '';
          console.log(`  ${sign}${change.amount} ${change.mint === 'SOL' ? 'SOL' : change.mint.slice(0, 8)}...`);
        });
      });

      return data;
    };

    getTransactionHistory("86xCnPeV69n6t3DnyGvkKobf9FdN2H9oiVDdaMpo2MMY");
    ```
  </Tab>

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

    def get_transaction_history(address: str):
        url = f"https://api.helius.xyz/v1/wallet/{address}/history"
        headers = {"X-Api-Key": "YOUR_API_KEY"}

        response = requests.get(url, headers=headers)
        response.raise_for_status()

        data = response.json()

        print(f"Found {len(data['data'])} transactions")

        # Display recent transactions
        for tx in data['data']:
            date = datetime.fromtimestamp(tx['timestamp']).strftime('%Y-%m-%d %H:%M:%S')
            status = 'Failed' if tx.get('error') else 'Success'

            print(f"\n{status} - {date}")
            print(f"Signature: {tx['signature'][:20]}...")
            print(f"Fee: {tx['fee']} SOL")

            # Show balance changes
            for change in tx['balanceChanges']:
                sign = '+' if change['amount'] > 0 else ''
                mint_display = 'SOL' if change['mint'] == 'SOL' else change['mint'][:8] + '...'
                print(f"  {sign}{change['amount']} {mint_display}")

        return data

    get_transaction_history("86xCnPeV69n6t3DnyGvkKobf9FdN2H9oiVDdaMpo2MMY")
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={"system"}
    curl "https://api.helius.xyz/v1/wallet/86xCnPeV69n6t3DnyGvkKobf9FdN2H9oiVDdaMpo2MMY/history?api-key=YOUR_API_KEY"
    ```
  </Tab>
</Tabs>

### Paginasi untuk riwayat lengkap

Ambil semua transaksi menggunakan paginasi dengan parameter `before`:

<Tabs>
  <Tab title="JavaScript">
    ```javascript theme={"system"}
    const getAllTransactionHistory = async (address) => {
      let allTransactions = [];
      let before = null;

      do {
        const url = before
          ? `https://api.helius.xyz/v1/wallet/${address}/history?api-key=YOUR_API_KEY&before=${before}`
          : `https://api.helius.xyz/v1/wallet/${address}/history?api-key=YOUR_API_KEY`;

        const response = await fetch(url);
        const data = await response.json();

        allTransactions = allTransactions.concat(data.data);
        before = data.pagination.hasMore ? data.pagination.nextCursor : null;

        console.log(`Fetched ${allTransactions.length} transactions so far...`);

      } while (before);

      console.log(`\nTotal transactions: ${allTransactions.length}`);
      return allTransactions;
    };

    getAllTransactionHistory("86xCnPeV69n6t3DnyGvkKobf9FdN2H9oiVDdaMpo2MMY");
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={"system"}
    def get_all_transaction_history(address: str):
        all_transactions = []
        before = None

        while True:
            url = f"https://api.helius.xyz/v1/wallet/{address}/history"
            params = {"api-key": "YOUR_API_KEY"}

            if before:
                params["before"] = before

            response = requests.get(url, params=params, headers={"X-Api-Key": "YOUR_API_KEY"})
            response.raise_for_status()

            data = response.json()
            all_transactions.extend(data['data'])

            print(f"Fetched {len(all_transactions)} transactions so far...")

            if not data['pagination']['hasMore']:
                break

            before = data['pagination']['nextCursor']

        print(f"\nTotal transactions: {len(all_transactions)}")
        return all_transactions

    get_all_transaction_history("86xCnPeV69n6t3DnyGvkKobf9FdN2H9oiVDdaMpo2MMY")
    ```
  </Tab>
</Tabs>

## Parameter kueri

| Parameter       | Tipe    | Default        | Deskripsi                                                                                            |
| --------------- | ------- | -------------- | ---------------------------------------------------------------------------------------------------- |
| `limit`         | integer | 100            | Jumlah maksimum transaksi per permintaan (1-100)                                                     |
| `before`        | string  | -              | Ambil transaksi sebelum tanda tangan ini (gunakan `pagination.nextCursor` dari respons sebelumnya)   |
| `after`         | string  | -              | Ambil transaksi setelah tanda tangan ini (untuk paginasi dalam urutan menaik)                        |
| `type`          | string  | -              | Filter berdasarkan jenis transaksi (misalnya, SWAP, TRANSFER, NFT\_SALE, TOKEN\_MINT)                |
| `tokenAccounts` | string  | balanceChanged | Filter transaksi yang melibatkan akun token: `none`, `balanceChanged` (direkomendasikan), atau `all` |

### Jenis transaksi yang tersedia

Parameter `type` mendukung pemfilteran berdasarkan jenis transaksi berikut:

`SWAP`, `TRANSFER`, `NFT_SALE`, `NFT_BID`, `NFT_LISTING`, `NFT_MINT`, `NFT_CANCEL_LISTING`, `TOKEN_MINT`, `BURN`, `COMPRESSED_NFT_MINT`, `COMPRESSED_NFT_TRANSFER`, `COMPRESSED_NFT_BURN`, `CREATE_STORE`, `WHITELIST_CREATOR`, `ADD_TO_WHITELIST`, `REMOVE_FROM_WHITELIST`, `AUCTION_MANAGER_CLAIM_BID`, `EMPTY_PAYMENT_ACCOUNT`, `UPDATE_PRIMARY_SALE_METADATA`, `ADD_TOKEN_TO_VAULT`, `ACTIVATE_VAULT`, `INIT_VAULT`, `INIT_BANK`, `INIT_STAKE`, `MERGE_STAKE`, `SPLIT_STAKE`, `CREATE_AUCTION_MANAGER`, `START_AUCTION`, `CREATE_AUCTION_MANAGER_V2`, `UPDATE_EXTERNAL_PRICE_ACCOUNT`, `EXECUTE_TRANSACTION`

### Contoh filter

<Tabs>
  <Tab title="Filter by Type">
    ```javascript theme={"system"}
    // Get only SWAP transactions
    const url = `https://api.helius.xyz/v1/wallet/${address}/history?api-key=YOUR_API_KEY&type=SWAP`;
    ```
  </Tab>

  <Tab title="Token Accounts Filter">
    ```javascript theme={"system"}
    // Exclude spam by only including transactions that changed token balances
    const url = `https://api.helius.xyz/v1/wallet/${address}/history?api-key=YOUR_API_KEY&tokenAccounts=balanceChanged`;

    // Only show direct wallet interactions
    const url = `https://api.helius.xyz/v1/wallet/${address}/history?api-key=YOUR_API_KEY&tokenAccounts=none`;
    ```
  </Tab>

  <Tab title="Combined Filters">
    ```javascript theme={"system"}
    // Get only NFT sales that changed balances
    const url = `https://api.helius.xyz/v1/wallet/${address}/history?api-key=YOUR_API_KEY&type=NFT_SALE&tokenAccounts=balanceChanged`;
    ```
  </Tab>
</Tabs>

## Format respons

```json theme={"system"}
{
  "data": [
    {
      "signature": "5wHu1qwD7Jsj3xqWjdSEJmYr3Q5f5RjXqjqQJ7jqEj7jqEj7jqEj7jqEj7jqEj7jqE",
      "timestamp": 1704067200,
      "slot": 250000000,
      "fee": 0.000005,
      "feePayer": "86xCnPeV69n6t3DnyGvkKobf9FdN2H9oiVDdaMpo2MMY",
      "error": null,
      "balanceChanges": [
        {
          "mint": "So11111111111111111111111111111111111111111",
          "amount": -0.05,
          "decimals": 9
        },
        {
          "mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
          "amount": 50.0,
          "decimals": 6
        }
      ]
    }
  ],
  "pagination": {
    "hasMore": true,
    "nextCursor": "5wHu1qwD7Jsj3xqWjdSEJmYr3Q5f5RjXqjqQJ7jqEj7jqEj7jqEj7jqEj7jqEj7jqE"
  }
}
```

### Catatan bidang

* **`timestamp`**: detik Unix. Nilainya mungkin `null` untuk transaksi sangat baru yang belum diproses sepenuhnya.
* **`error`**: `null` untuk transaksi yang berhasil; nilai kesalahan untuk transaksi yang gagal. Transaksi yang gagal tetap dikenai biaya.
* **`balanceChanges`**: perubahan aset dompet dalam transaksi — `amount` positif berarti token diterima, sedangkan `amount` negatif berarti token dikirim atau dibelanjakan.
* **`mint`** (di dalam `balanceChanges`): alamat mint token, atau `"SOL"` untuk SOL native.
* **`amount`** (di dalam `balanceChanges`): **mudah dibaca**, sudah dibagi dengan `decimals` — `-0.05` berarti −0,05 SOL, bukan −0,05 lamport. Endpoint ini tidak menyertakan bidang mentah `amountRaw`.

#### Contoh perubahan saldo

```javascript theme={"system"}
// Swap: Sold 0.05 SOL, received 5 USDC
{
  "balanceChanges": [
    { "mint": "SOL", "amount": -0.05, "decimals": 9 },
    { "mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", "amount": 5.0, "decimals": 6 }
  ]
}

// Simple transfer: Sent 10 USDC
{
  "balanceChanges": [
    { "mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", "amount": -10.0, "decimals": 6 }
  ]
}
```

## Kasus penggunaan

### Menghitung total volume perdagangan

Jumlahkan semua transfer untuk mendapatkan volume perdagangan:

```javascript theme={"system"}
const calculateTradingVolume = async (address, tokenMint) => {
  const transactions = await getAllTransactionHistory(address);

  let totalVolume = 0;

  transactions.forEach(tx => {
    tx.balanceChanges.forEach(change => {
      if (change.mint === tokenMint) {
        totalVolume += Math.abs(change.amount);
      }
    });
  });

  console.log(`Total ${tokenMint} volume: ${totalVolume}`);
  return totalVolume;
};

// Example: Calculate total USDC volume
calculateTradingVolume(
  "86xCnPeV69n6t3DnyGvkKobf9FdN2H9oiVDdaMpo2MMY",
  "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v" // USDC
);
```

### Membuat laporan pajak

Buat laporan transaksi untuk pelaporan pajak:

```javascript theme={"system"}
const generateTaxReport = async (address, year) => {
  const transactions = await getAllTransactionHistory(address);

  const startDate = new Date(`${year}-01-01`).getTime() / 1000;
  // Set to end of December 31st (23:59:59.999) to include all transactions from that day
  const endDate = new Date(`${year}-12-31T23:59:59.999Z`).getTime() / 1000;

  const taxableTransactions = transactions
    .filter(tx => tx.timestamp >= startDate && tx.timestamp <= endDate)
    .map(tx => ({
      date: new Date(tx.timestamp * 1000).toISOString(),
      signature: tx.signature,
      fee: tx.fee,
      balanceChanges: tx.balanceChanges,
      explorerUrl: `https://orbmarkets.io/tx/${tx.signature}`
    }));

  console.log(`Found ${taxableTransactions.length} transactions in ${year}`);

  // Export as JSON
  const report = {
    address,
    year,
    transactionCount: taxableTransactions.length,
    transactions: taxableTransactions
  };

  console.log(JSON.stringify(report, null, 2));
  return report;
};

generateTaxReport("86xCnPeV69n6t3DnyGvkKobf9FdN2H9oiVDdaMpo2MMY", 2024);
```

### Melacak transaksi yang gagal

Temukan semua transaksi yang gagal untuk memahami kesalahannya:

```javascript theme={"system"}
const getFailedTransactions = async (address) => {
  const data = await getTransactionHistory(address);

  const failed = data.data.filter(tx => tx.error !== null);

  console.log(`Found ${failed.length} failed transactions`);

  failed.forEach(tx => {
    const date = new Date(tx.timestamp * 1000).toLocaleString();
    console.log(`\n${date}`);
    console.log(`Signature: ${tx.signature}`);
    console.log(`Error: ${tx.error}`);
    console.log(`Fee Paid: ${tx.fee} SOL`);
  });

  return failed;
};
```

### Merekonstruksi saldo historis

Hitung saldo pada titik waktu tertentu:

```javascript theme={"system"}
const getHistoricalBalance = async (address, targetTimestamp) => {
  const transactions = await getAllTransactionHistory(address);

  // Filter to transactions before target date
  const relevantTxs = transactions.filter(tx => tx.timestamp <= targetTimestamp);

  // Sum all balance changes
  const balances = {};

  relevantTxs.forEach(tx => {
    tx.balanceChanges.forEach(change => {
      if (!balances[change.mint]) {
        balances[change.mint] = 0;
      }
      balances[change.mint] += change.amount;
    });
  });

  console.log(`Historical balances as of ${new Date(targetTimestamp * 1000).toLocaleString()}:`);
  Object.entries(balances).forEach(([mint, balance]) => {
    console.log(`${mint}: ${balance}`);
  });

  return balances;
};

// Example: Get balances on Jan 1, 2024
getHistoricalBalance(
  "86xCnPeV69n6t3DnyGvkKobf9FdN2H9oiVDdaMpo2MMY",
  new Date("2024-01-01").getTime() / 1000
);
```

Untuk mendapatkan saldo pasti satu token pada titik waktu tertentu, endpoint [Historical Balance](/docs/id/wallet-api/balance-at) membacanya langsung dari saldo akhir on-chain, bukan dengan menjumlahkan perubahan di sisi klien.

### Menganalisis biaya transaksi

Hitung total biaya yang dibayarkan:

```javascript theme={"system"}
const analyzeFees = async (address) => {
  const transactions = await getAllTransactionHistory(address);

  const totalFees = transactions.reduce((sum, tx) => sum + tx.fee, 0);
  const avgFee = totalFees / transactions.length;

  const successfulTxs = transactions.filter(tx => !tx.error);
  const failedTxs = transactions.filter(tx => tx.error);

  const wastedFees = failedTxs.reduce((sum, tx) => sum + tx.fee, 0);

  console.log(`Total Transactions: ${transactions.length}`);
  console.log(`Successful: ${successfulTxs.length}`);
  console.log(`Failed: ${failedTxs.length}`);
  console.log(`Total Fees Paid: ${totalFees.toFixed(6)} SOL`);
  console.log(`Average Fee: ${avgFee.toFixed(6)} SOL`);
  console.log(`Wasted on Failed Txs: ${wastedFees.toFixed(6)} SOL`);

  return {
    totalFees,
    avgFee,
    wastedFees,
    successRate: (successfulTxs.length / transactions.length) * 100
  };
};
```

## Praktik terbaik

* **Gunakan paginasi untuk mendapatkan riwayat lengkap.** Beberapa dompet memiliki ratusan ribu transaksi; selalu gunakan paginasi saat mengambil semuanya.
* **Cache data historis.** Transaksi historis tidak pernah berubah. Simpan transaksi tersebut di cache lokal dan hanya ambil transaksi baru.
* **Tangani transaksi yang gagal.** Periksa bidang `error` untuk membedakan transaksi yang berhasil dan gagal. Transaksi yang gagal tetap dikenai biaya.
* **Gunakan stempel waktu untuk pemfilteran tanggal.** Stempel waktu dinyatakan dalam detik Unix. Konversikan ke tanggal lokal untuk tampilan dan pemfilteran.

## Kesalahan umum

| Kode Kesalahan | Deskripsi                          | Solusi                                                             |
| -------------- | ---------------------------------- | ------------------------------------------------------------------ |
| 400            | Format alamat dompet tidak valid   | Pastikan alamat tersebut merupakan alamat Solana base58 yang valid |
| 401            | API key tidak ada atau tidak valid | Pastikan API key Anda disertakan dalam permintaan                  |
| 429            | Rate limit terlampaui              | Kurangi frekuensi permintaan atau tingkatkan paket Anda            |

## Langkah berikutnya

<CardGroup cols={3}>
  <Card title="Token Transfers" icon="arrow-right-arrow-left" href="/docs/id/wallet-api/transfers">
    Tampilan khusus transfer dengan informasi pengirim/penerima — lebih sederhana daripada riwayat lengkap.
  </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/history">
    Skema permintaan dan respons untuk riwayat transaksi.
  </Card>
</CardGroup>
