개발자를 위한 문서 / JSON-RPC
구독
구독 종류는 네 가지이며, HTTP 리스너가 아닌 서버에서 제공됩니다. 미니블록 스트림이 사는 곳이 여기이고, 그것은 다른 체인에서는 찾을 수 없는 이 체인의 유일한 표면입니다.
별도의 서버
HTTP 포트에는 구독이 존재하지 않습니다
HTTP 엔드포인트를 상대로 한 eth_subscribe는 -32601로 답합니다. 노드는 어디에도 jsonrpsee 구독을 등록하지 않습니다. 소켓은 자기 리스너 위에서 도는 별도의 수제 서버이며, 구독이 제공되는 유일한 곳입니다.
레플리카에는 WebSocket 서버가 아예 없습니다 - 리스너는 리더 경로에서만 띄워집니다. 구독은 리더 전용 표면입니다.
| 엔드포인트 | Value |
|---|---|
| 엔드포인트 | wss://rpc.picklechain.xyz/ws/공개 테스트 네트워크. 예제는 $WS_URL로 적습니다 |
| 직접 운영하는 노드 | ws://127.0.0.1:8546자기 기계에서 띄운 노드의 기본 WebSocket 포트 |
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.
핸드셰이크
eth_subscribe와 pickle_subscribe는 서로 바꿔 쓸 수 있게 받아들여지며 똑같이 동작합니다.
// ->
{"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.
네 가지 종류
One notification per sealed EVM block.
알아 둘 점. 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.
알아 둘 점. 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.
알아 둘 점. 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.
알아 둘 점. "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.
실제 예제
미니블록 스트림이며, 퍼스트파티 피드가 쓰는 폴백까지 함께 보입니다. 폴백은 중요합니다. 소켓이 끊기는 것은 정상이고, 폴링 경로가 빈틈 없이 따라잡는 방법입니다.
// 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.소켓이 닫히면 마지막으로 본 높이부터 pickle_miniBlockNumber를 폴링한 다음 pickle_getMiniBlockByNumber를 부르십시오. 따라잡기에는 상한을 두십시오 - 레퍼런스 클라이언트는 한 번에 최대 100개를 가져옵니다 - 그러지 않으면 긴 단절이 공유된 무거운 읽기 예산을 상대로 한 요청 폭주로 바뀝니다.
한도와 드롭 정책
| 한도 | 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 |
느린 구독자는 조용히 데이터를 잃습니다
각 스트림은 깊이 1024의 브로드캐스트 채널입니다. 뒤처진 구독자는 노드의 메모리를 불리도록 허용되는 대신 스트림에서 떨어져 나갑니다 - 오류 프레임을 받는 것이 아니라 빈틈을 받게 됩니다. 미니블록 스케줄링 목표에서 그 버퍼는 몇 초의 여유이므로, 큐에 밀어 넣는 것보다 무거운 이벤트별 작업은 소켓 바깥에 있어야 합니다.
이 한도들 중 환경 변수로 조정할 수 있는 것은 없으며, 연결 상한은 accept 시점에 강제됩니다. 257번째 연결은 오류 프레임 없이 닫히므로, 거부가 아니라 네트워크 장애처럼 보입니다.
소켓 위의 일반 호출
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.
오류 코드는 전송 계층마다 다릅니다
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.