Diese Seite ist eine Community-Übersetzung und dient nur zur Orientierung; maßgeblich ist die englische Originalversion.
Englisches Original ↗

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:

  1. allMids: * Abonnement-Nachricht: { "type": "allMids", "dex": "<dex>" } * Datenformat: AllMids * Das Feld dex gibt die Perp-DEX an, von der die Mids bezogen werden. * Hinweis: Das Feld dex ist optional. Wird es nicht angegeben, wird die erste Perp-DEX verwendet. Spot-Mids sind nur bei der ersten Perp-DEX enthalten.
  2. notification: * Abonnement-Nachricht: { "type": "notification", "user": "<address>" } * Datenformat: Notification
  3. webData3 : * Abonnement-Nachricht: { "type": "webData3", "user": "<address>" } * Datenformat: WebData3
  4. twapStates : * Abonnement-Nachricht: { "type": "twapStates", "user": "<address>", "dex": "<dex>" } * Datenformat: TwapStates
  5. clearinghouseState: * Abonnement-Nachricht: { "type": "clearinghouseState", "user": "<address>", "dex": "<dex>" } * Datenformat: ClearinghouseState
  6. openOrders: * Abonnement-Nachricht: { "type": "openOrders", "user": "<address>", "dex": "<dex>" } * Datenformat: OpenOrders
  7. candle: * 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[]
  8. 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: WsBook
  9. trades: * Abonnement-Nachricht: { "type": "trades", "coin": "<coin_symbol>" } * Datenformat: WsTrade[]
  10. orderUpdates:
    • Abonnement-Nachricht: { "type": "orderUpdates", "user": "<address>" }
    • Datenformat: WsOrder[]
  11. userEvents:
    • Abonnement-Nachricht: { "type": "userEvents", "user": "<address>" }
    • Datenformat: WsUserEvent
    • Hinweis: Der Channel-Name für userEvents-Nachrichten ist "channel": "user"
  12. userFills:
    • Abonnement-Nachricht: { "type": "userFills", "user": "<address>" }
    • Optionaler Parameter: aggregateByTime: bool
    • Datenformat: WsUserFills
  13. userFundings:
    • Abonnement-Nachricht: { "type": "userFundings", "user": "<address>" }
    • Datenformat: WsUserFundings
  14. userNonFundingLedgerUpdates:
    • Abonnement-Nachricht: { "type": "userNonFundingLedgerUpdates", "user": "<address>" }
    • Datenformat: WsUserNonFundingLedgerUpdates
  15. activeAssetCtx:
    • Abonnement-Nachricht: { "type": "activeAssetCtx", "coin": "<coin_symbol>" }
    • Datenformat: WsActiveAssetCtx oder WsActiveSpotAssetCtx
  16. activeAssetData: (unterstützt nur Perps)
    • Abonnement-Nachricht: { "type": "activeAssetData", "user": "<address>", "coin": "<coin_symbol>" }
    • Datenformat: WsActiveAssetData
  17. userTwapSliceFills:
    • Abonnement-Nachricht: { "type": "userTwapSliceFills", "user": "<address>" }
    • Datenformat: WsUserTwapSliceFills
  18. userTwapHistory:
    • Abonnement-Nachricht: { "type": "userTwapHistory", "user": "<address>" }
    • Datenformat: WsUserTwapHistory
  19. bbo :
    • Abonnement-Nachricht: { "type": "bbo", "coin": "<coin>" }
    • Datenformat: WsBbo
  20. spotState
    • Abonnement-Nachricht: { "type": "spotState", "user": "<address>", "isPortfolioMargin": bool }
    • Datenformat: WsSpotState
    • isPortfolioMargin ist ein optionales Argument
  21. allDexsClearinghouseState
    1. Abonnement-Nachricht: { "type": "allDexsClearinghouseState", "user": "<address>" }
    2. Datenformat: WsAllDexsClearinghouseState
  22. allDexsAssetCtxs
    1. Abonnement-Nachricht: { "type": "allDexsAssetCtxs" }
    2. Datenformat: WsAllDexsAssetCtxs
  23. outcomeMetaUpdates
    1. Abonnement-Nachricht: { "type": "outcomeMetaUpdates" }
    2. Datenformat: WsOutcomeMetaUpdates
  24. fastAssetCtxs
    1. { "method": "subscribe", "subscription": { "type": "fastAssetCtxs" } }
    2. Datenformat: base64-kodiertes und komprimiertes WsFastAssetCtxs
    3. 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), Browser new 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" }}
    4. 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-Fills
  • WsUserFundings : Snapshot der Funding-Zahlungen, gefolgt von Funding-Zahlungen zur vollen Stunde
  • WsUserNonFundingLedgerUpdates: Ledger-Updates ohne Funding-Zahlungen: Auszahlungen, Einzahlungen, Übertragungen und Liquidationen
  • WsBbo : Bbo-Updates, die nur gesendet werden, wenn sich der Bbo in einem Block ändert
  • WsSpotState : Spot-State-Update.
  • WsAllDexsClearinghouseState : Clearinghouse-States über alle DEXs für einen bestimmten Nutzer
  • WsAllDexsAssetCtxs : Asset-Kontexte über alle DEXs
  • WsOutcomeMetaUpdates : Ä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:

  1. 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.

Offizielle Quelle: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/websocket/subscriptions
Quellstand: · Mirror erstellt: · Community-Übersetzung; die englische Fassung ist maßgeblich
Inoffizielle Community-Übersetzung der Hyperliquid-Dokumentation. Inhalte © Hyperliquid; maßgeblich ist die englische Version. Quelle: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/websocket/subscriptions