Para desenvolvedores / JSON-RPC
Inscrições
Quatro tipos de inscrição, num servidor que não é o ouvinte HTTP. É aqui que vive o fluxo de miniblocos, a única superfície daqui que você não encontrará em outra cadeia.
Um servidor separado
As inscrições não existem na porta HTTP
eth_subscribe contra o ponto de acesso HTTP responde -32601. O nó não registra nenhuma inscrição jsonrpsee em lugar algum; o socket é um servidor escrito à mão, no seu próprio ouvinte, e é o único lugar onde as inscrições são servidas.
Uma réplica não tem servidor WebSocket algum - o ouvinte só é lançado no caminho do líder. As inscrições são uma superfície reservada ao líder.
| Ponto de acesso | Value |
|---|---|
| Ponto de acesso | wss://rpc.picklechain.xyz/ws/a rede de teste pública; os exemplos a escrevem como $WS_URL |
| Um nó que você mesmo roda | ws://127.0.0.1:8546a porta WebSocket padrão de um nó iniciado na sua própria máquina |
On a deployment behind a reverse proxy, both /ws and /ws/ are served as two separate locations with no redirect between them: a WebSocket client mostly does not follow a 301 on its handshake, so whichever spelling was redirected would simply fail to connect.
O aperto de mão
eth_subscribe e pickle_subscribe são aceitos indiferentemente e se comportam de forma idêntica:
// ->
{"jsonrpc":"2.0","id":1,"method":"pickle_subscribe","params":["miniBlocks"]}
// <-
{"jsonrpc":"2.0","id":1,"result":"0x1"}
// <- then, per event
{"jsonrpc":"2.0","method":"eth_subscription","params":{"subscription":"0x1","result":{…}}}- Subscription ids come from a per-connection counter starting at 1, so two connections both see 0x1. Do not treat an id as globally unique.
- Notifications always arrive under the method name eth_subscription, even for a subscription opened as pickle_subscribe. Unwrap the payload at params.result.
- eth_unsubscribe and pickle_unsubscribe both return a boolean: true if the id was found on this connection, false otherwise.
Os quatro tipos
One notification per sealed EVM block.
Vale saber. The payload is a nine-field summary - number, hash, parentHash, timestamp, mixHash, baseFeePerGas, transactionCount, miniBlockFrom, miniBlockTo - and not the full header that eth_getBlockByNumber returns. transactionCount is a decimal number. A client that needs gasLimit, gasUsed or logsBloom must re-fetch the block.
miniBlocks
alias: newMiniBlocksThe preconfirmation stream: one notification per sealed mini-block, at the mini-block scheduling target. Both spellings are the same stream.
Vale saber. Mini-block fields break the eth_* hex convention on purpose: number, evmBlockNumber, timestampUs and each receipt's gasUsed are decimal JSON numbers, and the timestamp is in microseconds.
Logs as they are indexed, with the standard address and topics filtering. An absent or empty filter means every log.
Vale saber. A malformed topics filter answers -32602 before an id is allocated, so a failed subscribe leaves you with no subscription rather than a silent one.
Transaction hashes, as a bare string payload.
Vale saber. "Pending" does not mean what it means elsewhere. There is no public mempool; a hash is published only AFTER the transaction has executed and been indexed. Treat this as an executed-transaction feed, not a mempool feed.
Um exemplo completo
O fluxo de miniblocos, com a alternativa que o fluxo de primeira parte usa. A alternativa importa: um socket caído é normal, e a via da sondagem é como você recupera o atraso sem buracos.
// WS_URL: wss://rpc.picklechain.xyz/ws/ on the public testnet, or a node of your own.
// The /ws path is required - an upgrade at the bare origin answers 405.
const socket = new WebSocket(WS_URL);
socket.addEventListener("open", () => {
socket.send(JSON.stringify({
jsonrpc: "2.0", id: 1, method: "pickle_subscribe", params: ["miniBlocks"],
}));
});
socket.addEventListener("message", (event) => {
const message = JSON.parse(event.data);
// The subscribe reply carries an id; notifications carry params.result.
if (!message.params) return;
const mini = message.params.result;
// Decimal numbers, not hex quantities - and microseconds, not seconds.
console.log(mini.number, mini.transactions.length, mini.timestampUs);
});
// A slow handler is DROPPED from the stream rather than buffered, so do the
// work elsewhere and keep this callback cheap.Se o socket fechar, sonde pickle_miniBlockNumber e depois pickle_getMiniBlockByNumber a partir da última altura vista. Limite a recuperação - o cliente de referência busca no máximo 100 por passagem - ou uma desconexão longa se transforma numa rajada de pedidos contra o orçamento compartilhado de leituras pesadas.
Limites e política de expulsão
| Limite | Value |
|---|---|
| Message size | 256 KiBframe and message both; oversized answers -32005 "message too large" |
| Connections | 256excess connections are dropped at accept, with no error frame - your client sees a closed socket, not a rejection |
| Subscriptions per connection | 32-32005 "subscription limit reached" |
| Requests per second | 100 per connection-32005 "request rate limit exceeded" |
| Stream depth | 1024 per streama subscriber that falls behind is DROPPED from the stream rather than buffered, so a slow handler loses notifications silently. Do the work off the socket |
Os inscritos lentos perdem dados em silêncio
Cada fluxo é um canal de difusão com 1024 de profundidade. Um inscrito que fica para trás é expulso do fluxo em vez de ser deixado fazer crescer a memória do nó - você não recebe uma trama de erro, você recebe um buraco. Na meta de agendamento do minibloco, esse buffer representa alguns segundos de folga, portanto todo trabalho por evento mais pesado do que um empilhamento numa fila não tem lugar no socket.
Nenhum desses limites é ajustável pelo ambiente, e o teto de conexões é aplicado na aceitação: a 257a conexão é fechada sem trama de erro, o que parece uma falha de rede e não uma recusa.
As chamadas comuns no socket
Any frame that is not a subscribe or unsubscribe is forwarded to the same handler the HTTP port uses, so every method in the reference is callable over the socket.
Os códigos de erro diferem conforme o transporte
Error codes are re-wrapped on the way out. Every non-send failure comes back as -32603 regardless of its original code, so an eth_call revert is -32000 over HTTP and -32603 over the socket. A client that branches on the code needs to know which transport it is on.