StreamMiscEvents - Real-time Miscellaneous Event Streaming
Stream non-fill balance-affecting events from Hyperliquid L1 Gateway via gRPC. Monitor deposits, withdrawals, transfers, staking, and validator rewards in real-time.
Stream miscellaneous L1 events starting from a position, providing real-time access to every non-fill balance-affecting action on Hyperliquid: deposits, withdrawals, transfers, staking delegations, and validator rewards.
Full Code Examples
Clone our gRPC Code Examples Repository for complete, runnable implementations in Go, Python, and Node.js.
When to Use This Method
StreamMiscEvents is essential for:
- Deposit & Withdrawal Monitoring - Track funds entering and leaving accounts in real-time
- Treasury & Transfer Tracking - Follow spot transfers and internal
sendmovements - Staking & Delegation Analytics - Observe delegations, undelegations, and staking withdrawals
- Validator Reward Accounting - Reconcile per-epoch validator reward distributions
- Compliance & Audit Trails - Build a complete record of balance-affecting activity
Completes the Balance Picture
StreamMiscEvents covers everything StreamFills does not. Fills are trades; misc events are every other action that moves funds. Consume both streams together for a complete view of all balance-affecting activity.
Method signature
rpc StreamMiscEvents(StreamRequest) returns (stream Record) {}V3 accepts an inclusive position.block_number or Unix-millisecond position.timestamp. Explicit zero is invalid. A positioned call replays inclusively and then tails live; an empty request tails newly written miscellaneous events. This feed does not accept filters.
position: {
block_number: 1058646974
}Each Record contains optional block_number and timestamp cursors plus the raw misc_events_by_block envelope in data. A pruned position returns NOT_FOUND; a non-empty filter returns INVALID_ARGUMENT.
Response Stream
V3 carries the JSON-encoded misc_events_by_block envelope in Record.data.
Decode the data field to access:
- Block reference (
local_time,block_time,block_number) - An
eventsarray of miscellaneous L1 event objects (empty for most blocks)
Per-Block Delivery
An emitted source envelope can contain an empty events array. That is a valid source record, not a transport heartbeat, and it does not prove that the connection is healthy.
Clients must detect discontinuities and duplicates and persist only a cursor they actually received. Stream health comes from RPC status, deadlines, and reconnect handling; UNAVAILABLE means no new records arrived before the stream timeout.
Full Misc Events Spec
StreamMiscEvents emits a JSON payload matching Hyperliquid's misc_events_by_block format, passed through byte-for-byte from the node with no normalization. Below is the exact structure.
Top-level keys (always present):
{
"local_time": "2026-07-02T11:10:49.483839100", // ISO-8601 timestamp when node processed the block (nanosecond precision)
"block_time": "2026-07-02T11:10:47.023075863", // ISO-8601 timestamp from block consensus
"block_number": 1057659853, // Block height containing these events
"events": [] // Array of miscellaneous event objects (empty for most blocks)
}Each entry in events is a raw upstream Hyperliquid L1 event object:
| Field | Type | Description |
|---|---|---|
time | string | ISO-8601 timestamp of the event |
hash | string | Transaction hash. An all-zeros hash indicates a system-generated event (e.g. validator rewards) rather than a user transaction |
inner | object | Single-key object whose key is the event type discriminator (e.g. "LedgerUpdate", "Delegation", "CWithdrawal", "ValidatorRewards") |
Branch on the single key inside inner to determine the event type. The sections below cover the event types observed on mainnet; the upstream schema defines additional types, so treat these as examples rather than an exhaustive list. The authoritative schema reference is Hyperliquid's L1 data schemas documentation.
Guarantees and alignment:
eventscontains all miscellaneous events from the block, across all users.- An envelope may contain an empty
eventsarray; treat it as source data rather than a liveness signal. block_numberis sequential and distinct from the potentially skippingabci_block.roundconsensus value in StreamBlocks;block_timealigns withabci_block.time.
Developer tips:
- Branch on the key inside
innerand handle unknown event types defensively — the upstream set can grow. - Track the last processed
block_numberso you can resume cleanly after a reconnect. - Normalize amount fields (strings) to numeric types as appropriate.
- Treat the all-zeros
hashas the marker for system-generated events.
Event Types
LedgerUpdate
LedgerUpdate is the most common event type. It carries a users array (the involved addresses) and a delta object whose type field discriminates the specific ledger action.
{
"time": "2026-07-02T11:10:47.023075863",
"hash": "0xae740acbd26e0108afed043f0a9bcd02022d00b16d611fda523cb61e9161daf3",
"inner": {
"LedgerUpdate": {
"users": [
"0x2000000000000000000000000000000000000000",
"0x0a82a35f3e54aede3a20931f446836e6c69cae0b"
],
"delta": {
"type": "spotTransfer",
"token": "USDC",
"amount": "100.058362",
"usdcValue": "100.058362",
"user": "0x2000000000000000000000000000000000000000",
"destination": "0x0a82a35f3e54aede3a20931f446836e6c69cae0b",
"fee": "0.0",
"nativeTokenFee": "0.0",
"nonce": 2053915,
"feeToken": ""
}
}
}
}The delta.type discriminator determines the remaining fields. Observed types on mainnet include:
delta.type | Meaning | Notable fields |
|---|---|---|
send | Internal transfer between accounts | user, destination, token, amount, usdcValue, fee |
spotTransfer | Spot balance transfer | user, destination, token, amount, usdcValue, fee |
deposit | Funds deposited into an account | usdc |
withdraw | Funds withdrawn from an account | usdc, nonce, fee |
rewardsClaim | Rewards claimed | token, amount |
borrowLend | Borrow/lend operation | token, operation, amount, interestAmount |
More delta.type values exist upstream; branch defensively on delta.type and treat this table as examples, not an exhaustive list. Example deltas:
{ "type": "deposit", "usdc": "3494.915745" }
{ "type": "withdraw", "usdc": "89.15", "nonce": 1782990425200000, "fee": "1.0" }
{ "type": "rewardsClaim", "amount": "1.097128", "token": "USDC" }
{ "type": "borrowLend", "token": "USDC", "operation": "supply", "amount": "0.23068", "interestAmount": "0.0" }Delegation
Staking delegation and undelegation. The is_undelegate flag distinguishes the two directions.
{
"time": "2026-07-02T11:11:06.583481947",
"hash": "0xfa0716eba98e39b0fb80043f0a9cec02029400d1448158839dcfc23e6882139b",
"inner": {
"Delegation": {
"user": "0xd5a5ae523080973946ac67e34f5fc70671bd8667",
"validator": "0x5ac99df645f3414876c816caa18b2d234024b487",
"amount": "20.65611502",
"is_undelegate": true
}
}
}CWithdrawal
A staking withdrawal, which enters a pending state until finalization. The is_finalized flag reflects whether the withdrawal has completed.
{
"time": "2026-07-02T11:11:07.283636968",
"hash": "0xae4f651df8ef488eafc9043f0a9cf6021348000393e2676052181070b7e32279",
"inner": {
"CWithdrawal": {
"user": "0xd5a5ae523080973946ac67e34f5fc70671bd8667",
"amount": "20.65611502",
"is_finalized": false
}
}
}ValidatorRewards
Per-epoch validator reward distributions. These are system-generated, so they carry an all-zeros hash. The validator_to_reward array holds [validator_address, amount] pairs.
{
"time": "2026-07-02T11:11:00.042812129",
"hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
"inner": {
"ValidatorRewards": {
"validator_to_reward": [
["0x000000000056f99d36b6f2e0c51fd41496bbacb8", "0.2806444"],
["0x15458aed3c7a49b215fbfa863c6ff550c31e1a31", "0.22056816"],
["0x30c66ebc7f5ef4f340b424a26e4d944f60129815", "0.34709989"]
]
}
}
}Common Use Cases
Open V3 with an empty StreamRequest to tail newly written records, decode each Record.data envelope, and branch on the event's inner discriminator. To resume, set StreamRequest.position.block_number to a cursor you persisted and replay inclusively, deduplicating the committed record.
Error Handling and Reconnection
Reconnect with StreamRequest.position.block_number set to the last committed V3 cursor. Replay is inclusive, so deduplicate that record before advancing. Use bounded backoff for retryable RPC statuses.
Best Practices
- Connection Management: Implement robust reconnection logic with exponential backoff
- Resumable State: Follow the version-specific recovery guidance above and persist the cursor required by your selected API version
- Defensive Parsing: Branch on the key inside
inner(anddelta.typeforLedgerUpdate) and handle unknown types gracefully - Health Monitoring: Use RPC status, deadlines, and reconnect handling; empty source envelopes are not heartbeats
- Performance: Process events asynchronously to avoid blocking the stream
- Resource Cleanup: Properly close streams and connections on shutdown
Current Limitations
- Replay History: Available replay history varies by feed and endpoint. A cursor outside retained history returns
NOT_FOUND - Schema Coverage: The upstream event set can grow; treat the documented event and delta types as examples, not an exhaustive list
- Backpressure: High-volume periods may require careful handling to avoid overwhelming downstream systems
Resources
- GitHub: gRPC Code Examples - Complete working examples
- GetMiscEvents - Point-in-time miscellaneous event retrieval
- StreamFills - The sibling stream for trade executions; pair with misc events for complete balance coverage
- Hyperliquid L1 Data Schemas - Authoritative upstream event schema reference
Need help? Contact our support team or check the Hyperliquid gRPC documentation.
StreamFills - Real-time Fill Streaming
Stream continuous fill data from Hyperliquid L1 Gateway via gRPC. Monitor order executions in real-time.
StreamOrderStatuses - Real-time Order Status Streaming
Stream order lifecycle events from Hyperliquid L1 Gateway via gRPC. Track opens, fills, cancellations, and rejections per block in real time.