import { Hyperliquid } from "hyperliquid"; import type { ExchangeAdapter, ExchangeMarketInfo, ExchangePosition, ExchangeOrder, ExchangeBalance, ExchangeTrade, ExchangeFundingPayment, ExchangeKline } from "./interface.js"; import type { EvmSigner } from "../signer/index.js"; import type { AgentMeta } from "../settings.js"; export declare class HyperliquidAdapter implements ExchangeAdapter { readonly name = "hyperliquid"; readonly chain = "evm"; readonly aliases: readonly ["hl"]; /** * Reflects whether perp + spot share the same USDC pool (true for unified / * portfolio mode) or are separately margined (false for standard mode and * HIP-3 dex accounts). Populated during init() from _getAbstractionMode(); * defaults to false until init resolves so callers never assume unified * semantics for accounts that have never opted in. Codex v0.12.12 final QA #1. */ isUnifiedAccount: boolean; private sdk; private _address; private _privateKey; private _testnet; private _evmSigner?; private _agentSigner?; private _agentMeta?; private _useNoAgent; private _assetMap; private _assetMapReverse; private _szDecimalsMap; /** HIP-3 deployed perp dex name. Empty string = native (validator) perps. */ private _dex; private static _lastNonce; private _marketsCache; private _marketsCacheTime; private static readonly CACHE_TTL; constructor(privateKey?: string, testnet?: boolean); /** Set the HIP-3 deployed perp dex to query/trade on. */ setDex(dex: string): void; get dex(): string; get client(): Hyperliquid; get address(): string; get isTestnet(): boolean; /** Inject an external EVM signer. Call before init() to skip LocalEvmSigner creation. */ setSigner(signer: EvmSigner): void; /** * Set the user EVM address without attaching a signer. Used by read-only * paths (e.g. `wallet manage account-mode` show branch) that need to query * `/info` endpoints scoped to a master wallet but never sign. */ setAddress(address: string): void; /** Tier 1: inject agent OWS wallet signer. */ setAgentSigner(meta: AgentMeta, signer: EvmSigner): void; /** Bypass Tier 1 (agent) — use for --no-agent flag. */ setNoAgent(noAgent: boolean): void; /** True only when ALL THREE tiers are unconfigured. */ get isReadOnly(): boolean; /** Which signer tier is currently active (for debug/diagnostics). */ get activeSignerTier(): "agent" | "master" | "pk" | null; /** Resolve the active signer across three tiers. */ private _resolveSigner; init(): Promise; /** Load asset index map — supports native and HIP-3 dex. */ private _loadAssetMap; /** * Resolve a symbol to the canonical name in the asset map. * Handles: "ICP" → "ICP-PERP", "BTC-PERP" → "BTC-PERP", "km:GOOGL" → "km:GOOGL" */ resolveSymbol(symbol: string): string; /** Get szDecimals for a symbol (cached from init/getMeta) */ getSzDecimals(symbol: string): number; /** HL official price rounding: 5 significant figures */ private _hlRoundPrice; getAssetIndex(symbol: string): Promise; getMarkets(): Promise; getOrderbook(symbol: string): Promise<{ bids: [string, string][]; asks: [string, string][]; }>; private ensureAddress; /** Read-through cached clearinghouseState — returns cached data if fresh */ private _getClearinghouseState; /** * Read the user's account abstraction mode from HL. * * Returns the canonical mode used to branch collateral accounting: * - "unified" → spot clearinghouseState is the truth source (USDC total * is unified across spot + perp). app.hyperliquid.xyz default. * - "standard" → perp clearinghouseState is the truth source. Required * mode for builder fee accrual. * - "portfolio" → multi-asset cross-collateral; for now treated like * unified (spot truth). Refine when portfolio margin GA. * * Per SSOT Rule #2: an unrecognized venue response throws — no silent * default. HIP-3 dex accounts (`this._dex` set) bypass the lookup since * cross margin scopes per-DEX in standard semantics. * * Endpoint: `POST /info {"type":"userAbstraction","user":"0x..."}` → * returns one of `"unifiedAccount" | "disabled" | "portfolioMargin"`. */ _getAbstractionMode(): Promise<"unified" | "standard" | "portfolio">; /** Cached spot clearinghouse state — shared between getBalance() and HyperliquidSpotAdapter */ _getSpotClearinghouseState(): Promise>; getBalance(): Promise; getPositions(): Promise; getOpenOrders(): Promise; private _invalidateAccountCache; /** * Validate that an HL order actually filled. * HL API returns status "ok" even for 0-fill IoC orders. * Response shape: { status: "ok", response: { type: "order", data: { statuses: [...] } } } * Each status is one of: { filled: { totalSz, avgPx, oid } }, { resting: { oid } }, { error: "msg" } */ private _validateOrderFill; marketOrder(symbol: string, side: "buy" | "sell", size: string, opts?: { reduceOnly?: boolean; }): Promise; /** * Place a market order on a HIP-3 deployed dex. * Bypasses SDK's symbolConversion (which only knows native perps) * and constructs + signs the order action directly. */ private _dexMarketOrder; /** * Sign and send any exchange action via raw EIP-712 signing. * Bypasses the SDK entirely — works for order, batchModify, twapOrder, etc. */ private ensureSigner; /** * Normalize trailing zeros from price ('p') and size ('s') string fields * in an action object, recursively. Matches the SDK's normalizeTrailingZeros. * * The HL validator normalizes these fields before hashing; if we hash without * normalizing, the recovered signer address won't match → "User or API Wallet * does not exist" error. */ private static _normalizeAction; private _signAndSendAction; /** * Place an order via raw exchange API with EIP-712 signing. * This bypasses the SDK's symbolConversion and supports dex-specific orders. */ private _rawPlaceOrder; limitOrder(symbol: string, side: "buy" | "sell", price: string, size: string, opts?: { reduceOnly?: boolean; tif?: string; }): Promise; cancelOrder(symbol: string, orderId: string): Promise; cancelAllOrders(symbol?: string): Promise; editOrder(symbol: string, orderId: string, price: string, size: string): Promise; setLeverage(symbol: string, leverage: number, marginMode?: "cross" | "isolated"): Promise; stopOrder(symbol: string, side: "buy" | "sell", size: string, triggerPrice: string, opts?: { limitPrice?: string; reduceOnly?: boolean; }): Promise; getRecentTrades(symbol: string, limit?: number): Promise; getKlines(symbol: string, interval: string, startTime: number, endTime: number): Promise; getOrderHistory(limit?: number): Promise; getTradeHistory(limit?: number): Promise; getFundingPayments(limit?: number): Promise; getFundingHistory(symbol: string, limit?: number): Promise<{ time: number; rate: string; price: string | null; }[]>; /** * Place a trigger order (stop loss / take profit). * Python SDK: order() with trigger type {"trigger": {triggerPx, isMarket, tpsl: "tp"|"sl"}} */ triggerOrder(symbol: string, side: "buy" | "sell", size: string, triggerPrice: string, tpsl: "tp" | "sl", opts?: { isMarket?: boolean; reduceOnly?: boolean; grouping?: string; }): Promise; /** * Place a TWAP order. * Python SDK: not available in old SDK, available via raw exchange action. * nktkas TS SDK: twapOrder({twap: {a, b, s, r, m, t}}) */ twapOrder(symbol: string, side: "buy" | "sell", size: string, durationMinutes: number, opts?: { reduceOnly?: boolean; randomize?: boolean; }): Promise; /** * Cancel a TWAP order. */ twapCancel(symbol: string, twapId: number): Promise; /** * Update leverage for a symbol. * Uses SDK's built-in updateLeverage method. */ updateLeverage(symbol: string, leverage: number, isCross?: boolean): Promise; /** * Update isolated margin for a position. * amount > 0 to add margin, amount < 0 to remove */ updateIsolatedMargin(symbol: string, amount: number): Promise; /** * Withdraw from Hyperliquid L1 bridge. * Python SDK: withdraw_from_bridge(amount, destination) → action type "withdraw3" */ withdraw(amount: string, destination: string, _opts?: { assetId?: number; routeType?: number; }): Promise; /** * Transfer USD between accounts on Hyperliquid L1. * Python SDK: usd_transfer(amount, destination) */ usdTransfer(amount: number, destination: string): Promise; /** * Create a sub-account. */ createSubAccount(name: string): Promise; /** * Transfer USD between main and sub-account. */ subAccountTransfer(subAccountUser: string, isDeposit: boolean, amount: number): Promise; /** * Modify an existing order. */ modifyOrder(symbol: string, orderId: number, newSide: "buy" | "sell", newPrice: string, newSize: string, opts?: { reduceOnly?: boolean; }): Promise; /** * Schedule cancel: cancel all orders at a future time. * Max 10 triggers per day. */ scheduleCancel(timeMs?: number): Promise; /** * Set referral code. Silent — does not throw. */ autoSetReferrer(code?: string): Promise; /** * Get funding history for a symbol. */ getFundingHistoryRaw(symbol: string, startTime: number, endTime?: number): Promise; /** * Get user trade fills. */ getUserFills(startTime?: number, endTime?: number): Promise; /** * Get user portfolio analytics. */ getPortfolio(): Promise; /** * Query a specific order by OID. */ queryOrder(orderId: number): Promise; /** * Approve a builder fee. * Action type: approveBuilderFee */ approveBuilderFee(builder: string, maxFeeRate: string): Promise; /** * Vault deposit/withdraw. */ vaultTransfer(vaultAddress: string, isDeposit: boolean, usd: number): Promise; /** * Delegate/undelegate tokens for staking. */ tokenDelegate(validator: string, wei: string, isUndelegate?: boolean): Promise; /** * Claim staking rewards. */ claimRewards(): Promise; /** * List all available HIP-3 deployed perp dexes. */ listDeployedDexes(): Promise<{ name: string; deployer: string; assets: string[]; }[]>; /** * Get referral info. */ getReferralInfo(): Promise; /** * Get fee info. */ getUserFees(): Promise; /** * Get sub-accounts. */ getSubAccounts(): Promise; /** * Get historical orders (up to 2000). */ getHistoricalOrders(): Promise; /** * Get approved builders. */ getApprovedBuilders(): Promise; /** * Get vault details. */ getVaultDetails(vaultAddress: string): Promise; /** * Get delegations (staking). */ getDelegations(): Promise; /** * POST to /info endpoint. */ private _infoPost; /** * Public entry point for sending signed exchange actions. * Used by HyperliquidSpotAdapter to delegate signing. */ exchangeAction(action: Record): Promise; /** * Send a raw exchange action through the SDK. * Used for methods not directly exposed by the SDK. */ private _sendExchangeAction; }