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

# Solanaウォレットの過去のトークン残高の取得方法

> ウォレットのトークンまたはネイティブSOLの残高を過去のタイムスタンプ、日時、またはスロットで照会します。PnL、コストベース、税務報告、およびウォレット状態の再構築に最適です。

<Note>
  Wallet APIはベータ版です。エンドポイントおよびレスポンス形式は変更される可能性があります。
</Note>

## 概要

Historical Balanceエンドポイントは、過去の特定の時点でウォレットの特定のトークン（またはネイティブSOL）の残高がどうだったのかを答えます。[Balances](/ja/wallet-api/balances) エンドポイントが現在の保有を報告するのに対し、`balance-at`は任意のタイムスタンプ、日時、またはスロットでの保有を報告します。

ウォレットとトークンが関与する要求された時点の直前またはその時点での**最新の取引を見つけ**、その取引からウォレットの**取引後の残高**を読み取ります。取引の取引後の残高は、その取引から次の取引までの間に保有した残高です。したがって「時刻Tの残高」は、時刻T以前またはその時点でのブロック時間（またはスロット）での最後の関連取引の取引後の残高です。通常のウォレットでは、これは推定ではなく正確な値です。

* **トークン (SPL / Token-2022)**: 取引の取引後トークン残高から読み取り、そのミントに対するウォレットのトークンアカウントで合計します。
* **ネイティブSOL**: 取引のラプトルの取引後残高から読み取ります。ネイティブSOLを擬似ミントとしてアドレス指定します。`So11111111111111111111111111111111111111111`。

## 使用するタイミング

Historical Balance APIを使用する場合:

* **PnL計算**: 期間の開始と終了時の保有を決定します。
* **コストベースと税ロット**: 取得または処分イベントでの残高を再構築します。
* **紛争解決**: 特定の瞬間にウォレットが何を保持していたかを証明します。
* **スナップショットの検証**: エアドロップやガバナンススナップショット時のウォレットの残高を確認します。
* **会計と監査**: 期間境界でのウォレット状態を再構築します。

## クイックスタート

### タイムスタンプでのトークン残高

UnixタイムスタンプでのウォレットのUSDC残高を取得します:

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

### 日時でのトークン残高

タイムスタンプの代わりに人間が読める日時を渡します。スペースは`%20`でURLエンコードすることを忘れないでください。

```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"
```

### スロットでのネイティブSOL残高

ネイティブSOLの場合は、擬似ミント`So11111111111111111111111111111111111111111`を使用します。スロットに基づいたクエリは正確で決定的です。

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

## クエリパラメータ

| パラメータ      | 必須     | タイプ    | 説明                                                                           |
| ---------- | ------ | ------ | ---------------------------------------------------------------------------- |
| `mint`     | はい     | string | トークンミントアドレス。ネイティブSOLの場合は`So11111111111111111111111111111111111111111`を使用します。 |
| `time`     | いずれか一つ | int    | Unixタイムスタンプ（**秒**）。この時点での残高。                                                 |
| `datetime` | いずれか一つ | string | 日時文字列。例: `2025-01-10 19:20:00`。デフォルトではUTCです。                                 |
| `slot`     | いずれか一つ | int    | スロット番号。このスロットでの残高。正確で決定的です。                                                  |

`time`, `datetime`, `slot`の**いずれか一つ**を提供する必要があります。0または複数を提供すると、`400`エラーが返されます。

### 日時形式

受け入れ可能な形式:

* 日付のみ: `2025-01-10` → UTCの真夜中
* 日付 + 時刻: `2025-01-10 19:20:00` または `2025-01-10T19:20:00`（秒はオプション） → UTC
* 明示的なタイムゾーン: `2025-01-10T19:20:00Z`, `2025-01-10T19:20:00+02:00`, `2025-01-10T19:20:00-05:00` → 指定通りに処理

無効またはサポートされていない形式（`01/10/2025`, `2025-13-10`, `2025-02-30`）は`400`エラーを返します。

<Warning>
  日時はデフォルトではUTCとして解釈されます。`2025-01-10 19:20:00`のような単純な日時は、あなたの現地時間ではなくUTCとして扱われます。別の意図がある場合は明示的なタイムゾーンオフセットを含めてください。レスポンスの`requested.time`フィールドは、解釈を確認できるように解決されたエポック秒を示します。
</Warning>

## レスポンス形式

```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"
  }
}
```

### フィールドノート

