hyperliquid_dart 0.17.0
hyperliquid_dart: ^0.17.0 copied to clipboard
A Dart SDK for the Hyperliquid DEX — REST API, WebSocket subscriptions, EIP-712 signing, and order management.
hyperliquid_dart #
A Dart SDK for the Hyperliquid decentralized exchange (DEX). Trade perpetual futures with REST API, WebSocket streams, and EIP-712 signing.
Features #
- REST API — 61 methods/actions across InfoClient (34) and ExchangeClient (27) for market data, account info, trading, transfers, TWAP, HIP-4, and vault operations
- Spot & Perpetual Trading — Full support for both spot markets and perpetual futures
- Vault Operations — Query vaults, check positions, deposit/withdraw funds
- WebSocket — 29 typed real-time subscriptions plus raw subscribe for market, account, DEX, spot, TWAP, and HIP-4 streams
- EIP-712 Signing — Full signing support with wallet-agnostic interface
- Wallet Adapters — Built-in support for raw private keys; bring your own wallet (Privy, Web3Auth, etc.)
- Type-Safe — Comprehensive Dart models for all API responses
- HIP-3 DEX Support — Query and trade on builder-deployed perpetual DEXs
- HIP-4 Outcome Markets — Outcome metadata, asset helpers, split/merge/negate actions, and outcome order support
- Minimal Dependencies — Only 5 runtime dependencies, no bloat
- Release Validated — Analyzer-clean package with unit tests and guarded live integration coverage
- Focused Roadmap — Normal trading and streaming are covered; remaining work targets newer account/admin, staking, borrow/lend, Bridge2, and deployer endpoints
Installation #
Add to your pubspec.yaml:
dependencies:
hyperliquid_dart: ^0.17.0
Or use the GitHub repository during development:
dependencies:
hyperliquid_dart:
git:
url: https://github.com/Riten-Zone/Hyperliquid-Dart-SDK.git
ref: main
Local path development also works:
dependencies:
hyperliquid_dart:
path: ../Hyperliquid-Dart-SDK
Then run:
dart pub get # or flutter pub get
Quick Start #
Read-Only API (No Wallet Needed) #
import 'package:hyperliquid_dart/hyperliquid_dart.dart';
void main() async {
// Create an InfoClient for read-only queries
final info = InfoClient();
// Fetch current prices
final mids = await info.allMids();
print('BTC: \$${mids['BTC']}');
// Fetch candlestick data
final candles = await info.candleSnapshot(
coin: 'BTC',
interval: '1h',
startTime: DateTime.now().subtract(Duration(days: 1)).millisecondsSinceEpoch,
endTime: DateTime.now().millisecondsSinceEpoch,
);
print('Fetched ${candles.length} candles');
// Fetch orderbook
final book = await info.l2Book('BTC');
print('Best bid: ${book.bids.first.price}');
print('Best ask: ${book.asks.first.price}');
info.close();
}
Trading (Requires Wallet) #
import 'package:hyperliquid_dart/hyperliquid_dart.dart';
void main() async {
// Create a wallet adapter (this example uses raw private key)
final wallet = PrivateKeyWalletAdapter('0xYOUR_PRIVATE_KEY');
// Create an ExchangeClient for trading
final exchange = ExchangeClient(wallet: wallet);
// Set leverage
await exchange.updateLeverage(
asset: 0, // BTC
leverage: 10,
isCross: true,
);
// Place a limit order
final result = await exchange.placeOrder(
orders: [
OrderWire.limit(
asset: 0, // BTC
isBuy: true,
limitPx: '50000', // $50,000
sz: '0.001', // 0.001 BTC
tif: TimeInForce.gtc,
),
],
);
print('Order placed: ${result.status}');
exchange.close();
}
Real-Time WebSocket Streams #
import 'package:hyperliquid_dart/hyperliquid_dart.dart';
void main() async {
final ws = WebSocketClient();
await ws.connect();
// Subscribe to live prices
final midsHandle = ws.subscribeAllMids((mids) {
print('BTC: \$${mids['BTC']}');
});
// Subscribe to orderbook updates
final bookHandle = ws.subscribeL2Book('BTC', (book) {
print('Bid: ${book.bids.first.price}, Ask: ${book.asks.first.price}');
});
// Keep running for 10 seconds
await Future.delayed(Duration(seconds: 10));
// Cleanup
await midsHandle.cancel();
await bookHandle.cancel();
await ws.dispose();
}
Wallet Integration #
The SDK uses a WalletAdapter interface, allowing you to integrate any wallet provider.
Using Raw Private Key (Built-in) #
final wallet = PrivateKeyWalletAdapter('0xYOUR_PRIVATE_KEY');
⚠️ Security: Never hardcode private keys in production. Use environment variables or secure storage.
Custom Wallet Integration (e.g., Privy) #
class PrivyWalletAdapter implements WalletAdapter {
final PrivyClient _privy;
PrivyWalletAdapter(this._privy);
@override
Future<String> getAddress() async {
return await _privy.getAddress();
}
@override
Future<String> signTypedData(Map<String, dynamic> typedData) async {
return await _privy.eth_signTypedData_v4(typedData);
}
}
// Use it
final wallet = PrivyWalletAdapter(myPrivyClient);
final exchange = ExchangeClient(wallet: wallet);
API Reference #
InfoClient (Read-Only) - 34 Methods Available #
Read-only methods cover normal market data, account data, spot metadata, HIP-3 DEX metadata, HIP-4 outcome metadata, vaults, fees, ledger updates, funding data, and portfolio history.
Perpetual Futures Market Data
| Method | Description |
|---|---|
allMids() |
Get current mid prices for all perpetual assets |
candleSnapshot(coin, interval, startTime, endTime) |
Get OHLCV candles for a coin |
candleSnapshotPaginated(coin, interval, startTime, endTime) |
Auto-paginated candle queries for large time ranges |
l2Book(coin) |
Get orderbook snapshot |
metaAndAssetCtxs(dex?) |
Get perpetual futures metadata and contexts (supports HIP-3 DEXs) |
meta(dex?) |
Get perpetual futures metadata only (supports HIP-3 DEXs) |
universeNames() |
Get asset universe names (convenience method) |
recentTrades(coin) |
Get recent trades for a coin |
Spot Market Data
| Method | Description |
|---|---|
spotMeta() |
Get all spot tokens metadata (tokens, universes) |
spotMetaAndAssetCtxs() |
Get spot metadata + market data (prices, volumes) |
getSpotAssetId(tokenName) |
Resolve a spot pair to its order asset ID |
tokenDetails(tokenId) |
Get detailed token information by token ID |
spotClearinghouseState(address) |
Get user's spot token balances |
HIP-4 Outcome Markets
| Method | Description |
|---|---|
outcomeMeta() |
Get HIP-4 outcome and question metadata |
settledOutcome(outcome) |
Get settlement metadata for a settled outcome, or null if unsettled |
Account & Order Data
| Method | Description |
|---|---|
clearinghouseState(address) |
Get perpetual account state (balance, positions) |
openOrders(address) |
Get user's open orders |
frontendOpenOrders(address) |
Get user's open orders including trigger orders |
historicalOrders(address) |
Get up to 2000 most recent orders |
userFills(address) |
Get user's trade fills history |
userFillsByTime(user, startTime, endTime?) |
Get user's fills filtered by time range |
userFunding(user, startTime, endTime?) |
Get user's funding payments |
userFees(user) |
Get user's fee rates, referral discounts, staking discounts, and volume |
userNonFundingLedgerUpdates(user, startTime, endTime?) |
Get deposits, withdrawals, transfers, liquidations, and other non-funding ledger entries |
fundingHistory(coin, startTime, endTime?) |
Get historical funding rates for a coin |
orderStatus(user, oid) |
Get order status by order ID |
portfolio(user) |
Get portfolio with historical account value and PnL |
Sub-Accounts & HIP-3 DEXs
| Method | Description |
|---|---|
subAccounts(user) |
Get user's sub-accounts with balances and positions |
perpDexs() |
Get all HIP-3 builder-deployed perpetual DEXs |
maxBuilderFee(user, builder) |
Get max approved builder fee |
Vault Operations 🆕
| Method | Description |
|---|---|
vaultDetails(vaultAddress, user?) |
Get detailed vault information including performance, followers, and portfolio history |
vaultSummaries() |
Get summaries for all vaults (may return empty - known API issue) |
leadingVaults(user) |
Get all vaults managed by a specific vault leader |
userVaultEquities(user) |
Get user's vault deposits and equity across all vaults |
ExchangeClient (Trading) - 27 Actions Available #
Signed actions cover normal order management, TWAP, leverage/margin, USDC and spot transfers, sub-account transfers, HIP-4 outcome actions, builder-fee approval, and vault transfers.
Order Management
| Method | Description |
|---|---|
placeOrder(orders, grouping, builder, vaultAddress?) |
Place limit/market/trigger orders |
cancelOrders(cancels, vaultAddress?) |
Cancel orders by order ID |
cancelOrdersByCloid(asset, cloids, vaultAddress?) |
Cancel orders by client order ID |
modify(oid, order, vaultAddress?) |
Modify an existing order (price, size) |
batchModify(modifies, vaultAddress?) |
Modify multiple orders in a single atomic request |
scheduleCancel(time) |
Schedule all orders to cancel at a specific time |
TWAP Orders
| Method | Description |
|---|---|
twapOrder(twap, vaultAddress?) |
Place TWAP (time-weighted average price) order |
twapCancel(cancel, vaultAddress?) |
Cancel an active TWAP order |
Account Management
| Method | Description |
|---|---|
updateLeverage(asset, leverage, isCross, vaultAddress?) |
Set leverage for a perpetual asset |
updateIsolatedMargin(asset, isBuy, ntli, vaultAddress?) |
Add/remove isolated margin |
usdTransfer(destination, amount) |
Transfer USDC between accounts/sub-accounts |
usdClassTransfer(amount, toPerp) |
Transfer USDC between spot and perp accounts |
usdSend(destination, amount) |
Send spot USDC internally on Hyperliquid |
withdraw(destination, amount) |
Withdraw USDC to another address |
approveBuilderFee(builder, maxFeeRate) |
Approve a builder fee for HIP-3 DEXs |
Spot Token Operations
| Method | Description |
|---|---|
spotUser(action) |
Toggle spot dusting settings |
spotSend(destination, token, amount) |
Send spot tokens to another address |
sendAsset(destination, token, amount, dex?, subAccount?) |
Transfer assets between DEXs/addresses/sub-accounts |
subAccountTransfer(amount, subAccount, isDeposit) |
Transfer USDC to/from sub-accounts (perp DEX) |
subAccountSpotTransfer(token, amount, subAccount, isDeposit) |
Transfer spot tokens to/from sub-accounts |
HIP-4 Outcome Actions
| Method | Description |
|---|---|
userOutcome(operation) |
Submit a raw HIP-4 user outcome operation |
placeOutcomeOrder(outcome, side, isBuy, limitPx, sz) |
Place a HIP-4 outcome limit order |
splitOutcome(outcome, amount) |
Split quote tokens into Yes and No shares |
mergeOutcome(outcome, amount?) |
Merge Yes and No shares back into quote tokens |
mergeQuestion(question, amount?) |
Merge Yes shares across a question |
negateOutcome(question, outcome, amount) |
Convert No shares into Yes shares of other outcomes |
Vault Operations 🆕
| Method | Description |
|---|---|
vaultTransfer(vaultAddress, isDeposit, usd) |
Deposit/withdraw USDC to/from vaults ($5 minimum, 24h lockup) |
WebSocketClient (Real-Time) - 29 Typed Subscriptions Available #
Market Data Streams
| Method | Description |
|---|---|
subscribeAllMids(callback) |
Live mid prices for all perpetual assets |
subscribeAssetCtxs(callback, dex?) |
Live contexts for all perpetual assets |
subscribeFastAssetCtxs(callback) |
Fast mark/mid asset context stream |
subscribeL2Book(coin, callback) |
Live orderbook updates for a coin |
subscribeCandle(coin, interval, callback) |
Live OHLCV candle updates |
subscribeTrades(coin, callback) |
Live trades stream for a coin |
subscribeBbo(coin, callback) |
Best bid/offer updates |
subscribeActiveAssetCtx(coin, callback) |
Live context for one perpetual asset |
subscribeActiveAssetData(user, coin, callback) |
Live user-specific data for one perpetual asset |
subscribeAllDexsAssetCtxs(callback) |
Live asset contexts across all DEXs |
Account Streams
| Method | Description |
|---|---|
subscribeClearinghouseState(address, callback, dex?) |
User clearinghouse state snapshots and updates |
subscribeOpenOrders(address, callback, dex?) |
User open-order snapshots and updates |
subscribeUserFills(address, callback) |
Live trade fills for user |
subscribeUserHistoricalOrders(address, callback) |
User historical order updates |
subscribeOrderUpdates(address, callback) |
Order status updates for user |
subscribeUserFundings(address, callback) |
Live funding payments for user |
subscribeUserNonFundingLedgerUpdates(address, callback) |
Live non-funding ledger updates |
subscribeUserEvents(address, callback) |
User event stream (clearinghouse state changes, etc.) |
subscribeNotification(address, callback) |
Account notifications |
subscribeWebData2(address, callback) |
Aggregated account data stream |
subscribeWebData3(address, callback) |
Aggregated account data stream |
subscribeAllDexsClearinghouseState(address, callback) |
User clearinghouse state across all DEXs |
Spot Streams
| Method | Description |
|---|---|
subscribeSpotState(address, callback) |
User spot balances and spot state updates |
subscribeSpotAssetCtxs(callback) |
Live contexts for all spot assets |
subscribeActiveSpotAssetCtx(coin, callback) |
Live context for one spot asset |
TWAP Streams
| Method | Description |
|---|---|
subscribeTwapStates(address, callback) |
Active TWAP orders status |
subscribeUserTwapHistory(address, callback) |
TWAP order history events |
subscribeUserTwapSliceFills(address, callback) |
Individual TWAP slice fill notifications |
Other
| Method | Description |
|---|---|
subscribeOutcomeMetaUpdates(callback) |
HIP-4 outcome metadata updates |
subscribeRaw(key, message, callback) |
Generic raw subscription for any type |
HIP-4 Outcome Market Usage #
HIP-4 outcomes are spot-like markets with special asset IDs. The IDs come from
outcomeMeta():
final info = InfoClient();
final meta = await info.outcomeMeta();
final question = meta.questions.first;
final outcome = meta.outcomes.firstWhere(
(o) => o.outcome == question.namedOutcomes.first,
);
final yesAsset = getOutcomeAssetId(outcome: outcome.outcome, side: 0);
final noAsset = getOutcomeAssetId(outcome: outcome.outcome, side: 1);
print('Yes coin: ${getOutcomeSpotCoin(outcome: outcome.outcome, side: 0)}');
print('No coin: ${getOutcomeSpotCoin(outcome: outcome.outcome, side: 1)}');
print('Yes asset id: $yesAsset');
print('No asset id: $noAsset');
Outcome asset formulas:
encoding = 10 * outcome + side
spot coin = #<encoding>
token name = +<encoding>
asset id = 100000000 + encoding
Only sides 0 and 1 are valid. Outcome order books are merged: buying Yes at
price p is equivalent to selling No at price 1 - p. On settlement, Yes
converts to settleFraction quote tokens and No converts to
1 - settleFraction.
To split and merge quote tokens:
final wallet = PrivateKeyWalletAdapter('0xYOUR_PRIVATE_KEY');
final exchange = ExchangeClient(wallet: wallet);
await exchange.splitOutcome(outcome: outcome.outcome, amount: '1.0');
await exchange.mergeOutcome(outcome: outcome.outcome, amount: '1.0');
To place an outcome order, use placeOutcomeOrder(). It calculates the HIP-4
asset ID internally:
await exchange.placeOutcomeOrder(
outcome: outcome.outcome,
side: 0, // usually Yes
isBuy: true,
limitPx: '0.01',
sz: '1.0',
tif: TimeInForce.alo,
);
HIP-4 trading uses spot-side quote liquidity, usually spot USDC. Move USDC from
perp to spot with usdClassTransfer(amount: ..., toPerp: false) if needed.
Examples #
See the example/ directory for more examples:
hyperliquid_dart_example.dart— Comprehensive demohip4_outcome_example.dart— HIP-4 metadata, asset IDs, split/merge, and guarded order examplehip3_trading_example.dart— HIP-3 DEX metadata and asset IDsspot_order_trading_example.dart— Spot order placement and cancellation
Testing #
# Unit tests (no wallet needed)
dart test --exclude-tags integration
# Integration tests (requires HYPERLIQUID_PRIVATE_KEY env var)
HYPERLIQUID_PRIVATE_KEY=0x... dart test --tags integration
Architecture #
- Minimal Dependencies:
http,web_socket_channel,pointycastle,msgpack_dart,convert - Wallet-Agnostic: Abstract
WalletAdapterinterface - Type-Safe: Comprehensive models for all API responses
- Memory-Efficient: Designed for long-running applications
Roadmap #
Completed
- Done: REST API — InfoClient (34 methods) + ExchangeClient (27 actions)
- Done: WebSocket subscriptions (29 typed subscriptions, plus raw subscribe)
- Done: EIP-712 signing with wallet-agnostic interface
- Done: PrivateKeyWalletAdapter for raw private keys
- Done: Perpetual futures trading (orders, leverage, positions)
- Done: TWAP orders (place, cancel, monitor via WebSocket)
- Done: Spot market metadata, token details, balance, and price queries
- Done: Spot token trading (buy/sell, send, dust settings, perp/spot transfers, sub-account transfers)
- Done: Spot WebSocket streams (active spot asset context, user spot state, all spot asset contexts)
- Done: HIP-3 DEX support (query DEXs, metadata, trade on builder-deployed perps)
- Done: HIP-4 outcome-market metadata, asset helpers, split/merge/negate actions, and examples
- Done: Sub-account queries and USDC transfers
- Done: Vault operations (query vaults, deposit/withdraw, check positions)
- Done: Vault-aware aggregate WebSocket data through
webData3 - Done: Order modification (single and batch)
- Done: Builder fee approval
- Done: Paginated candle queries for large time ranges
- Done: Portfolio, fee, funding, ledger, trade, and order-status endpoints
- Done: Published to pub.dev
- Done: Comprehensive dartdoc comments and generated pub.dev API docs
Future
- Planned: Low-risk Info parity for rate limits, referrals, staking reads, abstraction state, TWAP slice fills, borrow/lend, and newer status endpoints
- Planned: Signed account/admin actions such as API wallet approval, request-weight reservation, reward claiming, staking actions, abstraction setters, and EVM transfer with data
- Planned: Bridge2 deposit-with-permit helpers
- Planned: Dedicated HIP-1/HIP-2 spot deploy and HIP-3 perp deploy clients
- Planned: Typed models for currently raw WebSocket payloads (
clearinghouseState,openOrders,assetCtxs,webData2, selected account event streams) - Planned: Broader live integration coverage for signed actions that depend on account balance, volume, or permissions
Contributing #
Contributions welcome! Please open an issue or PR on GitHub.
License #
MIT License - see LICENSE for details.
Disclaimer #
This SDK is provided as-is. Trading crypto involves risk. The authors are not responsible for any losses incurred.
Links #
Built with ❤️ for the Hyperliquid community