Skip to main content

Subscribe

Use the same subscription object with method: "unsubscribe" to stop delivery. Each stream requires a 0x-prefixed wallet address; addresses are case insensitive.

Delivery and recovery

The subscription acknowledgment precedes an initial snapshot, including an empty snapshot. Snapshots contain the latest 100 matching rows, oldest first. Live messages contain only new or changed rows, in batches of at most 100. All messages carry data.user, data.isSnapshot, and Notional’s data.blockNumber committed-state watermark. The snapshot read and publication finish synchronously before live delivery can begin. Rows use the same projection as HTTP ledger history, including assigned-market funding, LP accrual journals, and outcome operation state. Amounts remain decimal strings, timestamps remain Unix milliseconds, and unavailable accounting metadata remains absent or null. Upsert by the canonical row’s id, an opaque stable string. A terminal withdrawal keeps the pending withdrawal’s id even though its hash and time can change. Outcome operations also retain their identity through pending, active, reconciliation, and terminal statuses. Separate rows from one transaction have distinct IDs. Do not deduplicate by timestamp or transaction hash alone, and do not let an older pending row replace a terminal row. On reconnect, resubscribe and read HTTP history to recover gaps larger than the snapshot and lifecycle changes to older rows. A snapshot is a recent window, not a replacement for complete cached history. The frontend performs this recovery and retains live rows while HTTP reads finish. Successful HTTP reads refresh nonterminal stream state received before the request; stream updates received during the request still take precedence. Terminal receipts remain retained across reconnects, including before the first successful HTTP read. Cache and subscription identities include the wallet and network. HTTP remains available for complete retained history and exports. There is no durable WebSocket replay cursor or exactly-once delivery guarantee. Consumers must tolerate duplicates and repeated snapshots. Dropped messages at the server’s backpressure limit close the connection so recovery can run. Projection failures also close affected streams. HTTP history uses bounded timestamp pages (2,000 rows by default); complete recovery and exports traverse every page with a fixed endTime. Each stream seeds its accounting projection from canonical history, independently of HTTP page limits, then applies newly committed transactions and journal rows in committed order. Old lifecycle changes and backdated funding remain deliverable without replaying retained history for every update. A new wallet initializes its LP replay when its first wallet event arrives. Projection state is disposable: unsubscribe, restart, or a missed commit requires a fresh snapshot; commit gaps close affected streams.

Funding envelope

Positive usdc means funding received; negative means paid. fundingRate copies ledger.delta.rate when present and is omitted when unavailable. ledger preserves the complete HTTP row.

Non-funding envelope

{ "channel": "userNonFundingLedgerUpdates", "data": { "user": "0x...", "isSnapshot": true, "blockNumber": 123, "nonFundingLedgerUpdates": [] } } Every array element is a canonical ledger row, including id, hash, time, delta, and any status, transfer, or outcome metadata. Transfers retain native asset units; outcome activity retains exact signed outcome.assetDeltas. Interest is delivered exclusively by userBorrowLendInterest.

Borrow/lend envelope

{ "channel": "userBorrowLendInterest", "data": { "user": "0x...", "isSnapshot": false, "blockNumber": 123, "interest": [] } } Each element contains time, token, borrow, supply, and ledger. borrow is the positive magnitude of a borrower charge; supply is lender interest income. The opposite side is "0". Both are in token units. The signed amount, eligible balance or debt, rate basis, APR, and accrual interval remain unchanged in ledger. pUSD borrower charges stay in pUSD. USDC supplier distributions classified as rewards remain on the non-funding stream. The canonical projection does not currently itemize pUSD supplier yield.

Hyperliquid compatibility

The subscription names, { channel, data } envelopes, user and isSnapshot fields, and funding and non-funding array names follow Hyperliquid’s subscription contract. The userBorrowLendInterest name, interest array, and time/token/borrow/supply fields were verified against the official deployed client on October 16, 2026; this stream is absent from the published subscription list. The testnet client and live testnet snapshots were also checked on October 17, 2026. All three streams use the same payload array names above. The observed funding snapshot contained 100 rows ordered oldest first; non-funding snapshots also arrived oldest first. The deployed frontend retains 100 funding/interest rows on desktop, 30 on mobile, and 30 non-funding rows. It sorts newest first, resubscribes after reconnect, and merges live funding ahead of complete HTTP funding history. Notional keeps its existing recent-history display limit and HTTP fallback, while preserving settled receipts when a read replica lags. The testnet trading client was rechecked on October 19, 2026. Its deployed history modules still use these stream selectors, bounded live history, and separate complete HTTP reads. Notional additionally reconciles mutable operation statuses and retains terminal receipts as described above. Notional intentionally adds blockNumber, canonical row IDs, and the lossless ledger field on funding and interest entries. Non-funding entries use Notional ledger deltas, including withdrawal rather than Hyperliquid’s withdraw, pending/failed statuses, and multi-asset outcome metadata. These describe the user’s Notional ledger, including omnibus allocations; they are not raw events from an individual Hyperliquid account. Funding and interest entries remain separate canonical legs even when they share a market/token and timestamp. Notional therefore deduplicates by row id, rather than the deployed client’s funding key of coin plus timestamp. Interest token uses Notional’s canonical ledger asset label, including pUSD; paid and earned amounts keep their native units and decimal-string precision. The official HTTP history contract uses userFunding (singular) for funding and userNonFundingLedgerUpdates for other activity, with inclusive millisecond startTime/endTime bounds. Time-range requests are paginated at 500 entries or distinct blocks. Notional’s HTTP recovery and exports use its ledger read with types, inclusive startTime/endTime, limit, and the stable row afterId boundary. Complete reads keep one fixed endTime while traversing pages and fail if any page is unavailable or incomplete. The WebSocket reconnect guidance allows recovery from a fresh subscription snapshot or an HTTP history read. Notional uses both because a bounded snapshot can omit older lifecycle changes. Its existing socket heartbeat sends { "method": "ping" } and accepts { "channel": "pong" }, matching the documented heartbeat protocol.