# 지갑 토큰 잔액 API: ERC-20 자산 및 전송 내역

> Source: https://docs.blockvectra.com/ko/guides/wallet-assets/

블록체인 지갑 데이터 API로 지갑 자산 페이지를 구축하세요: 0이 아닌 ERC-20 보유 자산은 [Token Balances API](https://blockvectra.com/en/data/balances/)를 사용하고, 지갑 이력은 [Token Transfers API](https://blockvectra.com/en/data/transfers/)를 사용합니다. 개발자와 AI 에이전트는 동일한 인증 요청을 사용합니다. 쿼리하기 전에 [GET /v1/status](https://api.blockvectra.com/v1/data)를 확인하고 선택한 체인의 `data_features`와 `data_status`를 확인하세요. 잔액 지원 범위는 체인마다 다릅니다. 요청 파라미터와 응답 스키마는 [Data API 레퍼런스](https://docs.blockvectra.com/en/api/data/)에 있습니다.

## 이 가이드를 통해 완료할 수 있는 작업

* 키를 사용하여 [지갑 토큰 잔액 조회](#요청-1-주소-잔액) 및 0이 아닌 ERC-20 보유 자산 페이지네이션.
* 고정된 블록 윈도우 내에서 [지갑 전송 내역 조회](#요청-2-주소-전송-내역) 및 선택한 주소에 대한 커서 추적.
* [토큰 메타데이터 보완](#요청-3-토큰-메타데이터-및-tokensbatch)을 통해 누락된 필드를 보존하면서 원시 정수 잔액과 함께 이름과 심볼 표시.

## 지갑 자산 페이지에 필요한 세 가지 데이터

지갑 자산 페이지는 주소의 ERC-20 토큰 잔액, 토큰 전송 내역 및 토큰 메타데이터를 표시할 수 있습니다. Data API는 각각에 대한 엔드포인트를 제공합니다:

* **잔액**: `GET /{chain}/addresses/{address}/balances`는 주소의 0이 아닌 ERC-20 잔액을 `token` 주소 오름차순으로 반환하며, 가능한 경우 토큰 `symbol`과 `decimals`를 포함합니다. 잔액이 없는 주소는 `data: []`와 함께 `200`을 반환합니다.
* **전송 내역**: `GET /{chain}/addresses/{address}/transfers`는 필수 블록 윈도우 내에서 해당 주소가 관련된 토큰 전송을 `(block_number, log_index)` 내림차순으로 반환합니다.
* **토큰 메타데이터**: `GET /{chain}/tokens/{token}`은 컨트랙트 주소별로 단일 토큰의 이름, 심볼, 소수점 자릿수(decimals) 및 총 공급량을 읽습니다. `POST /{chain}/tokens:batch`는 한 번의 요청으로 최대 100개 주소에 대해 동일한 메타데이터를 읽습니다.

세 가지 엔드포인트 모두 `https://api.blockvectra.com/v1/data`을 기본 URL로 사용하고 `x-api-key` 요청 헤더를 사용하며, 예제 체인으로는 `robinhood_mainnet`을 사용합니다. 이들은 각각 `balances`, `transfers`, `token_metadata` 기능에 속합니다. 각 기능을 제공하는 체인은 [지원 체인](https://docs.blockvectra.com/en/chains/) 페이지를 참조하세요. 해당 기능이 없는 체인에서 엔드포인트를 호출하면 `422 no_coverage`를 반환합니다.

## 요청 1: 주소 잔액

이 엔드포인트는 필요한 파라미터가 적기 때문에 페이지의 첫 번째 요청으로 적합합니다:

* `{chain}` (경로 파라미터, 필수): 체인 식별자, `GET /chains` 항목의 `chain` 값 (예: `robinhood_mainnet`). 대소문자를 구분하여 정확히 일치해야 하며, 별칭이나 숫자 체인 ID는 허용되지 않습니다.
* `{address}` (경로 파라미터, 필수): 20바이트 주소. `0x` 접두사는 선택 사항이며 대소문자 모두 허용됩니다.
* `limit` (쿼리 파라미터, 선택): 페이지 크기입니다. 기본값은 50이며, 500을 초과하는 값은 500으로 제한됩니다. `0` 또는 정수가 아닌 값은 `400 bad_request`를 반환합니다.
* `cursor` (쿼리 파라미터, 선택): 이전 응답의 `next_cursor` 값으로, 다음 페이지를 가져오기 위해 변경 없이 전달합니다. 커서는 이를 발급한 체인, 엔드포인트 및 쿼리 파라미터에 대해서만 유효하며, 다른 곳에서 재사용하면 `400 bad_request`를 반환합니다.

키셋(keyset) 기반으로 페이지네이션됩니다: `next_cursor`는 다음 페이지가 있을 때만 나타납니다. 마지막 페이지에서는 이 키가 완전히 생략되며, 결코 `null`이 되지 않습니다.

**cURL**

```bash
export BLOCKVECTRA_API_KEY=rgw_your_api_key

curl -s "https://api.blockvectra.com/v1/data/robinhood_mainnet/addresses/0x1111111111111111111111111111111111111111/balances?limit=50" \
  -H "x-api-key: $BLOCKVECTRA_API_KEY"
```


  **TypeScript**

```ts
const address = "0x1111111111111111111111111111111111111111";
const url = new URL(
  `https://api.blockvectra.com/v1/data/robinhood_mainnet/addresses/${address}/balances`,
);
url.searchParams.set("limit", "50");

const res = await fetch(url, {
  headers: { "x-api-key": process.env.BLOCKVECTRA_API_KEY! },
});
const balanceBody = await res.json();
console.log(balanceBody.data, balanceBody.meta);

// npx tsx example.mts
```


  **Python**

```python
import os
import requests

address = "0x1111111111111111111111111111111111111111"
res = requests.get(
    f"https://api.blockvectra.com/v1/data/robinhood_mainnet/addresses/{address}/balances",
    params={"limit": 50},
    headers={"x-api-key": os.environ["BLOCKVECTRA_API_KEY"]},
)
res.raise_for_status()
balance_body = res.json()
print(balance_body["data"], balance_body["meta"])
```


응답 외층 구조는 `AddressBalanceListEnvelope`로, `data`와 `meta`를 포함합니다. `data`의 각 항목은 `AddressBalance`입니다:

| 필드         | 타입                  | 설명                                                                                       |
| ---------- | ------------------- | ---------------------------------------------------------------------------------------- |
| `token`    | `string` (address)  | 토큰 컨트랙트 주소입니다. 정규 형식은 `0x`와 40자리의 소문자 16진수 문자입니다.                                        |
| `balance`  | `string` (decimal)  | `2^53`을 초과할 수 있는 원시 정수 잔액으로, JSON 숫자가 아닌 일반 10진수 문자열로 반환되며 지수 표기법이나 16진수 표기법을 사용하지 않습니다. |
| `symbol`   | `string` 또는 `null`  | 토큰 심볼이며, 제공되지 않는 경우 `null`입니다.                                                           |
| `decimals` | `integer` 또는 `null` | 토큰 소수점 자릿수로 `0`\~`255` 사이이며, 제공되지 않는 경우 `null`입니다.                                       |

## 요청 2: 주소 전송 내역

전송 내역 엔드포인트는 명시적인 블록 윈도우가 필요합니다: `from_block`과 `to_block`이 모두 필수이며 `from_block <= to_block`을 만족해야 합니다. 몇 가지 파라미터가 추가로 사용됩니다:

* `standard` (쿼리 파라미터, 필수): `erc20` 또는 `erc721`. 주소 범위 쿼리는 `erc1155`를 다루지 않으며, 전달 시 `422 no_coverage`를 반환합니다.
* `direction` (쿼리 파라미터, 선택): `in`, `out`, 또는 `any`. 기본값은 `any`이며 주소를 기준으로 방향을 필터링합니다.
* `token` (쿼리 파라미터, 선택): 결과를 특정 토큰 컨트랙트로 제한합니다.
* `clamp` (쿼리 파라미터, 선택): 리터럴 문자열 `true`만 활성화하며, 다른 모든 값은 `false`로 처리됩니다.

윈도우 경계 및 최종 확정성: `as_of_block`보다 큰 명시적 `to_block`은 `clamp=true`로 `as_of_block`까지 잘라내지 않는 한 `409 not_indexed_yet`을 반환합니다. 체인의 한도(`GET /chains`의 `limits.max_window_blocks`)보다 넓은 윈도우는 `clamp=true`로 이전 블록부터 잘라내지 않는 한(`from_block`을 높이고 `to_block`을 고정) `409 window_too_large`를 반환합니다. `from_block` 자체가 이미 `as_of_block`을 지난 경우 `clamp=true`여도 엄격하게 `409`를 반환합니다. 윈도우가 잘리거나 부분적으로만 포함된 경우 응답의 `meta.coverage`는 `"partial"`이며, 그렇지 않으면 `"full"`입니다.

전송 레코드에서 ERC-20 항목에는 `amount`가 추가되고, ERC-721 항목에는 `token_id`가 추가됩니다. 둘 다 `token`, `standard`, `from`, `to`, `block_number`, `block_timestamp`, `tx_hash`, `tx_index`, `log_index`를 포함합니다.

**cURL**

```bash
export BLOCKVECTRA_API_KEY=rgw_your_api_key

# 1) Read as_of_block from the balances response.
AS_OF_BLOCK=$(curl -s "https://api.blockvectra.com/v1/data/robinhood_mainnet/addresses/0x1111111111111111111111111111111111111111/balances" \
  -H "x-api-key: $BLOCKVECTRA_API_KEY" | grep -o '"as_of_block":[0-9]*' | cut -d: -f2)

# 2) clamp=true truncates a too-wide window, or a to_block above as_of_block, instead of returning 409.
curl -s "https://api.blockvectra.com/v1/data/robinhood_mainnet/addresses/0x1111111111111111111111111111111111111111/transfers?standard=erc20&from_block=0&to_block=$AS_OF_BLOCK&direction=any&clamp=true" \
  -H "x-api-key: $BLOCKVECTRA_API_KEY"
```


  **TypeScript**

```ts
const address = "0x1111111111111111111111111111111111111111";

// 1) Read as_of_block from any previous response's meta.
const head = await fetch(
  `https://api.blockvectra.com/v1/data/robinhood_mainnet/addresses/${address}/balances`,
  { headers: { "x-api-key": process.env.BLOCKVECTRA_API_KEY! } },
).then((r) => r.json());

// 2) Use as_of_block as the transfer window's upper bound.
const url = new URL(
  `https://api.blockvectra.com/v1/data/robinhood_mainnet/addresses/${address}/transfers`,
);
url.searchParams.set("standard", "erc20");
url.searchParams.set("from_block", "0");
url.searchParams.set("to_block", String(head.meta.as_of_block));
url.searchParams.set("direction", "any");
url.searchParams.set("clamp", "true");

const res = await fetch(url, {
  headers: { "x-api-key": process.env.BLOCKVECTRA_API_KEY! },
});
const body = await res.json();
console.log(body.data, body.meta);

// npx tsx example.mts
```


  **Python**

```python
import os
import requests

address = "0x1111111111111111111111111111111111111111"
headers = {"x-api-key": os.environ["BLOCKVECTRA_API_KEY"]}

# 1) Read as_of_block from any previous response's meta.
head = requests.get(
    f"https://api.blockvectra.com/v1/data/robinhood_mainnet/addresses/{address}/balances",
    headers=headers,
).json()

# 2) Use as_of_block as the transfer window's upper bound.
res = requests.get(
    f"https://api.blockvectra.com/v1/data/robinhood_mainnet/addresses/{address}/transfers",
    params={
        "standard": "erc20",
        "from_block": 0,
        "to_block": head["meta"]["as_of_block"],
        "direction": "any",
        "clamp": "true",
    },
    headers=headers,
)
res.raise_for_status()
body = res.json()
print(body["data"], body["meta"])
```


## 전체 전송 내역 페이지네이션

주소 전송 내역 엔드포인트의 `next_cursor`는 낙관적입니다: 페이지가 정확히 `limit`개의 행을 반환할 때만 나타나므로, 페이지에 `next_cursor`가 있더라도 마지막 페이지일 수 있습니다. 페이지가 비어 있다고 해서 멈추지 마시고, `next_cursor` 키가 사라질 때까지 추적하세요.

아래 코드는 해당 윈도우 내의 모든 전송 내역을 가져옵니다:

**TypeScript**

```ts
const address = "0x1111111111111111111111111111111111111111";
const head = await fetch(
  `https://api.blockvectra.com/v1/data/robinhood_mainnet/addresses/${address}/balances`,
  { headers: { "x-api-key": process.env.BLOCKVECTRA_API_KEY! } },
).then((r) => r.json());
const asOfBlock = head.meta.as_of_block;
const transfers: unknown[] = [];
let cursor: string | undefined;

do {
  const url = new URL(
    `https://api.blockvectra.com/v1/data/robinhood_mainnet/addresses/${address}/transfers`,
  );
  url.searchParams.set("standard", "erc20");
  url.searchParams.set("from_block", "0");
  url.searchParams.set("to_block", String(asOfBlock));
  url.searchParams.set("limit", "500");
  // clamp truncates from the older end
  url.searchParams.set("clamp", "true");
  if (cursor) url.searchParams.set("cursor", cursor);

  const res = await fetch(url, {
    headers: { "x-api-key": process.env.BLOCKVECTRA_API_KEY! },
  });
  const page = await res.json();
  transfers.push(...page.data);
  cursor = page.next_cursor; // absent on the last page
} while (cursor);
```


  **Python**

```python
import os
import requests

address = "0x1111111111111111111111111111111111111111"
head = requests.get(
    f"https://api.blockvectra.com/v1/data/robinhood_mainnet/addresses/{address}/balances",
    headers={"x-api-key": os.environ["BLOCKVECTRA_API_KEY"]},
).json()
as_of_block = head["meta"]["as_of_block"]
transfers = []
cursor = None

while True:
    params = {
        "standard": "erc20",
        "from_block": 0,
        "to_block": as_of_block,
        "limit": 500,
        # clamp truncates from the older end
        "clamp": "true",
    }
    if cursor:
        params["cursor"] = cursor
    res = requests.get(
        f"https://api.blockvectra.com/v1/data/robinhood_mainnet/addresses/{address}/transfers",
        params=params,
        headers={"x-api-key": os.environ["BLOCKVECTRA_API_KEY"]},
    )
    res.raise_for_status()
    page = res.json()
    transfers.extend(page["data"])
    cursor = page.get("next_cursor")  # absent on the last page
    if not cursor:
        break
```


## 요청 3: 토큰 메타데이터 및 tokens:batch

단일 토큰은 `GET /{chain}/tokens/{token}`으로 읽습니다. 이 경로는 페이지네이션 없이 `{chain}`과 `{token}`만 받습니다. 응답 외층 구조는 `TokenEnvelope`이며, `data`는 `Token`입니다:

| 필드                    | 타입                   | 설명                                                                                                                                                 |
| --------------------- | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `address`             | `string` (address)   | 토큰 컨트랙트 주소입니다.                                                                                                                                     |
| `standard`            | `string`             | `erc20`, `erc721`, 또는 `unknown`.                                                                                                                   |
| `name`                | `string` 또는 `null`   | 토큰 이름이며, 제공되지 않는 경우 `null`입니다.                                                                                                                     |
| `symbol`              | `string` 또는 `null`   | 토큰 심볼이며, 제공되지 않는 경우 `null`입니다.                                                                                                                     |
| `decimals`            | `integer` 또는 `null`  | 토큰 소수점 자릿수로 `0`\~`255` 사이이며, 제공되지 않는 경우 `null`입니다.                                                                                                 |
| `total_supply`        | `string` 또는 `null`   | 원시 총 공급량입니다. API는 `decimals` 배율을 적용하지 않습니다. 제공되지 않는 경우 `null`입니다.                                                                                  |
| `first_seen_block`    | `integer` (int64)    | 토큰이 처음 발견된 블록 높이입니다.                                                                                                                               |
| `metadata_updated_at` | `string` (timestamp) | 메타데이터가 마지막으로 업데이트된 UTC 시간입니다.                                                                                                                      |
| `metadata_block`      | `integer` (int64)    | 메타데이터를 읽어온 블록 높이입니다.                                                                                                                               |
| `metadata_status`     | `string`             | `ok`, `partial`, 또는 `unavailable`.                                                                                                                 |
| `metadata_issues`     | `object`             | `name`, `symbol`, `decimals`, `total_supply`를 키로 하고 `reverted`, `no_data`, `invalid_encoding`, 또는 `temporarily_unavailable`을 값으로 갖는 필드별 이슈 레코드입니다. |

유효한 20바이트 주소가 아닌 `{token}`은 `400 bad_request`를 반환합니다. 알 수 없는 `{token}`은 `404 not_found`를 반환하고, 알 수 없는 `{chain}`은 `404 unknown_chain`을 반환합니다.

잔액 엔드포인트는 가능한 경우 이미 `symbol`과 `decimals`를 포함하지만 둘 다 `null`일 수 있습니다. 지갑에 있는 모든 토큰의 이름과 소수점 자릿수를 채우려면 `POST /{chain}/tokens:batch`를 사용하세요:

* 요청 본문은 요청당 최대 100개의 주소를 갖는 `{"addresses": [...]}`입니다. 100개를 초과하거나 유효한 20바이트 주소가 아닌 항목이 포함된 경우 `400 bad_request`를 반환합니다(첫 번째 유효하지 않은 주소에서 실패).
* 찾을 수 없는 주소는 오류를 발생시키지 않으며 `data.missing`에 나열되고, `data.tokens`에는 메타데이터를 찾은 토큰만 포함됩니다.
* 중복 주소는 `tokens`와 `missing` 모두에서 첫 번째 등장 요청 순서대로 중복이 제거됩니다.

**cURL**

```bash
export BLOCKVECTRA_API_KEY=rgw_your_api_key

# Single token
curl -s "https://api.blockvectra.com/v1/data/robinhood_mainnet/tokens/0x1111111111111111111111111111111111111111" \
  -H "x-api-key: $BLOCKVECTRA_API_KEY"

# Batch: up to 100 addresses per request
curl -s -X POST "https://api.blockvectra.com/v1/data/robinhood_mainnet/tokens:batch" \
  -H "x-api-key: $BLOCKVECTRA_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"addresses":["0x1111111111111111111111111111111111111111","0x2222222222222222222222222222222222222222"]}'
```


  **TypeScript**

```ts
// Single token
const single = await fetch(
  "https://api.blockvectra.com/v1/data/robinhood_mainnet/tokens/0x1111111111111111111111111111111111111111",
  { headers: { "x-api-key": process.env.BLOCKVECTRA_API_KEY! } },
).then((r) => r.json());
console.log(single.data);

// Batch: group by 100 addresses to enrich the tokens from the balances response
const BATCH_SIZE = 100;
const addresses = balanceBody.data.map((item: { token: string }) => item.token);
const tokens = new Map<string, unknown>();
const missing: string[] = [];

for (let i = 0; i < addresses.length; i += BATCH_SIZE) {
  const res = await fetch("https://api.blockvectra.com/v1/data/robinhood_mainnet/tokens:batch", {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "x-api-key": process.env.BLOCKVECTRA_API_KEY!,
    },
    body: JSON.stringify({ addresses: addresses.slice(i, i + BATCH_SIZE) }),
  });
  const body = await res.json();
  for (const token of body.data.tokens) tokens.set(token.address, token);
  missing.push(...body.data.missing);
}

// npx tsx example.mts
```


  **Python**

```python
import os
import requests

headers = {"x-api-key": os.environ["BLOCKVECTRA_API_KEY"]}

# Single token
single = requests.get(
    f"https://api.blockvectra.com/v1/data/robinhood_mainnet/tokens/0x1111111111111111111111111111111111111111",
    headers=headers,
).json()
print(single["data"])

# Batch: group by 100 addresses to enrich the tokens from the balances response
BATCH_SIZE = 100
addresses = [item["token"] for item in balance_body["data"]]
tokens = {}
missing = []

for i in range(0, len(addresses), BATCH_SIZE):
    res = requests.post(
        f"https://api.blockvectra.com/v1/data/robinhood_mainnet/tokens:batch",
        json={"addresses": addresses[i : i + BATCH_SIZE]},
        headers={**headers, "Content-Type": "application/json"},
    )
    res.raise_for_status()
    body = res.json()
    for token in body["data"]["tokens"]:
        tokens[token["address"]] = token
    missing.extend(body["data"]["missing"])
```


## 소수점 자릿수에 따른 금액 변환

잔액 필드 `balance`와 ERC-20 전송 필드 `amount`는 10진수 문자열(`UInt256String`)로 렌더링된 원시 정수입니다. 토큰의 `total_supply` 또한 `decimals` 배율이 적용되지 않은 원시 온체인 정수입니다. 사람이 읽을 수 있는 수량을 표시하려면 해당 토큰의 `decimals`로 나누세요.

* `decimals`는 잔액 항목 자체의 `symbol`/`decimals`에서 가져오거나 `GET /{chain}/tokens/{token}` 및 `POST /{chain}/tokens:batch`에서 가져올 수 있으며, `null`일 수 있습니다.
* 이러한 값은 `2^53`을 초과할 수 있으므로 JSON 숫자로 산술 연산을 수행하지 마세요: TypeScript에서는 `BigInt`를, Python에서는 `Decimal`을 사용하여 정밀도 손실을 방지하기 위해 10진수 문자열을 있는 그대로 파싱하세요.

**TypeScript**

```ts
function toDisplayAmount(raw: string, decimals: number | null): string {
  if (decimals === null) return raw; // no decimals metadata: keep the raw integer
  const value = BigInt(raw);
  const base = 10n ** BigInt(decimals);
  const whole = value / base;
  const fraction = (value % base)
    .toString()
    .padStart(decimals, "0")
    .replace(/0+$/, "");
  return fraction ? `${whole}.${fraction}` : whole.toString();
}

// balance.balance is a raw decimal string; decimals comes from the same item or tokens:batch.
const display = toDisplayAmount(balance.balance, balance.decimals);
```


  **Python**

```python
from decimal import Decimal


def to_display_amount(raw: str, decimals: int | None) -> str:
    if decimals is None:
        return raw  # no decimals metadata: keep the raw integer
    value = Decimal(raw)  # parse the decimal string exactly
    return format(value.scaleb(-decimals).normalize(), "f")


# balance["balance"] is a raw decimal string; decimals comes from the same item or tokens:batch.
display = to_display_amount(balance["balance"], balance["decimals"])
```


## 데이터 최신성

모든 체인 범위 성공 응답은 `meta`를 전달합니다:

* `as_of_block`: 체인의 가장 최신 완전 기록 블록입니다. 블록 범위 엔드포인트는 이 높이까지 데이터를 제공합니다.
* `safe_block`: 노드의 합의 `safe` 블록 태그를 나타내는 마커입니다(알 수 없는 동안 `null`). 결코 `finalized_block`보다 낮지 않으며 응답을 자르거나 거부하거나 지연시키지 않습니다.
* `finalized_block`: 노드의 합의 `finalized` 블록 태그를 나타내는 마커입니다(알 수 없는 동안 `null`). 응답을 자르거나 거부하거나 지연시키지 않으며, 클라이언트는 마커로부터 필요한 안전 수준(예: 확인 상태)을 결정합니다.
* `coverage`: `"full"` 또는 `"partial"`. 주소 전송 내역 및 유사 엔드포인트는 `clamp`로 인해 제공되는 윈도우가 좁아졌거나 윈도우가 체인의 첫 번째 인덱싱된 블록보다 이전에서 시작할 때 `"partial"`을 보고합니다.
* `refreshed_at`: 응답 배후의 데이터가 마지막으로 업데이트된 시간(UTC)입니다. `null`일 수 있으며, `null`은 데이터 업데이트 시간을 알 수 없어 오래된 것으로 처리해야 함을 의미합니다. 블록 기반 엔드포인트는 항상 값을 반환합니다.
* 또한 `chain`, `chain_slug`, `chain_external_id`를 반복합니다.

일반적인 패턴: 첫 번째 응답에서 `meta.as_of_block`을 읽어 최신 인덱싱된 블록까지 조회하고, 확인 상태를 표시하려면 `meta.safe_block` / `meta.finalized_block`을 확인하세요.

## 1회 페이지 로드에 대한 CU 추정

모든 메서드는 플랫폼 플랜 API에서 읽은 CU 가중치에 따라 과금됩니다:

**호출당 CU 가중치**

| 메서드 | 호출당 CU |
| --- | --- |
| `data.address_balances` | 25 |
| `data.address_transfers` | 25 |
| `data.tokens_batch` | 10 |

**1회 페이지 로드(예상)**

잔액 요청 1회 + 전송 3페이지 + `tokens:batch` 요청 1회, 총 5회 호출로 약 110 CU입니다. 실제 사용량은 페이지 수와 토큰 수에 따라 달라집니다.

과금 결정 및 비과금 오류 응답에 대해서는 [과금 규칙](https://docs.blockvectra.com/en/guides/billing-rules/)을 참조하세요. 인덱싱된 전송 내역이 아닌 가장 최근 블록의 로그가 필요한 경우, `eth_getLogs`로 전환할지 결정하기 전에 먼저 [최신 노드 데이터 vs 인덱싱된 이력](https://docs.blockvectra.com/en/guides/logs-vs-transfers/)을 확인하세요.

## 다음 단계

* [데이터셋 디렉터리 살펴보기](https://blockvectra.com/en/data/): BlockVectra가 인덱싱하는 모든 데이터셋을 확인하세요.
* [무료 플랜 및 요금 확인](https://blockvectra.com/en/pricing/#free): 계정에 포함된 혜택을 확인하세요.
* [콘솔에 로그인](https://console.blockvectra.com/login/?next=%2Fkeys%2F): API key를 생성하세요.
