# Limites de débit RPC et rétro-remplissage des logs HyperEVM

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

## Réponse directe

Le RPC public officiel HyperEVM par défaut autorise 50 blocs par requête `eth_getLogs` (source : [documentation JSON-RPC](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/hyperevm/json-rpc) officielle d'Hyperliquid). Sur BlockVectra, les requêtes `eth_getLogs` authentifiées couvrent jusqu'à 1,000 blocs par requête (`hyperevm_mainnet.max_logs_block_range` issu de [GET /v1/chains](https://api.blockvectra.com/v1/chains)), en incluant les deux bornes. Une plage plus large renvoie HTTP 200, le code JSON-RPC `-32602` et `logs_range_too_large`, avec `retryable: false` (consultez le [catalogue des erreurs](https://docs.blockvectra.com/fr/errors/#logs_range_too_large)) ; découpez en `[from, min(from + max − 1, end)]`, enregistrez votre curseur et avancez jusqu'à la fin plus un après chaque succès pour reprendre vos exécutions. La limite de débit par IP du RPC public officiel et les limites par clé de BlockVectra sont décrites séparément dans [Limites de débit du RPC public officiel et 429](#official-public-rpc-rate-limits-and-429) et les paramètres de service ci-dessous.

* **Première étape :** [Lire le dernier bloc sans clé API](#1-read-the-latest-block-without-an-api-key) à l'aide de la commande curl ci-dessous.
* **Terminé quand :** Le script de rétro-remplissage affiche `fromBlock`, `toBlock` et un tableau `result` pour chaque segment dans la fenêtre choisie ; un tableau vide signifie qu'aucun log correspondant n'a été trouvé dans ce segment.

[Paramètres de chaîne et options d'accès](https://blockvectra.com/fr/chains/hyperevm_mainnet/).

## Tâches que ce guide vous aide à accomplir

* [Sonder le RPC HyperEVM](#connect-with-viem-or-ethers) avec une lecture publique en utilisant viem ou ethers avant de sélectionner des méthodes authentifiées.
* [Rétro-remplir une fenêtre de logs bornée](#three-step-task-backfill-a-bounded-hyperevm-log-window) dans la limite `eth_getLogs` d'HyperEVM, avec des décisions de nouvelle tentative basées sur l'erreur renvoyée.
* [Lire l'activité d'une adresse](#using-data-api-endpoints-instead-of-extensive-getlogs-scanning) via les transactions et transferts indexés avec une clé, en vérifiant les métadonnées de couverture et de fraîcheur renvoyées.

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

## Tâche en trois étapes : rétro-remplir une fenêtre de logs HyperEVM bornée

Lisez le dernier bloc sans clé, créez une clé, puis récupérez les logs d'événements pour un contrat sur une fenêtre de blocs finie.

Choisissez le contrat et la fenêtre de blocs dont vous avez besoin. Cette tâche couvre cette fenêtre bornée ; elle ne garantit pas l'historique complet du contrat.

### 1. Lire le dernier bloc sans clé API

```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":[]}'
```

Le `result` JSON-RPC est le dernier numéro de bloc en hexadécimal. Il s'agit du `public.url` HyperEVM publié par [GET /v1/chains](https://api.blockvectra.com/v1/chains). La liste `public.methods` de l'endpoint public n'inclut pas `eth_getLogs` ; l'étape 3 nécessite une clé.

### 2. Créer une clé API

<div data-attribution-ref="docs-hyperevm-task">
  [Créer une clé pour ce rétro-remplissage](https://console.blockvectra.com/login/?next=%2Fkeys%2F). Créez une clé et enregistrez le secret affiché dans la boîte de dialogue pour l'utiliser avec `hyperevm_mainnet`.

  Pour un agent IA utilisant HTTP sans navigateur, suivez le <a href="/fr/guides/programmatic-signup/">Guide d'inscription programmatique</a>. Transmettez la valeur `ref` valide de l'URL du guide dans le corps JSON de `POST /auth/siwe/login` au lieu du `docs-signup` de l'exemple ; omettez-la si elle n'est pas disponible. Ne demandez pas à l'utilisateur de coller la clé dans le chat.
</div>

### 3. Rétro-remplir les logs avec votre clé

Modèle de départ complet : [blockvectra/hyperevm-backfill](https://github.com/blockvectra/hyperevm-backfill)

Enregistrez le script suivant sous le nom `hyperevm-task.ts`. Il fonctionne avec Node.js 24 ou une version ultérieure, sans paquets supplémentaires. Définissez `BLOCKVECTRA_API_KEY` avec votre clé enregistrée et `LOG_ADDRESS` avec l'adresse du contrat émetteur que vous souhaitez inspecter ; conservez la clé sur votre serveur ou dans un terminal local.

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

Par défaut, le script récupère les `max_logs_block_range` blocs les plus récents, ou moins près de la genèse. Il lit cette limite depuis `/v1/chains` au moment de l'exécution. Pour sélectionner une autre fenêtre finie, définissez `FROM_BLOCK` et `TO_BLOCK` avec des numéros de bloc décimaux ou hexadécimaux `0x` avant l'exécution. Les fenêtres plus grandes sont divisées en segments consécutifs, chacun au maximum de la limite publiée.

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

Les requêtes s'exécutent de manière séquentielle. Une erreur JSON-RPC n'est réessayée que lorsque `error.data.retryable` est `true`, avec un maximum de quatre tentatives par requête, un recul exponentiel avec gigue (jitter), et la prise en charge de `Retry-After` en secondes ou sous forme de date HTTP. Une attente supérieure à 30 secondes interrompt le script afin que vous puissiez le réexécuter plus tard. Les échecs réseau, les délais d'attente dépassés, les réponses malformées et les erreurs non réessayables provoquent un arrêt immédiat ; le script se termine en échec plutôt que de signaler un rétro-remplissage complet.

Chaque ligne de la sortie standard contient les champs `fromBlock`, `toBlock` et le tableau `result` d'un segment. `result: []` indique qu'aucun log correspondant n'a été trouvé dans ce segment. Lisez ces champs dans chaque log :

| Champ                                             | Signification                                                                                             |
| ------------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
| `address`                                         | Contrat ayant émis l'événement.                                                                           |
| `blockNumber`, `blockHash`                        | Bloc contenant le log ; le numéro est en hexadécimal.                                                     |
| `transactionHash`, `transactionIndex`, `logIndex` | Position de la transaction et du log ; les index sont en hexadécimal.                                     |
| `topics`, `data`                                  | Arguments d'événements indexés et arguments non indexés encodés en ABI ; à décoder avec l'ABI du contrat. |
| `removed`                                         | Indique si le log a été supprimé par une réorganisation de chaîne.                                        |

Le dernier bloc n'est pas un marqueur de finalité. Si vous avez besoin d'une fenêtre historique stable, choisissez un `TO_BLOCK` confirmé pour votre application et gérez les réorganisations de chaîne.

Pour une fenêtre de `B = TO_BLOCK − FROM_BLOCK + 1` blocs et une limite publiée `L`, le nombre de segments est `N = ceil(B / L)`. Lisez `method_weights[].cu_weight` pour `eth_getLogs` et `eth_blockNumber` depuis [GET /v1/plans](https://console-api.blockvectra.com/v1/plans). Le script affiche une estimation sur l'erreur standard : `N × weight(eth_getLogs) + weight(eth_blockNumber)`, y compris sa recherche de tête avec clé. Cela exclut les appels supplémentaires et les nouvelles tentatives facturables ; consultez les [règles de facturation](https://docs.blockvectra.com/fr/guides/billing-rules/) pour le règlement. Les CU dépendent des appels, et non du nombre de logs renvoyés.

**Remise d'événements :** Utilisez la scrutation HTTP par segments ci-dessous, ou envoyez les événements des adresses surveillées vers un récepteur HTTPS avec le [push webhook](https://docs.blockvectra.com/fr/guides/webhook-push/). **GET /v1/push/chains liste les chaînes prises en charge** et les paramètres de confirmation ; authentifiez-vous avec `x-api-key`. Les signatures de webhook, la déduplication et le rejeu sont traités dans ce guide. Le push webhook est distinct des abonnements WebSocket (`ws` et `subscriptions` dans `/v1/chains`).

## Se connecter avec viem ou ethers

| Paramètre / Endpoint | Valeur / Modèle | Authentification |
|---|---|---|
| Chain ID (EIP-155) | `999` | — |
| JSON-RPC (clé dans le chemin) | `POST https://api.blockvectra.com/v1/hyperevm_mainnet/{api_key}` | Clé API dans le chemin d'URL |
| JSON-RPC (clé dans l'en-tête) | `POST https://api.blockvectra.com/v1/hyperevm_mainnet` | En-tête x-api-key: {api_key} |
| Base de la Data API | `GET https://api.blockvectra.com/v1/data/hyperevm_mainnet/…` | En-tête x-api-key: {api_key} |
| Statut public | `GET https://api.blockvectra.com/v1/status` | Non authentifié (public) |

Les développeurs et les agents IA peuvent utiliser les mêmes paramètres côté serveur. Utilisez Node.js 24 ou une version ultérieure, viem 2 ou ethers 6, et commencez par des lectures publiques. Définissez `BLOCKVECTRA_API_KEY` de manière sécurisée dans l'environnement pour les méthodes nécessitant une clé. Gardez les clés et les URL RPC contenant des clés hors du code de navigateur, des logs et du contrôle de version.

Enregistrez ceci sous le nom `network.mjs`. Il lit `chain_id` et la politique des méthodes depuis [GET /v1/chains](https://api.blockvectra.com/v1/chains). Pour les lectures sans clé, utilisez le `public.url` du catalogue et uniquement les méthodes listées dans `public.methods` ; la disponibilité HTTP publique n'implique pas l'accès 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');
```

Enregistrez sous le nom `viem-client.mjs`, installez avec `npm install viem@2`, puis exécutez `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());
```

Pour ethers, enregistrez sous le nom `ethers-client.mjs`, installez avec `npm install ethers@6`, puis exécutez `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();
```

## Déployer avec Foundry ou Hardhat

Le catalogue actuel de `hyperevm_mainnet` indique `ws=false` et ne liste pas `eth_sendRawTransaction` dans `methods.allow`. Utilisez BlockVectra pour les lectures ; le déploiement nécessite un RPC qui prend en charge la diffusion. Définissez `DEPLOY_RPC_URL` sur l'URL HTTP authentifiée de ce fournisseur. Ne supposez pas qu'il partage les limites de méthodes ou de plages de logs de BlockVectra. Vérifiez l'ID de chaîne sélectionné avant de signer.

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

Poursuivez avec le [tutoriel de déploiement partagé Foundry ou Hardhat](https://docs.blockvectra.com/fr/guides/deploy-contract/). Approvisionnez le déployeur en HYPE EVM et examinez les exigences d'architecture à deux blocs ci-dessous avant un déploiement volumineux.

## HYPE, petits blocs et déploiements volumineux

Le [guide officiel du réseau HyperEVM](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/hyperevm) identifie HYPE comme le token de gas, avec 18 décimales (consulté le : 2026-10-07). Assurez-vous que le déployeur détient des HYPE sur HyperEVM ; un solde HyperCore seul ne constitue pas le solde de gas EVM. Suivez les instructions de transfert natif liées lors du déplacement de fonds.

Le [guide de l'architecture à deux blocs](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/hyperevm/dual-block-architecture) décrit des petits blocs rapides et des grands blocs plus lents pour les transactions plus volumineuses (consulté le : 2026-10-07). Estimez d'abord le gas de déploiement. Pour les déploiements dépassant le budget des petits blocs, le déployeur doit être un utilisateur HyperCore existant et signer l'action Core `{"type":"evmUserModify","usingBigBlocks":true}` ; définir une limite de gas de transaction plus élevée seule ne sélectionne pas les grands blocs. Restaurez `usingBigBlocks=false` ensuite pour revenir aux petits blocs.

Sur un fournisseur qui les prend en charge, utilisez `eth_usingBigBlocks` pour vérifier le mode d'adresse et `eth_bigBlockGasPrice` pour les frais de base des grands blocs. La [référence officielle JSON-RPC](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/hyperevm/json-rpc) documente ces méthodes (consulté le : 2026-10-07). Vérifiez les méthodes du fournisseur choisi ; utilisez `/v1/chains` pour BlockVectra. Le déploiement minimal ci-dessus cible un petit contrat et ne modifie pas le mode de compte Core.

## Données HyperCore et HyperEVM

Le RPC EVM sert les contrats, les reçus et les logs. Les données de trading et les actions d'HyperCore utilisent l'API Core. Les contrats peuvent lire l'état de Core via des précompilations et envoyer des actions via CoreWriter ; utilisez le [guide d'interaction officiel](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/hyperevm/interacting-with-hypercore) lors de l'intégration de ces parcours (consulté le : 2026-10-07). Les logs EVM ne remplacent pas les requêtes de carnet d'ordres ou de positions Core.

Les transactions système d'HyperEVM (telles que les transferts d'HyperCore vers HyperEVM) ne sont pas incluses dans les réponses standard de `eth_getBlockByNumber` et sont fournies séparément par le RPC officiel via `eth_getSystemTxsByBlockNumber` et `eth_getSystemTxsByBlockHash` (voir la [documentation JSON-RPC officielle](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/hyperevm/json-rpc), consulté le : 2026-10-07). Les données de blocs, de transactions et de Data API d'HyperEVM de BlockVectra n'incluent actuellement pas les transactions système ; utilisez ces deux méthodes RPC officielles directement lorsque vous avez besoin des données de transactions système.

## Gérer l'erreur officielle 10055

Le [guide officiel d'HyperEVM](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/hyperevm) définit `10055` comme une erreur frontière entre Core et l'EVM, englobant les échecs de nonce, de fonds insuffisants, de hash en double et de remplacement sous-évalué (consulté le : 2026-10-07). Inspectez le message du RPC de diffusion avant de décider de la méthode de récupération :

* **Nonce :** comparez `eth_getTransactionCount` avec vos transactions en attente ; sérialisez les soumissions d'un même déployeur et réconciliez son prochain nonce.
* **Fonds :** vérifiez le solde HYPE EVM du déployeur par rapport à la valeur plus le coût en gas.
* **Hash en double :** recherchez la transaction et le reçu existants avant de soumettre une autre transaction.
* **Frais de remplacement :** vérifiez le nonce et les frais existants, puis appliquez la politique de remplacement du diffuseur ; répéter les mêmes octets n'augmente pas les frais.

Le code `10055` à lui seul ne justifie pas des nouvelles tentatives aveugles. Consultez les erreurs et leurs conseils de récupération séparément dans la [référence des erreurs BlockVectra](https://docs.blockvectra.com/fr/errors/).

## Limites de débit du RPC public officiel et 429

La [documentation officielle sur les limites de débit](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/rate-limits-and-user-limits) d'Hyperliquid spécifie au maximum 100 requêtes JSON-RPC EVM par minute et par IP pour `rpc.hyperliquid.xyz/evm`. Sa [documentation JSON-RPC](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/hyperevm/json-rpc) limite également `eth_getLogs` à 50 blocs par requête et jusqu'à 4 topics. Consulté le : 2026-10-07.

Sur HTTP 429, suspendez les requêtes et respectez en priorité l'en-tête `Retry-After` (en secondes ou date HTTP). S'il est absent, utilisez un recul exponentiel avec gigue et un nombre maximal de tentatives, en réessayant le même segment inachevé. Réduisez la concurrence et la fréquence de scrutation, et découpez les requêtes de logs en segments respectant la limite de l'endpoint. Le découpage en segments seul n'élimine pas les limites de débit ; les clients partageant une même IP doivent coordonner leur cadence de requêtes.

Pour l'endpoint avec clé de BlockVectra, lisez `max_logs_block_range`, `methods.allow` et `methods.deny` de `hyperevm_mainnet` depuis [GET /v1/chains](https://api.blockvectra.com/v1/chains) au lieu d'appliquer l'étendue de blocs ou la limite de requêtes par minute du RPC public officiel. La cadence des requêtes est soumise séparément aux valeurs `cu_per_sec`, `burst_cu` de la clé et au plafond d'appels du forfait gratuit (voir la section suivante). En cas de 429, inspectez `error.data.reason` et `retryable` ; `request_exceeds_burst` nécessite des requêtes plus petites plutôt que des réessais inchangés avec temporisation.

## Paramètres et règles de service de BlockVectra

BlockVectra dessert le mainnet HyperEVM via des endpoints JSON-RPC et REST Data API :

1. **Paramètres de chaîne et limites de logs** :
   Depuis `GET /v1/chains` pour `hyperevm_mainnet` :
   * **Identifiant de chaîne (Slug)** : `hyperevm_mainnet`, Chain ID `999`.
   * **`max_logs_block_range`** : Régie par le champ `max_logs_block_range` de `GET /v1/chains`. Une seule requête `eth_getLogs` peut couvrir au maximum ce nombre de blocs (`toBlock − fromBlock + 1`). Tout dépassement renvoie HTTP 200 avec le code d'erreur JSON-RPC `-32602` (`eth_getLogs block range too large: max <N> blocks`), qui n'est pas facturé.
   * **`state_window_blocks`** : Régie par le champ `state_window_blocks` de `GET /v1/chains`. Les appels de lecture d'état (tels que `eth_call` et `eth_getBalance`) sont soumis à la fenêtre de rétention déclarée par ce champ (lorsqu'il vaut `null`, l'état complet est conservé sans limite de fenêtre glissante).
   * **Politique des méthodes** : Régie par `methods.allow` et `methods.deny`. Les méthodes EVM standard (`eth_blockNumber`, `eth_getLogs`, `eth_call`, `eth_getBalance`, `eth_getBlockByNumber`, `eth_getTransactionReceipt`, etc.) sont autorisées ; les méthodes de filtre et d'abonnement (`eth_subscribe`, `eth_unsubscribe`, `eth_newFilter`, `eth_newBlockFilter`) sont refusées, renvoyant `-32601` (non facturé).
2. **Limites de débit du forfait gratuit et mise à niveau** :
   Depuis `GET /v1/plans` :
   * **`free.max_calls_per_sec`** : jusqu'à 25 appels par seconde, partagés entre toutes les clés du compte, toutes les chaînes et la Data API.
   * **Limites par défaut par clé** : Chaque clé API dispose d'un bucket de CU (recharge `cu_per_sec`, capacité `burst_cu` — les valeurs par défaut sont 400 CU/s et un burst de 1,600 CU). Les méthodes sont mesurées selon les poids en Compute Units (CU).
   * **Mise à niveau des limites** : Après une recharge, la limite d'appels par seconde à l'échelle du compte est supprimée ; chaque clé reste soumise aux limites de débit en Compute Units (CU) et de burst. Pour les tarifs et unités de facturation actuels, consultez la [page Tarifs](https://blockvectra.com/fr/pricing/).

## Rétro-remplissage des logs historiques : eth\_getLogs découpé et logique de nouvelle tentative

Lors de l'interrogation de logs historiques, les larges intervalles doivent être divisés en segments contigus bornés par le `max_logs_block_range` de la chaîne cible. Les stratégies de nouvelle tentative des clients doivent inspecter le champ `retryable` à l'intérieur des réponses d'erreur.

### Évaluation de retryable dans les réponses d'erreur

Sur BlockVectra, les objets d'erreur JSON-RPC incluent une charge utile `error.data` contenant `reason`, `docs_url` et `retryable` (booléen) :

* **`retryable: true`** : Conditions transitoires, notamment surcharge du service (`overloaded`), limite d'appels par seconde du forfait gratuit (`free_plan_call_limit`), synchronisation du nœud (`node_syncing`), ou amont indisponible (`upstream_unavailable`). Les clients doivent respecter l'en-tête `Retry-After` lorsqu'il est présent ou appliquer un recul exponentiel avec gigue.
* **`retryable: false`** : Erreurs non transitoires, telles qu'une étendue de blocs dépassant les limites (`-32602` / `logs_range_too_large`), des paramètres invalides (`invalid_params`), une clé API manquante (`missing_api_key`), ou une requête dépassant la capacité de burst (`-32022` / `request_exceeds_burst`). Réessayer sans ajuster les paramètres ne réussira pas.

Voici la réponse renvoyée lorsqu'une clé API est omise :

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

## Utiliser les endpoints de la Data API au lieu d'une analyse intensive par getLogs

Lorsqu'une application suit l'historique des transactions ou les mouvements de jetons pour une adresse spécifique, l'analyse via `eth_getLogs` nécessite d'émettre des requêtes séquentielles par segments bornées par `max_logs_block_range` et d'analyser les logs bruts d'événements Transfer.

La Data API de BlockVectra fournit des endpoints REST pré-indexés pour `hyperevm_mainnet`, prenant en charge des fenêtres allant jusqu'à 100 000 blocs avec pagination par curseur :

1. **Transactions d'adresse** : `GET /v1/data/hyperevm_mainnet/addresses/{address}/transactions`
   * Paramètres : `from_block` (requis), `to_block` (requis), `direction` (facultatif : `from`, `to`, `any`, par défaut `any`), `clamp` (chaîne booléenne facultative, par défaut `false` ; lorsqu'elle est définie sur `true`, les fenêtres dépassant 100 000 blocs ou supérieures à `as_of_block` sont tronquées au lieu de renvoyer 409), `limit` (facultatif, max 500), `cursor` (jeton de pagination).
2. **Transferts de jetons d'adresse** : `GET /v1/data/hyperevm_mainnet/addresses/{address}/transfers`
   * Paramètres : `standard` (requis : `erc20` ou `erc721` ; `erc1155` ne peut pas être interrogé par adresse et renvoie `422 no_coverage`), `token` (filtre de contrat de jeton facultatif), `from_block` (requis), `to_block` (requis), `direction` (facultatif : `in`, `out`, `any`), `clamp` (facultatif), `limit`, `cursor`.

### Structure de la réponse

Les réponses utilisent des schémas d'enveloppe standard :

* `data` : Tableau d'enregistrements. Les transactions incluent `hash`, `block_number`, `block_timestamp`, `from`, `to`, `value`, `tx_index`, `gas_limit`, `gas_used` et `status`. Les transferts incluent `token`, `standard`, `from`, `to`, `block_number`, `block_timestamp`, `tx_hash`, `tx_index` et `log_index` (`amount` pour ERC-20, `token_id` pour ERC-721).
* `next_cursor` : Jeton de pagination opaque renvoyé lorsque des enregistrements ultérieurs existent (absent sur la dernière page, pas `null`).
* `meta` : Métadonnées contenant `chain`, `chain_slug`, `chain_external_id`, `as_of_block`, `safe_block`, `finalized_block`, `coverage` (`full` ou `partial`) et `refreshed_at`.

### Exemple de code : requêtes 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);
```


## Suivi en temps réel : scrutation des nouveaux blocs

Pour un transport HTTP, suivez les blocs par scrutation et récupérez les logs d'événements par segments consécutifs dans la limite de `max_logs_block_range`. Ne sélectionnez WebSocket que lorsque `/v1/chains` indique `ws=true` et l'entrée `subscriptions` requise. Pour la remise vers un récepteur HTTPS, utilisez le [push webhook](https://docs.blockvectra.com/fr/guides/webhook-push/).

Pour tester le contrat `Hello` déployé, définissez `LOG_ADDRESS` sur son adresse. Envoyez `ping()` via le RPC de diffusion, puis rétro-remplissez le bloc du reçu à l'aide du script de rétro-remplissage de cette page. Poursuivez à partir du dernier segment terminé pour les nouveaux événements.

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

### Flux de scrutation

1. Émettez des appels légers périodiques vers `eth_blockNumber` pour inspecter la tête de chaîne la plus récente.
2. Comparez le numéro de bloc renvoyé avec le `lastSeenBlock` précédemment traité.
3. Si `currentBlock > lastSeenBlock`, découpez `[lastSeenBlock + 1, currentBlock]` en segments d'au plus `max_logs_block_range`. Ne persistez `lastSeenBlock` qu'après avoir traité avec succès chaque segment ; en cas d'échec, réessayez le segment inachevé. Dédupliquez par `(blockHash, transactionHash, logIndex)` et rejouez un chevauchement après reconnexion pour réconcilier les réorganisations.
4. Les fonctions `watchBlockNumber` ou `watchBlocks` de viem implémentent nativement la scrutation HTTP sous un transport HTTP, permettant une personnalisation via le paramètre `pollingInterval` (comme 1000 ms).

### Scruter les logs d'événements par segments bornés

Enregistrez sous le nom `poll-logs.mjs` à côté de `network.mjs` et `viem-client.mjs`. Définissez `BLOCKVECTRA_API_KEY`, `LOG_ADDRESS` et `FROM_BLOCK`, puis exécutez `node poll-logs.mjs`. Cet exemple fini échantillonne la tête 12 fois, à cinq secondes d'intervalle, et interroge chaque nouvelle plage par segments séquentiels. Une erreur interrompt le script avant d'avancer le segment en échec.

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

Chaque sortie enregistre un segment terminé. Pour reprendre, définissez `FROM_BLOCK` sur son `to + 1` ; les consommateurs durables doivent enregistrer ensemble les événements et le curseur, dédupliquer et réconcilier les réorganisations comme décrit ci-dessus. Pour le code 429 ou d'autres défaillances réessayables, appliquez les conseils de recul temporisé au même segment inachevé.

## Guides connexes

* Retrouvez l'URL RPC publique, les méthodes prises en charge et les limites actuelles sur la [page de la chaîne HyperEVM](https://blockvectra.com/fr/chains/hyperevm_mainnet/).
* Pour les règles complètes sur les étendues `eth_getLogs` et les algorithmes de découpage, consultez [Limites de plage de blocs eth\_getLogs et requêtes découpées](https://docs.blockvectra.com/fr/guides/getlogs-block-range/).
* Pour comparer `eth_getLogs` avec les transferts de la Data API, comprendre les bornes `as_of_block` et les marqueurs `safe_block` / `finalized_block`, consultez [eth\_getLogs et transferts indexés : couverture et finalité](https://docs.blockvectra.com/fr/guides/logs-vs-transfers/).
* Pour des détails sur la mesure en CU, les erreurs non facturées et les nouvelles tentatives, consultez [Ce qui n'est pas facturé : codes d'erreur et règles de facturation](https://docs.blockvectra.com/fr/guides/billing-rules/).

## Prochaines étapes

* [Parcourir le catalogue des jeux de données](https://blockvectra.com/fr/data/) pour découvrir chaque jeu de données indexé par BlockVectra.
* [Consulter le forfait gratuit et les tarifs](https://blockvectra.com/fr/pricing/#free) pour vérifier ce que comprend votre compte.
* [Se connecter à la console](https://console.blockvectra.com/login/?next=%2Fkeys%2F) pour créer une API key.
