Abonnements WebSocket
Connectez-vous aux points de terminaison WebSocket de BlockVectra pour eth_subscribe newHeads et logs. Découvrez les modes de connexion, les règles de filtrage, le repli de reconnexion et la récupération.
BlockVectra fournit des connexions WebSocket sécurisées (wss://) pour diffuser en temps réel des abonnements aux événements Ethereum aux côtés des requêtes JSON-RPC standard.
Choisir entre WebSocket, Webhook ou polling
Utilisez WebSocket pour obtenir newHeads en direct et des logs filtrés lorsque votre application peut maintenir une connexion. Utilisez l'API Webhook blockchain pour recevoir l'activité des portefeuilles surveillés sur un point de terminaison HTTPS, avec vérification de signature sur le corps brut, nouvelles tentatives et rejeu des correspondances conservées. Utilisez le polling HTTP pour la surveillance planifiée des paiements ERC-20 et le rétro-remplissage des logs historiques. Le guide des stablecoins présente également un récepteur Webhook pour USDT / USDC. Pour une comparaison architecturale de la prise en charge des chaînes, des exigences du récepteur et des compromis de récupération pour les développeurs et les agents IA, consultez le guide pour choisir entre Webhooks, WebSocket ou polling RPC.
La prise en charge de WebSocket est issue des champs ws et subscriptions dans GET /v1/chains ; la prise en charge de Push provient de la liste authentifiée GET /v1/push/chains. Une chaîne sans support WebSocket peut néanmoins utiliser les Webhooks d'adresse si elle y est répertoriée.
Les déconnexions WebSocket nécessitent un réabonnement et un rétro-remplissage ; elles n'émettent pas les événements de contrôle Push subscription.gap ou chain.reorg. Pour les Webhooks, un écart nécessite un balayage de plage ; un avis de réorganisation impose de marquer ou d'ignorer les événements remplacés avant de conserver les événements canoniques automatiquement relivrés. Le rejeu Push renvoie les correspondances conservées, et non les données antérieures à l'ajout d'une adresse ou d'une chaîne ou pendant que l'abonnement était hors ligne. Consultez les règles de facturation et la référence des erreurs lors de la mise en œuvre de la récupération.
Chaînes disponibles
Vous pouvez vérifier si les abonnements WebSocket sont actifs sur un réseau en lisant ws (booléen) et subscriptions (tableau des types pris en charge) dans GET /v1/chains.
Le tableau ci-dessous indique les réseaux sur lesquels la prise en charge de WebSocket est activée :
| Chaîne | Endpoint WebSocket (clé dans le chemin) |
|---|---|
| Robinhood Chain | wss://api.blockvectra.com/v1/robinhood_mainnet/{api_key} |
| Robinhood Chain Testnet | wss://api.blockvectra.com/v1/robinhood_testnet/{api_key} |
Connexion et authentification
Les clients établissent une connexion WebSocket TLS sécurisée (wss://). L'API key peut être fournie de deux manières :
- Clé dans le chemin :
wss://api.blockvectra.com/v1/{chain}/{api_key} - Clé dans l'en-tête :
wss://api.blockvectra.com/v1/{chain}avec l'en-têtex-api-key: {api_key}ouAuthorization: Bearer {api_key}lors du handshake de mise à niveau HTTP (Upgrade).
Avec une clé dans le chemin, cette dernière est utilisée et les deux en-têtes d'authentification sont ignorés. Sans clé dans le chemin, un en-tête x-api-key non vide prévaut sur Authorization: Bearer. Les API WebSocket des navigateurs ne peuvent pas définir ces en-têtes ; utilisez l'URL avec la clé dans le chemin.
Contrôles d'admission lors du handshake
Le handshake peut échouer pour les motifs suivants :
- Authentification : l'absence d'API key renvoie HTTP 401 (
missing_api_key) ; une API key inconnue, désactivée ou révoquée renvoie HTTP 401 (invalid_api_key) ; si l'authentification est temporairement indisponible, la réponse est HTTP 503 (auth_unavailable). - Solde du compte : un compte dont le solde prépayé est nul ou négatif renvoie HTTP 402 (
balance_exhausted) ; si l'état de facturation ne peut pas être confirmé, la réponse est HTTP 503 (billing_unavailable). - Limites de connexion : le dépassement de la limite par clé (20 connexions) ou par compte (50 connexions) renvoie HTTP 429 (
ws_connection_limit). - Disponibilité de la chaîne : demander une chaîne inconnue ou non desservie renvoie HTTP 404 (
unknown_chain). - Capacité du serveur : lorsque le serveur est occupé ou surchargé, le handshake renvoie HTTP 503 (
overloaded) avec un en-têteRetry-After.
Une fois connectés, les clients peuvent envoyer des requêtes JSON-RPC 2.0 standard (telles que eth_blockNumber ou eth_call) et des méthodes de contrôle d'abonnement formatées en trames de texte UTF-8.
Règles de facturation
- L'établissement d'une connexion, le maintien d'une connexion inactive ouverte et les battements de cœur ping/pong ne sont pas facturés.
- Les appels
eth_subscribeeteth_unsubscriberéussis sont facturés, y compris un désabonnement renvoyantfalse; les appels échoués ne sont pas facturés. Les appels JSON-RPC ordinaires suivent les règles de facturation JSON-RPC. - Les notifications
newHeadscomptent une seule fois par hash de bloc par connexion, quel que soit le nombre d'abonnementsnewHeadssur cette connexion. - Les notifications
logscomptent une fois par abonnement par hash de bloc et phase contenant des logs correspondants ; les blocs sans correspondance ne sont pas facturés. Plusieurs logs correspondants dans le même bloc et la même phase ne multiplient pas les frais. Les abonnements distincts sont comptabilisés séparément, même lorsque leurs filtres se chevauchent. Les logs de réorganisation (removed: true) constituent une unité distincte ; un bloc de remplacement à la même hauteur a un hash différent et représente une unité différente. - Les notifications ne sont facturées qu'après avoir été vidées avec succès dans le tampon d'envoi du socket ; les notifications en file d'attente ou abandonnées qui n'ont pas été vidées ne sont pas facturées. Les notifications mises en file d'attente avant la réponse à un
eth_unsubscribesont facturées si elles ont été vidées. Les messages WebSocket ne comportent aucun en-tête de facturation HTTP ; consultez l'utilisation du compte pour connaître les CU mesurées.
Méthodes d'abonnement
L'API implémente l'interface pub/sub standard d'Ethereum : eth_subscribe et eth_unsubscribe.
newHeads
Émet un nouvel objet d'en-tête de bloc chaque fois qu'un nouveau bloc est ajouté au sommet de la chaîne.
- Requête d'abonnement :
{"jsonrpc":"2.0","id":1,"method":"eth_subscribe","params":["newHeads"]} - Réponse d'abonnement : renvoie un identifiant d'abonnement hexadécimal opaque :
{"jsonrpc":"2.0","id":1,"result":"0x1"} - Trame de notification push :
{"jsonrpc":"2.0","method":"eth_subscription","params":{"subscription":"0x1","result":{"number":"0x1b4","hash":"0x..."}}}
logs
Émet des événements de log correspondant aux critères de filtrage spécifiés.
-
Exigence de filtre : chaque filtre d'abonnement aux
logsdoit spécifier uneaddress(une adresse de contrat ou un tableau d'adresses) ou untopic0(la première position de topic, non nulle). Un filtre ne spécifiant ni l'un ni l'autre (comme{}ou{"topics":[null,"0x..."]}) est rejeté avec le code d'erreur-32602(logs_filter_required). -
Limites des filtres : 100 adresses au maximum ; au plus 4 positions de topics avec un maximum de 16 hashs candidats par position.
-
Capacité des filtres : si les filtres de logs actifs atteignent la capacité maximale, l'abonnement renvoie le code d'erreur
-32022(ws_filter_capacity). -
Réorganisations de chaîne : si un bloc est supprimé en raison d'une réorganisation de chaîne, les notifications pour les logs supprimés comportent
"removed": true. -
Requête d'abonnement :
{"jsonrpc":"2.0","id":2,"method":"eth_subscribe","params":["logs",{"address":"0x1234567890123456789012345678901234567890"}]}
eth_unsubscribe
Résilie un abonnement actif à l'aide de son identifiant d'abonnement.
- Requête de désabonnement :
{"jsonrpc":"2.0","id":3,"method":"eth_unsubscribe","params":["0x1"]} - Réponse de désabonnement :
{"jsonrpc":"2.0","id":3,"result":true}
Exemples exécutables
Connectez-vous à l'aide de viem v2 via createPublicClient et le transport webSocket. Remplacez {chain} par l'identifiant de la chaîne cible et {api_key} par votre API key :
import { createPublicClient, webSocket } from 'viem';
const apiKey = process.env.BLOCKVECTRA_API_KEY || '{api_key}';
const url = `wss://api.blockvectra.com/v1/robinhood_mainnet/${apiKey}`;
const client = createPublicClient({
transport: webSocket(url),
});
// 1. S'abonner aux nouveaux en-têtes de blocs (newHeads)
const unwatchBlocks = client.watchBlocks({
onBlock: (block) => {
console.log('New block header received:', block.number, block.hash);
},
onError: (error) => {
console.error('watchBlocks error:', error);
},
});
// 2. S'abonner aux logs d'événements de contrat (le filtre exige address ou topic0)
const unwatchEvents = client.watchEvent({
address: '0x1234567890123456789012345678901234567890',
onLogs: (logs) => {
console.log('Matching logs received:', logs);
},
onError: (error) => {
console.error('watchEvent error:', error);
},
});Codes de fermeture et actions du client
Lorsque le serveur met fin à une session WebSocket, il envoie une trame Close contenant un code de fermeture spécifique et un motif court. Le tableau ci-dessous liste les codes de fermeture émis par le serveur et les actions recommandées :
| Code de fermeture | Chaîne du motif | Description | Réessayable | Action du client |
|---|---|---|---|---|
| 1001 | idle | Connexion inactive sans abonnements ni messages pendant 3 600 secondes (1 heure) | Oui | Se reconnecter selon les besoins. |
| 1003 | binary frames are not accepted | Trame WebSocket binaire reçue ; trames de texte UTF-8 uniquement | Non | Ne pas se reconnecter automatiquement. Mettre à jour le client pour envoyer des trames de texte. |
| 1009 | message too large | La charge utile entrante a dépassé 1 Mio | Non | Ne pas se reconnecter automatiquement. Découper les requêtes volumineuses ou réduire la taille de la charge utile. |
| 1012 | service restart | Redémarrage du serveur, ou durée de vie maximale de la session atteinte (24 heures) | Oui | Se reconnecter avec un délai aléatoire (jitter), rétablir les abonnements et rattraper les données manquées. |
| 1013 | chain unavailable | Chaîne indisponible | Oui | Se reconnecter avec un repli exponentiel aléatoire (full-jitter), rétablir les abonnements et rattraper les données manquées. |
| 1013 | overloaded | Serveur temporairement surchargé | Oui | Se reconnecter avec un repli exponentiel aléatoire (full-jitter), rétablir les abonnements et rattraper les données manquées. |
| 4402 | insufficient balance | Solde du compte épuisé | Non | Ne pas se reconnecter automatiquement. Rechargez votre solde, puis reconnectez-vous. |
| 4404 | invalid api key | L'API key est inconnue, désactivée ou révoquée | Non | Ne pas se reconnecter automatiquement. Vérifiez ou renouvelez votre API key dans la console avant de vous reconnecter. |
| 4408 | slow consumer | Le serveur ferme la session dont la file d'attente push dépasse 512 Kio et abandonne les notifications en attente ; les clients peuvent ne pas recevoir de trame Close (le navigateur signale 1006) | Oui | Traitez les déconnexions inattendues (aucune trame Close reçue, le navigateur signale 1006) comme le code 4408 : reconnectez-vous avec un délai, rétablissez les abonnements et rattrapez les données abandonnées avec eth_getLogs ; réduisez les abonnements ou lisez plus rapidement. |
| 4429 | push rate exceeded | Le débit de notification a dépassé 1 000 pushs/seconde | Oui | Réduisez les abonnements ou affinez les filtres ; reconnectez-vous avec un délai, réabonnez-vous et effectuez un rattrapage. |
| 4503 | billing unavailable | Facturation temporairement indisponible | Oui | État transitoire ; reconnectez-vous avec un repli exponentiel aléatoire (full-jitter). |
Reconnexion et repli exponentiel
Pour éviter les tempêtes de reconnexion synchronisées lors des coupures de connexion, les clients doivent mettre en œuvre un repli exponentiel avec gigue complète (full jitter) :
- Formule de repli : avant la n-ième tentative de reconnexion (n = 0, 1, 2, ...), attendez une durée choisie uniformément au hasard :
delay = random(0, min(20s, 0.5s * 2^n)) - Réinitialisation du compteur : ne réinitialisez le compteur de tentatives n à 0 qu'après avoir maintenu une connexion ininterrompue et stable pendant au moins
60 secondes. - Code de fermeture 1012 : introduisez un délai initial aléatoire avant la première tentative de reconnexion pour éviter les pics de reconnexion synchronisés.
- Codes non réessayables : ne vous reconnectez pas automatiquement lors des codes 4402, 4404, 1003 ou 1009.
Rétro-remplissage des données manquées après reconnexion
Les abonnements WebSocket ne persistent pas entre les connexions ; les notifications émises pendant une déconnexion ne sont pas conservées sur le serveur. Après reconnexion, les clients doivent appliquer une stratégie de rattrapage :
- Rétro-remplir les logs avec
eth_getLogs:- Persistez le numéro de bloc le plus élevé traité avec succès (
last_processed_block). - Appelez immédiatement
eth_subscribe("logs", ...)dès la reconnexion pour capturer les événements en direct. - Interrogez les blocs manqués via
eth_getLogsavecfromBlock: last_processed_block + 1ettoBlock: "latest"(ou le premier bloc reçu du flux en direct). - Si l'écart de déconnexion dépasse le
max_logs_block_rangedu réseau (issu deGET /v1/chains), partitionnez les requêtes en segments ne dépassant pas cette limite. - Dédupliquez les entrées de logs à la frontière de la requête à l'aide du tuple unique
(blockHash, transactionHash, logIndex).
- Persistez le numéro de bloc le plus élevé traité avec succès (
- Rétro-remplir les en-têtes de blocs avec
eth_getBlockByNumber:- Enregistrez le dernier numéro de bloc et son hash reçus avant la déconnexion.
- Réabonnez-vous à
newHeads. - Interrogez
eth_getBlockByNumber("latest", false)et récupérez séquentiellement les blocs intermédiaires manquants. Vérifiez la continuité de la chaîne viaparentHashpour détecter les réorganisations.
Limites
| Limite | Valeur | Résultat en cas de dépassement |
|---|---|---|
| Abonnements par connexion WebSocket | 100 | -32022 subscription_limit |
Abonnements newHeads par connexion WebSocket | 4 | -32022 subscription_limit |
Exigences de filtre pour l'abonnement aux logs | Doit spécifier une address ou un topic0 (première position dans topics) | -32602 logs_filter_required |
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 :