本ページはコミュニティ翻訳です。参考用であり、内容は英語版を優先します。
英語の原文を見る ↗

サブスクリプション

このページでは、WebSocket APIを使用したデータストリームのサブスクリプションについて説明します。

サブスクリプションメッセージ

特定のデータフィードをサブスクライブするには、サブスクリプションメッセージを送信する必要があります。サブスクリプションメッセージのフォーマットは以下の通りです:

{
  "method": "subscribe",
  "subscription": { ... }
}

サブスクリプションのackには、時系列データ(例:ユーザーの約定)に関する以前のデータのスナップショットが含まれます。これらのスナップショットメッセージには isSnapshot: true のタグが付けられており、以前のメッセージが既に処理済みの場合は無視できます。

subscriptionオブジェクトには、サブスクライブしたい特定フィードの詳細が含まれます。以下のサブスクリプションタイプから選択し、対応するプロパティを指定してください:

  1. allMids: * Subscription message: { "type": "allMids", "dex": "<dex>" } * Data format: AllMids * dex フィールドは、ミッドプライスを取得する対象のperp dexを表します。 * dex フィールドはオプションであることに注意してください。指定されない場合、最初のperp dexが使用されます。スポットのミッドプライスは最初のperp dexと一緒にのみ含まれます。
  2. notification: * Subscription message: { "type": "notification", "user": "<address>" } * Data format: Notification
  3. webData3 : * Subscription message: { "type": "webData3", "user": "<address>" } * Data format: WebData3
  4. twapStates : * Subscription message: { "type": "twapStates", "user": "<address>", "dex": "<dex>" } * Data format: TwapStates
  5. clearinghouseState: * Subscription message: { "type": "clearinghouseState", "user": "<address>", "dex": "<dex>" } * Data format: ClearinghouseState
  6. openOrders: * Subscription message: { "type": "openOrders", "user": "<address>", "dex": "<dex>" } * Data format: OpenOrders
  7. candle: * Subscription message: { "type": "candle", "coin": "<coin_symbol>", "interval": "<candle_interval>" } * Supported intervals: "1m", "3m", "5m", "15m", "30m", "1h", "2h", "4h", "8h", "12h", "1d", "3d", "1w", "1M" * Data format: Candle[]
  8. l2Book: * Subscription message: { "type": "l2Book", "coin": "<coin_symbol>" } * Optional parameters: nSigFigs: int, mantissa: int , fast: boolean (fastの場合5レベル、slowの場合20レベル) * Data format: WsBook
  9. trades: * Subscription message: { "type": "trades", "coin": "<coin_symbol>" } * Data format: WsTrade[]
  10. orderUpdates:
    • Subscription message: { "type": "orderUpdates", "user": "<address>" }
    • Data format: WsOrder[]
  11. userEvents:
    • Subscription message: { "type": "userEvents", "user": "<address>" }
    • Data format: WsUserEvent
    • 注: userEvents メッセージのチャンネル名は "channel": "user" です
  12. userFills:
    • Subscription message: { "type": "userFills", "user": "<address>" }
    • Optional parameter: aggregateByTime: bool
    • Data format: WsUserFills
  13. userFundings:
    • Subscription message: { "type": "userFundings", "user": "<address>" }
    • Data format: WsUserFundings
  14. userNonFundingLedgerUpdates:
    • Subscription message: { "type": "userNonFundingLedgerUpdates", "user": "<address>" }
    • Data format: WsUserNonFundingLedgerUpdates
  15. activeAssetCtx:
    • Subscription message: { "type": "activeAssetCtx", "coin": "<coin_symbol>" }
    • Data format: WsActiveAssetCtx または WsActiveSpotAssetCtx
  16. activeAssetData: (永続契約のみ対応)
    • Subscription message: { "type": "activeAssetData", "user": "<address>", "coin": "<coin_symbol>" }
    • Data format: WsActiveAssetData
  17. userTwapSliceFills:
    • Subscription message: { "type": "userTwapSliceFills", "user": "<address>" }
    • Data format: WsUserTwapSliceFills
  18. userTwapHistory:
    • Subscription message: { "type": "userTwapHistory", "user": "<address>" }
    • Data format: WsUserTwapHistory
  19. bbo :
    • Subscription message: { "type": "bbo", "coin": "<coin>" }
    • Data format: WsBbo
  20. spotState
    • Subscription message: { "type": "spotState", "user": "<address>", "isPortfolioMargin": bool }
    • Data format: WsSpotState
    • isPortfolioMargin はオプションの引数です
  21. allDexsClearinghouseState
    1. Subscription message: { "type": "allDexsClearinghouseState", "user": "<address>" }
    2. Data format: WsAllDexsClearinghouseState
  22. allDexsAssetCtxs
    1. Subscription message: { "type": "allDexsAssetCtxs" }
    2. Data format: WsAllDexsAssetCtxs
  23. outcomeMetaUpdates
    1. Subscription message: { "type": "outcomeMetaUpdates" }
    2. Data format: WsOutcomeMetaUpdates
  24. fastAssetCtxs
    1. { "method": "subscribe", "subscription": { "type": "fastAssetCtxs" } }
    2. Data format: base64エンコードされ圧縮された WsFastAssetCtxs
    3. データを読むには、順番に適用します:\ 1. base64デコードしてバイト列にする\ 2. 展開:raw DEFLATEストリーム(RFC 1951)— zlib(RFC 1950)やgzip(RFC 1952)のラッパーはありません。Pythonでは zlib.decompress(b, wbits=-15)、ブラウザでは new DecompressionStream("deflate-raw")、Nodeでは\ fflate.inflateSync\ 3. UTF-8デコードしてJSONとしてパースする\ 4. 実装をテストするための例\ payload: "q1ZyCnFWsqpWyk0syg6oULJSsjQ3NTDQM1Wq1VFyDfFAkTI2MzXQMwJLVVRWWfmFuTiiyBuamOoZKdXWAgA="\ decoded: { "BTC": { "markPx": "97500.5" }, "ETH": { "markPx": "3650.25" }, "xyz:NVDA": { "markPx": "145.2" }}
    4. 最初のメッセージはスナップショットで、以降のメッセージには更新されたコインのみが含まれます。更新のないフィールドは省略されます。

