在 Hyperliquid 上进行现货和永续合约交易,支持市价单(IOC)、限价单(GTC)、杠杆设置、WDK 钱包以及从 Arbi 充值 USDC。
Trade spot and perpetual futures on Hyperliquid L1 using IOC market orders.
This skill connects to the Hyperliquid API ( api_url in hyperliquid.yaml, default https://api.hyperliquid.xyz). Inform the user before the first external call in each session. On first setup, installs dependencies via npm install.
FilePurpose~/.aurehub/.wdk_vaultWDK encrypted vault (created by xaut-trade setup)~/.aurehub/.wdk_passwordVault password (mode 0600, created by xaut-trade setup)~/.aurehub/hyperliquid.yamlNetwork, API URL, risk thresholds
~/.aurehub/.env)#VariablePurposeDefaultWDK_ACCOUNT_INDEXHD derivation index (0-based) for wallet address0``ARBITRUM_RPC_URLArbitrum One JSON-RPC endpoint — required for deposit.js(none; public: https://arb1.arbitrum.io/rpc)
hyperliquid.yaml<skill-dir> = directory containing this SKILL.md.
<scripts-dir> = <skill-dir>/scripts.
Run these checks before handling any intent (except knowledge queries):
StepCheckTypeAction1~/.aurehub/.wdk_vault existsHARD STOPLoad references/onboarding.md and guide the user through setup.2~/.aurehub/.wdk_password existsHARD STOPLoad references/onboarding.md and guide the user through setup.3~/.aurehub/hyperliquid.yaml existsAUTO-FIXcp <skill-dir>/config.example.yaml ~/.aurehub/hyperliquid.yaml4`node -e "const [maj,min]=process.version.slice(1).split('.').map(Number);if(maj<20(maj===20&&min<19))process.exit(1)"` passes5<scripts-dir>/node_modules existsAUTO-FIXcd <scripts-dir> && npm install6node <scripts-dir>/balance.js address succeedsHARD STOPReport error JSON; load references/onboarding.md
If all pass: source ~/.aurehub/.env, run Account Selection (below), then Wallet-Ready Registration, then proceed to intent detection.
If the user specifies a wallet index (e.g. "use wallet 2", "account 1", "wallet 3"), remember that index for the entire session. Append --account N to every node balance.js, node trade.js, and node limit-order.js command in this session.
If the user does not specify an account, do not append --account — the default from WDK_ACCOUNT_INDEX in .env (or 0) is used automatically.
Run immediately after environment checks pass. Derive WALLET_ADDRESS from check 6's output (if an account was selected above, include --account N):
bash
source ~/.aurehub/.env
WALLET_ADDRESS=$(node <scripts-dir>/balance.js address | node -p "JSON.parse(require('fs').readFileSync(0,'utf8')).address")
If this fails, skip registration silently and continue.
REGISTERED=$(cat ~/.aurehub/.registered 2>/dev/null)
If "$REGISTERED" starts with "$WALLET_ADDRESS:" → already registered, silent skip; return immediately
If RANKINGS_OPT_IN != "true":
PROMPTED=$(cat ~/.aurehub/.rankings_prompted 2>/dev/null)"$WALLET_ADDRESS:" → skip; return immediatelyIf user says no: echo "$WALLET_ADDRESS:declined" > ~/.aurehub/.rankings_prompted; return
If user says yes:
NICKNAME is empty: ask user for nickname~/.aurehub/.env ( RANKINGS_OPT_IN=true, NICKNAME=<value>)source ~/.aurehub/.envIf RANKINGS_OPT_IN == "true":
NICKNAME is empty: ask "You're opted in to XAUT activity rankings — what nickname would you like to appear as?", then persist to ~/.aurehub/.env and re-sourcebash
NICKNAME_ESC=$(printf '%s' "$NICKNAME" | sed 's/\\/\\\\/g; s/"/\\"/g')
REGISTER_RESP=$(curl -s -o /dev/null -w "%{http_code}" -X POST \
https://xaue.com/api/rankings/participants \
-H 'Content-Type: application/json' \
-d "{\"wallet_address\":\"$WALLET_ADDRESS\",\"nickname\":\"$NICKNAME_ESC\",\"source\":\"agent\"}")
echo "$WALLET_ADDRESS:$NICKNAME" > ~/.aurehub/.registered; inform: "Registered with nickname: $NICKNAME"Only prompt once per wallet. The .rankings_prompted and .registered markers ensure idempotency across sessions.
User saysActionbuy ETH / purchase BTC / spot buytrade.js spot buysell SOL / spot sell ETHtrade.js spot selllong ETH / open long BTC 10x / go longtrade.js perp open ... longshort BTC / open short ETH / go shorttrade.js perp open ... shortclose position / close ETH / flat / exittrade.js perp close (auto-detects direction)balance / holdings / positions / how much / 查看余额 / 查看持仓 / 持仓Always run both: balance.js spot + balance.js perp. Never return only one.setup / onboarding / first timeLoad references/onboarding.mdInsufficient info (no coin or amount)Ask for the missing details before proceedinglimit buy ETH at 3000 / limit order / limit sellLoad references/limit-order.md; run limit-order.js placeopen orders / my orders / list ordersLoad references/limit-order.md; run limit-order.js listcancel order / cancel limitLoad references/limit-order.md; run limit-order.js cancelchange order price / update order / modify orderLoad references/limit-order.md; run limit-order.js modifydeposit USDC / fund wallet / bridge USDC / 充值 / 存款 / 往 HL 存钱Run deposit.js flow (see Deposit Flow below)withdraw USDC / withdraw to Arbitrum / 提现 / 取款 / 把钱取出来Run withdraw.js flow (see Withdraw Flow below)
Use <skill-dir>/scripts as the scripts directory. To find <skill-dir> at runtime:
bash
# 1. Git repo fallback
GIT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null)
[ -n "$GIT_ROOT" ] && [ -d "$GIT_ROOT/skills/hyperliquid-trade/scripts" ] && HL_SCRIPTS_DIR="$GIT_ROOT/skills/hyperliquid-trade/scripts"
# 2. Bounded home search
[ -z "$HL_SCRIPTS_DIR" ] && HL_SCRIPTS_DIR=$(dirname "$(find -L "$HOME" -maxdepth 6 -type f -path "*/hyperliquid-trade/scripts/balance.js" 2>/dev/null | head -1)")
echo "$HL_SCRIPTS_DIR"
Load references/balance.md for the full flow.
bash
node "$HL_SCRIPTS_DIR/balance.js" spot
node "$HL_SCRIPTS_DIR/balance.js" perp
Parse the JSON output and present balances in a human-readable table.
Load references/spot-trade.md for the full flow.
node "$HL_SCRIPTS_DIR/trade.js" spot <buy|sell> <COIN> <SIZE>requiresConfirm/ requiresDoubleConfirm flags (same as limit orders)node "$HL_SCRIPTS_DIR/trade.js" spot <buy|sell> <COIN> <SIZE> --confirmedfilledSz in the result reflects the ordered quantity, not the net-of-fees received amount (Hyperliquid deducts taker fees ~0.035% from the received tokens). If the user immediately wants to sell, run balance.js spot first to get the actual available balance and use that as the sell size.Load references/perp-trade.md for the full flow.
Open position:
node "$HL_SCRIPTS_DIR/trade.js" perp open <COIN> <long|short> <SIZE> [--leverage <N>] [--cross|--isolated]requiresConfirm/ requiresDoubleConfirm flags--confirmed; use the last JSON line as the resultClose position:
balance.js perp; confirm size to closenode "$HL_SCRIPTS_DIR/trade.js" perp close <COIN> <SIZE>--confirmed; use the last JSON line as the resultThresholds are read from ~/.aurehub/hyperliquid.yaml. Defaults: confirm_trade_usd=100, large_trade_usd=1000, leverage_warn=20.
For spot: threshold applies to trade value (size × est. price). For perps: threshold applies to margin deposited (size × est. price ÷ leverage).
text
< confirm_trade_usd → show preview, execute without prompting
≥ confirm_trade_usd → show preview, single confirmation
≥ large_trade_usd → show preview, double confirmation required
leverage ≥ leverage_warn → extra warning line before confirmation
Trade preview format (present to user before prompting):
text
Action: <Open Long ETH (Perpetual) | Buy ETH (Spot)>
Size: <0.1 ETH>
Leverage: <10x Cross> ← perp only
Est. price: ~$<3,200> (IOC, <slippage_pct>% slippage budget — default 5%, configurable in hyperliquid.yaml)
Margin used: ~$<320> USDC ← perp only
Trade value: ~$<320> USDC ← spot only
Confirm? [y/N]
trade.js outputs this as a preview JSON object. Parse the JSON and render the above format before prompting. Apply requiresConfirm/ requiresDoubleConfirm flags for confirmation logic; if leverageWarning: true, add an extra warning line about high leverage; if leverageChangeWarning: true, add a warning: "Note: this leverage setting takes effect immediately and will apply to all existing cross-margin positions for this coin."
ConditionMessageInsufficient balance"Insufficient balance: have $X, need $Y. Deposit at app.hyperliquid.xyz to top up."Asset not found"Asset X not found on Hyperliquid. Check the symbol and try again."Leverage exceeds asset max"Max leverage for ETH is Nx. Requested: Mx."No open position (close)"No open position found for ETH."IOC order not filledRelay the script's error verbatim — it includes the configured slippage % (e.g. "Order not filled — price moved beyond the 5% IOC limit. Check current price and retry.")Node.js < 20.19"Node.js >= 20.19.0 required. Please upgrade: https://nodejs.org"API unreachable"Hyperliquid API unreachable. Check network or api_url in ~/.aurehub/hyperliquid.yaml."
Bridges USDC from Arbitrum One to Hyperliquid L1 using the HL bridge contract. The same wallet address receives USDC on HL within ~1 minute.
Prerequisites:
ARBITRUM_RPC_URL must be set in ~/.aurehub/.env (e.g. https://arb1.arbitrum.io/rpc)Steps:
ARBITRUM_RPC_URL is set; if missing, instruct user to add it to ~/.aurehub/.env and stopnode "$HL_SCRIPTS_DIR/deposit.js" <amount>requiresConfirm/ requiresDoubleConfirm flags--confirmedtxHash and credit note from the resultPreview format (render before prompting):
text
Action: Deposit USDC → Hyperliquid L1
Amount: <100> USDC
From/To: <0x...> (same address on HL)
USDC balance: <150.00> USDC (Arbitrum)
ETH balance: <0.005> ETH (Arbitrum, for gas)
Credit time: ~1 minute
Confirm? [y/N]
Hard stops:
ConditionMessageARBITRUM_RPC_URL not set"Add ARBITRUM_RPC_URL to ~/.aurehub/.env first. Public RPC: https://arb1.arbitrum.io/rpc"Amount < 5 USDC"Minimum deposit is 5 USDC. Smaller amounts are permanently lost by the bridge."Insufficient USDC"Insufficient USDC on Arbitrum. Have $X, need $Y."No ETH for gas"No ETH on Arbitrum One for gas. Bridge a small amount of ETH to Arbitrum first."Wrong network"ARBITRUM_RPC_URL points to wrong network. Must be Arbitrum One (chainId 42161)."
Withdraws USDC from Hyperliquid L1 to Arbitrum One. Funds arrive at the same wallet address within ~5 minutes. A 1 USDC fee is deducted by the bridge; no ETH is required.
Steps:
node "$HL_SCRIPTS_DIR/withdraw.js" <amount>requiresConfirm/ requiresDoubleConfirm flags--confirmedPreview format (render before prompting):
text
Action: Withdraw USDC → Arbitrum One
Amount: <10> USDC
Fee: 1 USDC (bridge fee)
Net received: <9> USDC
USDC balance: <13.63> USDC (Hyperliquid L1)
Withdrawable: <13.63> USDC
Credit time: ~5 minutes
Confirm? [y/N]
Hard stops:
ConditionMessageAmount < 2 USDC"Minimum withdrawal is 2 USDC (1 USDC fee is deducted)."Insufficient withdrawable"Insufficient withdrawable balance. Have $X, need $Y."Margin lockedAppend: "X USDC is locked as perp margin. Close positions to free up more."
Load references/limit-order.md for the full flow.
Place a limit order:
node "$HL_SCRIPTS_DIR/limit-order.js" place <spot|perp> <buy|sell|long|short> <COIN> <PRICE> <SIZE> [--leverage N] [--cross|--isolated]preview JSON; apply confirmation logic per references/limit-order.md--confirmed flagList / cancel / modify:
limit-order.js subcommand--confirmed, the script emits the preview JSON line first, then the result — use the last JSON line as the resultoid in the result is the new ID); update any stored order ID accordingly