diff --git a/core/src/exchanges/hyperliquid/fetcher.ts b/core/src/exchanges/hyperliquid/fetcher.ts index 036952b2..ca9329a6 100644 --- a/core/src/exchanges/hyperliquid/fetcher.ts +++ b/core/src/exchanges/hyperliquid/fetcher.ts @@ -142,6 +142,19 @@ export interface HyperliquidRawUserState { withdrawable: string; } +// Spot balance entry — coin/token + total/hold/entryNtl in token units (already human-readable). +export interface HyperliquidRawSpotBalance { + coin: string; + token: number; + total: string; + hold: string; + entryNtl: string; +} + +export interface HyperliquidRawSpotState { + balances: HyperliquidRawSpotBalance[]; +} + // Per-coin context from spotMetaAndAssetCtxs (only the fields we use) export interface HyperliquidRawSpotAssetCtx { coin: string; // "#NNNN" for outcome legs @@ -334,6 +347,13 @@ export class HyperliquidFetcher implements IExchangeFetcher { + return this.postInfo({ + type: 'spotClearinghouseState', + user: walletAddress, + }); + } + async fetchRawUserState(walletAddress: string): Promise { return this.postInfo({ type: 'clearinghouseState', diff --git a/core/src/exchanges/hyperliquid/index.ts b/core/src/exchanges/hyperliquid/index.ts index b4cd04c3..7e388677 100644 --- a/core/src/exchanges/hyperliquid/index.ts +++ b/core/src/exchanges/hyperliquid/index.ts @@ -171,8 +171,11 @@ export class HyperliquidExchange extends PredictionMarketExchange { async fetchBalance(): Promise { const wallet = this.requireWallet(); - const raw = await this.fetcher.fetchRawUserState(wallet); - return this.normalizer.normalizeBalance(raw); + const [perp, spot] = await Promise.all([ + this.fetcher.fetchRawUserState(wallet), + this.fetcher.fetchRawSpotState(wallet), + ]); + return this.normalizer.normalizeBalance(perp, spot); } async fetchPositions(): Promise { diff --git a/core/src/exchanges/hyperliquid/normalizer.ts b/core/src/exchanges/hyperliquid/normalizer.ts index 906191c6..5ccfe0de 100644 --- a/core/src/exchanges/hyperliquid/normalizer.ts +++ b/core/src/exchanges/hyperliquid/normalizer.ts @@ -26,6 +26,7 @@ import { HyperliquidRawOpenOrder, HyperliquidRawPosition, HyperliquidRawUserState, + HyperliquidRawSpotState, HyperliquidRawOutcomeMeta, HyperliquidRawMid, } from './fetcher'; @@ -459,17 +460,36 @@ export class HyperliquidNormalizer implements IExchangeNormalizer 0) { + result.push({ + currency: 'USDC_PERP', + total: perpTotal, + available: perpTotal - perpLocked, + locked: perpLocked, + }); + } + + return result; } // -- Private helpers -------------------------------------------------------