ユーザーアドレス

マスターアカウントまたはサブアカウントに関連付けられたアカウントデータをサブスクライブするには、そのアカウントの実際のアドレスを渡す必要があります。よくある落とし穴は、エージェントウォレットのアドレスを使用してしまい、空の結果が返されることです。

データ形式

サブスクリプションが成功すると、サーバーは channel プロパティが "subscriptionResponse" に設定されたメッセージで応答し、data フィールドに元のサブスクリプションが含まれます。その後、サーバーは channel プロパティが対応するサブスクリプションタイプ(例: "allMids")に設定され、data フィールドにサブスクライブされたデータを含むメッセージの送信を開始します。

data フィールドの形式はサブスクリプションタイプによって異なります:

  • AllMids: すべてのミッドプライス。
  • Format: AllMids { mids: Record<string, string> }
  • Notification: 通知メッセージ。
  • Format: Notification { notification: string }
  • WebData3: ユーザーに関する集約情報。主にフロントエンドで使用されます。
  • Format: WebData3
  • WsTrade[]: 約定更新の配列。
  • Format: WsTrade[]
  • WsBook: オーダーブックのスナップショット更新。
  • Format: WsBook { coin: string; levels: [Array<WsLevel>, Array<WsLevel>]; time: number; }
  • WsOrder: ユーザーの注文更新。
  • Format: WsOrder[]
  • WsUserEvent: 注文更新以外のユーザーイベント
  • Format: WsUserEvent { "fills": [WsFill] | "funding": WsUserFunding | "liquidation": WsLiquidation | "nonUserCancel": [WsNonUserCancel] }
  • WsUserFills : 約定のスナップショットに続いてストリーミングされる約定
  • WsUserFundings : ファンディング支払いのスナップショットに続いて毎正時に送られるファンディング支払い
  • WsUserNonFundingLedgerUpdates: ファンディング支払いを含まない台帳更新:出金、入金、送金、清算
  • WsBbo : bboがブロック内で変化した場合にのみ送信されるbbo更新
  • WsSpotState : スポットの状態更新。
  • WsAllDexsClearinghouseState : 特定ユーザーの全dexにわたる清算所の状態
  • WsAllDexsAssetCtxs : 全dexにわたるアセットコンテキスト
  • WsOutcomeMetaUpdates : アウトカムメタの変更

WsUserFills、WsUserFundings などのストリーミングユーザーエンドポイントでは、最初のメッセージは isSnapshot: true を持ち、それ以降のストリーミング更新は isSnapshot: false を持ちます。

データ型定義

WebSocket APIで使用されるデータ型の定義は以下の通りです:

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;
}

上記のデータ型はTypeScript形式であり、その使用法はそれぞれのサブスクリプションタイプに対応していることに注意してください。

例

サブスクリプションメッセージを使用して異なるフィードをサブスクライブするいくつかの例を以下に示します:

  1. すべてのミッドプライスをサブスクライブする:

json { "method": "subscribe", "subscription": { "type": "allMids" } } 2. 特定ユーザーの通知をサブスクライブする:

json { "method": "subscribe", "subscription": { "type": "notification", "user": "<address>" } } 3. 特定ユーザーのWebデータをサブスクライブする:

json { "method": "subscribe", "subscription": { "type": "webData3", "user": "<address>" } } 4. 特定のコインとインターバルのローソク足更新をサブスクライブする:

json { "method": "subscribe", "subscription": { "type": "candle", "coin": "<coin_symbol>", "interval": "<candle_interval>" } } 5. 特定コインのオーダーブック更新をサブスクライブする:

json { "method": "subscribe", "subscription": { "type": "l2Book", "coin": "<coin_symbol>" } } 6. 特定コインの約定をサブスクライブする:

json { "method": "subscribe", "subscription": { "type": "trades", "coin": "<coin_symbol>" } }

WebSocketフィードからの解除

Hyperliquid WebSocket APIの特定のデータフィードを解除するには、以下の形式の解除メッセージを送信する必要があります:

{
  "method": "unsubscribe",
  "subscription": { ... }
}

subscription オブジェクトは、フィードをサブスクライブした際に送信された元のサブスクリプションメッセージと一致している必要があります。これにより、サーバーは解除したい特定のフィードを識別できます。この解除メッセージを送信することで、指定されたフィードのそれ以降の更新の送信を停止するようサーバーに通知します。

特定のフィードの解除は、その時点でアクティブな他のサブスクリプションには影響しないことに注意してください。複数のフィードを解除するには、それぞれ適切なサブスクリプション詳細を含む複数の解除メッセージを送信できます。

英語の公式ソース: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/websocket/subscriptions
原文取得日: · ミラー構築日: · コミュニティ翻訳。英語版を優先
非公式のコミュニティ翻訳です。著作権は Hyperliquid に帰属し、内容は英語版を優先します。 出典: https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/websocket/subscriptions