* **`wallet`**: 照会されたウォレットアドレスのエコー。
* **`mint`**: 照会されたミントのエコー（ネイティブの場合はSOLの擬似ミント）。
* **`isNative`**: 結果がネイティブSOLの場合は`true`。
* **`balance`**: **10進文字列**としての人間が読める量 — 文字列であり数値ではないため、大きな残高でも精度を失いません。末尾のゼロはトリムされます（`"1.5"`ではなく`"1.500000"`）。
* **`balanceRaw`**: 最小単位での正確な量（SOLの場合はラプトル）として、文字列。
* **`decimals`**: トークンの小数点以下の桁数（SOLでは9）。
* **`requested`**: クエリのエコー。`datetime`が使用された場合、`time`も解決されたエポック秒で設定され、UTCの解釈が表示されます。
* **`asOf`**: 残高が読み取られた取引（`slot`, `blockTime`, `signature`）。

`asOf: null`はエラーではなくゼロを意味します。要求された時点でウォレットに一致する取引がない場合、エンドポイントは`200`を返し、`balance: "0"`と`asOf: null` — ウォレットはその時点までにトークンを保持していなかったことを示します。

## 使用ケース

### 期間中の残高変動

2つの時点での保有を比較します。

```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 };
};
```

### スナップショットの適格性確認

ウォレットがスナップショットスロットでトークンを保持していたかを確認します。

```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;
};
```

## ベストプラクティス

* **決定的な結果には`slot`を使用します。** `time`と`datetime`はバリデーター報告のブロック時間を通じて解決され、数秒のドリフトが発生する可能性があります。正確さが重要な場合（スナップショット、監査）、`slot`でクエリします。
* **残高を文字列として解析します。** `balance`と`balanceRaw`は精度を維持するために文字列です。計算には`BigInt(balanceRaw)`（またはあなたの言語の任意精度整数）を使用します - 浮動小数点数にキャストしないでください。
* **`asOf: null`をゼロと見なします。** `null` `asOf`は、要求された時点でそのトークンに対するウォレットの活動がなかったことを意味する成功した応答です。エラーとして扱わないでください。
* **過去の結果をキャッシュします。** 過去の時点での残高は変わりません。繰り返しのAPI呼び出しを避けるために結果を永久にキャッシュします。

## 共通のエラー

| エラーコード | 説明                                                                              | 解決策                                  |
| ------ | ------------------------------------------------------------------------------- | ------------------------------------ |
| 400    | `mint` が欠落している、有効でないミント、`time`, `datetime`, `slot` の0個または複数、または解釈できない`datetime` | 有効なミントと正確に1つの時点パラメータを提供します           |
| 401    | APIキーが欠落しているか無効                                                                 | リクエストにAPIキーが含まれていることを確認します           |
| 404    | パス内の無効なウォレットアドレス                                                                | アドレスが有効なbase58 Solanaアドレスであることを確認します |
| 429    | レート制限を超過                                                                        | リクエスト頻度を下げるか、プランをアップグレードします          |
| 502    | 上流のRPCエラーまたはタイムアウト                                                              | 指数バックオフを使用して再試行します                   |

## 制限事項

* **マルチトークンアカウントウォレットは過少カウントされる可能性があります。** 残高は最新の一致する取引から読み取られます。一般的なケース（ミントごとに1つの関連トークンアカウント）は正確です。複数のトークンアカウントに同じミントを保持しているウォレットでは、最新の取引がそれらの一部にしか触れていない場合、過少カウントされる可能性があります。
* **非常に大きな残高のネイティブSOLの精度。** 約9,007,199 SOL（2⁵³ラプトル）を超えるSOL残高は、上流で精度が失われる可能性があります。トークン量は影響されません。
* **`time`/`datetime`の精度はバリデーター報告のブロック時間に依存します**が、数秒ドリフトする可能性があります。正確で決定的な結果には`slot`を使用します。
* **リクエストあたり1つのトークンのみ。** 複数のミントや「時刻Tでのすべての残高」のバッチ形式はありません。

## 次のステップ

<CardGroup cols={3}>
  <Card title="ウォレットの残高" icon="scale-balanced" href="/ja/wallet-api/balances">
    USD値を含むウォレットの現在のトークンおよびNFT保有を取得。
  </Card>

  <Card title="ウォレットAPIの概要" icon="wallet" href="/ja/wallet-api/overview">
    すべてのウォレットAPIエンドポイントおよび共通規約。
  </Card>

  <Card title="APIリファレンス" icon="code" href="/ja/api-reference/wallet-api/balance-at">
    履歴のある残高のリクエストおよびレスポンススキーマ。
  </Card>
</CardGroup>
