サブスクリプション
このページでは、WebSocket APIを使用したデータストリームのサブスクリプションについて説明します。
サブスクリプションメッセージ
特定のデータフィードをサブスクライブするには、サブスクリプションメッセージを送信する必要があります。サブスクリプションメッセージのフォーマットは以下の通りです:
{
"method": "subscribe",
"subscription": { ... }
}
サブスクリプションのackには、時系列データ(例:ユーザーの約定)に関する以前のデータのスナップショットが含まれます。これらのスナップショットメッセージには isSnapshot: true のタグが付けられており、以前のメッセージが既に処理済みの場合は無視できます。
subscriptionオブジェクトには、サブスクライブしたい特定フィードの詳細が含まれます。以下のサブスクリプションタイプから選択し、対応するプロパティを指定してください:
allMids: * Subscription message:{ "type": "allMids", "dex": "<dex>" }* Data format:AllMids*dexフィールドは、ミッドプライスを取得する対象のperp dexを表します。 *dexフィールドはオプションであることに注意してください。指定されない場合、最初のperp dexが使用されます。スポットのミッドプライスは最初のperp dexと一緒にのみ含まれます。notification: * Subscription message:{ "type": "notification", "user": "<address>" }* Data format:NotificationwebData3: * Subscription message:{ "type": "webData3", "user": "<address>" }* Data format:WebData3twapStates: * Subscription message:{ "type": "twapStates", "user": "<address>", "dex": "<dex>" }* Data format:TwapStatesclearinghouseState:* Subscription message:{ "type": "clearinghouseState", "user": "<address>", "dex": "<dex>" }* Data format:ClearinghouseStateopenOrders: * Subscription message:{ "type": "openOrders", "user": "<address>", "dex": "<dex>" }* Data format:OpenOrderscandle: * 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[]l2Book: * Subscription message:{ "type": "l2Book", "coin": "<coin_symbol>" }* Optional parameters:nSigFigs: int,mantissa: int,fast: boolean(fastの場合5レベル、slowの場合20レベル) * Data format:WsBooktrades: * Subscription message:{ "type": "trades", "coin": "<coin_symbol>" }* Data format:WsTrade[]orderUpdates:- Subscription message:
{ "type": "orderUpdates", "user": "<address>" } - Data format:
WsOrder[]
- Subscription message:
userEvents:- Subscription message:
{ "type": "userEvents", "user": "<address>" } - Data format:
WsUserEvent - 注:
userEventsメッセージのチャンネル名は"channel": "user"です
- Subscription message:
userFills:- Subscription message:
{ "type": "userFills", "user": "<address>" } - Optional parameter:
aggregateByTime: bool - Data format:
WsUserFills
- Subscription message:
userFundings:- Subscription message:
{ "type": "userFundings", "user": "<address>" } - Data format:
WsUserFundings
- Subscription message:
userNonFundingLedgerUpdates:- Subscription message:
{ "type": "userNonFundingLedgerUpdates", "user": "<address>" } - Data format:
WsUserNonFundingLedgerUpdates
- Subscription message:
activeAssetCtx:- Subscription message:
{ "type": "activeAssetCtx", "coin": "<coin_symbol>" } - Data format:
WsActiveAssetCtxまたはWsActiveSpotAssetCtx
- Subscription message:
activeAssetData: (永続契約のみ対応)- Subscription message:
{ "type": "activeAssetData", "user": "<address>", "coin": "<coin_symbol>" } - Data format:
WsActiveAssetData
- Subscription message:
userTwapSliceFills:- Subscription message:
{ "type": "userTwapSliceFills", "user": "<address>" } - Data format:
WsUserTwapSliceFills
- Subscription message:
userTwapHistory:- Subscription message:
{ "type": "userTwapHistory", "user": "<address>" } - Data format:
WsUserTwapHistory
- Subscription message:
bbo:- Subscription message:
{ "type": "bbo", "coin": "<coin>" } - Data format:
WsBbo
- Subscription message:
spotState- Subscription message:
{ "type": "spotState", "user": "<address>", "isPortfolioMargin": bool } - Data format:
WsSpotState isPortfolioMarginはオプションの引数です
- Subscription message:
allDexsClearinghouseState- Subscription message:
{ "type": "allDexsClearinghouseState", "user": "<address>" } - Data format:
WsAllDexsClearinghouseState
- Subscription message:
allDexsAssetCtxs- Subscription message:
{ "type": "allDexsAssetCtxs" } - Data format:
WsAllDexsAssetCtxs
- Subscription message:
outcomeMetaUpdates- Subscription message:
{ "type": "outcomeMetaUpdates" } - Data format:
WsOutcomeMetaUpdates
- Subscription message:
fastAssetCtxs- { "method": "subscribe", "subscription": { "type": "fastAssetCtxs" } }
- Data format: base64エンコードされ圧縮された
WsFastAssetCtxs - データを読むには、順番に適用します:\
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" }} - 最初のメッセージはスナップショットで、以降のメッセージには更新されたコインのみが含まれます。更新のないフィールドは省略されます。
ユーザーアドレス
マスターアカウントまたはサブアカウントに関連付けられたアカウントデータをサブスクライブするには、そのアカウントの実際のアドレスを渡す必要があります。よくある落とし穴は、エージェントウォレットのアドレスを使用してしまい、空の結果が返されることです。
データ形式
サブスクリプションが成功すると、サーバーは 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形式であり、その使用法はそれぞれのサブスクリプションタイプに対応していることに注意してください。
例
サブスクリプションメッセージを使用して異なるフィードをサブスクライブするいくつかの例を以下に示します:
- すべてのミッドプライスをサブスクライブする:
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 オブジェクトは、フィードをサブスクライブした際に送信された元のサブスクリプションメッセージと一致している必要があります。これにより、サーバーは解除したい特定のフィードを識別できます。この解除メッセージを送信することで、指定されたフィードのそれ以降の更新の送信を停止するようサーバーに通知します。
特定のフィードの解除は、その時点でアクティブな他のサブスクリプションには影響しないことに注意してください。複数のフィードを解除するには、それぞれ適切なサブスクリプション詳細を含む複数の解除メッセージを送信できます。