
Hyperliquid
- 26 installs
- 638 repo stars
- Updated March 7, 2026
- sundial-org/awesome-openclaw-skills
Helps with ai & agent building tasks during AI-assisted development.
About
hyperliquid is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.
- hyperliquid
- AI & Agent Building
- AI-coding skill
Hyperliquid by the numbers
- 26 all-time installs (skills.sh)
- Ranked #9,702 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/sundial-org/awesome-openclaw-skills --skill hyperliquidAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 26 |
|---|---|
| repo stars | ★ 638 |
| Last updated | March 7, 2026 |
| Repository | sundial-org/awesome-openclaw-skills ↗ |
What it does
Helps with ai & agent building tasks during AI-assisted development.
Files
Hyperliquid Trading Skill
Full trading and portfolio management for Hyperliquid perpetual futures exchange.
Prerequisites
Install dependencies once:
cd skills/hyperliquid/scripts && npm installAuthentication
For read-only operations (balance, positions, prices):
- Set
HYPERLIQUID_ADDRESSenvironment variable - No private key needed
For trading operations:
- Set
HYPERLIQUID_PRIVATE_KEYenvironment variable - Address derived automatically from private key
Testnet:
- Set
HYPERLIQUID_TESTNET=1to use testnet
Core Operations
Portfolio Monitoring
Check balance:
HYPERLIQUID_ADDRESS=0x... node scripts/hyperliquid.mjs balanceView positions with P&L:
HYPERLIQUID_ADDRESS=0x... node scripts/hyperliquid.mjs positionsCheck open orders:
HYPERLIQUID_ADDRESS=0x... node scripts/hyperliquid.mjs ordersView trade history:
HYPERLIQUID_ADDRESS=0x... node scripts/hyperliquid.mjs fillsGet price for a coin:
node scripts/hyperliquid.mjs price BTCTrading Operations
All trading commands require HYPERLIQUID_PRIVATE_KEY.
Place limit orders:
# Buy 0.1 BTC at $45,000
HYPERLIQUID_PRIVATE_KEY=0x... node scripts/hyperliquid.mjs buy BTC 0.1 45000
# Sell 1 ETH at $3,000
HYPERLIQUID_PRIVATE_KEY=0x... node scripts/hyperliquid.mjs sell ETH 1 3000Market orders (with 5% slippage protection):
# Market buy 0.5 BTC
HYPERLIQUID_PRIVATE_KEY=0x... node scripts/hyperliquid.mjs market-buy BTC 0.5
# Market sell 2 ETH
HYPERLIQUID_PRIVATE_KEY=0x... node scripts/hyperliquid.mjs market-sell ETH 2Cancel orders:
# Cancel specific order
HYPERLIQUID_PRIVATE_KEY=0x... node scripts/hyperliquid.mjs cancel BTC 12345
# Cancel all orders
HYPERLIQUID_PRIVATE_KEY=0x... node scripts/hyperliquid.mjs cancel-all
# Cancel all orders for specific coin
HYPERLIQUID_PRIVATE_KEY=0x... node scripts/hyperliquid.mjs cancel-all BTCOutput Formatting
All commands output JSON. Parse and format for chat display:
For balance/portfolio:
- Show total equity, available balance
- List positions with size, entry price, unrealized P&L
- Summarize open orders
For trade execution:
- Confirm order details before executing
- Report order ID and status after execution
- Show filled price if immediately executed
Safety Guidelines
Before executing trades: 1. Confirm trade parameters with user (coin, size, direction, price) 2. Show current price and position for context 3. Calculate estimated cost/proceeds
Position sizing:
- Warn if trade is >20% of account equity
- Suggest appropriate sizes based on account balance
Price checks:
- For limit orders, compare limit price to current market price
- Warn if limit price is >5% away from market (likely mistake)
Error Handling
Common errors:
- "Address required" → Set HYPERLIQUID_ADDRESS or HYPERLIQUID_PRIVATE_KEY
- "Private key required" → Trading needs HYPERLIQUID_PRIVATE_KEY
- "Unknown coin" → Check available coins with
metacommand - HTTP errors → Check network connection and API status
When errors occur:
- Show the error message to user
- Suggest fixes (set env vars, check coin names, verify balance)
- Don't retry trades automatically
Workflow Examples
"How's my Hyperliquid portfolio?" 1. Run balance to get total equity 2. Run positions to get open positions 3. Format summary: equity, positions with P&L, total unrealized P&L
"Buy 0.5 BTC on Hyperliquid" 1. Run price BTC to get current price 2. Run balance to verify sufficient funds 3. Confirm with user: "Buy 0.5 BTC at market? Current price: $X. Estimated cost: $Y" 4. Execute market-buy BTC 0.5 5. Report order result
"What's the current BTC price on Hyperliquid?" 1. Run price BTC 2. Format response: "BTC: $X on Hyperliquid"
"Close my ETH position" 1. Run positions to get current ETH position size 2. If long → market-sell, if short → market-buy 3. Execute with position size 4. Report result
Advanced Features
List all available coins:
node scripts/hyperliquid.mjs metaQuery other addresses:
# Check someone else's positions (read-only, public data)
node scripts/hyperliquid.mjs positions 0x1234...Notes
- All sizes are in base currency (BTC, ETH, etc.)
- Prices are in USD
- Market orders use limit orders with 5% slippage protection
- Hyperliquid uses perpetual futures, not spot trading
- Check references/api.md for full API documentation
Hyperliquid Trading Skill for Clawdbot
Full-featured Clawdbot skill for trading Hyperliquid perpetual futures. Monitor your portfolio, analyze markets with charts/volume, and execute trades with AI assistance.
Features
Core Trading
- Portfolio Monitoring: Balance, positions, P&L tracking
- Order Execution: Market and limit orders (long & short)
- Order Management: Cancel specific orders or all at once
- Trade History: View recent fills
- Security: Read-only mode by default, trading requires explicit private key
Market Analysis Tools 🆕
- Chart Data with Volume: Historical price action via CoinGecko
- Momentum Detection: Automated signal generation (strong bull/bear/neutral)
- Volume Analysis: Compare current volume vs average
- Multi-timeframe: 1-hour and 6-hour trend analysis
- 228+ Assets: Trade any perpetual on Hyperliquid
Strategy Support 🆕
- Position Monitoring: Check P&L with automated alerts
- Risk Management: 10% position size, stop losses, profit targets
- Market Scanner: Quick overview of all major assets
- Decision Support: Wait for high-probability setups
Installation
# Install via ClawdHub (recommended)
clawdhub install hyperliquid
# Or install manually in your Clawdbot workspace
cd skills
# Clone or copy the hyperliquid skill folder here
# Install dependencies
cd hyperliquid/scripts
npm installConfiguration
Read-Only (Portfolio Monitoring)
Set your Hyperliquid address to check balances and positions without private key access:
export HYPERLIQUID_ADDRESS=0xYourAddressTrading (Requires Private Key)
For executing trades, set your private key:
export HYPERLIQUID_PRIVATE_KEY=0xYourPrivateKeyOr use `.env` file (recommended for security):
cd hyperliquid
cp .env.example .env
# Edit .env with your credentials
nano .env⚠️ Security: Never commit your .env file. It's already in .gitignore.
Testnet
To use Hyperliquid testnet:
export HYPERLIQUID_TESTNET=1Usage
Market Analysis (New!)
Analyze market with charts and volume:
cd scripts
./analyze-coingecko.mjs
# Output includes:
# - Recent price action (last 10 hours)
# - Volume analysis vs average
# - Momentum signals (strong/weak bull/bear)
# - 6-hour trend direction
# - Trading recommendationQuick market scan:
./scan-market.mjs
# Shows current prices for:
# - BTC, ETH, SOL, AVAX, DOGE, ARB
# - First 20 available perpetualsCheck your positions:
./check-positions.mjs
# Shows:
# - Account equity and available balance
# - Open positions with P&L
# - Profit target/stop loss alerts
# - Current BTC/ETH/SOL pricesDirect CLI Trading
# Check balance
node scripts/hyperliquid.mjs balance
# View positions with P&L
node scripts/hyperliquid.mjs positions
# Get current BTC price
node scripts/hyperliquid.mjs price BTC
# Place market orders
node scripts/hyperliquid.mjs market-buy SOL 0.1
node scripts/hyperliquid.mjs market-sell ETH 0.5
# Place limit orders
node scripts/hyperliquid.mjs limit-buy BTC 0.001 88000
node scripts/hyperliquid.mjs limit-sell ETH 1 3100
# Cancel all orders
node scripts/hyperliquid.mjs cancel-allThrough Clawdbot
Once installed, interact naturally:
- "Analyze the crypto market on Hyperliquid"
- "What's the momentum on BTC right now?"
- "Check my Hyperliquid positions"
- "Show me current SOL price and volume"
- "Enter a BTC long position"
- "Close my ETH position"
Commands Reference
Read Operations (No Private Key Needed)
balance [address]- Show account balance and equitypositions [address]- Show open positions with P&Lprice <coin>- Get current price (auto-adds -PERP)meta- List all available coins
Trading Operations (Requires HYPERLIQUID_PRIVATE_KEY)
market-buy <coin> <size>- Market buy (5% slippage protection)market-sell <coin> <size>- Market sell (5% slippage protection)limit-buy <coin> <size> <price>- Place limit buy orderlimit-sell <coin> <size> <price>- Place limit sell ordercancel-all [coin]- Cancel all orders (optionally for one coin)
Analysis Scripts
analyze-coingecko.mjs- Full market analysis with charts/volumecheck-positions.mjs- Monitor open positions and P&Lscan-market.mjs- Quick price overview
Strategy Examples
Momentum Scalping (Recommended for Small Accounts)
# 1. Analyze market conditions
./analyze-coingecko.mjs
# 2. If signal is "STRONG BULLISH" or "STRONG BEARISH", check position size
# Account: $100, 10% position = $10
# 3. Enter trade
node hyperliquid.mjs market-buy ETH 0.0033 # ~$10 position
# 4. Monitor position every 30-60 minutes
./check-positions.mjs
# 5. Exit at +2% profit target or -1% stop loss
node hyperliquid.mjs market-sell ETH 0.0033Risk Parameters (Example)
- Position Size: 10% of account per trade
- Max Loss: 1% per trade (stop loss)
- Profit Target: 2% per trade
- Max Positions: 1 at a time (focus)
- Entry Signal: Volume >1.5x average + price move >0.5%
Architecture
- CLI Client:
scripts/hyperliquid.mjs- Official Hyperliquid SDK wrapper - Market Analysis:
scripts/analyze-coingecko.mjs- CoinGecko API integration - Position Monitor:
scripts/check-positions.mjs- Real-time P&L tracking - Market Scanner:
scripts/scan-market.mjs- Quick price overview - Skill Definition:
SKILL.md- Instructions for Clawdbot - API Reference:
references/api.md- Hyperliquid API docs - Dependencies: Official
hyperliquidnpm package,node-fetch
API & Data Sources
Trading:
- Hyperliquid API (mainnet:
https://api.hyperliquid.xyz) - Official SDK:
hyperliquidnpm package
Market Data:
- CoinGecko Free API (no auth required)
- 24-hour historical data with volume
- Automatic momentum signal generation
Safety Features
- Read-only by default: No private key needed for monitoring
- Slippage protection: Market orders use 5% limit buffer
- Position size validation: Checks minimum order size ($10)
- Stop loss alerts: Automated notifications when hit
- Profit target tracking: Know when to take gains
- Clear signal thresholds: Only trade strong momentum (>0.5% + volume)
Trading Strategy Support
The skill includes a complete momentum scalping strategy:
Entry Criteria:
- Price move >0.5% in 15-30 minutes
- Volume >1.5x average (confirms momentum)
- Clear directional bias (not choppy)
Position Management:
- Set 2% profit target
- Set 1% stop loss
- Monitor every 30-60 minutes
- Max hold time: 4 hours
Exit Rules:
- Hit profit target → Close immediately
- Hit stop loss → Close immediately
- No momentum → Close at breakeven
- Max time reached → Close position
Development
Built with:
- Node.js (ES modules)
- Official Hyperliquid SDK for trading
- CoinGecko API for market analysis
- node-fetch for HTTP requests
Updates
v2.0.0 (2026-01-27)
- 🎉 Integrated official Hyperliquid SDK
- 📊 Added chart/volume analysis via CoinGecko
- 🎯 Automated momentum signal detection
- 📈 Position monitoring with P&L alerts
- 🔧 Fixed all trading operations
- 📝 Complete strategy documentation
v1.0.0 (2026-01-27)
- Initial release
- Basic trading functionality
- Portfolio monitoring
License
MIT
About Clawdbot
Clawdbot is an AI assistant framework with extensible skills. Learn more at https://clawd.bot
---
Disclaimer: This is unofficial software. Use at your own risk. Trading cryptocurrency perpetual futures is high risk. Always verify trades before execution. The automated signals are for informational purposes only and not financial advice.
Hyperliquid API Reference
Base URLs
- Mainnet:
https://api.hyperliquid.xyz - Testnet:
https://api.hyperliquid-testnet.xyz
Authentication
Trading operations require signing with your Ethereum private key:
1. Create action object (e.g., order, cancel) 2. Add timestamp 3. Sign message with ethers.js wallet.signMessage() 4. Send signed action to /exchange endpoint
Read-only operations require no authentication.
Information Endpoints
All use POST to /info with JSON body specifying type.
Clearinghouse State
Get account balance, positions, and margin info:
{
"type": "clearinghouseState",
"user": "0x..."
}Response:
{
"assetPositions": [
{
"position": {
"coin": "BTC",
"szi": "0.5", // Position size
"entryPx": "45000.0", // Entry price
"positionValue": "22500.0",
"unrealizedPnl": "500.0"
},
"type": "oneWay"
}
],
"crossMarginSummary": {
"accountValue": "50000.0",
"totalMarginUsed": "5000.0"
}
}Open Orders
{
"type": "openOrders",
"user": "0x..."
}User Fills (Trade History)
{
"type": "userFills",
"user": "0x..."
}Market Data
All mid prices:
{ "type": "allMids" }Returns: { "BTC": "45123.5", "ETH": "3021.2", ... }
Meta (available coins):
{ "type": "meta" }Returns universe of tradeable assets with specs.
Trading Endpoints
All use POST to /exchange with signed action.
Place Order
{
"type": "order",
"orders": [{
"a": 0, // Asset index (from meta)
"b": true, // true = buy, false = sell
"p": "45000.0", // Limit price
"s": "0.5", // Size
"r": false, // Reduce-only
"t": {
"limit": { "tif": "Gtc" } // Time-in-force
}
}],
"grouping": "na",
"signature": "0x...",
"timestamp": 1234567890
}Cancel Order
{
"type": "cancel",
"cancels": [{
"a": 0, // Asset index
"o": 12345 // Order ID
}],
"signature": "0x...",
"timestamp": 1234567890
}Cancel All Orders
{
"type": "cancel",
"cancels": [],
"signature": "0x...",
"timestamp": 1234567890
}Order Types
- Limit: Standard limit order with price
- Market: Achieved via limit order with aggressive price and slippage buffer
- Post-only:
"t": { "limit": { "tif": "Alo" } }(add liquidity only)
Asset Indexing
Assets referenced by index (0, 1, 2...). Get mapping from meta endpoint:
- BTC is typically index 0
- ETH is typically index 1
- Query meta to get current mapping
Position Size Convention
- Positive size = long position
- Negative size = short position
- Size in base currency (e.g., BTC, ETH)
Error Responses
HTTP 200 with error object:
{
"status": "err",
"response": {
"type": "error",
"message": "Insufficient margin"
}
}Common errors:
- Insufficient margin
- Invalid signature
- Unknown coin
- Order size too small/large
- Price precision error
Rate Limits
Hyperliquid has rate limits. Space out requests, especially in loops.
Documentation
Official docs: https://hyperliquid.gitbook.io/hyperliquid-docs/
#!/usr/bin/env node
/**
* Get chart data from CoinGecko API (free, no auth)
*/
import fetch from 'node-fetch';
async function getChartData(coinId, days = 1) {
// Don't specify interval - let CoinGecko auto-select (free tier limitation)
const url = `https://api.coingecko.com/api/v3/coins/${coinId}/market_chart?vs_currency=usd&days=${days}`;
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${await response.text()}`);
}
const data = await response.json();
return data;
}
async function analyzeCoin(coinId, coinName) {
console.log(`\n=== ${coinName} Analysis ===\n`);
try {
const data = await getChartData(coinId, 1); // Last 24 hours
const prices = data.prices.slice(-10); // Last 10 data points
const volumes = data.total_volumes.slice(-10);
// Recent price action
console.log('Recent Price Action (last 10 hours):');
console.log('Time Price Volume');
console.log('─'.repeat(60));
for (let i = 0; i < prices.length; i++) {
const time = new Date(prices[i][0]).toLocaleTimeString();
const price = prices[i][1].toFixed(2);
const volume = (volumes[i][1] / 1000000).toFixed(2) + 'M';
console.log(`${time.padEnd(20)} $${price.padStart(10)} $${volume.padStart(8)}`);
}
// Calculate metrics
const currentPrice = prices[prices.length - 1][1];
const prevPrice = prices[prices.length - 2][1];
const price6hAgo = prices[Math.max(0, prices.length - 7)][1];
const change1h = ((currentPrice - prevPrice) / prevPrice) * 100;
const change6h = ((currentPrice - price6hAgo) / price6hAgo) * 100;
// Volume analysis
const currentVolume = volumes[volumes.length - 1][1];
const avgVolume = volumes.slice(0, -1).reduce((sum, v) => sum + v[1], 0) / (volumes.length - 1);
const volumeRatio = currentVolume / avgVolume;
console.log('\n📊 Metrics:');
console.log(` Current Price: $${currentPrice.toFixed(2)}`);
console.log(` Change (1h): ${change1h > 0 ? '+' : ''}${change1h.toFixed(2)}%`);
console.log(` Change (6h): ${change6h > 0 ? '+' : ''}${change6h.toFixed(2)}%`);
console.log(` Current Volume: $${(currentVolume / 1000000).toFixed(2)}M`);
console.log(` Avg Volume (9h): $${(avgVolume / 1000000).toFixed(2)}M`);
console.log(` Volume Ratio: ${volumeRatio.toFixed(2)}x ${volumeRatio > 1.5 ? '🔥 HIGH' : volumeRatio < 0.7 ? '❄️ LOW' : '📊 NORMAL'}`);
// Momentum signal
console.log('\n🎯 Momentum Signal:');
const strongUp = change1h > 0.5 && volumeRatio > 1.3;
const weakUp = change1h > 0 && change1h < 0.5;
const strongDown = change1h < -0.5 && volumeRatio > 1.3;
if (strongUp) {
console.log(' ✅ STRONG BULLISH - Price surging with high volume');
console.log(' → Consider LONG entry');
} else if (weakUp) {
console.log(' ⚠️ WEAK BULLISH - Price up but momentum unclear');
console.log(' → Wait for confirmation');
} else if (strongDown) {
console.log(' 🔴 STRONG BEARISH - Price dropping with high volume');
console.log(' → Consider SHORT entry');
} else {
console.log(' ⏸️ NEUTRAL - No clear momentum');
console.log(' → Wait for clearer signal');
}
// Trend
console.log('\n📈 Trend (6h):');
if (change6h > 1) {
console.log(` 🚀 Uptrend (+${change6h.toFixed(2)}%)`);
} else if (change6h < -1) {
console.log(` 📉 Downtrend (${change6h.toFixed(2)}%)`);
} else {
console.log(` ➡️ Sideways (${change6h.toFixed(2)}%)`);
}
return {
coin: coinName,
currentPrice,
change1h,
change6h,
volumeRatio,
signal: strongUp ? 'strong_bull' : weakUp ? 'weak_bull' : strongDown ? 'strong_bear' : 'neutral'
};
} catch (err) {
console.error(`Error: ${err.message}`);
return null;
}
}
// Main
console.log('🔍 Fetching market data from CoinGecko...\n');
const btc = await analyzeCoin('bitcoin', 'BTC');
const eth = await analyzeCoin('ethereum', 'ETH');
console.log('\n' + '='.repeat(80));
console.log('\n📋 TRADING RECOMMENDATION:\n');
if (btc && eth) {
if (btc.signal === 'strong_bull' || eth.signal === 'strong_bull') {
const coin = btc.signal === 'strong_bull' ? 'BTC' : 'ETH';
console.log(`✅ TRADE SIGNAL: Enter ${coin} LONG`);
console.log(` Strong momentum confirmed with volume`);
} else if (btc.signal === 'strong_bear' || eth.signal === 'strong_bear') {
const coin = btc.signal === 'strong_bear' ? 'BTC' : 'ETH';
console.log(`✅ TRADE SIGNAL: Enter ${coin} SHORT`);
console.log(` Strong selling pressure with volume`);
} else {
console.log(`⏸️ NO TRADE: Wait for clearer momentum signal`);
console.log(` Current momentum is too weak to justify entry`);
}
}
console.log('\n' + '='.repeat(80));
#!/usr/bin/env node
/**
* Get historical candles and volume for technical analysis
*/
import { Hyperliquid } from 'hyperliquid';
const sdk = new Hyperliquid({ enableWs: false });
async function analyzeCoin(coin, interval = '15m', lookback = 20) {
console.log(`\n=== ${coin} Analysis (${interval} candles) ===\n`);
// Get candle data
const candles = await sdk.info.getCandleSnapshot({
coin,
interval,
startTime: Date.now() - (lookback * getIntervalMs(interval)),
endTime: Date.now()
});
if (!candles || candles.length === 0) {
console.log('No candle data available');
return null;
}
// Recent candles
const recentCandles = candles.slice(-5);
console.log('Recent Candles:');
console.log('Time Open High Low Close Volume');
console.log('─'.repeat(80));
for (const c of recentCandles) {
const time = new Date(c.t).toLocaleTimeString();
console.log(
`${time.padEnd(20)} ${c.o.padEnd(9)} ${c.h.padEnd(9)} ${c.l.padEnd(9)} ${c.c.padEnd(9)} ${c.v}`
);
}
// Calculate metrics
const latest = candles[candles.length - 1];
const previous = candles[candles.length - 2];
const current = parseFloat(latest.c);
const prev = parseFloat(previous.c);
const change = ((current - prev) / prev) * 100;
// Volume analysis
const avgVolume = candles.slice(-10).reduce((sum, c) => sum + parseFloat(c.v), 0) / 10;
const currentVolume = parseFloat(latest.v);
const volumeRatio = currentVolume / avgVolume;
console.log('\n📊 Metrics:');
console.log(` Current Price: $${current}`);
console.log(` Change (${interval}): ${change > 0 ? '+' : ''}${change.toFixed(2)}%`);
console.log(` Current Volume: ${currentVolume.toFixed(2)}`);
console.log(` Avg Volume (10 bars): ${avgVolume.toFixed(2)}`);
console.log(` Volume Ratio: ${volumeRatio.toFixed(2)}x ${volumeRatio > 1.5 ? '🔥 HIGH' : volumeRatio < 0.7 ? '❄️ LOW' : '📊 NORMAL'}`);
// Momentum detection
const priceUp = change > 0;
const volumeUp = volumeRatio > 1.2;
console.log('\n🎯 Momentum Signal:');
if (priceUp && volumeUp) {
console.log(' ✅ BULLISH - Price up with high volume (strong momentum)');
} else if (priceUp && !volumeUp) {
console.log(' ⚠️ WEAK BULLISH - Price up but low volume (weak momentum)');
} else if (!priceUp && volumeUp) {
console.log(' 🔴 BEARISH - Price down with high volume (strong selling)');
} else {
console.log(' ⏸️ NEUTRAL - No clear momentum');
}
// Simple support/resistance
const highs = candles.slice(-20).map(c => parseFloat(c.h));
const lows = candles.slice(-20).map(c => parseFloat(c.l));
const resistance = Math.max(...highs);
const support = Math.min(...lows);
console.log('\n📈 Levels:');
console.log(` Resistance: $${resistance} (${((resistance - current) / current * 100).toFixed(2)}% away)`);
console.log(` Support: $${support} (${((current - support) / current * 100).toFixed(2)}% away)`);
return {
coin,
current,
change,
volumeRatio,
signal: priceUp && volumeUp ? 'bullish' : !priceUp && volumeUp ? 'bearish' : 'neutral',
resistance,
support
};
}
function getIntervalMs(interval) {
const units = {
'm': 60000,
'h': 3600000,
'd': 86400000
};
const match = interval.match(/^(\d+)([mhd])$/);
if (!match) return 60000;
return parseInt(match[1]) * units[match[2]];
}
// Main
const coins = process.argv.slice(2);
if (coins.length === 0) {
coins.push('BTC-PERP', 'ETH-PERP');
}
for (const coin of coins) {
try {
await analyzeCoin(coin);
} catch (err) {
console.error(`Error analyzing ${coin}:`, err.message);
}
}
console.log('\n' + '='.repeat(80));
#!/usr/bin/env node
/**
* Check current positions and calculate P&L
*/
import { Hyperliquid } from 'hyperliquid';
import { readFileSync, writeFileSync } from 'fs';
const sdk = new Hyperliquid({
privateKey: process.env.HYPERLIQUID_PRIVATE_KEY,
enableWs: false
});
const stateFile = '/home/ana/clawd/trading-state.json';
async function main() {
console.log('=== HYPERLIQUID POSITION CHECK ===\n');
const address = sdk.walletAddress || process.env.HYPERLIQUID_ADDRESS;
if (!address) {
console.error('Error: No wallet address available');
process.exit(1);
}
console.log(`Checking address: ${address}\n`);
// Get current state
const state = await sdk.info.perpetuals.getClearinghouseState(address);
// Get current prices
const prices = await sdk.info.getAllMids();
console.log('Account Status:');
console.log(` Equity: $${state.marginSummary.accountValue}`);
console.log(` Available: $${state.withdrawable}`);
console.log(` Margin Used: $${state.marginSummary.totalMarginUsed}`);
if (state.assetPositions && state.assetPositions.length > 0) {
console.log('\n=== OPEN POSITIONS ===');
for (const pos of state.assetPositions) {
const p = pos.position;
const coin = p.coin;
const currentPrice = parseFloat(prices[coin]);
const entryPrice = parseFloat(p.entryPx);
const size = parseFloat(p.szi);
const pnl = parseFloat(p.unrealizedPnl);
const pnlPct = (pnl / Math.abs(size * entryPrice)) * 100;
console.log(`\n${coin}:`);
console.log(` Direction: ${size > 0 ? 'LONG' : 'SHORT'}`);
console.log(` Size: ${Math.abs(size)}`);
console.log(` Entry: $${entryPrice}`);
console.log(` Current: $${currentPrice}`);
console.log(` P&L: $${pnl.toFixed(2)} (${pnlPct > 0 ? '+' : ''}${pnlPct.toFixed(2)}%)`);
// Check if profit target or stop loss hit
if (pnlPct >= 2) {
console.log(` ⚠️ PROFIT TARGET HIT! Consider taking profit.`);
} else if (pnlPct <= -1) {
console.log(` 🛑 STOP LOSS HIT! Consider closing position.`);
}
}
} else {
console.log('\n✅ No open positions');
}
// Current prices
console.log('\n=== CURRENT PRICES ===');
console.log(`BTC-PERP: $${prices['BTC-PERP']}`);
console.log(`ETH-PERP: $${prices['ETH-PERP']}`);
console.log(`SOL-PERP: $${prices['SOL-PERP']}`);
// Update state file
try {
const tradingState = JSON.parse(readFileSync(stateFile, 'utf8'));
tradingState.last_check = new Date().toISOString();
tradingState.current_positions = state.assetPositions || [];
tradingState.parameters.account_size = parseFloat(state.marginSummary.accountValue);
writeFileSync(stateFile, JSON.stringify(tradingState, null, 2));
console.log('\n✅ Trading state updated');
} catch (err) {
console.log('\n⚠️ Could not update trading state:', err.message);
}
}
main().catch(console.error);
#!/usr/bin/env node
/**
* Hyperliquid CLI - Trading and portfolio management
* Using official Hyperliquid SDK
*/
import { Hyperliquid } from 'hyperliquid';
// Helper to ensure coin name has -PERP suffix
function normalizeCoin(coin) {
if (!coin) return coin;
const upper = coin.toUpperCase();
if (upper.endsWith('-PERP') || upper.endsWith('-SPOT')) return upper;
return upper + '-PERP'; // Default to perpetuals
}
async function main() {
const args = process.argv.slice(2);
const command = args[0];
if (!command || command === 'help') {
console.log(`
Hyperliquid CLI - Trading and Portfolio Management
ENVIRONMENT VARIABLES:
HYPERLIQUID_PRIVATE_KEY Private key for trading (optional for read-only)
HYPERLIQUID_ADDRESS Address to query (defaults to private key address)
HYPERLIQUID_TESTNET Set to '1' for testnet
READ OPERATIONS (no private key needed):
balance [address] Show account balance and equity
positions [address] Show open positions with P&L
orders [address] Show open orders
fills [address] Show recent trade history
price <coin> Get current price for a coin (auto-adds -PERP)
meta List all available coins
TRADING OPERATIONS (requires HYPERLIQUID_PRIVATE_KEY):
market-buy <coin> <size> Market buy (with slippage protection)
market-sell <coin> <size> Market sell (with slippage protection)
limit-buy <coin> <size> <price> Place limit buy order
limit-sell <coin> <size> <price> Place limit sell order
cancel-all [coin] Cancel all orders (optionally for one coin)
EXAMPLES:
export HYPERLIQUID_ADDRESS=0x1234...
hyperliquid balance
hyperliquid price BTC
export HYPERLIQUID_PRIVATE_KEY=0xabc...
hyperliquid market-buy SOL 0.1
hyperliquid cancel-all
`);
process.exit(0);
}
const privateKey = process.env.HYPERLIQUID_PRIVATE_KEY;
const address = process.env.HYPERLIQUID_ADDRESS;
const isTestnet = process.env.HYPERLIQUID_TESTNET === '1';
// Initialize SDK
const sdk = new Hyperliquid({
privateKey: privateKey || undefined,
testnet: isTestnet,
enableWs: false, // Disable WebSocket for CLI usage
});
try {
switch (command) {
case 'balance': {
const addr = args[1] || address || sdk.walletAddress;
if (!addr) throw new Error('Address required (set HYPERLIQUID_ADDRESS or HYPERLIQUID_PRIVATE_KEY)');
const state = await sdk.info.perpetuals.getClearinghouseState(addr);
console.log(JSON.stringify(state, null, 2));
break;
}
case 'positions': {
const addr = args[1] || address || sdk.walletAddress;
if (!addr) throw new Error('Address required');
const state = await sdk.info.perpetuals.getClearinghouseState(addr);
console.log(JSON.stringify(state.assetPositions || [], null, 2));
break;
}
case 'orders': {
const addr = args[1] || address || sdk.walletAddress;
if (!addr) throw new Error('Address required');
const state = await sdk.info.perpetuals.getClearinghouseState(addr);
// Open orders are in state data
console.log(JSON.stringify(state.assetPositions || [], null, 2));
break;
}
case 'fills': {
const addr = args[1] || address || sdk.walletAddress;
if (!addr) throw new Error('Address required');
const updates = await sdk.info.perpetuals.getUserNonFundingLedgerUpdates(addr);
console.log(JSON.stringify(updates, null, 2));
break;
}
case 'price': {
const coin = normalizeCoin(args[1]);
if (!coin) throw new Error('Coin required');
const prices = await sdk.info.getAllMids();
if (!prices[coin]) throw new Error(`Unknown coin: ${coin}`);
console.log(prices[coin]);
break;
}
case 'meta': {
const meta = await sdk.info.perpetuals.getMeta();
console.log(JSON.stringify(meta.universe, null, 2));
break;
}
case 'market-buy':
case 'market-sell': {
if (!privateKey) throw new Error('Private key required for trading');
const coin = normalizeCoin(args[1]);
const size = args[2];
if (!coin || !size) {
throw new Error(`Usage: hyperliquid ${command} <coin> <size>`);
}
const isBuy = command === 'market-buy';
// Get current price for slippage calculation
const prices = await sdk.info.getAllMids();
const currentPrice = parseFloat(prices[coin]);
if (!currentPrice) throw new Error(`Unknown coin: ${coin}`);
// 5% slippage protection
const slippagePrice = isBuy
? currentPrice * 1.05
: currentPrice * 0.95;
const result = await sdk.exchange.placeOrder({
coin,
is_buy: isBuy,
sz: parseFloat(size),
limit_px: slippagePrice,
order_type: { limit: { tif: 'Ioc' } }, // Immediate or cancel
reduce_only: false,
});
console.log(JSON.stringify(result, null, 2));
break;
}
case 'limit-buy':
case 'limit-sell': {
if (!privateKey) throw new Error('Private key required for trading');
const coin = normalizeCoin(args[1]);
const size = args[2];
const price = args[3];
if (!coin || !size || !price) {
throw new Error(`Usage: hyperliquid ${command} <coin> <size> <price>`);
}
const isBuy = command === 'limit-buy';
const result = await sdk.exchange.placeOrder({
coin,
is_buy: isBuy,
sz: parseFloat(size),
limit_px: parseFloat(price),
order_type: { limit: { tif: 'Gtc' } }, // Good til cancelled
reduce_only: false,
});
console.log(JSON.stringify(result, null, 2));
break;
}
case 'cancel-all': {
if (!privateKey) throw new Error('Private key required for trading');
const coin = args[1] ? normalizeCoin(args[1]) : undefined;
const result = await sdk.custom.cancelAllOrders(coin);
console.log(JSON.stringify(result, null, 2));
break;
}
default:
console.error(`Unknown command: ${command}`);
console.log('Run "hyperliquid help" for usage');
process.exit(1);
}
} catch (error) {
console.error('Error:', error.message);
if (error.response) {
console.error('Response:', JSON.stringify(error.response, null, 2));
}
process.exit(1);
}
}
main();
{
"name": "hyperliquid-cli",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "hyperliquid-cli",
"version": "1.0.0",
"dependencies": {
"ethers": "^6.9.0",
"hyperliquid": "^1.7.7",
"node-fetch": "^3.3.2",
"ws": "^8.19.0"
}
},
"node_modules/@adraffy/ens-normalize": {
"version": "1.10.1",
"resolved": "https://registry.npmjs.org/@adraffy/ens-normalize/-/ens-normalize-1.10.1.tgz",
"integrity": "sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==",
"license": "MIT"
},
"node_modules/@msgpack/msgpack": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/@msgpack/msgpack/-/msgpack-3.1.3.tgz",
"integrity": "sha512-47XIizs9XZXvuJgoaJUIE2lFoID8ugvc0jzSHP+Ptfk8nTbnR8g788wv48N03Kx0UkAv559HWRQ3yzOgzlRNUA==",
"license": "ISC",
"engines": {
"node": ">= 18"
}
},
"node_modules/@noble/curves": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.2.0.tgz",
"integrity": "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==",
"license": "MIT",
"dependencies": {
"@noble/hashes": "1.3.2"
},
"funding": {
"url": "https://paulmillr.com/funding/"
}
},
"node_modules/@noble/hashes": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.3.2.tgz",
"integrity": "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==",
"license": "MIT",
"engines": {
"node": ">= 16"
},
"funding": {
"url": "https://paulmillr.com/funding/"
}
},
"node_modules/@types/node": {
"version": "22.7.5",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.5.tgz",
"integrity": "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==",
"license": "MIT",
"dependencies": {
"undici-types": "~6.19.2"
}
},
"node_modules/aes-js": {
"version": "4.0.0-beta.5",
"resolved": "https://registry.npmjs.org/aes-js/-/aes-js-4.0.0-beta.5.tgz",
"integrity": "sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==",
"license": "MIT"
},
"node_modules/asynckit": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
"license": "MIT"
},
"node_modules/axios": {
"version": "1.13.4",
"resolved": "https://registry.npmjs.org/axios/-/axios-1.13.4.tgz",
"integrity": "sha512-1wVkUaAO6WyaYtCkcYCOx12ZgpGf9Zif+qXa4n+oYzK558YryKqiL6UWwd5DqiH3VRW0GYhTZQ/vlgJrCoNQlg==",
"license": "MIT",
"dependencies": {
"follow-redirects": "^1.15.6",
"form-data": "^4.0.4",
"proxy-from-env": "^1.1.0"
}
},
"node_modules/call-bind-apply-helpers": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
"integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/combined-stream": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
"license": "MIT",
"dependencies": {
"delayed-stream": "~1.0.0"
},
"engines": {
"node": ">= 0.8"
}
},
"node_modules/data-uri-to-buffer": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz",
"integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==",
"license": "MIT",
"engines": {
"node": ">= 12"
}
},
"node_modules/delayed-stream": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
"license": "MIT",
"engines": {
"node": ">=0.4.0"
}
},
"node_modules/dotenv": {
"version": "16.6.1",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz",
"integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==",
"license": "BSD-2-Clause",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://dotenvx.com"
}
},
"node_modules/dunder-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
"es-errors": "^1.3.0",
"gopd": "^1.2.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-define-property": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-errors": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-object-atoms": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/es-set-tostringtag": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
"integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
"license": "MIT",
"dependencies": {
"es-errors": "^1.3.0",
"get-intrinsic": "^1.2.6",
"has-tostringtag": "^1.0.2",
"hasown": "^2.0.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/ethers": {
"version": "6.16.0",
"resolved": "https://registry.npmjs.org/ethers/-/ethers-6.16.0.tgz",
"integrity": "sha512-U1wulmetNymijEhpSEQ7Ct/P/Jw9/e7R1j5XIbPRydgV2DjLVMsULDlNksq3RQnFgKoLlZf88ijYtWEXcPa07A==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/ethers-io/"
},
{
"type": "individual",
"url": "https://www.buymeacoffee.com/ricmoo"
}
],
"license": "MIT",
"dependencies": {
"@adraffy/ens-normalize": "1.10.1",
"@noble/curves": "1.2.0",
"@noble/hashes": "1.3.2",
"@types/node": "22.7.5",
"aes-js": "4.0.0-beta.5",
"tslib": "2.7.0",
"ws": "8.17.1"
},
"engines": {
"node": ">=14.0.0"
}
},
"node_modules/ethers/node_modules/ws": {
"version": "8.17.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz",
"integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==",
"license": "MIT",
"engines": {
"node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": ">=5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
"optional": true
},
"utf-8-validate": {
"optional": true
}
}
},
"node_modules/fetch-blob": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz",
"integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/jimmywarting"
},
{
"type": "paypal",
"url": "https://paypal.me/jimmywarting"
}
],
"license": "MIT",
"dependencies": {
"node-domexception": "^1.0.0",
"web-streams-polyfill": "^3.0.3"
},
"engines": {
"node": "^12.20 || >= 14.13"
}
},
"node_modules/follow-redirects": {
"version": "1.15.11",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz",
"integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/RubenVerborgh"
}
],
"license": "MIT",
"engines": {
"node": ">=4.0"
},
"peerDependenciesMeta": {
"debug": {
"optional": true
}
}
},
"node_modules/form-data": {
"version": "4.0.5",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz",
"integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==",
"license": "MIT",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"es-set-tostringtag": "^2.1.0",
"hasown": "^2.0.2",
"mime-types": "^2.1.12"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/formdata-polyfill": {
"version": "4.0.10",
"resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
"integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
"license": "MIT",
"dependencies": {
"fetch-blob": "^3.1.2"
},
"engines": {
"node": ">=12.20.0"
}
},
"node_modules/function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
"license": "MIT",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-intrinsic": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
"integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
"license": "MIT",
"dependencies": {
"call-bind-apply-helpers": "^1.0.2",
"es-define-property": "^1.0.1",
"es-errors": "^1.3.0",
"es-object-atoms": "^1.1.1",
"function-bind": "^1.1.2",
"get-proto": "^1.0.1",
"gopd": "^1.2.0",
"has-symbols": "^1.1.0",
"hasown": "^2.0.2",
"math-intrinsics": "^1.1.0"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
"license": "MIT",
"dependencies": {
"dunder-proto": "^1.0.1",
"es-object-atoms": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/gopd": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-symbols": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/has-tostringtag": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
"integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
"license": "MIT",
"dependencies": {
"has-symbols": "^1.0.3"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/hasown": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
"license": "MIT",
"dependencies": {
"function-bind": "^1.1.2"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/hyperliquid": {
"version": "1.7.7",
"resolved": "https://registry.npmjs.org/hyperliquid/-/hyperliquid-1.7.7.tgz",
"integrity": "sha512-i+mey+chqabb0IFZ2TSpG9ztvr3lgSQQcxEjoVwWbVs8gSEqlwPfDzpYDEmWbhZBRfakIU+AwlD7Z2cH9dgMTQ==",
"hasInstallScript": true,
"license": "MIT",
"dependencies": {
"@msgpack/msgpack": "^3.0.0-beta2",
"axios": "^1.7.2",
"dotenv": "^16.5.0",
"ethers": "^6.13.2",
"ws": "^8.18.2"
},
"engines": {
"node": ">=16.0.0"
}
},
"node_modules/math-intrinsics": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
"license": "MIT",
"engines": {
"node": ">= 0.4"
}
},
"node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/mime-types": {
"version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"license": "MIT",
"dependencies": {
"mime-db": "1.52.0"
},
"engines": {
"node": ">= 0.6"
}
},
"node_modules/node-domexception": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
"integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
"deprecated": "Use your platform's native DOMException instead",
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/jimmywarting"
},
{
"type": "github",
"url": "https://paypal.me/jimmywarting"
}
],
"license": "MIT",
"engines": {
"node": ">=10.5.0"
}
},
"node_modules/node-fetch": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz",
"integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==",
"license": "MIT",
"dependencies": {
"data-uri-to-buffer": "^4.0.0",
"fetch-blob": "^3.1.4",
"formdata-polyfill": "^4.0.10"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/node-fetch"
}
},
"node_modules/proxy-from-env": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
"license": "MIT"
},
"node_modules/tslib": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz",
"integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==",
"license": "0BSD"
},
"node_modules/undici-types": {
"version": "6.19.8",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz",
"integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==",
"license": "MIT"
},
"node_modules/web-streams-polyfill": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz",
"integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==",
"license": "MIT",
"engines": {
"node": ">= 8"
}
},
"node_modules/ws": {
"version": "8.19.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz",
"integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==",
"license": "MIT",
"engines": {
"node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": ">=5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
"optional": true
},
"utf-8-validate": {
"optional": true
}
}
}
}
}
{
"name": "hyperliquid-cli",
"version": "1.0.0",
"type": "module",
"dependencies": {
"ethers": "^6.9.0",
"hyperliquid": "^1.7.7",
"node-fetch": "^3.3.2",
"ws": "^8.19.0"
}
}
#!/usr/bin/env node
import { Hyperliquid } from 'hyperliquid';
const sdk = new Hyperliquid({ enableWs: false });
console.log('Fetching current prices...\n');
const prices = await sdk.info.getAllMids();
// Major assets
const majors = ['BTC-PERP', 'ETH-PERP', 'SOL-PERP', 'AVAX-PERP', 'DOGE-PERP', 'ARB-PERP'];
console.log('=== MAJOR ASSETS ===');
for (const coin of majors) {
if (prices[coin]) {
console.log(`${coin.padEnd(12)} $${prices[coin]}`);
}
}
// Find top movers (we'll need historical data for this, so just show available assets for now)
console.log('\n=== AVAILABLE PERPS (first 20) ===');
const perps = Object.keys(prices)
.filter(k => k.endsWith('-PERP'))
.slice(0, 20);
for (const coin of perps) {
console.log(`${coin.padEnd(12)} $${prices[coin]}`);
}
console.log(`\nTotal perpetuals available: ${Object.keys(prices).filter(k => k.endsWith('-PERP')).length}`);