Abonnements
Diese Seite beschreibt das Abonnieren von Datenströmen über die WebSocket-API.
Abonnement-Nachrichten
Um bestimmte Daten-Feeds zu abonnieren, müssen Sie eine Abonnement-Nachricht senden. Das Format der Abonnement-Nachricht ist wie folgt:
{
"method": "subscribe",
"subscription": { ... }
}
Die Abonnement-Bestätigung liefert einen Snapshot vorheriger Daten für Zeitreihendaten (z. B. User Fills). Diese Snapshot-Nachrichten sind mit isSnapshot: true gekennzeichnet und können ignoriert werden, falls die vorherigen Nachrichten bereits verarbeitet wurden.
Das Abonnement-Objekt enthält die Details des jeweiligen Feeds, den Sie abonnieren möchten. Wählen Sie aus den folgenden Abonnement-Typen und geben Sie die entsprechenden Eigenschaften an:
allMids: * Abonnement-Nachricht:{ "type": "allMids", "dex": "<dex>" }* Datenformat:AllMids* Das Felddexgibt die Perp-DEX an, von der die Mids bezogen werden. * Hinweis: Das Felddexist optional. Wird es nicht angegeben, wird die erste Perp-DEX verwendet. Spot-Mids sind nur bei der ersten Perp-DEX enthalten.notification: * Abonnement-Nachricht:{ "type": "notification", "user": "<address>" }* Datenformat:NotificationwebData3: * Abonnement-Nachricht:{ "type": "webData3", "user": "<address>" }* Datenformat:WebData3twapStates: * Abonnement-Nachricht:{ "type": "twapStates", "user": "<address>", "dex": "<dex>" }* Datenformat:TwapStatesclearinghouseState:* Abonnement-Nachricht:{ "type": "clearinghouseState", "user": "<address>", "dex": "<dex>" }* Datenformat:ClearinghouseStateopenOrders: * Abonnement-Nachricht:{ "type": "openOrders", "user": "<address>", "dex": "<dex>" }* Datenformat:OpenOrderscandle: * Abonnement-Nachricht:{ "type": "candle", "coin": "<coin_symbol>", "interval": "<candle_interval>" }* Unterstützte Intervalle: "1m", "3m", "5m", "15m", "30m", "1h", "2h", "4h", "8h", "12h", "1d", "3d", "1w", "1M" * Datenformat:Candle[]l2Book: * Abonnement-Nachricht:{ "type": "l2Book", "coin": "<coin_symbol>" }* Optionale Parameter:nSigFigs: int,mantissa: int,fast: boolean(5 Stufen bei fast, 20 Stufen bei slow) * Datenformat:WsBooktrades: * Abonnement-Nachricht:{ "type": "trades", "coin": "<coin_symbol>" }* Datenformat:WsTrade[]orderUpdates:- Abonnement-Nachricht:
{ "type": "orderUpdates", "user": "<address>" } - Datenformat:
WsOrder[]
- Abonnement-Nachricht:
userEvents:- Abonnement-Nachricht:
{ "type": "userEvents", "user": "<address>" } - Datenformat:
WsUserEvent - Hinweis: Der Channel-Name für
userEvents-Nachrichten ist"channel": "user"
- Abonnement-Nachricht:
userFills:- Abonnement-Nachricht:
{ "type": "userFills", "user": "<address>" } - Optionaler Parameter:
aggregateByTime: bool - Datenformat:
WsUserFills
- Abonnement-Nachricht:
userFundings:- Abonnement-Nachricht:
{ "type": "userFundings", "user": "<address>" } - Datenformat:
WsUserFundings
- Abonnement-Nachricht:
userNonFundingLedgerUpdates:- Abonnement-Nachricht:
{ "type": "userNonFundingLedgerUpdates", "user": "<address>" } - Datenformat:
WsUserNonFundingLedgerUpdates
- Abonnement-Nachricht:
activeAssetCtx:- Abonnement-Nachricht:
{ "type": "activeAssetCtx", "coin": "<coin_symbol>" } - Datenformat:
WsActiveAssetCtxoderWsActiveSpotAssetCtx
- Abonnement-Nachricht:
activeAssetData: (unterstützt nur Perps)- Abonnement-Nachricht:
{ "type": "activeAssetData", "user": "<address>", "coin": "<coin_symbol>" } - Datenformat:
WsActiveAssetData
- Abonnement-Nachricht:
userTwapSliceFills:- Abonnement-Nachricht:
{ "type": "userTwapSliceFills", "user": "<address>" } - Datenformat:
WsUserTwapSliceFills
- Abonnement-Nachricht:
userTwapHistory:- Abonnement-Nachricht:
{ "type": "userTwapHistory", "user": "<address>" } - Datenformat:
WsUserTwapHistory
- Abonnement-Nachricht:
bbo:- Abonnement-Nachricht:
{ "type": "bbo", "coin": "<coin>" } - Datenformat:
WsBbo
- Abonnement-Nachricht:
spotState- Abonnement-Nachricht:
{ "type": "spotState", "user": "<address>", "isPortfolioMargin": bool } - Datenformat:
WsSpotState isPortfolioMarginist ein optionales Argument
- Abonnement-Nachricht:
allDexsClearinghouseState- Abonnement-Nachricht:
{ "type": "allDexsClearinghouseState", "user": "<address>" } - Datenformat:
WsAllDexsClearinghouseState
- Abonnement-Nachricht:
allDexsAssetCtxs- Abonnement-Nachricht:
{ "type": "allDexsAssetCtxs" } - Datenformat:
WsAllDexsAssetCtxs
- Abonnement-Nachricht:
outcomeMetaUpdates- Abonnement-Nachricht:
{ "type": "outcomeMetaUpdates" } - Datenformat:
WsOutcomeMetaUpdates
- Abonnement-Nachricht:
fastAssetCtxs- { "method": "subscribe", "subscription": { "type": "fastAssetCtxs" } }
- Datenformat: base64-kodiertes und komprimiertes
WsFastAssetCtxs - Zum Lesen der Daten wenden Sie der Reihe nach Folgendes an:\
1. base64-Dekodierung in Bytes\
2. Dekomprimierung: ein roher DEFLATE-Stream (RFC 1951) — es gibt keinen zlib- (RFC 1950) oder gzip-Wrapper (RFC 1952). Python
zlib.decompress(b, wbits=-15), Browsernew DecompressionStream("deflate-raw"), Node\fflate.inflateSync\ 3. UTF-8-Dekodierung und Parsen als JSON\ 4. Beispiel zum Testen Ihrer Implementierung\ payload:"q1ZyCnFWsqpWyk0syg6oULJSsjQ3NTDQM1Wq1VFyDfFAkTI2MzXQMwJLVVRWWfmFuTiiyBuamOoZKdXWAgA="\ decoded:{ "BTC": { "markPx": "97500.5" }, "ETH": { "markPx": "3650.25" }, "xyz:NVDA": { "markPx": "145.2" }} - Die erste Nachricht ist ein Snapshot; nachfolgende Nachrichten enthalten nur Coins, die aktualisiert wurden. Felder ohne Aktualisierungen werden ausgelassen.
Nutzeradresse
Um die Kontodaten eines Haupt- oder Subkontos zu abonnieren, müssen Sie die tatsächliche Adresse dieses Kontos angeben. Ein häufiger Fehler ist die Verwendung der Adresse einer Agent-Wallet, was zu einem leeren Ergebnis führt.
Datenformate
Der Server antwortet auf erfolgreiche Abonnements mit einer Nachricht, deren channel-Eigenschaft auf "subscriptionResponse" gesetzt ist, zusammen mit dem Feld data, das das ursprüngliche Abonnement enthält. Anschließend beginnt der Server, Nachrichten zu senden, deren channel-Eigenschaft auf den entsprechenden Abonnement-Typ gesetzt ist, z. B. "allMids", und deren Feld data die abonnierten Daten liefert.
Das Format des Feldes data hängt vom Abonnement-Typ ab:
AllMids: Alle Mid-Preise.- Format:
AllMids { mids: Record<string, string> } Notification: Eine Benachrichtigungsnachricht.- Format:
Notification { notification: string } WebData3: Zusammengefasste Informationen über einen Nutzer, hauptsächlich für das Frontend verwendet.- Format:
WebData3 WsTrade[]: Ein Array von Trade-Updates.- Format:
WsTrade[] WsBook: Updates des Orderbuch-Snapshots.- Format:
WsBook { coin: string; levels: [Array<WsLevel>, Array<WsLevel>]; time: number; } WsOrder: Updates der Nutzer-Orders.- Format:
WsOrder[] WsUserEvent: Nutzerereignisse, die keine Order-Updates sind- Format:
WsUserEvent { "fills": [WsFill] | "funding": WsUserFunding | "liquidation": WsLiquidation | "nonUserCancel": [WsNonUserCancel] } WsUserFills: Fills-Snapshot, gefolgt von Streaming-FillsWsUserFundings: Snapshot der Funding-Zahlungen, gefolgt von Funding-Zahlungen zur vollen StundeWsUserNonFundingLedgerUpdates: Ledger-Updates ohne Funding-Zahlungen: Auszahlungen, Einzahlungen, Übertragungen und LiquidationenWsBbo: Bbo-Updates, die nur gesendet werden, wenn sich der Bbo in einem Block ändertWsSpotState: Spot-State-Update.WsAllDexsClearinghouseState: Clearinghouse-States über alle DEXs für einen bestimmten NutzerWsAllDexsAssetCtxs: Asset-Kontexte über alle DEXsWsOutcomeMetaUpdates: Änderungen an den Outcome-Metadaten
Bei den Streaming-Nutzer-Endpunkten wie WsUserFills,WsUserFundings hat die erste Nachricht isSnapshot: true, und die folgenden Streaming-Updates haben isSnapshot: false.
Datentypdefinitionen
Hier sind die Definitionen der in der WebSocket-API verwendeten Datentypen:
interface WsTrade {
coin: string;
side: string;
px: string;
sz: string;
hash: string;
time: number;
// tid is 50-bit hash of (buyer_oid, seller_oid).
// For a globally unique trade id, use (block_time, coin, tid)
tid: number;
users: [string, string] // [buyer, seller]
}
// Snapshot feed, pushed on each block that is at least 0.5 since last push
interface WsBook {
coin: string;
levels: [Array<WsLevel>, Array<WsLevel>];
time: number;
}
interface WsBbo {
coin: string;
time: number;
bbo: [WsLevel | null, WsLevel | null];
}
interface WsLevel {
px: string; // price
sz: string; // size
n: number; // number of orders
}
interface Notification {
notification: string;
}
interface AllMids {
mids: Record<string, string>;
}
interface Candle {
t: number; // open millis
T: number; // close millis
s: string; // coin
i: string; // interval
o: number; // open price
c: number; // close price
h: number; // high price
l: number; // low price
v: number; // volume (base unit)
n: number; // number of trades
}
type WsUserEvent = {"fills": WsFill[]} | {"funding": WsUserFunding} | {"liquidation": WsLiquidation} | {"nonUserCancel" :WsNonUserCancel[]};
interface WsUserFills {
isSnapshot?: boolean;
user: string;
fills: Array<WsFill>;
}
interface WsFill {
coin: string;
px: string; // price
sz: string; // size
side: string;
time: number;
startPosition: string;
dir: string; // used for frontend display
closedPnl: string;
hash: string; // L1 transaction hash
oid: number; // order id
crossed: boolean; // whether order crossed the spread (was taker)
fee: string; // negative means rebate
tid: number; // unique trade id
liquidation?: FillLiquidation;
feeToken: string; // the token the fee was paid in
builderFee?: string; // amount paid to builder, also included in fee
}
interface FillLiquidation {
liquidatedUser?: string;
markPx: number;
method: "market" | "backstop";
}
interface WsUserFunding {
time: number;
coin: string;
usdc: string;
szi: string;
fundingRate: string;
}
interface WsLiquidation {
lid: number;
liquidator: string;
liquidated_user: string;
liquidated_ntl_pos: string;
liquidated_account_value: string;
}
interface WsNonUserCancel {
coin: String;
oid: number;
}
interface WsOrder {
order: WsBasicOrder;
status: string; // See https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint#query-order-status-by-oid-or-cloid for a list of possible values
statusTimestamp: number;
}
interface WsBasicOrder {
coin: string;
side: string;
limitPx: string;
sz: string;
oid: number;
timestamp: number;
origSz: string;
cloid: string | undefined;
}
interface WsActiveAssetCtx {
coin: string;
ctx: PerpsAssetCtx;
}
interface WsActiveSpotAssetCtx {
coin: string;
ctx: SpotAssetCtx;
}
type SharedAssetCtx = {
dayNtlVlm: number;
prevDayPx: number;
markPx: number;
midPx?: number;
};
type PerpsAssetCtx = SharedAssetCtx & {
funding: number;
openInterest: number;
oraclePx: number;
};
type SpotAssetCtx = SharedAssetCtx & {
circulatingSupply: number;
};
interface WsActiveAssetData {
user: string;
coin: string;
leverage: Leverage;
maxTradeSzs: [number, number];
availableToTrade: [number, number];
}
interface WsTwapSliceFill {
fill: WsFill;
twapId: number;
}
interface WsUserTwapSliceFills {
isSnapshot?: boolean;
user: string;
twapSliceFills: Array<WsTwapSliceFill>;
}
interface TwapState {
coin: string;
user: string;
side: string;
sz: number;
executedSz: number;
executedNtl: number;
minutes: number;
reduceOnly: boolean;
randomize: boolean;
timestamp: number;
}
type TwapStatus = "activated" | "terminated" | "finished" | "error";
interface WsTwapHistory {
state: TwapState;
status: {
status: TwapStatus;
description: string;
};
time: number;
}
interface WsUserTwapHistory {
isSnapshot?: boolean;
user: string;
history: Array<WsTwapHistory>;
}
// Additional undocumented fields in WebData3 will be removed on a future update
interface WebData3 {
userState: {
agentAddress: string | null;
agentValidUntil: number | null;
serverTime: number;
cumLedger: number;
isVault: boolean;
user: string;
optOutOfSpotDusting?: boolean;
dexAbstractionEnabled?: boolean;
};
perpDexStates: Array<PerpDexState>;
}
interface PerpDexState {
totalVaultEquity: number;
perpsAtOpenInterestCap?: Array<string>;
leadingVaults?: Array<LeadingVault>;
}
interface LeadingVault {
address: string;
name: string;
}
interface ClearinghouseState {
dex: string;
user: string;
clearinghouseState: InnerClearinghouseState;
}
interface InnerClearinghouseState {
assetPositions: Array<AssetPosition>;
marginSummary: MarginSummary;
crossMarginSummary: MarginSummary;
crossMaintenanceMarginUsed: number;
withdrawable: number;
}
interface MarginSummary {
accountValue: number;
totalNtlPos: number;
totalRawUsd: number;
totalMarginUsed: number;
}
interface AssetPosition { type: "oneWay"; position: Position }
interface OpenOrders {
dex: string;
user: string;
orders: Array<Order>;
}
interface TwapStates {
dex: string;
user: string;
states: Array<[number, TwapState]>;
}
interface WsSpotState {
user: string;
spotState: SpotState;
}
interface SpotState {
balances: Array<UserBalance>;
}
interface UserBalance {
coin: string;
token?: number;
hold: string;
total: string;
entryNtl: string;
}
interface WsAllDexsClearinghouseState {
user: string;
clearinghouseStates: Array<[string, InnerClearinghouseState]>;
}
interface WsAllDexsAssetCtxs {
ctxs: Array<[string, Array<PerpsAssetCtx>]>;
}
type WsOutcomeMetaUpdates = [WsOutcomeMetaUpdate];
type WsOutcomeMetaUpdate =
| { outcomeCreated: OutcomeSpec }
| { outcomeSettled: number }
| { questionUpdated: QuestionSpec }
| { questionSettled: number };
type OutcomeSpec = {
outcome: number;
name: string;
description: string;
sideSpecs: [OutcomeSideSpec, OutcomeSideSpec];
};
type OutcomeSideSpec = {
name: string;
};
type QuestionSpec = {
question: number;
name: string;
description: string;
fallbackOutcome: number;
namedOutcomes: number[];
settledNamedOutcomes: number[];
};
type FFastAssetCtx = {
markPx?: number;
midPx?: number | null;
};
type WsFastAssetCtxs = Record<string, FFastAssetCtx>;
WsUserNonFundingLedgerUpdates
interface WsUserNonFundingLedgerUpdate {
time: number;
hash: string;
delta: WsLedgerUpdate;
}
type WsLedgerUpdate =
| WsDeposit
| WsWithdraw
| WsInternalTransfer
| WsSubAccountTransfer
| WsLedgerLiquidation
| WsVaultDelta
| WsVaultWithdrawal
| WsVaultLeaderCommission
| WsSpotTransfer
| WsAccountClassTransfer
| WsSpotGenesis
| WsRewardsClaim;
interface WsDeposit {
type: "deposit";
usdc: number;
}
interface WsWithdraw {
type: "withdraw";
usdc: number;
nonce: number;
fee: number;
}
interface WsInternalTransfer {
type: "internalTransfer";
usdc: number;
user: string;
destination: string;
fee: number;
}
interface WsSubAccountTransfer {
type: "subAccountTransfer";
usdc: number;
user: string;
destination: string;
}
interface WsLedgerLiquidation {
type: "liquidation";
// NOTE: for isolated positions this is the isolated account value
accountValue: number;
leverageType: "Cross" | "Isolated";
liquidatedPositions: Array<LiquidatedPosition>;
}
interface LiquidatedPosition {
coin: string;
szi: number;
}
interface WsVaultDelta {
type: "vaultCreate" | "vaultDeposit" | "vaultDistribution";
vault: string;
usdc: number;
}
interface WsVaultWithdrawal {
type: "vaultWithdraw";
vault: string;
user: string;
requestedUsd: number;
commission: number;
closingCost: number;
basis: number;
netWithdrawnUsd: number;
}
interface WsVaultLeaderCommission {
type: "vaultLeaderCommission";
user: string;
usdc: number;
}
interface WsSpotTransfer = {
type: "spotTransfer";
token: string;
amount: number;
usdcValue: number;
user: string;
destination: string;
fee: number;
}
interface WsAccountClassTransfer = {
type: "accountClassTransfer";
usdc: number;
toPerp: boolean;
}
interface WsSpotGenesis = {
type: "spotGenesis";
token: string;
amount: number;
}
interface WsRewardsClaim = {
type: "rewardsClaim";
amount: number;
}
Bitte beachten Sie, dass die oben genannten Datentypen im TypeScript-Format vorliegen und ihre Verwendung den jeweiligen Abonnement-Typen entspricht.
Beispiele
Hier sind einige Beispiele für das Abonnieren verschiedener Feeds mithilfe der Abonnement-Nachrichten:
- Alle Mid-Preise abonnieren:
json
{ "method": "subscribe", "subscription": { "type": "allMids" } }
2. Benachrichtigungen für einen bestimmten Nutzer abonnieren:
json
{ "method": "subscribe", "subscription": { "type": "notification", "user": "<address>" } }
3. Web-Daten für einen bestimmten Nutzer abonnieren:
json
{ "method": "subscribe", "subscription": { "type": "webData3", "user": "<address>" } }
4. Candle-Updates für einen bestimmten Coin und ein bestimmtes Intervall abonnieren:
json
{ "method": "subscribe", "subscription": { "type": "candle", "coin": "<coin_symbol>", "interval": "<candle_interval>" } }
5. Orderbuch-Updates für einen bestimmten Coin abonnieren:
json
{ "method": "subscribe", "subscription": { "type": "l2Book", "coin": "<coin_symbol>" } }
6. Trades für einen bestimmten Coin abonnieren:
json
{ "method": "subscribe", "subscription": { "type": "trades", "coin": "<coin_symbol>" } }
Abmelden von WebSocket-Feeds
Um einen bestimmten Daten-Feed über die Hyperliquid-WebSocket-API abzubestellen, müssen Sie eine Abmelde-Nachricht im folgenden Format senden:
{
"method": "unsubscribe",
"subscription": { ... }
}
Das subscription-Objekt sollte mit der ursprünglichen Abonnement-Nachricht übereinstimmen, die beim Abonnieren des Feeds gesendet wurde. Dadurch kann der Server den spezifischen Feed identifizieren, den Sie abbestellen möchten. Durch das Senden dieser Abmelde-Nachricht weisen Sie den Server an, keine weiteren Updates für den angegebenen Feed zu senden.
Bitte beachten Sie, dass das Abbestellen eines bestimmten Feeds keine Auswirkungen auf andere Abonnements hat, die Sie zu diesem Zeitpunkt möglicherweise aktiv haben. Um mehrere Feeds abzubestellen, können Sie mehrere Abmelde-Nachrichten senden, jeweils mit den entsprechenden Abonnement-Details.