WebSocket API Protocols
This document describes the WebSocket protocol used when connecting directly to a Hathor full node.
Endpoint Resolution
The WebSocket endpoint is derived from the HTTP base URL.
Example
| Input (HTTP) | Output (WebSocket) |
|---|---|
https://node1.mainnet.hathor.network/v1a/ | wss://node1.mainnet.hathor.network/v1a/ws/ |
Rules
http→wshttps→wss- Append
/ws/to the base path
Message Framing
- Each WebSocket frame contains a single JSON object
- All messages MUST include a
typefield - Message types may be namespaced using colons
Example
{
"type": "stream:history:vertex"
}
Some numeric fields may exceed JavaScript's safe integer limits.
Use a parser that supports BigInt when necessary.
Keepalive (Ping / Pong)
Client → Server
{ "type": "ping" }
Server → Client
{ "type": "pong" }
Capability Discovery
On connection, the server may send:
{
"type": "capabilities",
"capabilities": ["history-streaming"]
}
Supported Capabilities
history-streaming→ Enables streaming history APIs
Metrics & Status Events
Best Block Height
{
"type": "height_updated",
"best_block_height": 12345
}
Dashboard
{
"type": "dashboard",
"best_block_height": 12345
}
Addresses Loaded
{
"type": "addresses_loaded"
}
Address Subscription
Controls which addresses will receive wallet-related updates.
Subscribe
{
"type": "subscribe_address",
"address": "<base58-address>"
}
Unsubscribe
{
"type": "unsubscribe_address",
"address": "<base58-address>"
}
Limits and Error Handling
Address subscription requests are not guaranteed to succeed.
A full node may reject a subscription request for reasons such as:
- limits on the number of subscribed addresses per connection or wallet
- invalid or malformed addresses
- node-side resource constraints
- temporary operational issues
Subscription Response
{
"type": "subscribe_address",
"success": true,
"message": "optional"
}
Failure Response
{
"type": "subscribe_address",
"success": false,
"message": "<error-message>"
}
Client Behavior
When "success": false:
- Treat the subscription as failed.
- Do not assume the address is being tracked.
- Stop attempting to sync that address unless the failure condition is resolved.
- Log or surface the message when available.
Public full nodes may enforce limits on the number of subscribed addresses for a single wallet or connection.
Applications should not assume unlimited subscriptions and must handle rejections gracefully.
Address History Event
{
"type": "wallet:address_history",
"history": { ... }
}
History Object
The list of minimum fields for the history object includes:
tx_id: stringversion: numberweight: numbertimestamp: numberis_voided: booleaninputs: arrayoutputs: arrayparents: string[]
Optional Fields
signalBitsnoncetoken_nametoken_symboltokensheightprocessingStatus- Nano-contract fields:
nc_idnc_blueprint_idnc_methodnc_argsnc_pubkeync_addressnc_context
first_block
History Streaming Protocol
This protocol is available when the history-streaming capability is supported.
It enables streaming of transaction history using an identified stream (id) and supports:
- Flow control via windowing
- Ordered delivery using sequence numbers (
seq) - Optional acknowledgments for controlled consumption
Message Types
The history streaming protocol defines a set of message types used to control the stream lifecycle and exchange data between the client and server.
Client → Server
These messages are used by the client to initiate, control, and manage a history stream:
request:history:xpub→ Start a history stream using an extended public key (xpub)request:history:manual→ Start a history stream using a manually provided list of addressesrequest:history:ack→ Acknowledge received items and optionally advance the stream window (used for flow control)
Server → Client
These messages are emitted by the server to deliver streamed data and communicate the state of the stream:
stream:history:begin→ Indicates the start of a history streamstream:history:address→ Signals a new address context within the streamstream:history:vertex→ Delivers a transaction or block (history item)stream:history:end→ Indicates that the stream has completedstream:history:error→ Indicates that an error occurred during streaming
Acknowledgment (ACK)
Used when flow control is enabled, this message allows the client to inform the server of the last successfully processed item in the stream.
By sending an acknowledgment, the client:
- Confirms receipt of messages up to a given sequence number (
ack) - Allows the server to continue sending additional data within the configured window
{
"type": "request:history:ack",
"id": "<stream-id>",
"ack": 10
}
XPub Streaming
XPub streaming allows the client to request transaction history for all addresses derived from an extended public key (xpub), following standard hierarchical deterministic (HD) wallet derivation.
Request
{
"type": "request:history:xpub",
"id": "<stream-id>",
"xpub": "<xpub>",
"first-index": 0,
"gap-limit": 20,
"window-size": 10
}
Fields
id→ Unique identifier for the stream. Used to correlate all subsequent streaming eventsxpub→ Extended public key used to derive addressesfirst-index→ Starting index for address derivationgap-limit→ Maximum number of consecutive unused addresses before stopping derivationwindow-size→ Optional value that enables flow control and acknowledgment (ACK) behavior
Behavior
- The server derives addresses from the provided
xpubusing standard HD wallet rules - History is streamed incrementally using
stream:history:*events - If
window-sizeis provided:- The server limits the number of unacknowledged messages
- The client must send
request:history:ackmessages to continue receiving data
- Streaming continues until:
- All history has been sent, or
- The client stops the stream
Stream Events
The server emits the following events to deliver and control the history stream.
Begin
Indicates the start of a stream.
{
"type": "stream:history:begin",
"id": "<stream-id>",
"seq": 1
}
Address
Marks a new address context within the stream.
{
"type": "stream:history:address",
"id": "<stream-id>",
"address": "<address>",
"index": 0,
"seq": 2
}
Vertex
Contains a transaction or block from the history.
{
"type": "stream:history:vertex",
"id": "<stream-id>",
"data": {},
"seq": 3
}
End
Indicates that the stream has completed.
{
"type": "stream:history:end",
"id": "<stream-id>",
"seq": 100
}
Error
Indicates that an error occurred during streaming.
{
"type": "stream:history:error",
"id": "<stream-id>",
"message": "<error-message>"
}
Manual Address Streaming
Allows the client to stream history for a custom list of addresses.
First Batch
{
"type": "request:history:manual",
"id": "<stream-id>",
"first": true,
"addresses": [[0, "<address>"]],
"first-index": 0,
"gap-limit": 20,
"window-size": 10
}
Subsequent Batches
{
"type": "request:history:manual",
"id": "<stream-id>",
"first": false,
"addresses": [[1, "<address>"]]
}
Fields
addresses→ List of[index, address]pairsfirst→ Indicates whether this is the initial batchwindow-size→ Optional, enables flow control
Stream Behavior
- Uses the same
stream:history:*events as xpub streaming - Events are scoped by
idand must be processed in order - Ordering is guaranteed via
seq
Flow Control
Controls how many messages can be in-flight at any time.
Concepts
window-size→ Maximum unacknowledged messagesack→ Last processed sequence number
Behavior
- Client sets
window-size - Server sends messages up to the limit
- Client sends ACK
- Server resumes streaming
Guarantees
- No message loss
- Controlled delivery rate
- Deterministic ordering