Add support for WebSocket & filter RPC.
Why
fxevm's gateway serves standard Ethereum JSON-RPC over plain HTTP only. Two closely related parts
of that standard surface are missing entirely, and both are documented as known, deliberate gaps
rather than oversights (docs/COMPATIBILITY.md:95-96, :464-466):
- WebSocket transport. No
ws:// (or wss://) endpoint at all — only HTTP.
- Server-side filters and subscriptions. No
eth_newBlockFilter / eth_getFilterChanges /
eth_uninstallFilter, no eth_subscribe / eth_unsubscribe. The documented workaround is "poll
eth_blockNumber and eth_getLogs instead."
That workaround is fine for a one-off script, but not for the class of software this gap actually
blocks: anything that needs to react to new blocks or events rather than busy-poll for them —
indexers, monitoring/alerting, relayers, and any Ethereum client library that opens a WS connection
by default instead of falling back to HTTP polling. (Paladin, an EVM privacy-execution engine, is
one concrete example: its core blockchain client refuses to start without a working WS connection,
and its block indexer relies specifically on eth_newBlockFilter/eth_getFilterChanges.)
This epic closes both gaps.
Foundational decision: WS shares the HTTP port
- fxevm serves WS on the same listener/port as HTTP (
gateway.Listen), dispatched by the Upgrade: websocket header — exactly how go-ethereum's own node package runs HTTP and WS together (node/rpcstack.go's isWebsocket / httpServer.ServeHTTP).
- This also matches the common Ethereum-node convention of one RPC port serving both transports
simpler to document, firewall, and deploy than a second port only some callers would ever use.
Add support for WebSocket & filter RPC.
Why
fxevm's gateway serves standard Ethereum JSON-RPC over plain HTTP only. Two closely related parts
of that standard surface are missing entirely, and both are documented as known, deliberate gaps
rather than oversights (
docs/COMPATIBILITY.md:95-96,:464-466):ws://(orwss://) endpoint at all — only HTTP.eth_newBlockFilter/eth_getFilterChanges/eth_uninstallFilter, noeth_subscribe/eth_unsubscribe. The documented workaround is "polleth_blockNumberandeth_getLogsinstead."That workaround is fine for a one-off script, but not for the class of software this gap actually
blocks: anything that needs to react to new blocks or events rather than busy-poll for them —
indexers, monitoring/alerting, relayers, and any Ethereum client library that opens a WS connection
by default instead of falling back to HTTP polling. (Paladin, an EVM privacy-execution engine, is
one concrete example: its core blockchain client refuses to start without a working WS connection,
and its block indexer relies specifically on
eth_newBlockFilter/eth_getFilterChanges.)This epic closes both gaps.
Foundational decision: WS shares the HTTP port
gateway.Listen), dispatched by theUpgrade: websocketheader — exactly how go-ethereum's ownnodepackage runs HTTP and WS together (node/rpcstack.go'sisWebsocket/httpServer.ServeHTTP).simpler to document, firewall, and deploy than a second port only some callers would ever use.