Suscripciones WebSocket

Conéctate a los endpoints WebSocket de BlockVectra para eth_subscribe newHeads y logs. Conoce los métodos de conexión, las reglas de filtros, las esperas entre reconexiones y la recuperación.

BlockVectra ofrece conexiones WebSocket seguras (wss://) para recibir suscripciones a eventos de Ethereum en tiempo real junto con solicitudes JSON-RPC estándar.

Elegir WebSocket, Webhook o sondeo

Usa WebSocket para recibir newHeads y logs filtrados en directo cuando tu aplicación pueda mantener una conexión. Usa la Blockchain Webhook API para recibir la actividad de las billeteras observadas en un endpoint HTTPS, con verificación de firmas sobre el cuerpo sin procesar, reintentos y reenvío de coincidencias conservadas. Usa el sondeo HTTP para supervisar pagos ERC-20 periódicamente y recuperar logs históricos. La guía de stablecoins también muestra un receptor Webhook de USDT / USDC. Para comparar la arquitectura en cuanto a cadenas compatibles, requisitos del receptor y ventajas e inconvenientes de recuperación para desarrolladores y agentes de IA, consulta la guía para elegir Webhooks, WebSocket o sondeo RPC.

La compatibilidad con WebSocket se indica en ws y subscriptions de GET /v1/chains; la compatibilidad con Push se indica en la lista autenticada GET /v1/push/chains. Una cadena sin WebSocket puede seguir usando Webhooks de direcciones si aparece en esa lista.

Las desconexiones de WebSocket requieren volver a suscribirse y recuperar los datos faltantes; no emiten los eventos de control Push subscription.gap ni chain.reorg. En los Webhooks, un intervalo sin datos requiere un escaneo de rango; un aviso de reorganización requiere marcar o descartar los eventos sustituidos antes de conservar los eventos canónicos que se vuelven a entregar automáticamente. El reenvío de Push vuelve a enviar las coincidencias conservadas, no los datos anteriores a la incorporación de una dirección o cadena ni los del período en que la suscripción estuvo desconectada. Revisa las reglas de facturación y la referencia de errores al implementar la recuperación.

Cadenas disponibles

Puedes comprobar si las suscripciones WebSocket están activas en una red leyendo ws (booleano) y subscriptions (matriz de tipos compatibles) en GET /v1/chains.

La siguiente tabla muestra las redes en las que WebSocket está habilitado:

CadenaEndpoint WebSocket (clave en la ruta)
Robinhood Chainwss://api.blockvectra.com/v1/robinhood_mainnet/{api_key}
Robinhood Chain Testnetwss://api.blockvectra.com/v1/robinhood_testnet/{api_key}

Conexión y autenticación

Los clientes establecen una conexión WebSocket segura con TLS (wss://). La API key puede proporcionarse de dos formas:

  • API key en la ruta: wss://api.blockvectra.com/v1/{chain}/{api_key}
  • API key en la cabecera: wss://api.blockvectra.com/v1/{chain} con la cabecera x-api-key: {api_key} o Authorization: Bearer {api_key} durante la negociación HTTP Upgrade.

Si hay una API key en la ruta, se usa esa API key y se ignoran ambas cabeceras de autenticación. Sin API key en la ruta, un x-api-key no vacío tiene prioridad sobre Authorization: Bearer. Las API WebSocket del navegador no pueden establecer estas cabeceras; usa la URL con API key en la ruta.

Comprobaciones de admisión durante la negociación

La negociación puede fallar por:

  • Autenticación: La ausencia de API key devuelve HTTP 401 (missing_api_key); una API key desconocida, deshabilitada o revocada devuelve HTTP 401 (invalid_api_key); si la autenticación no está disponible temporalmente, la respuesta es HTTP 503 (auth_unavailable).
  • Saldo de la cuenta: Una cuenta con saldo de prepago cero o negativo devuelve HTTP 402 (balance_exhausted); si no se puede confirmar el estado de facturación, la respuesta es HTTP 503 (billing_unavailable).
  • Límites de conexión: Superar el límite por API key (20 conexiones) o por cuenta (50 conexiones) devuelve HTTP 429 (ws_connection_limit).
  • Disponibilidad de la cadena: Solicitar una cadena desconocida o no servida devuelve HTTP 404 (unknown_chain).
  • Capacidad del servidor: Cuando el servidor está ocupado o sobrecargado, la negociación devuelve HTTP 503 (overloaded) con una cabecera Retry-After.

Una vez conectados, los clientes pueden enviar solicitudes JSON-RPC 2.0 estándar (como eth_blockNumber o eth_call) y métodos de control de suscripciones como tramas de texto UTF-8.

Reglas de facturación

  • Establecer una conexión, mantener abierta una conexión inactiva y los mensajes de mantenimiento ping/pong no se facturan.
  • Las llamadas correctas a eth_subscribe y eth_unsubscribe se facturan, incluida una cancelación que devuelva false; las llamadas fallidas no se facturan. Las llamadas JSON-RPC ordinarias siguen las reglas de facturación de JSON-RPC.
  • Las notificaciones newHeads se contabilizan una vez por hash de bloque y por conexión, independientemente de cuántas suscripciones newHeads tenga la conexión.
  • Las notificaciones logs se contabilizan una vez por suscripción, hash de bloque y fase con logs coincidentes; los bloques sin coincidencias no se facturan. Varios logs coincidentes en el mismo bloque y fase no multiplican el cargo. Las suscripciones independientes se contabilizan por separado, incluso si sus filtros se solapan. Los logs de reorganización (removed: true) forman una unidad aparte; un bloque de sustitución a la misma altura tiene otro hash y constituye otra unidad.
  • Las notificaciones solo se facturan después de enviarse correctamente al búfer de envío del socket; las notificaciones en cola o descartadas que no se enviaron no se facturan. Las notificaciones encoladas antes de una respuesta eth_unsubscribe cuentan si se envían. Los mensajes WebSocket no incluyen cabeceras HTTP de facturación; consulta el uso de la cuenta para conocer las CU medidas.

Métodos de suscripción

La API implementa la interfaz estándar pub/sub de Ethereum: eth_subscribe y eth_unsubscribe.

newHeads

Emite un objeto de cabecera de bloque nuevo cada vez que se añade un bloque al extremo de la cadena.

  • Solicitud de suscripción:
    {"jsonrpc":"2.0","id":1,"method":"eth_subscribe","params":["newHeads"]}
  • Respuesta de suscripción: Devuelve un identificador hexadecimal opaco de suscripción:
    {"jsonrpc":"2.0","id":1,"result":"0x1"}
  • Trama de notificación Push:
    {"jsonrpc":"2.0","method":"eth_subscription","params":{"subscription":"0x1","result":{"number":"0x1b4","hash":"0x..."}}}

logs

Emite logs de eventos que coinciden con los criterios de filtro especificados.

  • Requisito del filtro: Cada filtro de suscripción logs debe especificar un address (una dirección de contrato o una matriz de direcciones) o un topic0 (la primera posición de tema, no nula). Un filtro que no especifique ninguno (como {} o {"topics":[null,"0x..."]}) se rechaza con el código de error -32602 (logs_filter_required).

  • Límites del filtro: Como máximo 100 direcciones; como máximo 4 posiciones de temas con hasta 16 hashes candidatos por posición.

  • Capacidad de filtros: Si los filtros de logs activos alcanzan la capacidad máxima, la suscripción devuelve el código de error -32022 (ws_filter_capacity).

  • Reorganizaciones de la cadena: Si se elimina un bloque por una reorganización de la cadena, las notificaciones de los logs eliminados llevan "removed": true.

  • Solicitud de suscripción:

    {"jsonrpc":"2.0","id":2,"method":"eth_subscribe","params":["logs",{"address":"0x1234567890123456789012345678901234567890"}]}

eth_unsubscribe

Termina una suscripción activa mediante su identificador.

  • Solicitud de cancelación de suscripción:
    {"jsonrpc":"2.0","id":3,"method":"eth_unsubscribe","params":["0x1"]}
  • Respuesta de cancelación de suscripción:
    {"jsonrpc":"2.0","id":3,"result":true}

Ejemplos ejecutables

Conéctate con viem v2 mediante createPublicClient y el transporte webSocket. Sustituye {chain} por el identificador de la cadena de destino y {api_key} por tu 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. Subscribe to new block headers (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. Subscribe to contract event logs (filter requires address or topic0)
const unwatchEvents = client.watchEvent({
  address: '0x1234567890123456789012345678901234567890',
  onLogs: (logs) => {
    console.log('Matching logs received:', logs);
  },
  onError: (error) => {
    console.error('watchEvent error:', error);
  },
});

Códigos de cierre y acciones del cliente

Cuando el servidor termina una sesión WebSocket, envía una trama Close con un código de cierre específico y un motivo breve. La siguiente tabla enumera los códigos de cierre que emite el servidor y las acciones recomendadas:

Código de cierreCadena de motivoDescripciónSe puede reintentarAcción del cliente
1001idleConexión inactiva sin suscripciones ni mensajes durante 3600 segundos (1 hora)SíVuelve a conectarte según sea necesario.
1003binary frames are not acceptedSe recibió una trama WebSocket binaria; solo se admiten tramas de texto UTF-8NoNo vuelvas a conectarte automáticamente. Actualiza el cliente para enviar tramas de texto.
1009message too largeLa carga útil entrante superó 1 MiBNoNo vuelvas a conectarte automáticamente. Divide las solicitudes grandes o reduce el tamaño de la carga útil.
1012service restartEl servidor se está reiniciando o la sesión alcanzó su duración máxima (24 horas)SíVuelve a conectarte con esperas aleatorias entre reintentos, restablece las suscripciones y recupera los datos faltantes.
1013chain unavailableCadena no disponibleSíVuelve a conectarte con espera exponencial y aleatoriedad completa, restablece las suscripciones y recupera los datos faltantes.
1013overloadedServidor temporalmente sobrecargadoSíVuelve a conectarte con espera exponencial y aleatoriedad completa, restablece las suscripciones y recupera los datos faltantes.
4402insufficient balanceSaldo de la cuenta agotadoNoNo vuelvas a conectarte automáticamente. Recarga tu saldo y después vuelve a conectarte.
4404invalid api keyAPI key desconocida, deshabilitada o revocadaNoNo vuelvas a conectarte automáticamente. Verifica o rota la API key en la consola antes de volver a conectarte.
4408slow consumerEl servidor cierra una sesión cuya cola de notificaciones Push supera 512 KiB y descarta las notificaciones pendientes; los clientes pueden no recibir una trama de cierre (el navegador informa 1006)SíTrata las desconexiones inesperadas (sin trama de cierre recibida, el navegador informa 1006) como 4408: vuelve a conectarte con esperas entre reintentos, restablece las suscripciones y recupera los datos descartados con eth_getLogs; reduce las suscripciones o lee más rápido.
4429push rate exceededLa frecuencia de notificaciones superó 1,000 notificaciones Push/segundoSíReduce las suscripciones o restringe los filtros; vuelve a conectarte con esperas entre reintentos, suscríbete de nuevo y recupera los datos faltantes.
4503billing unavailableFacturación temporalmente no disponibleSíEstado transitorio; vuelve a conectarte con espera exponencial y aleatoriedad completa.

Reconexión y espera exponencial

Para evitar avalanchas de reconexiones sincronizadas cuando se interrumpen las conexiones, los clientes deben implementar esperas exponenciales con aleatoriedad completa:

  • Fórmula de espera: Antes del intento de reconexión n-ésimo (n = 0, 1, 2, ...), espera una duración elegida uniformemente al azar:
    delay = random(0, min(20s, 0.5s * 2^n))
  • Reinicia el contador: Reinicia el contador de reintentos n a 0 solo después de mantener una conexión estable e ininterrumpida durante al menos 60 seconds.
  • Código de cierre 1012: Introduce una espera inicial aleatoria antes del primer intento de reconexión para evitar picos de reconexiones sincronizadas.
  • Códigos no reintentables: No vuelvas a conectarte automáticamente ante 4402, 4404, 1003 ni 1009.

Recuperación de datos faltantes tras la reconexión

Las suscripciones WebSocket no se conservan entre conexiones; el servidor no retiene las notificaciones emitidas durante una desconexión. Tras volver a conectarse, los clientes deben ejecutar una estrategia para ponerse al día:

  1. Recupera logs con eth_getLogs:
    • Conserva el número de bloque más alto procesado correctamente (last_processed_block).
    • Llama inmediatamente a eth_subscribe("logs", ...) al volver a conectarte para capturar los eventos en directo.
    • Consulta los bloques faltantes mediante eth_getLogs con fromBlock: last_processed_block + 1 y toBlock: "latest" (o el primer bloque recibido del flujo en directo).
    • Si el intervalo de desconexión supera max_logs_block_range de la red (de GET /v1/chains), divide las consultas en segmentos que no superen ese límite.
    • Elimina los logs duplicados entre las consultas usando la tupla única (blockHash, transactionHash, logIndex).
  2. Recupera cabeceras de bloque con eth_getBlockByNumber:
    • Registra el último número y hash de bloque recibidos antes de la desconexión.
    • Vuelve a suscribirte a newHeads.
    • Consulta eth_getBlockByNumber("latest", false) y obtén secuencialmente los bloques intermedios faltantes. Verifica la continuidad de la cadena con parentHash para detectar reorganizaciones.

Límites

LímiteValorResultado al superarlo
Suscripciones por conexión WebSocket100-32022 subscription_limit
Suscripciones newHeads por conexión WebSocket4-32022 subscription_limit
Requisitos del filtro de suscripción logsDebe especificar un address o un topic0 (primera posición de topics)-32602 logs_filter_required

Próximos pasos

Última actualización:

En esta página