# Limites de taxa de RPC da HyperEVM e recuperação de logs

> Source: https://docs.blockvectra.com/pt-br/guides/hyperevm-backfill/

## Resposta direta

O RPC público oficial padrão da HyperEVM permite 50 blocos por consulta `eth_getLogs` (fonte: [documentação JSON-RPC](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/hyperevm/json-rpc) oficial da Hyperliquid). Na BlockVectra, requisições autenticadas de `eth_getLogs` cobrem até 1,000 blocos por consulta (`hyperevm_mainnet.max_logs_block_range` de [GET /v1/chains](https://api.blockvectra.com/v1/chains)), incluindo ambos os extremos. Um intervalo maior retorna HTTP 200, JSON-RPC `-32602` e `logs_range_too_large`, com `retryable: false` (consulte o [catálogo de erros](https://docs.blockvectra.com/en/errors/#logs_range_too_large)); divida em `[from, min(from + max − 1, end)]`, salve seu cursor e avance para o fim mais um após o sucesso para retomar as execuções. O limite de taxa por IP do RPC público oficial e os limites de chave da BlockVectra são descritos separadamente em [Limites de taxa do RPC público oficial e 429](#official-public-rpc-rate-limits-and-429) e nos parâmetros de serviço abaixo.

## Tarefas que este guia ajuda você a realizar

* [Testar o RPC da HyperEVM](#connect-with-viem-or-ethers) com uma leitura pública usando viem ou ethers antes de selecionar métodos autenticados.
* [Recuperar uma janela delimitada de logs](#three-step-task-backfill-a-bounded-hyperevm-log-window) dentro do limite de `eth_getLogs` da HyperEVM, com decisões de nova tentativa baseadas no erro retornado.
* [Ler a atividade do endereço](#using-data-api-endpoints-instead-of-extensive-getlogs-scanning) por meio de transações e transferências indexadas com uma chave, verificando a cobertura retornada e os metadados de atualização.

<span id="bounded-log-backfill-task" />

## Tarefa em três passos: recuperar uma janela delimitada de logs da HyperEVM

Leia o bloco mais recente sem uma chave, crie uma chave e, em seguida, recupere logs de eventos de um contrato ao longo de uma janela finita de blocos.

Escolha o contrato e a janela de blocos necessários. Esta tarefa cobre essa janela delimitada; ela não garante o histórico completo do contrato.

### 1. Ler o bloco mais recente sem uma API key

```bash
curl -sS "https://api.blockvectra.com/v1/hyperevm_mainnet/public" \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}'
```

O `result` do JSON-RPC é o número do bloco mais recente em hexadecimal. Esta é a `public.url` da HyperEVM publicada por [GET /v1/chains](https://api.blockvectra.com/v1/chains). Os `public.methods` do endpoint público não incluem `eth_getLogs`; o passo 3 exige uma chave.

### 2. Criar uma API key

<div data-attribution-ref="docs-hyperevm-task">
  [Crie uma chave para esta recuperação](https://console.blockvectra.com/login/?next=%2Fkeys%2F). Crie uma chave e salve o segredo exibido na caixa de diálogo para uso com `hyperevm_mainnet`.

  Para um agente de IA usando HTTP sem navegador, siga o <a href="/en/guides/programmatic-signup/">guia de cadastro programático</a>. Passe a `ref` válida da URL do guia no corpo JSON de `POST /auth/siwe/login` em vez de `docs-signup` do exemplo; omita-a se indisponível. Não peça ao usuário para colar a chave no chat.
</div>

### 3. Recuperar logs com sua chave

Modelo inicial completo: [blockvectra/hyperevm-backfill](https://github.com/blockvectra/hyperevm-backfill)

Salve o seguinte script como `hyperevm-task.ts`. Ele é executado com Node.js 24 ou superior, sem pacotes adicionais. Defina `BLOCKVECTRA_API_KEY` com sua chave salva e `LOG_ADDRESS` com o endereço do contrato emissor que deseja inspecionar; mantenha a chave em seu servidor ou em um terminal local.

```bash
export BLOCKVECTRA_API_KEY='replace-with-your-key'
export LOG_ADDRESS='replace-with-contract-address'
node hyperevm-task.ts
```

Por padrão, o script recupera os `max_logs_block_range` blocos mais recentes, ou menos próximo ao bloco de gênese. Ele lê esse limite de `/v1/chains` em tempo de execução. Para selecionar outra janela finita, defina `FROM_BLOCK` e `TO_BLOCK` com números de blocos decimais ou hexadecimais com prefixo `0x` antes de executar. Janelas maiores são divididas em partes consecutivas, cada uma com no máximo o limite publicado.

```ts
const apiKey = process.env.BLOCKVECTRA_API_KEY;
const address = process.env.LOG_ADDRESS;
if (!apiKey || apiKey === "replace-with-your-key") throw new Error("Set BLOCKVECTRA_API_KEY");
if (!address || !/^0x[0-9a-f]{40}$/i.test(address)) throw new Error("Set LOG_ADDRESS to a contract address");

const fromBlock = process.env.FROM_BLOCK;
const toBlock = process.env.TO_BLOCK;
if ((fromBlock !== undefined || toBlock !== undefined) && (!fromBlock || !toBlock)) {
  throw new Error("Set both FROM_BLOCK and TO_BLOCK");
}

const chainsUrl = "https://api.blockvectra.com/v1/chains";
const rpcUrl = new URL("./hyperevm_mainnet", chainsUrl).href;
async function readJson(url: string) {
  const response = await fetch(url, { signal: AbortSignal.timeout(15_000) });
  if (!response.ok) throw new Error(`Metadata HTTP ${response.status}`);
  return response.json();
}
const catalog = await readJson(chainsUrl);
const chain = catalog.chains.find((item: { chain: string }) => item.chain === "hyperevm_mainnet");
if (!chain || !Number.isSafeInteger(chain.max_logs_block_range) || chain.max_logs_block_range <= 0) {
  throw new Error("Missing or invalid max_logs_block_range");
}
if (!chain.methods.allow.includes("eth_getLogs") || chain.methods.deny.includes("eth_getLogs")) {
  throw new Error("eth_getLogs is unavailable on this chain");
}
const maxRange = BigInt(chain.max_logs_block_range);
const plans = await readJson("https://console-api.blockvectra.com/v1/plans");
function weight(method: string): bigint {
  const row = plans.method_weights.find((item: { method: string }) => item.method === method);
  if (!row || !Number.isSafeInteger(row.cu_weight) || row.cu_weight <= 0) {
    throw new Error(`Missing or invalid CU weight for ${method}`);
  }
  return BigInt(row.cu_weight);
}
const headWeight = weight("eth_blockNumber");
const logsWeight = weight("eth_getLogs");

type RpcBody = {
  result?: unknown;
  error?: { code: number; data?: { retryable?: boolean } };
};
async function rpc(method: string, params: unknown[]): Promise<unknown> {
  for (let attempt = 0; attempt < 4; attempt++) {
    const response = await fetch(rpcUrl, {
      method: "POST",
      redirect: "error",
      headers: { "Content-Type": "application/json", "x-api-key": apiKey! },
      body: JSON.stringify({ jsonrpc: "2.0", id: 1, method, params }),
      signal: AbortSignal.timeout(15_000),
    });
    const body = await response.json() as RpcBody;
    if (response.ok && !body.error && body.result !== undefined) return body.result;
    if (body.error?.data?.retryable !== true || attempt === 3) {
      throw new Error(`RPC failed: HTTP ${response.status}, code ${body.error?.code ?? "unknown"}`);
    }
    const retryAfter = response.headers.get("Retry-After");
    const delay = retryAfter === null ? 0 : /^\d+$/.test(retryAfter)
      ? Number(retryAfter) * 1000 : Date.parse(retryAfter) - Date.now();
    if (delay > 30_000) throw new Error("Retry-After exceeds 30 seconds; rerun later");
    const backoff = 1000 * 2 ** attempt + Math.random() * 250;
    await new Promise((resolve) => setTimeout(resolve, Math.max(backoff, Number.isFinite(delay) ? delay : 0)));
  }
  throw new Error("Retry limit reached");
}
function block(value: string): bigint {
  if (!/^(0x[0-9a-f]+|[0-9]+)$/i.test(value)) throw new Error("Invalid block number");
  return BigInt(value);
}
const head = await rpc("eth_blockNumber", []);
if (typeof head !== "string" || !/^0x[0-9a-f]+$/i.test(head)) throw new Error("Invalid chain head");
const latest = block(head);
const end = toBlock ? block(toBlock) : latest;
const start = fromBlock ? block(fromBlock)
  : end >= maxRange - 1n ? end - maxRange + 1n : 0n;
if (start > end || end > latest) throw new Error("Require 0 <= FROM_BLOCK <= TO_BLOCK <= latest");
const chunks = (end - start + maxRange) / maxRange;
console.error(`Window ${start}..${end}; chunks=${chunks}; estimated CU=${headWeight + chunks * logsWeight}`);

const hex = (value: bigint) => `0x${value.toString(16)}`;
for (let from = start; from <= end; from += maxRange) {
  const to = from + maxRange - 1n < end ? from + maxRange - 1n : end;
  const result = await rpc("eth_getLogs", [{ address, fromBlock: hex(from), toBlock: hex(to) }]);
  if (!Array.isArray(result)) throw new Error("Expected eth_getLogs result array");
  console.log(JSON.stringify({ fromBlock: hex(from), toBlock: hex(to), result }));
}
```

As requisições são executadas sequencialmente. Um erro JSON-RPC é repetido somente quando `error.data.retryable` for `true`, com no máximo quatro tentativas por requisição, recuo exponencial com jitter e suporte a segundos ou data HTTP em `Retry-After`. Uma espera superior a 30 segundos interrompe o script para que você possa executá-lo novamente mais tarde. Falhas de rede, tempos limites esgotados, respostas malformadas e erros não repetíveis interrompem imediatamente; o script encerra com erro em vez de relatar uma recuperação concluída.

Cada linha da saída padrão contém o `fromBlock`, `toBlock` e o array `result` de uma parte. `result: []` significa que não há logs correspondentes nessa parte. Leia estes campos em cada log:

| Campo                                             | Significado                                                                                                      |
| ------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| `address`                                         | Contrato que emitiu o evento.                                                                                    |
| `blockNumber`, `blockHash`                        | Bloco contendo o log; o número é hexadecimal.                                                                    |
| `transactionHash`, `transactionIndex`, `logIndex` | Posição da transação e do log; os índices são hexadecimais.                                                      |
| `topics`, `data`                                  | Argumentos indexados do evento e argumentos não indexados codificados em ABI; decodifique com a ABI do contrato. |
| `removed`                                         | Indica se o log foi removido por uma reorganização de cadeia.                                                    |

O bloco mais recente não é um marcador de finalidade. Se você precisar de uma janela histórica estável, escolha um `TO_BLOCK` confirmado da sua aplicação e trate reorganizações de cadeia.

Para uma janela de `B = TO_BLOCK − FROM_BLOCK + 1` blocos e um limite publicado `L`, a quantidade de partes é `N = ceil(B / L)`. Leia `method_weights[].cu_weight` para `eth_getLogs` e `eth_blockNumber` em [GET /v1/plans](https://console-api.blockvectra.com/v1/plans). O script imprime uma estimativa na saída de erro padrão: `N × weight(eth_getLogs) + weight(eth_blockNumber)`, incluindo sua consulta autenticada do bloco mais recente. Isso exclui chamadas extras e quaisquer novas tentativas tarifáveis; consulte as [regras de faturamento](https://docs.blockvectra.com/en/guides/billing-rules/) para a liquidação. O consumo de CU depende das chamadas, e não do número de logs retornados.

**Entrega de eventos:** Use o polling HTTP em partes abaixo, ou envie eventos de endereços monitorados para um receptor HTTPS com [envio de webhook](https://docs.blockvectra.com/en/guides/webhook-push/). **GET /v1/push/chains lista as redes suportadas** e as configurações de confirmação; autentique com `x-api-key`. Assinaturas de webhook, desduplicação e repetição são abordadas nesse guia. O envio de webhook é separado das inscrições via WebSocket (`ws` e `subscriptions` em `/v1/chains`).

## Conectar-se com viem ou ethers

| Parâmetro / Endpoint | Valor / Modelo | Autenticação |
|---|---|---|
| Chain ID (EIP-155) | `999` | — |
| JSON-RPC (chave no caminho) | `POST https://api.blockvectra.com/v1/hyperevm_mainnet/{api_key}` | API key no caminho da URL |
| JSON-RPC (chave no cabeçalho) | `POST https://api.blockvectra.com/v1/hyperevm_mainnet` | Cabeçalho x-api-key: {api_key} |
| Base da Data API | `GET https://api.blockvectra.com/v1/data/hyperevm_mainnet/…` | Cabeçalho x-api-key: {api_key} |
| Status público | `GET https://api.blockvectra.com/v1/status` | Sem autenticação (público) |

Desenvolvedores e agentes de IA podem usar as mesmas configurações no servidor. Utilize Node.js 24 ou superior, viem 2 ou ethers 6 e comece com leituras públicas. Configure `BLOCKVECTRA_API_KEY` de forma segura no ambiente para métodos autenticados. Mantenha chaves e URLs RPC contendo chaves fora do código do navegador, de logs e de sistemas de controle de versão.

Salve este arquivo como `network.mjs`. Ele lê `chain_id` e a política de métodos a partir de [GET /v1/chains](https://api.blockvectra.com/v1/chains). Para leituras sem chave, use a `public.url` do catálogo e apenas os métodos listados em `public.methods`; a disponibilidade HTTP pública não implica acesso via WebSocket.

```js
const chainSlug = process.env.BLOCKVECTRA_CHAIN ?? 'hyperevm_mainnet';
const key = process.env.BLOCKVECTRA_API_KEY;
const catalogUrl = 'https://api.blockvectra.com/v1/chains';
const response = await fetch(catalogUrl, { signal: AbortSignal.timeout(15_000) });
if (!response.ok) throw new Error(`Chains HTTP ${response.status}`);
const catalog = await response.json();
export const chainInfo = catalog.chains.find(item => item.chain === chainSlug);
if (!chainInfo || !Number.isSafeInteger(chainInfo.chain_id) || chainInfo.chain_id <= 0) {
  throw new Error('Missing chain or chain_id');
}
export function allows(method) {
  const matches = pattern => pattern.endsWith('*')
    ? method.startsWith(pattern.slice(0, -1)) : pattern === method;
  if (!key) return (chainInfo.public?.methods ?? []).some(matches);
  return (chainInfo.methods?.allow ?? []).some(matches)
    && !(chainInfo.methods?.deny ?? []).some(matches);
}
if (!allows('eth_chainId')) throw new Error('eth_chainId is unavailable');
export const rpcUrl = key
  ? new URL(`./${chainSlug}/${encodeURIComponent(key)}`, catalogUrl).href
  : chainInfo.public?.url;
if (!rpcUrl) throw new Error('Public RPC is unavailable; set BLOCKVECTRA_API_KEY');
```

Salve como `viem-client.mjs`, instale com `npm install viem@2` e execute `node viem-client.mjs`.

```js
import { createPublicClient, defineChain, http } from 'viem';
import { chainInfo, rpcUrl } from './network.mjs';

export const chain = defineChain({
  id: chainInfo.chain_id,
  name: chainInfo.name,
  nativeCurrency: { name: 'HYPE', symbol: 'HYPE', decimals: 18 },
  rpcUrls: { default: { http: [rpcUrl] } },
});
export const client = createPublicClient({ chain, transport: http(rpcUrl) });
if (await client.getChainId() !== chain.id) throw new Error('RPC chain ID mismatch');
console.error(await client.getBlockNumber());
```

Para o ethers, salve como `ethers-client.mjs`, instale com `npm install ethers@6` e execute `node ethers-client.mjs`.

```js
import { JsonRpcProvider } from 'ethers';
import { chainInfo, rpcUrl } from './network.mjs';

const provider = new JsonRpcProvider(rpcUrl, chainInfo.chain_id, { batchMaxCount: 1 });
const network = await provider.getNetwork();
if (network.chainId !== BigInt(chainInfo.chain_id)) throw new Error('RPC chain ID mismatch');
console.log(await provider.getBlockNumber());
provider.destroy();
```

## Fazer deploy com Foundry ou Hardhat

O catálogo atual de `hyperevm_mainnet` possui `ws=false` e não lista `eth_sendRawTransaction` em `methods.allow`. Use a BlockVectra para leituras; o deploy requer um RPC com suporte a transmissão (broadcasting). Defina `DEPLOY_RPC_URL` com a URL HTTP autenticada desse provedor. Não presuma que ele compartilhe a política de métodos ou os limites de intervalo de logs da BlockVectra. Verifique o chain ID selecionado antes de assinar.

```bash
: "${DEPLOY_RPC_URL:?Set a broadcasting RPC URL}"
export RPC_URL="$DEPLOY_RPC_URL"
export CHAIN_ID="$(node --input-type=module -e "import { chainInfo } from './network.mjs'; console.log(chainInfo.chain_id)")"
```

Continue com o [tutorial compartilhado de deploy com Foundry ou Hardhat](https://docs.blockvectra.com/en/guides/deploy-contract/). Financie a conta de deploy com HYPE EVM e revise os requisitos de bloco duplo abaixo antes de um deploy grande.

## HYPE, blocos pequenos e deploys grandes

O [guia oficial de rede da HyperEVM](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/hyperevm) identifica o HYPE como gas, com 18 decimais (acessado em: 07/10/2026). Certifique-se de que a conta de deploy possua HYPE na HyperEVM; o saldo na HyperCore isoladamente não é o saldo de gas EVM. Siga as instruções de transferência nativa vinculadas ao mover fundos.

O [guia de arquitetura de blocos duplos](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/hyperevm/dual-block-architecture) descreve blocos pequenos rápidos e blocos grandes mais lentos para transações maiores (acessado em: 07/10/2026). Estime o gas do deploy primeiro. Para deploys que excedam o limite de blocos pequenos, a conta de deploy deve ser de um usuário existente da HyperCore e assinar a ação Core `{"type":"evmUserModify","usingBigBlocks":true}`; definir apenas um limite de gas maior para a transação não seleciona blocos grandes. Restaure `usingBigBlocks=false` depois para retornar aos blocos pequenos.

Em um provedor que ofereça suporte, use `eth_usingBigBlocks` para verificar o modo do endereço e `eth_bigBlockGasPrice` para a taxa base de blocos grandes. A [referência oficial de JSON-RPC](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/hyperevm/json-rpc) documenta esses métodos (acessado em: 07/10/2026). Verifique os métodos do provedor escolhido; use `/v1/chains` para a BlockVectra. O deploy mínimo acima tem como alvo um contrato pequeno e não altera o modo de conta Core.

## Dados de HyperCore e HyperEVM

O RPC EVM atende a contratos, recibos e logs. Dados de negociação e ações na HyperCore utilizam a API Core. Contratos podem ler o estado da Core por meio de pré-compilações e enviar ações pelo CoreWriter; utilize o [guia oficial de interação](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/hyperevm/interacting-with-hypercore) ao integrar esses fluxos (acessado em: 07/10/2026). Logs EVM não substituem consultas ao livro de ofertas ou posições da Core.

As transações de sistema da HyperEVM (como transferências da HyperCore para a HyperEVM) não estão incluídas nas respostas padrão de `eth_getBlockByNumber` e são fornecidas separadamente pelo RPC oficial por meio de `eth_getSystemTxsByBlockNumber` e `eth_getSystemTxsByBlockHash` (consulte a [documentação oficial de JSON-RPC](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/hyperevm/json-rpc), acessado em: 07/10/2026). Atualmente, os dados de blocos, transações e Data API da HyperEVM na BlockVectra não incluem transações de sistema; utilize esses dois métodos RPC oficiais diretamente quando precisar de dados de transações de sistema.

## Tratar o erro oficial 10055

O [guia oficial da HyperEVM](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/hyperevm) define `10055` como um erro de fronteira entre Core e EVM, incluindo falhas de nonce, saldo insuficiente, hash duplicado e taxa de substituição abaixo do exigido (acessado em: 07/10/2026). Inspecione a mensagem do RPC de transmissão antes de decidir como recuperar:

* **Nonce:** compare `eth_getTransactionCount` com suas transações pendentes; serialize os envios a partir de uma conta de deploy e reconcilie seu próximo nonce.
* **Saldo:** verifique o saldo de HYPE EVM da conta de deploy em relação ao valor transferido mais o custo de gas.
* **Hash duplicado:** consulte a transação existente e seu recibo antes de enviar outra transação.
* **Taxa de substituição:** verifique o nonce e a taxa existentes e, em seguida, utilize a política de substituição do transmissor; repetir os mesmos bytes não aumenta a taxa.

O código `10055` por si só não justifica repetições cegas. Leia os erros e suas orientações de recuperação separadamente na [referência de erros da BlockVectra](https://docs.blockvectra.com/en/errors/).

## Limites de taxa do RPC público oficial e 429

A [documentação oficial de limites de taxa](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/rate-limits-and-user-limits) da Hyperliquid especifica no máximo 100 requisições JSON-RPC EVM por minuto por IP para `rpc.hyperliquid.xyz/evm`. Sua [documentação JSON-RPC](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/hyperevm/json-rpc) também limita `eth_getLogs` a 50 blocos por consulta e até 4 topics. Acessado em: 07/10/2026.

Ao receber HTTP 429, pause as requisições e respeite primeiro o cabeçalho `Retry-After` (segundos ou uma data HTTP). Se estiver ausente, use recuo exponencial com jitter e um número limitado de tentativas, repetindo a mesma parte inacabada. Reduza a simultaneidade e a frequência de polling e divida as consultas de logs em partes dentro do limite do endpoint. O fracionamento por si só não elimina limites de taxa; clientes que compartilham um IP precisam coordenar sua taxa de requisições.

Para o endpoint autenticado da BlockVectra, leia `max_logs_block_range`, `methods.allow` e `methods.deny` de `hyperevm_mainnet` em [GET /v1/chains](https://api.blockvectra.com/v1/chains) em vez de aplicar o intervalo de blocos ou o limite de requisições por minuto do RPC público oficial. A taxa de requisições está sujeita separadamente a `cu_per_sec`, `burst_cu` da chave e ao limite de chamadas do plano gratuito (consulte a próxima seção). Em caso de 429, inspecione `error.data.reason` e `retryable`; `request_exceeds_burst` exige requisições menores em vez de repetições idênticas com recuo.

## Parâmetros e regras de serviço da BlockVectra

A BlockVectra atende à mainnet da HyperEVM por meio de endpoints JSON-RPC e REST Data API:

1. **Parâmetros da rede e limites de logs**:
   A partir de `GET /v1/chains` para `hyperevm_mainnet`:
   * **Identificador da rede (Slug)**: `hyperevm_mainnet`, Chain ID `999`.
   * **`max_logs_block_range`**: Regido pelo campo `max_logs_block_range` de `GET /v1/chains`. Uma única requisição `eth_getLogs` pode abranger no máximo esse número de blocos (`toBlock − fromBlock + 1`). Ultrapassar esse intervalo retorna HTTP 200 com código de erro JSON-RPC `-32602` (`eth_getLogs block range too large: max <N> blocks`), que não é tarifado.
   * **`state_window_blocks`**: Regido pelo campo `state_window_blocks` de `GET /v1/chains`. Chamadas de leitura de estado (como `eth_call` e `eth_getBalance`) estão sujeitas à janela de retenção declarada por esse campo (quando `null`, o estado completo é retido sem limite de janela deslizante).
   * **Política de métodos**: Regida por `methods.allow` e `methods.deny`. Métodos EVM padrão (`eth_blockNumber`, `eth_getLogs`, `eth_call`, `eth_getBalance`, `eth_getBlockByNumber`, `eth_getTransactionReceipt`, etc.) são permitidos; métodos de filtro e inscrição (`eth_subscribe`, `eth_unsubscribe`, `eth_newFilter`, `eth_newBlockFilter`) são negados, retornando `-32601` (não tarifado).
2. **Limites de taxa do plano gratuito e upgrade**:
   A partir de `GET /v1/plans`:
   * **`free.max_calls_per_sec`**: até 25 chamadas por segundo, compartilhadas entre todas as chaves da conta, todas as redes e a Data API.
   * **Limites padrão de chave**: Cada API key possui um balde de CU (taxa de recarga `cu_per_sec`, capacidade de pico `burst_cu` — os padrões são 400 CU/s e burst de 1,600 CU). Os métodos são tarifados por pesos de Unidades de Computação (CU).
   * **Aumentar limites**: Após a recarga, o limite de chamadas por segundo em toda a conta é removido; cada chave continua sujeita aos limites de taxa e pico de Unidades de Computação (CU). Para as tarifas e unidades de cobrança atuais, consulte a [página de preços](https://blockvectra.com/en/pricing/).

## Recuperação de logs históricos: eth\_getLogs em partes e lógica de novas tentativas

Ao consultar logs históricos, intervalos amplos devem ser divididos em partes contíguas delimitadas pelo `max_logs_block_range` da rede de destino. As estratégias de novas tentativas do cliente devem inspecionar o campo `retryable` nas respostas de erro.

### Avaliação de retryable em respostas de erro

Na BlockVectra, os objetos de erro JSON-RPC incluem um payload `error.data` contendo `reason`, `docs_url` e `retryable` (booleano):

* **`retryable: true`**: Condições transitórias, incluindo sobrecarga do serviço (`overloaded`), limite de chamadas por segundo do plano gratuito (`free_plan_call_limit`), sincronização do nó (`node_syncing`) ou indisponibilidade a montante (`upstream_unavailable`). Os clientes devem respeitar o cabeçalho `Retry-After` quando presente ou aplicar recuo exponencial com jitter.
* **`retryable: false`**: Erros não transitórios, como intervalo de blocos que excede os limites (`-32602` / `logs_range_too_large`), parâmetros inválidos (`invalid_params`), API key ausente (`missing_api_key`) ou requisição que excede a capacidade de pico (`-32022` / `request_exceeds_burst`). Repetir sem ajustar os parâmetros não terá sucesso.

Abaixo está a resposta retornada quando uma API key é omitida:

```json
{
  "jsonrpc": "2.0",
  "id": null,
  "error": {
    "code": -32024,
    "message": "missing API key: send it in the request path (/v1/{chain}/<api_key>) or in the x-api-key header",
    "data": {
      "reason": "missing_api_key",
      "docs_url": "https://docs.blockvectra.com/en/errors/#missing_api_key",
      "retryable": false
    }
  }
}
```

## Usar endpoints da Data API em vez de varreduras extensas com getLogs

Quando uma aplicação monitora o histórico de transações ou movimentações de tokens para um endereço específico, fazer varreduras via `eth_getLogs` exige a emissão de consultas sequenciais em partes delimitadas por `max_logs_block_range` e a análise de logs brutos do evento Transfer.

A BlockVectra Data API fornece endpoints REST pré-indexados para `hyperevm_mainnet`, suportando janelas de até 100.000 blocos com paginação baseada em cursor:

1. **Transações de endereços**: `GET /v1/data/hyperevm_mainnet/addresses/{address}/transactions`
   * Parâmetros: `from_block` (obrigatório), `to_block` (obrigatório), `direction` (opcional: `from`, `to`, `any`, padrão `any`), `clamp` (string booleana opcional, padrão `false`; quando definido como `true`, janelas que excedam 100.000 blocos ou maiores que `as_of_block` são truncadas em vez de retornar 409), `limit` (opcional, máx 500), `cursor` (token de paginação).
2. **Transferências de tokens de endereços**: `GET /v1/data/hyperevm_mainnet/addresses/{address}/transfers`
   * Parâmetros: `standard` (obrigatório: `erc20` ou `erc721`; `erc1155` não pode ser consultado por endereço e retorna `422 no_coverage`), `token` (filtro opcional por contrato de token), `from_block` (obrigatório), `to_block` (obrigatório), `direction` (opcional: `in`, `out`, `any`), `clamp` (opcional), `limit`, `cursor`.

### Estrutura de resposta

As respostas usam esquemas de envelope padrão:

* `data`: Array de registros. As transações incluem `hash`, `block_number`, `block_timestamp`, `from`, `to`, `value`, `tx_index`, `gas_limit`, `gas_used` e `status`. As transferências incluem `token`, `standard`, `from`, `to`, `block_number`, `block_timestamp`, `tx_hash`, `tx_index` e `log_index` (`amount` para ERC-20, `token_id` para ERC-721).
* `next_cursor`: Token opaco de paginação retornado quando existem registros subsequentes (ausente na página final, não `null`).
* `meta`: Metadados contendo `chain`, `chain_slug`, `chain_external_id`, `as_of_block`, `safe_block`, `finalized_block`, `coverage` (`full` ou `partial`) e `refreshed_at`.

### Exemplo de código: consultas à Data API

**cURL**

```bash
export BLOCKVECTRA_API_KEY="rgw_your_api_key"

# 1. Query address transaction history (clamp=true prevents 409 errors)
curl -s "https://api.blockvectra.com/v1/data/hyperevm_mainnet/addresses/0x2222222222222222222222222222222222222222/transactions?from_block=0&to_block=50000&clamp=true" \
  -H "x-api-key: $BLOCKVECTRA_API_KEY"

# 2. Query address ERC-20 token transfers
curl -s "https://api.blockvectra.com/v1/data/hyperevm_mainnet/addresses/0x2222222222222222222222222222222222222222/transfers?standard=erc20&from_block=0&to_block=50000&clamp=true" \
  -H "x-api-key: $BLOCKVECTRA_API_KEY"
```


  **TypeScript**

```ts
const apiKey = process.env.BLOCKVECTRA_API_KEY!;
const targetAddress = "0x2222222222222222222222222222222222222222";

let cursor: string | undefined;

do {
  const url = new URL(
    `https://api.blockvectra.com/v1/data/hyperevm_mainnet/addresses/${targetAddress}/transfers`,
  );
  url.searchParams.set("standard", "erc20");
  url.searchParams.set("from_block", "0");
  url.searchParams.set("to_block", "50000");
  url.searchParams.set("clamp", "true");
  if (cursor) {
    url.searchParams.set("cursor", cursor);
  }

  const res = await fetch(url, {
    headers: { "x-api-key": apiKey },
  });

  if (!res.ok) {
    throw new Error(`Data API HTTP ${res.status}`);
  }

  const body = (await res.json()) as {
    data: unknown[];
    next_cursor?: string;
  };

  console.log(`Fetched ${body.data.length} transfers`);
  cursor = body.next_cursor; // Loop terminates when cursor is absent
} while (cursor);
```


## Monitoramento em tempo real: polling de novos blocos

Para um transporte HTTP, acompanhe blocos por meio de polling e busque logs de eventos em partes consecutivas dentro de `max_logs_block_range`. Selecione WebSocket apenas quando `/v1/chains` informar `ws=true` e a entrada necessária em `subscriptions`. Para entrega em um receptor HTTPS, use [envio de webhook](https://docs.blockvectra.com/en/guides/webhook-push/).

Para exercitar o contrato `Hello` implantado, defina `LOG_ADDRESS` com o seu endereço. Envie `ping()` por meio do RPC de transmissão e, em seguida, recupere o bloco do recibo com o script de recuperação desta página. Continue a partir da última parte concluída para novos eventos.

```bash
cast send "$CONTRACT_ADDRESS" "ping()" --rpc-url "$DEPLOY_RPC_URL" \
  --private-key "$DEPLOYER_PRIVATE_KEY"
```

### Fluxo de polling

1. Realize chamadas periódicas leves a `eth_blockNumber` para inspecionar o bloco mais recente da cadeia.
2. Compare o número do bloco retornado com o `lastSeenBlock` processado anteriormente.
3. Se `currentBlock > lastSeenBlock`, divida `[lastSeenBlock + 1, currentBlock]` em partes de no máximo `max_logs_block_range`. Persista `lastSeenBlock` somente após processar com sucesso cada parte; em caso de falha, repita a parte inacabada. Elimine duplicatas por `(blockHash, transactionHash, logIndex)` e repita uma sobreposição após reconectar para reconciliar reorganizações.
4. `watchBlockNumber` ou `watchBlocks` do viem implementa nativamente o polling HTTP em transportes HTTP, permitindo a personalização por meio do parâmetro `pollingInterval` (como 1000 ms).

### Fazer polling de logs de eventos em partes delimitadas

Salve como `poll-logs.mjs` ao lado de `network.mjs` e `viem-client.mjs`. Defina `BLOCKVECTRA_API_KEY`, `LOG_ADDRESS` e `FROM_BLOCK`, e execute `node poll-logs.mjs`. Este exemplo finito consulta o bloco mais recente 12 vezes, com intervalos de cinco segundos, e consulta cada novo intervalo em partes sequenciais. Um erro interrompe o script antes de avançar a parte que falhou.

```js
import { isAddress } from 'viem';
import { client } from './viem-client.mjs';
import { chainInfo, allows } from './network.mjs';

const address = process.env.LOG_ADDRESS;
const start = process.env.FROM_BLOCK;
if (!address || !isAddress(address)) throw new Error('Set LOG_ADDRESS');
if (!/^(0x[0-9a-f]+|[0-9]+)$/i.test(start ?? '')) throw new Error('Set FROM_BLOCK');
if (!allows('eth_getLogs')) throw new Error('eth_getLogs requires an available keyed endpoint');
if (!Number.isSafeInteger(chainInfo.max_logs_block_range) || chainInfo.max_logs_block_range <= 0) {
  throw new Error('Invalid max_logs_block_range');
}
const max = BigInt(chainInfo.max_logs_block_range);
let from = BigInt(start);
for (let poll = 0; poll < 12; poll++) {
  const head = await client.getBlockNumber();
  while (from <= head) {
    const to = from + max - 1n < head ? from + max - 1n : head;
    const logs = await client.getLogs({ address, fromBlock: from, toBlock: to });
    console.log(JSON.stringify({ from: from.toString(), to: to.toString(), logs },
      (_, value) => typeof value === 'bigint' ? value.toString() : value));
    from = to + 1n;
  }
  if (poll < 11) await new Promise(resolve => setTimeout(resolve, 5_000));
}
```

Cada saída registra uma parte concluída. Para retomar, defina `FROM_BLOCK` com o seu `to + 1`; consumidores duráveis devem salvar eventos e cursor juntos, eliminar duplicatas e reconciliar reorganizações conforme descrito acima. Para 429 ou outras falhas repetíveis, aplique a orientação de recuo delimitado à mesma parte inacabada.

## Guias relacionados

* Encontre a URL do RPC público, os métodos suportados e os limites atuais na [página da rede HyperEVM](https://blockvectra.com/en/chains/hyperevm_mainnet/).
* Para obter regras completas sobre intervalos de `eth_getLogs` e algoritmos de divisão em partes, consulte [Limites de intervalo de blocos de eth\_getLogs e consultas em partes](https://docs.blockvectra.com/en/guides/getlogs-block-range/).
* Para comparar `eth_getLogs` com as transferências da Data API, compreender os limites de `as_of_block` e os marcadores `safe_block` / `finalized_block`, consulte [eth\_getLogs e transferências indexadas: cobertura e finalidade](https://docs.blockvectra.com/en/guides/logs-vs-transfers/).
* Para detalhes sobre tarifação em CU, erros não tarifados e novas tentativas, consulte [O que não é faturado: códigos de erro e regras de faturamento](https://docs.blockvectra.com/en/guides/billing-rules/).

## Próximos passos

* [Navegue pelo diretório de conjuntos de dados](https://blockvectra.com/en/data/) para ver todos os conjuntos de dados indexados pela BlockVectra.
* [Veja o plano gratuito e os preços](https://blockvectra.com/en/pricing/#free) para verificar o que sua conta inclui.
* [Entre no console](https://console.blockvectra.com/login/?next=%2Fkeys%2F) para criar uma API key.
