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

Trate limites de taxa de RPC e respostas 429 na HyperEVM, consulte eth_getLogs autenticado em intervalos delimitados, salve um cursor e recupere atividades perdidas.

Resposta direta

O RPC público oficial padrão da HyperEVM permite 50 blocos por consulta eth_getLogs (fonte: documentação 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), 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); 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 e nos parâmetros de serviço abaixo.

Tarefas que este guia ajuda você a realizar

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

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. Os public.methods do endpoint público não incluem eth_getLogs; o passo 3 exige uma chave.

2. Criar uma API key

Crie uma chave para esta recuperação. 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 guia de cadastro programático. 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.

3. Recuperar logs com sua chave

Modelo inicial completo: 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.

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.

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:

CampoSignificado
addressContrato que emitiu o evento.
blockNumber, blockHashBloco contendo o log; o número é hexadecimal.
transactionHash, transactionIndex, logIndexPosição da transação e do log; os índices são hexadecimais.
topics, dataArgumentos indexados do evento e argumentos não indexados codificados em ABI; decodifique com a ABI do contrato.
removedIndica 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. 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 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. 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 / EndpointValor / ModeloAutenticaçã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_mainnetCabeçalho x-api-key: {api_key}
Base da Data APIGET https://api.blockvectra.com/v1/data/hyperevm_mainnet/…Cabeçalho x-api-key: {api_key}
Status públicoGET https://api.blockvectra.com/v1/statusSem 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. 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.

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.

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.

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.

: "${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. 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 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 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 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 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, 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 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.

Limites de taxa do RPC público oficial e 429

A documentação oficial de limites de taxa 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 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 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.

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:

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

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"

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.

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.

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.

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

Próximos passos

Última atualização:

Nesta página