Limites de débit RPC et rétro-remplissage des logs HyperEVM
Sur BlockVectra, les requêtes eth_getLogs authentifiées HyperEVM couvrent jusqu'à 1,000 blocs, en comptant les deux bornes ; découpez les fenêtres plus longues et enregistrez le dernier bloc terminé pour reprendre.
Réponse directe
Le RPC public officiel HyperEVM par défaut autorise 50 blocs par requête eth_getLogs (source : documentation 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), 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) ; 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 et les paramètres de service ci-dessous.
- Première étape : Lire le dernier bloc sans clé API à l'aide de la commande curl ci-dessous.
- Terminé quand : Le script de rétro-remplissage affiche
fromBlock,toBlocket un tableauresultpour 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.
Tâches que ce guide vous aide à accomplir
- Sonder le RPC HyperEVM 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 dans la limite
eth_getLogsd'HyperEVM, avec des décisions de nouvelle tentative basées sur l'erreur renvoyée. - Lire l'activité d'une adresse 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.
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
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. 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
Créer une clé pour ce rétro-remplissage. 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 Guide d'inscription programmatique. 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.
3. Rétro-remplir les logs avec votre clé
Modèle de départ complet : 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.
export BLOCKVECTRA_API_KEY='replace-with-your-key'
export LOG_ADDRESS='replace-with-contract-address'
node hyperevm-task.tsPar 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.
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. 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 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. 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. 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.
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.
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.
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.
: "${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. 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 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 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 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 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, 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 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_getTransactionCountavec 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.
Limites de débit du RPC public officiel et 429
La documentation officielle sur les limites de débit 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 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 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 :
- Paramètres de chaîne et limites de logs :
Depuis
GET /v1/chainspourhyperevm_mainnet:- Identifiant de chaîne (Slug) :
hyperevm_mainnet, Chain ID999. max_logs_block_range: Régie par le champmax_logs_block_rangedeGET /v1/chains. Une seule requêteeth_getLogspeut 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 champstate_window_blocksdeGET /v1/chains. Les appels de lecture d'état (tels queeth_calleteth_getBalance) sont soumis à la fenêtre de rétention déclarée par ce champ (lorsqu'il vautnull, l'état complet est conservé sans limite de fenêtre glissante).- Politique des méthodes : Régie par
methods.allowetmethods.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é).
- Identifiant de chaîne (Slug) :
- 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.
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êteRetry-Afterlorsqu'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 :
{
"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 :
- 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éfautany),clamp(chaîne booléenne facultative, par défautfalse; lorsqu'elle est définie surtrue, les fenêtres dépassant 100 000 blocs ou supérieures àas_of_blocksont tronquées au lieu de renvoyer 409),limit(facultatif, max 500),cursor(jeton de pagination).
- Paramètres :
- Transferts de jetons d'adresse :
GET /v1/data/hyperevm_mainnet/addresses/{address}/transfers- Paramètres :
standard(requis :erc20ouerc721;erc1155ne peut pas être interrogé par adresse et renvoie422 no_coverage),token(filtre de contrat de jeton facultatif),from_block(requis),to_block(requis),direction(facultatif :in,out,any),clamp(facultatif),limit,cursor.
- Paramètres :
Structure de la réponse
Les réponses utilisent des schémas d'enveloppe standard :
data: Tableau d'enregistrements. Les transactions incluenthash,block_number,block_timestamp,from,to,value,tx_index,gas_limit,gas_usedetstatus. Les transferts incluenttoken,standard,from,to,block_number,block_timestamp,tx_hash,tx_indexetlog_index(amountpour ERC-20,token_idpour ERC-721).next_cursor: Jeton de pagination opaque renvoyé lorsque des enregistrements ultérieurs existent (absent sur la dernière page, pasnull).meta: Métadonnées contenantchain,chain_slug,chain_external_id,as_of_block,safe_block,finalized_block,coverage(fulloupartial) etrefreshed_at.
Exemple de code : requêtes 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"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.
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.
cast send "$CONTRACT_ADDRESS" "ping()" --rpc-url "$DEPLOY_RPC_URL" \
--private-key "$DEPLOYER_PRIVATE_KEY"Flux de scrutation
- Émettez des appels légers périodiques vers
eth_blockNumberpour inspecter la tête de chaîne la plus récente. - Comparez le numéro de bloc renvoyé avec le
lastSeenBlockprécédemment traité. - Si
currentBlock > lastSeenBlock, découpez[lastSeenBlock + 1, currentBlock]en segments d'au plusmax_logs_block_range. Ne persistezlastSeenBlockqu'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. - Les fonctions
watchBlockNumberouwatchBlocksde viem implémentent nativement la scrutation HTTP sous un transport HTTP, permettant une personnalisation via le paramètrepollingInterval(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.
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.
- Pour les règles complètes sur les étendues
eth_getLogset les algorithmes de découpage, consultez Limites de plage de blocs eth_getLogs et requêtes découpées. - Pour comparer
eth_getLogsavec les transferts de la Data API, comprendre les bornesas_of_blocket les marqueurssafe_block/finalized_block, consultez eth_getLogs et transferts indexés : couverture et finalité. - 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.
Prochaines étapes
- Parcourir le catalogue des jeux de données pour découvrir chaque jeu de données indexé par BlockVectra.
- Consulter le forfait gratuit et les tarifs pour vérifier ce que comprend votre compte.
- Se connecter à la console pour créer une API key.
Dernière mise à jour :
eth_getLogs block range
Pour logs_range_too_large, lisez max_logs_block_range de la chaîne, découpez l'intervalle de blocs inclusif dans cette limite et n'avancez qu'après le succès du segment en cours.
Comparaison avec Infura
Utilisez les crédits de cycle BlockVectra pour les tâches de lecture concentrées, payez par méthode sans abonnement RPC mensuel, et automatisez la création de compte et le financement en stablecoins.