Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion skills/hyperliquid-plugin/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "hyperliquid",
"description": "Hyperliquid on-chain perpetuals DEX — check positions, get market prices, place and cancel perpetual orders on Hyperliquid L1 (chain_id 999).",
"version": "0.3.2",
"version": "0.3.6",
"author": {
"name": "GeoGu360",
"github": "GeoGu360"
Expand Down
2 changes: 1 addition & 1 deletion skills/hyperliquid-plugin/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion skills/hyperliquid-plugin/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "hyperliquid-plugin"
version = "0.3.4"
version = "0.3.6"
edition = "2021"

[[bin]]
Expand Down
78 changes: 68 additions & 10 deletions skills/hyperliquid-plugin/SKILL.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
name: hyperliquid-plugin
description: Hyperliquid DEX — trade perps & spot, deposit from Arbitrum, withdraw to Arbitrum, transfer between perp and spot accounts, manage gas on HyperEVM.
version: "0.3.4"
version: "0.3.6"
author: GeoGu360
tags:
- perps
Expand All @@ -26,7 +26,7 @@ tags:
# Check for skill updates (1-hour cache)
UPDATE_CACHE="$HOME/.plugin-store/update-cache/hyperliquid-plugin"
CACHE_MAX=3600
LOCAL_VER="0.3.4"
LOCAL_VER="0.3.6"
DO_CHECK=true

if [ -f "$UPDATE_CACHE" ]; then
Expand All @@ -37,7 +37,7 @@ if [ -f "$UPDATE_CACHE" ]; then
fi

if [ "$DO_CHECK" = true ]; then
REMOTE_VER=$(curl -sf --max-time 3 "https://raw.githubusercontent.com/mig-pre/plugin-store/main/skills/hyperliquid-plugin/plugin.yaml" | grep '^version' | head -1 | tr -d '"' | awk '{print $2}')
REMOTE_VER=$(curl -sf --max-time 3 "https://raw.githubusercontent.com/okx/plugin-store/main/skills/hyperliquid-plugin/plugin.yaml" | grep '^version' | head -1 | tr -d '"' | awk '{print $2}')
if [ -n "$REMOTE_VER" ]; then
mkdir -p "$HOME/.plugin-store/update-cache"
echo "$REMOTE_VER" > "$UPDATE_CACHE"
Expand All @@ -47,7 +47,7 @@ fi
REMOTE_VER=$(cat "$UPDATE_CACHE" 2>/dev/null || echo "$LOCAL_VER")
if [ "$REMOTE_VER" != "$LOCAL_VER" ]; then
echo "Update available: hyperliquid-plugin v$LOCAL_VER -> v$REMOTE_VER. Updating..."
npx skills add mig-pre/plugin-store --skill hyperliquid-plugin --yes --global 2>/dev/null || true
npx skills add okx/plugin-store --skill hyperliquid-plugin --yes --global 2>/dev/null || true
echo "Updated hyperliquid-plugin to v$REMOTE_VER. Please re-read this SKILL.md."
fi
```
Expand All @@ -62,7 +62,7 @@ onchainos --version 2>/dev/null || curl -fsSL https://raw.githubusercontent.com/
npx skills add okx/onchainos-skills --yes --global

# 3. Install plugin-store skills (enables plugin discovery and management)
npx skills add mig-pre/plugin-store --skill plugin-store --yes --global
npx skills add okx/plugin-store --skill plugin-store --yes --global
```

### Install hyperliquid-plugin binary + launcher (auto-injected)
Expand All @@ -73,11 +73,11 @@ LAUNCHER="$HOME/.plugin-store/launcher.sh"
CHECKER="$HOME/.plugin-store/update-checker.py"
if [ ! -f "$LAUNCHER" ]; then
mkdir -p "$HOME/.plugin-store"
curl -fsSL "https://raw.githubusercontent.com/mig-pre/plugin-store/main/scripts/launcher.sh" -o "$LAUNCHER" 2>/dev/null || true
curl -fsSL "https://raw.githubusercontent.com/okx/plugin-store/main/scripts/launcher.sh" -o "$LAUNCHER" 2>/dev/null || true
chmod +x "$LAUNCHER"
fi
if [ ! -f "$CHECKER" ]; then
curl -fsSL "https://raw.githubusercontent.com/mig-pre/plugin-store/main/scripts/update-checker.py" -o "$CHECKER" 2>/dev/null || true
curl -fsSL "https://raw.githubusercontent.com/okx/plugin-store/main/scripts/update-checker.py" -o "$CHECKER" 2>/dev/null || true
fi

# Clean up old installation
Expand All @@ -99,15 +99,15 @@ case "${OS}_${ARCH}" in
mingw*_aarch64|msys*_aarch64|cygwin*_aarch64) TARGET="aarch64-pc-windows-msvc"; EXT=".exe" ;;
esac
mkdir -p ~/.local/bin
curl -fsSL "https://github.com/mig-pre/plugin-store/releases/download/plugins/hyperliquid-plugin@0.3.4/hyperliquid-plugin-${TARGET}${EXT}" -o ~/.local/bin/.hyperliquid-plugin-core${EXT}
curl -fsSL "https://github.com/okx/plugin-store/releases/download/plugins/hyperliquid-plugin@0.3.6/hyperliquid-plugin-${TARGET}${EXT}" -o ~/.local/bin/.hyperliquid-plugin-core${EXT}
chmod +x ~/.local/bin/.hyperliquid-plugin-core${EXT}

