Assinaturas via WebSocket
Conecte-se aos endpoints WebSocket da BlockVectra para eth_subscribe newHeads e logs. Conheça métodos de conexão, regras de filtro, recuo de reconexão e recuperação.
A BlockVectra fornece conexões WebSocket seguras (wss://) para streaming de assinaturas de eventos Ethereum em tempo real juntamente com requisições JSON-RPC padrão.
Escolher WebSocket, Webhook ou polling
Use WebSocket para newHeads em tempo real e logs filtrados quando sua aplicação puder manter uma conexão. Use a API de Webhooks de Blockchain para receber a atividade de carteiras monitoradas em um endpoint HTTPS, com verificação de assinatura no corpo bruto, novas tentativas e replay de correspondências retidas. Use polling via HTTP para monitoramento agendado de pagamentos ERC-20 e recuperação de logs históricos. O guia de stablecoins também apresenta um receptor de Webhooks para USDT / USDC. Para uma comparação arquitetural abrangendo suporte a redes, requisitos de receptor e trade-offs de recuperação para desenvolvedores e agentes de IA, consulte o guia de escolha entre Webhooks, WebSocket ou polling de RPC.
O suporte a WebSocket vem de ws e subscriptions em GET /v1/chains; o suporte a Push vem da lista autenticada GET /v1/push/chains. Uma rede sem suporte a WebSocket ainda pode usar Webhooks de endereços se estiver listada ali.
Desconexões de WebSocket exigem nova assinatura e preenchimento de histórico; elas não emitem os eventos de controle de Push subscription.gap ou chain.reorg. Para Webhooks, uma lacuna requer varredura de intervalo; uma notificação de reorg requer que eventos substituídos sejam marcados ou descartados antes de manter os eventos canônicos reenviados automaticamente. O replay de Push reenvia correspondências retidas, e não dados anteriores à inclusão de um endereço ou rede, ou enquanto a assinatura estava offline. Revise as regras de cobrança e a referência de erros ao implementar a recuperação.
Redes disponíveis
Você pode verificar se assinaturas via WebSocket estão ativas em uma rede lendo ws (booleano) e subscriptions (array de tipos suportados) em GET /v1/chains.
A tabela abaixo reflete as redes onde o suporte a WebSocket está habilitado:
| Rede | Endpoint WebSocket (chave no caminho) |
|---|---|
| Robinhood Chain | wss://api.blockvectra.com/v1/robinhood_mainnet/{api_key} |
| Robinhood Chain Testnet | wss://api.blockvectra.com/v1/robinhood_testnet/{api_key} |
Conexão e autenticação
Os clientes estabelecem uma conexão WebSocket TLS segura (wss://). A API key pode ser fornecida de duas maneiras:
- Chave no caminho:
wss://api.blockvectra.com/v1/{chain}/{api_key} - Chave no cabeçalho:
wss://api.blockvectra.com/v1/{chain}com o cabeçalhox-api-key: {api_key}ouAuthorization: Bearer {api_key}durante o handshake HTTP Upgrade.
Com uma chave no caminho, a chave do caminho é usada e ambos os cabeçalhos de autenticação são ignorados. Sem uma chave no caminho, um x-api-key não vazio tem precedência sobre Authorization: Bearer. APIs de WebSocket em navegadores não podem definir esses cabeçalhos; utilize a URL com a chave no caminho.
Verificações de admissão no handshake
O handshake pode falhar com:
- Autenticação: Uma API key ausente retorna HTTP 401 (
missing_api_key); uma API key desconhecida, desativada ou revogada retorna HTTP 401 (invalid_api_key); se a autenticação estiver temporariamente indisponível, a resposta será HTTP 503 (auth_unavailable). - Saldo da conta: Uma conta com saldo pré-pago zero ou negativo retorna HTTP 402 (
balance_exhausted); se o estado de cobrança não puder ser confirmado, a resposta será HTTP 503 (billing_unavailable). - Limites de conexão: Ultrapassar o limite por chave (20 conexões) ou o limite por conta (50 conexões) retorna HTTP 429 (
ws_connection_limit). - Disponibilidade da rede: Requisitar uma rede desconhecida ou não atendida retorna HTTP 404 (
unknown_chain). - Capacidade do servidor: Quando o servidor estiver ocupado ou sobrecarregado, o handshake retornará HTTP 503 (
overloaded) com um cabeçalhoRetry-After.
Uma vez conectados, os clientes podem enviar requisições JSON-RPC 2.0 padrão (como eth_blockNumber ou eth_call) e métodos de controle de assinatura formatados como quadros de texto UTF-8.
Regras de cobrança
- Estabelecer uma conexão, manter uma conexão ociosa aberta e batimentos de coração ping/pong não são cobrados.
- Chamadas bem-sucedidas a
eth_subscribeeeth_unsubscribesão cobradas, incluindo um cancelamento de assinatura que retornefalse; chamadas com falha não são cobradas. Chamadas JSON-RPC comuns seguem as regras de cobrança de JSON-RPC. - Notificações de
newHeadscontam uma vez por hash de bloco por conexão, independentemente de quantas assinaturasnewHeadsa conexão tiver. - Notificações de
logscontam uma vez por assinatura por hash de bloco e fase com logs correspondentes; blocos sem correspondências não são cobrados. Vários logs correspondentes no mesmo bloco e fase não multiplicam a cobrança. Assinaturas separadas contam separadamente, mesmo quando seus filtros se sobrepõem. Logs de reorganização (removed: true) formam uma unidade separada; um bloco de substituição na mesma altura tem um hash diferente e é uma unidade diferente. - Notificações são cobradas apenas após serem descarregadas com sucesso no buffer de envio do socket; notificações enfileiradas ou descartadas que não foram descarregadas não são cobradas. Notificações enfileiradas antes da resposta de um
eth_unsubscribecontam se forem descarregadas. Mensagens WebSocket não carregam cabeçalhos HTTP de cobrança; consulte o consumo da conta para ver as CU medidas.
Métodos de assinatura
A API implementa a interface pub/sub padrão do Ethereum: eth_subscribe e eth_unsubscribe.
newHeads
Emite um novo objeto de cabeçalho de bloco sempre que um novo bloco for anexado ao topo da cadeia.
- Requisição de assinatura:
{"jsonrpc":"2.0","id":1,"method":"eth_subscribe","params":["newHeads"]} - Resposta da assinatura: Retorna um identificador de assinatura hexadecimal opaco:
{"jsonrpc":"2.0","id":1,"result":"0x1"} - Quadro de notificação push:
{"jsonrpc":"2.0","method":"eth_subscription","params":{"subscription":"0x1","result":{"number":"0x1b4","hash":"0x..."}}}
logs
Emite eventos de log que correspondem aos critérios de filtro especificados.
-
Exigência de filtro: Todo filtro de assinatura de
logsdeve especificar umaddress(um endereço de contrato ou array de endereços) ou umtopic0(a primeira posição de tópico, não nula). Um filtro que não especifique nenhum dos dois (como{}ou{"topics":[null,"0x..."]}) é rejeitado com o código de erro-32602(logs_filter_required). -
Limites de filtros: No máximo 100 endereços; no máximo 4 posições de tópicos com no máximo 16 hashes candidatos por posição.
-
Capacidade de filtros: Se os filtros de log ativos atingirem a capacidade máxima, a assinatura retornará o código de erro
-32022(ws_filter_capacity). -
Reorganizações de cadeia: Se um bloco for removido devido a uma reorg de cadeia, as notificações de log para os logs removidos trarão
"removed": true. -
Requisição de assinatura:
{"jsonrpc":"2.0","id":2,"method":"eth_subscribe","params":["logs",{"address":"0x1234567890123456789012345678901234567890"}]}
eth_unsubscribe
Encerra uma assinatura ativa usando o identificador da assinatura.
- Requisição de cancelamento de assinatura:
{"jsonrpc":"2.0","id":3,"method":"eth_unsubscribe","params":["0x1"]} - Resposta do cancelamento de assinatura:
{"jsonrpc":"2.0","id":3,"result":true}
Exemplos executáveis
Conecte-se usando o viem v2 via createPublicClient e o transporte webSocket. Substitua {chain} pelo identificador da rede de destino e {api_key} pela sua 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 encerramento e ações do cliente
Quando o servidor encerra uma sessão WebSocket, ele envia um quadro Close com um código de encerramento específico e um motivo curto. A tabela abaixo lista os códigos de encerramento emitidos pelo servidor e as ações recomendadas:
| Código de encerramento | String de motivo | Descrição | Repetível | Ação do cliente |
|---|---|---|---|---|
| 1001 | idle | Conexão inativa sem assinaturas ou mensagens por 3600 segundos (1 hora) | Sim | Reconecte conforme necessário. |
| 1003 | binary frames are not accepted | Quadro WebSocket binário recebido; apenas quadros de texto UTF-8 são aceitos | Não | Não reconecte automaticamente. Atualize o cliente para enviar quadros de texto. |
| 1009 | message too large | Carga útil recebida excedeu 1 MiB | Não | Não reconecte automaticamente. Divida requisições grandes ou reduza o tamanho da carga útil. |
| 1012 | service restart | Servidor reiniciando ou a sessão atingiu o tempo de vida máximo (24 horas) | Sim | Reconecte usando recuo com jitter aleatório, restabeleça as assinaturas e recupere dados perdidos. |
| 1013 | chain unavailable | Rede indisponível | Sim | Reconecte usando recuo exponencial com full jitter, restabeleça as assinaturas e recupere dados perdidos. |
| 1013 | overloaded | Servidor temporariamente sobrecarregado | Sim | Reconecte usando recuo exponencial com full jitter, restabeleça as assinaturas e recupere dados perdidos. |
| 4402 | insufficient balance | Saldo da conta esgotado | Não | Não reconecte automaticamente. Recarregue seu saldo e reconecte. |
| 4404 | invalid api key | A API key é desconhecida, está desativada ou foi revogada | Não | Não reconecte automaticamente. Verifique ou rotacione a API key no console antes de reconectar. |
| 4408 | slow consumer | O servidor fecha uma sessão cuja fila de envio ultrapassa 512 KiB e descarta notificações pendentes; clientes podem não receber um quadro de encerramento (o navegador reporta 1006) | Sim | Trate desconexões inesperadas (nenhum quadro de encerramento recebido, navegador reporta 1006) como 4408: reconecte com recuo, restabeleça as assinaturas e preencha dados descartados com eth_getLogs; assine menos ou leia mais rápido. |
| 4429 | push rate exceeded | Taxa de notificação excedeu 1.000 envios/segundo | Sim | Reduza as assinaturas ou restrinja os filtros; reconecte com recuo, assine novamente e recupere dados. |
| 4503 | billing unavailable | Cobrança temporariamente indisponível | Sim | Estado transitório; reconecte usando recuo exponencial com full jitter. |
Reconexão e recuo exponencial
Para evitar tempestades de reconexão sincronizadas quando conexões caem, os clientes devem implementar recuo exponencial com full jitter:
- Fórmula de recuo: Antes da n-ésima tentativa de reconexão (n = 0, 1, 2, ...), aguarde por uma duração escolhida uniformemente ao acaso:
delay = random(0, min(20s, 0.5s * 2^n)) - Redefinição do contador: Redefina o contador de tentativas n para 0 somente após manter uma conexão ininterrupta e estável por pelo menos
60 segundos. - Código de encerramento 1012: Introduza um atraso inicial aleatório antes da primeira tentativa de reconexão para evitar picos sincronizados de reconexão.
- Códigos não repetíveis: Não reconecte automaticamente em 4402, 4404, 1003 ou 1009.
Recuperação de dados perdidos após a reconexão
Assinaturas via WebSocket não persistem entre conexões; notificações emitidas durante uma desconexão não são retidas no servidor. Após a reconexão, os clientes devem executar uma estratégia de sincronização:
- Recuperar logs com
eth_getLogs:- Persista o número de bloco mais alto processado com sucesso (
last_processed_block). - Chame imediatamente
eth_subscribe("logs", ...)na reconexão para capturar eventos em tempo real. - Consulte os blocos perdidos via
eth_getLogscomfromBlock: last_processed_block + 1etoBlock: "latest"(ou o primeiro bloco recebido do fluxo em tempo real). - Se a lacuna da desconexão exceder o
max_logs_block_rangeda rede (obtido emGET /v1/chains), divida as consultas em partes que não excedam esse limite. - Deduplique entradas de log no limite da consulta usando a tupla exclusiva
(blockHash, transactionHash, logIndex).
- Persista o número de bloco mais alto processado com sucesso (
- Recuperar cabeçalhos de blocos com
eth_getBlockByNumber:- Registre o número e o hash do bloco mais recente recebido antes da desconexão.
- Assine novamente
newHeads. - Consulte
eth_getBlockByNumber("latest", false)e busque os blocos intermediários ausentes sequencialmente. Verifique a continuidade da cadeia viaparentHashpara detectar reorgs.
Limites
| Limite | Valor | Resultado ao exceder |
|---|---|---|
| Assinaturas por conexão WebSocket | 100 | -32022 subscription_limit |
Assinaturas newHeads por conexão WebSocket | 4 | -32022 subscription_limit |
Requisitos de filtro da assinatura de logs | Deve especificar um address ou um topic0 (primeira posição em topics) | -32602 logs_filter_required |
Próximos passos
- Explore o diretório de conjuntos de dados para ver todos os conjuntos de dados indexados pela BlockVectra.
- Consulte o plano gratuito e os preços para verificar o que sua conta inclui.
- Entre no console para criar uma API key.
Última atualização: