> ## 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](/docs/ru/wallet-api/balances) возвращает *текущие* активы, а `balance-at` — активы на момент любой временной метки, даты и времени или слота.

Он находит **последнюю транзакцию на запрошенный момент времени или до него**, в которой участвовали кошелёк и токен, а затем считывает из неё **баланс кошелька после транзакции**. Баланс после транзакции сохраняется с момента этой транзакции до следующей, поэтому «баланс на момент T» — это баланс после последней соответствующей транзакции, время блока (или слот) которой не позднее T. Для типичного кошелька это точное, а не приблизительное значение.

* **Токены (SPL / Token-2022)**: данные считываются из балансов токенов после транзакции и суммируются по счетам токенов кошелька для данного минта.
* **Нативный SOL**: данные считываются из балансов лампортов после транзакции. Для нативного SOL укажите псевдоминт `So11111111111111111111111111111111111111111`.

## Когда использовать

Используйте Historical Balance API для следующих задач:

* **Расчёт PnL**: определение активов в начале и конце периода.
* **Себестоимость и налоговые лоты**: восстановление балансов на момент приобретения или выбытия.
* **Разрешение споров**: подтверждение активов кошелька в конкретный момент.
* **Проверка снимков**: проверка баланса кошелька на момент аирдропа или снимка для голосования.
* **Бухгалтерский учёт и аудит**: восстановление состояния кошелька на границах отчётных периодов.

## Быстрый старт

### Баланс токена на момент временной метки

Получите баланс USDC в кошельке на момент временной метки 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>

### Баланс токена на указанную дату и время

Передайте удобочитаемые дату и время вместо временной метки. Не забудьте закодировать пробел в URL как `%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"
```

### Баланс нативного 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`. Если не указать ни одного или указать несколько, возвращается ошибка `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 для нативного SOL).
* **`isNative`**: значение `true`, если результат относится к нативному SOL.
* **`balance`**: удобочитаемая сумма в виде **десятичной строки** — именно строки, а не числа, чтобы большие балансы не теряли точность. Конечные нули удаляются (`"1.5"`, а не `"1.500000"`).
* **`balanceRaw`**: точная сумма в минимальных единицах (в лампортах для SOL) в виде строки.
* **`decimals`**: количество десятичных разрядов токена (9 для SOL).
* **`requested`**: данные исходного запроса. При использовании `datetime` поле `time` также заполняется вычисленным количеством секунд от начала эпохи, что позволяет увидеть интерпретацию по UTC.
* **`asOf`**: транзакция, из которой был считан баланс (`slot`, `blockTime`, `signature`).

`asOf: null` означает нулевой баланс, а не ошибку. Если на запрошенный момент времени или до него у кошелька не было подходящей транзакции, эндпоинт возвращает `200` с `balance: "0"` и `asOf: null` — к тому моменту токенов в кошельке ещё не было.

## Сценарии использования

### Изменение баланса за период

Сравните активы в два момента времени:

```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` либо не удаётся обработать `datetime` | Укажите допустимый минт и ровно один параметр момента времени |
| 401 | Ключ API отсутствует или недействителен | Убедитесь, что ключ API включён в запрос |
| 404 | В пути указан недопустимый адрес кошелька | Убедитесь, что адрес является допустимым адресом Solana в формате base58 |
| 429 | Превышен лимит запросов | Снизьте частоту запросов или перейдите на более высокий тариф |
| 502 | Ошибка вышестоящего RPC-сервиса или истечение времени ожидания | Повторите запрос с экспоненциальной задержкой |

## Ограничения

* **Баланс кошельков с несколькими счетами токенов может быть занижен.** Баланс считывается из одной последней подходящей транзакции. В распространённом случае, когда для каждого минта существует один связанный счёт токена, результат точен. Если один и тот же минт хранится в нескольких счетах токенов кошелька, а последняя транзакция затронула только часть из них, баланс может быть занижен.
* **Точность нативного SOL при очень больших балансах.** Для балансов SOL свыше примерно 9 007 199 SOL (2⁵³ лампортов) точность может быть потеряна в вышестоящем сервисе. На суммы токенов это не влияет.
* **Точность `time`/`datetime` зависит от времени блоков, сообщаемого валидатором**, которое может отклоняться на несколько секунд. Для точных и детерминированных результатов используйте `slot`.
* **Один токен на запрос.** Пакетная форма для нескольких минтов или «всех балансов на момент T» отсутствует.

## Дальнейшие действия

<CardGroup cols={3}>
  <Card title="Wallet Balances" icon="scale-balanced" href="/docs/ru/wallet-api/balances">
    Получите текущие токены и NFT в кошельке с их стоимостью в долларах США.
  </Card>

  <Card title="Wallet API Overview" icon="wallet" href="/docs/ru/wallet-api/overview">
    Все эндпоинты Wallet API и общие соглашения.
  </Card>

  <Card title="API Reference" icon="code" href="/docs/ru/api-reference/wallet-api/balance-at">
    Схемы запросов и ответов для исторического баланса.
  </Card>
</CardGroup>


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