# Symlink CLI name to universal launcher
ln -sf "$LAUNCHER" ~/.local/bin/hyperliquid-plugin

# Register version
mkdir -p "$HOME/.plugin-store/managed"
echo "0.3.4" > "$HOME/.plugin-store/managed/hyperliquid-plugin"
echo "0.3.6" > "$HOME/.plugin-store/managed/hyperliquid-plugin"
```

### Report install (auto-injected, runs once)
Expand All @@ -127,7 +127,7 @@ if [ ! -f "$REPORT_FLAG" ]; then
# Report to Vercel stats
curl -s -X POST "https://plugin-store-dun.vercel.app/install" \
-H "Content-Type: application/json" \
-d '{"name":"hyperliquid-plugin","version":"0.3.4"}' >/dev/null 2>&1 || true
-d '{"name":"hyperliquid-plugin","version":"0.3.6"}' >/dev/null 2>&1 || true
# Report to OKX API (with HMAC-signed device token)
curl -s -X POST "https://www.okx.com/priapi/v1/wallet/plugins/download/report" \
-H "Content-Type: application/json" \
Expand Down Expand Up @@ -230,6 +230,60 @@ The binary `hyperliquid` must be in your PATH.

---

### 0. `quickstart` — Check Assets & Get Guided Next Step

Detects wallet state across Arbitrum and Hyperliquid in one call, then recommends the right next action. Use this when a user says "I want to start trading on Hyperliquid" or "what should I do first" without knowing their current status.

**Trigger phrases:**
- "帮我看下 Hyperliquid 状态" / "我要开始用 Hyperliquid"
- "我有多少资产在 HL" / "quickstart hyperliquid"
- "Hyperliquid 怎么用" / "I want to trade on Hyperliquid"
- "check my hyperliquid balance" / "what should I do on HL"

**Parameters:**

| Flag | Required | Description |
|------|----------|-------------|
| `--address` | No | EVM wallet address (defaults to onchainos wallet) |

**Output fields:** `wallet`, `assets.arb_usdc_balance`, `assets.hl_account_value_usd`, `assets.hl_withdrawable_usd`, `assets.hl_open_positions`, `positions[]`, `status`, `suggestion`, `next_command`

**Status values and flow:**

| `status` | Condition | `next_command` |
|----------|-----------|----------------|
| `active` | Has open HL positions | `hyperliquid positions` |
| `ready` | HL account ≥ $1, no positions | `hyperliquid order ...` |
| `needs_deposit` | Arbitrum USDC ≥ $5, HL empty | `hyperliquid deposit --amount X --confirm` |
| `low_balance` | Arbitrum USDC < $5 | `hyperliquid address` |
| `no_funds` | No USDC anywhere | `hyperliquid address` |

**Example:**
```
hyperliquid quickstart
```

```json
{
"ok": true,
"wallet": "0x87fb0647...",
"assets": {
"arb_usdc_balance": 1.63,
"hl_account_value_usd": 9.89,
"hl_withdrawable_usd": 8.77,
"hl_open_positions": 1
},
"positions": [
{ "coin": "BTC", "side": "long", "size": "0.00015", "entryPrice": "74633.0", "unrealizedPnl": "0.0015" }
],
"status": "active",
"suggestion": "You have open positions on Hyperliquid. Review them below.",
"next_command": "hyperliquid positions"
}
```

---

### 1. `positions` — Check Open Perp Positions

Shows open perpetual positions, unrealized PnL, margin usage, and account summary for a wallet.
Expand Down Expand Up @@ -904,6 +958,10 @@ All data returned by `hyperliquid positions`, `hyperliquid prices`, and exchange

## Changelog

### v0.3.6 (2026-04-17)

- **feat**: `quickstart` — new command; checks Arbitrum USDC balance + Hyperliquid account value + open positions in parallel via onchainos, returns structured JSON with `status` and `next_command` to guide first-time users from zero to first trade

### v0.3.2 (2026-04-13)

- **fix**: `order` — balance pre-flight: queries Perp + Spot + Arbitrum USDC in parallel before every order; stops early with fund landscape + deposit/transfer tip if perp balance is insufficient
Expand Down
22 changes: 22 additions & 0 deletions skills/hyperliquid-plugin/SKILL_SUMMARY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@

# hyperliquid -- Skill Summary

## Overview
This skill enables trading perpetual futures on Hyperliquid, a high-performance on-chain perpetuals exchange built on its own L1 blockchain. It provides comprehensive trading functionality including position management, order placement with stop-loss/take-profit brackets, market data retrieval, and USDC deposits from Arbitrum. All operations use USDC as the margin token and settle on Hyperliquid L1 with CEX-like speed but full on-chain transparency.

## Usage
Install the hyperliquid binary and ensure onchainos CLI is configured with your wallet. For write operations, first run commands without `--confirm` to preview, then add `--confirm` to sign and execute via EIP-712 signatures.

## Commands
| Command | Description |
|---------|-------------|
| `hyperliquid positions` | Check open perpetual positions and account summary |
| `hyperliquid prices` | Get current mid prices for all or specific markets |
| `hyperliquid order` | Place market/limit orders with optional TP/SL brackets |
| `hyperliquid close` | Market-close an open position |
| `hyperliquid tpsl` | Set stop-loss/take-profit on existing positions |
| `hyperliquid cancel` | Cancel open orders by order ID |
| `hyperliquid deposit` | Deposit USDC from Arbitrum to Hyperliquid |

## Triggers
Activate when users mention trading on Hyperliquid, checking Hyperliquid positions, placing perp orders, or managing stop-loss/take-profit levels. Also triggers for Hyperliquid-specific terms like "HL order", "HYPE perps", or phrases about opening/closing positions on the platform.
2 changes: 1 addition & 1 deletion skills/hyperliquid-plugin/plugin.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
schema_version: 1
name: hyperliquid-plugin
version: "0.3.4"
version: "0.3.6"
description: "Trade perpetuals on Hyperliquid — check positions, get prices, place market/limit orders with TP/SL brackets, close positions, deposit USDC"
author:
name: GeoGu360
Expand Down
8 changes: 4 additions & 4 deletions skills/hyperliquid-plugin/src/commands/cancel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,11 @@ pub async fn run(args: CancelArgs) -> anyhow::Result<()> {
);

if args.dry_run {
println!("\n[DRY RUN] Cancel not signed or submitted.");
eprintln!("\n[DRY RUN] Cancel not signed or submitted.");
return Ok(());
}
if !args.confirm {
println!("\n[PREVIEW] Add --confirm to sign and submit this cancellation.");
eprintln!("\n[PREVIEW] Add --confirm to sign and submit this cancellation.");
return Ok(());
}

Expand Down Expand Up @@ -187,11 +187,11 @@ pub async fn run(args: CancelArgs) -> anyhow::Result<()> {
);

if args.dry_run {
println!("\n[DRY RUN] Cancel not signed or submitted.");
eprintln!("\n[DRY RUN] Cancel not signed or submitted.");
return Ok(());
}
if !args.confirm {
println!("\n[PREVIEW] Add --confirm to sign and submit this batch cancellation.");
eprintln!("\n[PREVIEW] Add --confirm to sign and submit this batch cancellation.");
return Ok(());
}

Expand Down
6 changes: 3 additions & 3 deletions skills/hyperliquid-plugin/src/commands/close.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,13 +118,13 @@ pub async fn run(args: CloseArgs) -> anyhow::Result<()> {
);

if args.dry_run {
println!("\n[DRY RUN] Not signed or submitted.");
eprintln!("\n[DRY RUN] Not signed or submitted.");
return Ok(());
}

if !args.confirm {
println!("\n[PREVIEW] Add --confirm to sign and market-close this position.");
println!("WARNING: Market orders execute immediately at prevailing price.");
eprintln!("\n[PREVIEW] Add --confirm to sign and market-close this position.");
eprintln!("WARNING: Market orders execute immediately at prevailing price.");
return Ok(());
}

Expand Down
4 changes: 2 additions & 2 deletions skills/hyperliquid-plugin/src/commands/deposit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ pub async fn run(args: DepositArgs) -> anyhow::Result<()> {
});

// Step 2: Sign the permit via onchainos
println!("Signing USDC permit for {} USDC...", args.amount);
eprintln!("Signing USDC permit for {} USDC...", args.amount);
let sig_hex = onchainos_sign_eip712(&permit_typed_data, &wallet)?;

// Parse r, s, v from the 65-byte hex signature
Expand All @@ -189,7 +189,7 @@ pub async fn run(args: DepositArgs) -> anyhow::Result<()> {
let calldata = build_batched_deposit_calldata(&wallet, usdc_units, deadline, r, s, v);

// Step 4: Submit the transaction
println!("Depositing {:.6} USDC to Hyperliquid via Arbitrum bridge...", args.amount);
eprintln!("Depositing {:.6} USDC to Hyperliquid via Arbitrum bridge...", args.amount);
let deposit_result = wallet_contract_call(
ARBITRUM_CHAIN_ID,
HL_BRIDGE_ARBITRUM,
Expand Down
25 changes: 15 additions & 10 deletions skills/hyperliquid-plugin/src/commands/evm_send.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use clap::Args;
use sha3::{Digest, Keccak256};
use crate::config::{CHAIN_ID, info_url};
use crate::config::{CHAIN_ID, HYPER_EVM_RPC, info_url};
use crate::onchainos::{resolve_wallet, wallet_contract_call};
use crate::api::get_clearinghouse_state;
use crate::rpc::wait_tx_mined;

/// CoreWriter precompile on HyperEVM — executes HyperCore actions via msg.sender
const CORE_WRITER: &str = "0x3333333333333333333333333333333333333333";
Expand Down Expand Up @@ -170,19 +171,23 @@ pub async fn run(args: EvmSendArgs) -> anyhow::Result<()> {
// ── Execute ───────────────────────────────────────────────────────────

// Step 1: Move perp → spot
println!("Step 1/2 Transferring {} USDC from perp → spot via CoreWriter...", args.amount);
wallet_contract_call(CHAIN_ID, CORE_WRITER, &calldata_perp_to_spot, None, false)?;

// Give HyperCore time to settle the transfer (~2 HyperEVM blocks)
println!(" Waiting for HyperCore to process...");
tokio::time::sleep(std::time::Duration::from_secs(5)).await;
eprintln!("Step 1/2 Transferring {} USDC from perp → spot via CoreWriter...", args.amount);
let result1 = wallet_contract_call(CHAIN_ID, CORE_WRITER, &calldata_perp_to_spot, None, false)?;

// Wait for step 1 to be mined before submitting step 2 (HyperCore needs the tx on-chain)
eprintln!(" Waiting for HyperCore to process...");
let tx1_hash = result1["data"]["txHash"].as_str().unwrap_or("");
if !tx1_hash.is_empty() {
let confirmed = wait_tx_mined(tx1_hash, HYPER_EVM_RPC).await;
if !confirmed {
eprintln!(" Warning: step 1 tx confirmation timed out. Proceeding with step 2.");
}
}

// Step 2: Spot → HyperEVM address
println!("Step 2/2 Sending {} USDC from spot → HyperEVM {}...", args.amount, &destination[..10]);
eprintln!("Step 2/2 Sending {} USDC from spot → HyperEVM {}...", args.amount, &destination[..10]);
wallet_contract_call(CHAIN_ID, CORE_WRITER, &calldata_spot_to_evm, None, false)?;

tokio::time::sleep(std::time::Duration::from_secs(3)).await;

println!("{}", serde_json::json!({
"ok": true,
"action": "evm-send",
Expand Down
12 changes: 6 additions & 6 deletions skills/hyperliquid-plugin/src/commands/get_gas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ pub async fn run(args: GetGasArgs) -> anyhow::Result<()> {
.unwrap_or(0);

if existing < usdc_units as u128 {
println!("Approving USDC to relay solver...");
eprintln!("Approving USDC to relay solver...");
let approve_value_opt = if approve_value > 0 { Some(approve_value) } else { None };
let result = wallet_contract_call(
ARBITRUM_CHAIN_ID, approve_to, approve_calldata, approve_value_opt, false
Expand All @@ -164,12 +164,12 @@ pub async fn run(args: GetGasArgs) -> anyhow::Result<()> {
// Wait for the approve tx to be mined so deposit simulation succeeds
let tx_hash = result["data"]["txHash"].as_str().unwrap_or("");
if !tx_hash.is_empty() {
print!(" Waiting for approve tx {} to confirm...", tx_hash);
eprint!(" Waiting for approve tx {} to confirm...", tx_hash);
let confirmed = wait_tx_mined(tx_hash, ARBITRUM_RPC).await;
println!(" {}", if confirmed { "confirmed" } else { "timed out (proceeding anyway)" });
eprintln!(" {}", if confirmed { "confirmed" } else { "timed out (proceeding anyway)" });
}
} else {
println!("USDC allowance already sufficient, skipping approve.");
eprintln!("USDC allowance already sufficient, skipping approve.");
}
}

Expand All @@ -192,12 +192,12 @@ pub async fn run(args: GetGasArgs) -> anyhow::Result<()> {
.as_str()
.unwrap_or(request_id);

println!("Depositing {} USDC to relay solver...", args.amount);
eprintln!("Depositing {} USDC to relay solver...", args.amount);
let deposit_value_opt = if deposit_value > 0 { Some(deposit_value) } else { None };
wallet_contract_call(ARBITRUM_CHAIN_ID, deposit_to, deposit_calldata, deposit_value_opt, false)?;

// Poll relay.link status until HYPE arrives (max ~40s)
println!("Waiting for HYPE to arrive on HyperEVM (~{} seconds)...", time_est);
eprintln!("Waiting for HYPE to arrive on HyperEVM (~{} seconds)...", time_est);
let client = reqwest::Client::builder()
.timeout(std::time::Duration::from_secs(10))
.build()?;
Expand Down
1 change: 1 addition & 0 deletions skills/hyperliquid-plugin/src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ pub mod spot_prices;
pub mod tpsl;
pub mod transfer;
pub mod withdraw;
pub mod quickstart;
10 changes: 5 additions & 5 deletions skills/hyperliquid-plugin/src/commands/order.rs
Original file line number Diff line number Diff line change
Expand Up @@ -334,14 +334,14 @@ pub async fn run(args: OrderArgs) -> anyhow::Result<()> {
);

if args.dry_run {
println!("\n[DRY RUN] Order not signed or submitted.");
eprintln!("\n[DRY RUN] Order not signed or submitted.");
return Ok(());
}

if !args.confirm {
println!("\n[PREVIEW] Add --confirm to sign and submit this order.");
println!("WARNING: This will place a real perpetual order on Hyperliquid.");
println!(" Perpetuals trading involves significant risk including total loss.");
eprintln!("\n[PREVIEW] Add --confirm to sign and submit this order.");
eprintln!("WARNING: This will place a real perpetual order on Hyperliquid.");
eprintln!(" Perpetuals trading involves significant risk including total loss.");
return Ok(());
}

Expand All @@ -363,7 +363,7 @@ pub async fn run(args: OrderArgs) -> anyhow::Result<()> {
lev_result["response"].as_str().unwrap_or("unknown error")
);
}
println!(
eprintln!(
"Leverage set to {}x ({}) for {}",
lev, if is_cross { "cross" } else { "isolated" }, coin
);
Expand Down
Loading
Loading