{"skill":{"slug":"vincent-hyperliquid","displayName":"Vincent - Hyperliquid","summary":"Use this skill to create a HyperLiquid perpetuals and spot wallet for your agent. Trade perps, manage spot balances, transfer USDC between sub-accounts, get...","description":"---\nname: Vincent - HyperLiquid for agents\ndescription: Use this skill to create a HyperLiquid perpetuals and spot wallet for your agent. Trade perps, manage spot balances, transfer USDC between sub-accounts, get prices, place orders — all without exposing private keys.\nhomepage: https://heyvincent.ai\nsource: https://github.com/HeyVincent-ai/Vincent\nmetadata:\n  clawdbot:\n    homepage: https://heyvincent.ai\n    requires:\n      config:\n        - ${OPENCLAW_STATE_DIR:-$HOME/.openclaw}/credentials/agentwallet\n        - ./agentwallet\n---\n\n# Vincent - HyperLiquid for agents\n\nUse this skill to create a HyperLiquid perpetuals and spot wallet for your agent. Trade perps, check spot balances, and transfer USDC between perps and spot sub-accounts. The generated EOA **is** the HyperLiquid account — fund it directly via the HL bridge and start trading immediately with no Safe deployment or collateral approval steps.\n\n**The agent never sees the private key.** All operations are executed server-side. The agent receives a scoped API key that can only perform actions permitted by the wallet owner's policies.\n\nAll commands use the `@vincentai/cli` package. API keys are stored and resolved automatically.\n\n## Security Model\n\n**No environment variables are required.** The agent creates its own HyperLiquid wallet at runtime by calling the Vincent API, which returns a scoped API key. There is no pre-existing credential to configure.\n\n**The generated EOA is a standalone HyperLiquid account.** Unlike Polymarket (which deploys a Gnosis Safe), the EOA private key IS the HyperLiquid account. Deposits go directly to this address via the HyperLiquid bridge from Arbitrum, or via `usdSend` from another HL account.\n\n**The agent's API key is not a private key.** It is a scoped Bearer token enforced server-side. The Vincent server evaluates all policies before executing any trade. If a trade violates a policy, the server rejects it. If a trade requires human approval, the server holds it and notifies the wallet owner via Telegram.\n\n**All API calls go exclusively to `heyvincent.ai`** over HTTPS/TLS. The service calls `api.hyperliquid.xyz` server-side on the agent's behalf.\n\n**Key lifecycle:**\n\n- **Creation**: Agent runs `secret create` — Vincent generates the EOA, stores the key, returns `keyId`, `walletAddress`, and `claimUrl`.\n- **Claim**: Human operator uses the claim URL to take ownership and configure policies at `https://heyvincent.ai`.\n- **Revocation**: Wallet owner revokes the agent's API key from the frontend at any time.\n- **Re-linking**: Agent exchanges a one-time re-link token (generated by the owner) for a new key via `secret relink`.\n\n## Quick Start\n\n### 1. Check for Existing Keys\n\nBefore creating a new wallet, check if one already exists:\n\n```bash\nnpx @vincentai/cli@latest secret list --type HYPERLIQUID_WALLET\n```\n\nIf a key is returned, use its `id` as `--key-id` for all subsequent commands. If not, create one.\n\n### 2. Create a HyperLiquid Wallet\n\n```bash\nnpx @vincentai/cli@latest secret create --type HYPERLIQUID_WALLET --memo \"My HL perp wallet\"\n```\n\nReturns:\n\n- `keyId` — use for all future commands\n- `walletAddress` — the EOA address (this IS the HyperLiquid account)\n- `claimUrl` — share with the user to take ownership\n\nAfter creating, tell the user:\n\n> \"Here is your wallet claim URL: `<claimUrl>`. Use this to claim ownership, set spending policies, and monitor your agent's wallet activity at https://heyvincent.ai.\"\n\n**Important:** The wallet is empty at creation. The user must deposit USDC before trading.\n\n### 3. Get Balance\n\n```bash\nnpx @vincentai/cli@latest hyperliquid balance --key-id <KEY_ID>\n```\n\nReturns:\n\n- `walletAddress` — the EOA address\n- `accountValue` — total perps account value in USD (cross-margin)\n- `withdrawable` — USDC available to withdraw from the perps account\n- `positions` — array of open perpetual positions\n- `spotBalances` — array of spot token balances (each with `coin`, `token`, `hold`, `total`)\n\n### 4. Transfer Between Perps and Spot\n\nHyperLiquid has separate perps and spot sub-accounts. USDC must be in the correct sub-account before trading. Use `internal-transfer` to move USDC between them.\n\n```bash\n# Move 100 USDC from spot → perps (needed before perp trading)\nnpx @vincentai/cli@latest hyperliquid internal-transfer --key-id <KEY_ID> --amount 100 --to-perp true\n\n# Move 50 USDC from perps → spot (needed before spot trading)\nnpx @vincentai/cli@latest hyperliquid internal-transfer --key-id <KEY_ID> --amount 50 --to-perp false\n```\n\nParameters:\n\n- `--amount`: USDC amount to transfer (string, numeric)\n- `--to-perp`: `true` = spot→perps, `false` = perps→spot\n\n**Response codes:**\n- `200` — `status: \"executed\"` — transfer completed\n- `202` — `status: \"pending_approval\"` (human approval required by policy)\n- `403` — `status: \"denied\"` (rejected by policy)\n\n### 5. Withdraw USDC to External Address\n\nSend USDC from this HyperLiquid wallet to another HyperLiquid address via `usdSend`. This is an on-chain HL→HL transfer (instant, no gas).\n\n```bash\n# Withdraw 100 USDC to another HL address\nnpx @vincentai/cli@latest hyperliquid withdraw --key-id <KEY_ID> \\\n  --destination 0x1234567890abcdef1234567890abcdef12345678 --amount 100\n```\n\nParameters:\n\n- `--destination`: Target 0x address (must be a valid 40-hex-char Ethereum address)\n- `--amount`: USDC amount to send (string, numeric)\n\n**Response codes:**\n- `200` — `status: \"executed\"` — withdrawal completed\n- `202` — `status: \"pending_approval\"` (human approval required by policy)\n- `403` — `status: \"denied\"` (rejected by policy)\n\n### 6. Fund the Wallet\n\nDeposit USDC to the EOA address via:\n\n- **HyperLiquid bridge** from Arbitrum: visit `https://app.hyperliquid.xyz/portfolio` and bridge USDC to the EOA address\n- **HL→HL transfer** (`usdSend`) from another HL account — instant\n\nMinimum for a BTC perp trade: **$2 USDC** (covers $10 notional at 20x default leverage + taker fees).\n\n### 7. Browse Markets\n\n```bash\nnpx @vincentai/cli@latest hyperliquid markets --key-id <KEY_ID>\n```\n\nReturns a JSON object mapping coin names to mid prices (e.g. `{\"BTC\": \"105234.5\", \"ETH\": \"3412.0\", ...}`).\n\n### 8. Get Order Book\n\n```bash\nnpx @vincentai/cli@latest hyperliquid orderbook --key-id <KEY_ID> --coin BTC\n```\n\nReturns `levels` — a two-element array `[bids, asks]`. Each entry is `[price, size, numOrders]`. Use `levels[1][0][0]` for best ask, `levels[0][0][0]` for best bid.\n\n### 9. Place a Trade\n\n```bash\n# Market buy (IoC — fills immediately or cancels)\nnpx @vincentai/cli@latest hyperliquid trade --key-id <KEY_ID> \\\n  --coin BTC --is-buy true --sz 0.0001 \\\n  --limit-px 106000 --order-type market\n\n# Market sell to close (reduceOnly)\nnpx @vincentai/cli@latest hyperliquid trade --key-id <KEY_ID> \\\n  --coin BTC --is-buy false --sz 0.0001 \\\n  --limit-px 104000 --order-type market --reduce-only\n\n# GTC limit buy\nnpx @vincentai/cli@latest hyperliquid trade --key-id <KEY_ID> \\\n  --coin BTC --is-buy true --sz 0.0001 \\\n  --limit-px 100000 --order-type limit\n```\n\nParameters:\n\n- `--coin`: Asset name (e.g. `BTC`, `ETH`, `SOL`)\n- `--is-buy`: `true` for long, `false` for short/close\n- `--sz`: Size in base currency (e.g. `0.0001` BTC)\n- `--limit-px`: Price. For market orders, set slightly above ask (buy) or below bid (sell) to ensure fill. Recommended: `askPx * 1.005` for buys, `bidPx * 0.995` for sells.\n- `--order-type`: `market` (IoC) or `limit` (GTC)\n- `--reduce-only`: Pass when closing a position to prevent accidentally opening a new one in the opposite direction\n\n**Minimum notional:** $10 (e.g. 0.0001 BTC at $100k/BTC). Default leverage is 20x cross-margin.\n\n**Response codes:**\n- `200` — `status: \"executed\"` with `orderId` (numeric) and `fillDetails`\n- `202` — `status: \"pending_approval\"` (human approval required by policy)\n- `403` — `status: \"denied\"` (rejected by policy)\n\n### 10. View Open Orders\n\n```bash\n# All open orders\nnpx @vincentai/cli@latest hyperliquid open-orders --key-id <KEY_ID>\n\n# Filter by coin\nnpx @vincentai/cli@latest hyperliquid open-orders --key-id <KEY_ID> --coin BTC\n```\n\n### 11. View Trade History\n\n```bash\n# All fills\nnpx @vincentai/cli@latest hyperliquid trades --key-id <KEY_ID>\n\n# Filter by coin\nnpx @vincentai/cli@latest hyperliquid trades --key-id <KEY_ID> --coin ETH\n```\n\n### 12. Cancel Orders\n\n```bash\n# Cancel a specific order (requires coin and numeric order ID)\nnpx @vincentai/cli@latest hyperliquid cancel-order --key-id <KEY_ID> --coin BTC --oid <ORDER_ID>\n\n# Cancel all open orders\nnpx @vincentai/cli@latest hyperliquid cancel-all --key-id <KEY_ID>\n\n# Cancel all orders for a specific coin\nnpx @vincentai/cli@latest hyperliquid cancel-all --key-id <KEY_ID> --coin ETH\n```\n\n## Trading Engine: Stop-Loss, Take-Profit & Trailing Stop\n\nThe **Trading Engine** fully supports HyperLiquid. You can set automated stop-loss, take-profit, and trailing stop rules on any HL position. Rules execute automatically when price conditions are met — no LLM involved.\n\nFor HyperLiquid rules, use `--venue hyperliquid` and set `--market-id` / `--token-id` to the coin name (e.g. `BTC`, `ETH`, `SOL`). The `--trigger-price` is an absolute USD price (not 0–1 like Polymarket).\n\n### Stop-Loss\n\n```bash\nnpx @vincentai/cli@latest trading-engine create-rule --key-id <KEY_ID> \\\n  --venue hyperliquid --market-id BTC --token-id BTC \\\n  --rule-type STOP_LOSS --trigger-price 95000\n```\n\nSells the position if BTC drops to $95,000.\n\n### Take-Profit\n\n```bash\nnpx @vincentai/cli@latest trading-engine create-rule --key-id <KEY_ID> \\\n  --venue hyperliquid --market-id ETH --token-id ETH \\\n  --rule-type TAKE_PROFIT --trigger-price 4500\n```\n\nSells the position if ETH rises to $4,500.\n\n### Trailing Stop\n\n```bash\nnpx @vincentai/cli@latest trading-engine create-rule --key-id <KEY_ID> \\\n  --venue hyperliquid --market-id SOL --token-id SOL \\\n  --rule-type TRAILING_STOP --trigger-price 170 --trailing-percent 5\n```\n\nStop price ratchets up as SOL rises. Sells if SOL drops 5% from its peak.\n\n### Manage Rules\n\n```bash\n# List all rules\nnpx @vincentai/cli@latest trading-engine list-rules --key-id <KEY_ID>\n\n# Update trigger price\nnpx @vincentai/cli@latest trading-engine update-rule --key-id <KEY_ID> --rule-id <RULE_ID> --trigger-price 98000\n\n# Cancel a rule\nnpx @vincentai/cli@latest trading-engine delete-rule --key-id <KEY_ID> --rule-id <RULE_ID>\n\n# View rule events\nnpx @vincentai/cli@latest trading-engine events --key-id <KEY_ID>\n```\n\nFor full strategy docs (LLM-powered strategies, signal pipeline, drivers), see the **Trading Engine** skill.\n\n## Policies (Server-Side Enforcement)\n\nThe wallet owner controls what the agent can do by setting policies at `https://heyvincent.ai`. All policies are enforced server-side before any trade executes.\n\n| Policy                      | What it does                                                     |\n| --------------------------- | ---------------------------------------------------------------- |\n| **Spending limit (per tx)** | Max USD notional per trade                                       |\n| **Spending limit (daily)**  | Max USD notional per rolling 24 hours                            |\n| **Spending limit (weekly)** | Max USD notional per rolling 7 days                              |\n| **Require approval**        | Every trade needs human approval via Telegram                    |\n| **Approval threshold**      | Trades above a USD amount need human approval via Telegram       |\n\nIf a trade is blocked, the API returns `status: \"denied\"` with the reason. If approval is needed, `status: \"pending_approval\"` is returned and the wallet owner receives a Telegram notification.\n\n## Re-linking\n\nIf the agent loses its API key:\n\n1. User generates a re-link token from `https://heyvincent.ai`\n2. User gives the token to the agent\n3. Agent runs:\n\n```bash\nnpx @vincentai/cli@latest secret relink --token <TOKEN_FROM_USER>\n```\n\nRe-link tokens are one-time use and expire after 10 minutes.\n\n## Workflow Example\n\n```bash\n# 1. Create wallet\nnpx @vincentai/cli@latest secret create --type HYPERLIQUID_WALLET --memo \"HL wallet\"\n# → returns keyId, walletAddress, claimUrl\n\n# 2. Tell user: \"Fund <walletAddress> on HyperLiquid with USDC, then I can trade.\"\n\n# 3. Check balance after funding (returns both perps and spot balances)\nnpx @vincentai/cli@latest hyperliquid balance --key-id <KEY_ID>\n# → accountValue shows perps balance, spotBalances shows spot holdings\n\n# 4. Transfer USDC between sub-accounts if needed\n# Move 100 USDC from spot → perps before perp trading:\nnpx @vincentai/cli@latest hyperliquid internal-transfer --key-id <KEY_ID> --amount 100 --to-perp true\n# Move 50 USDC from perps → spot before spot trading:\nnpx @vincentai/cli@latest hyperliquid internal-transfer --key-id <KEY_ID> --amount 50 --to-perp false\n\n# 5. Withdraw USDC to another HL address\nnpx @vincentai/cli@latest hyperliquid withdraw --key-id <KEY_ID> \\\n  --destination 0xRecipientAddress --amount 50\n\n# 6. Get BTC mid price\nnpx @vincentai/cli@latest hyperliquid markets --key-id <KEY_ID>\n\n# 7. Get order book to find best ask\nnpx @vincentai/cli@latest hyperliquid orderbook --key-id <KEY_ID> --coin BTC\n# → levels[1][0][0] is best ask, e.g. \"105200.0\"\n\n# 8. Open long — 0.5% above ask to ensure IoC fill\nnpx @vincentai/cli@latest hyperliquid trade --key-id <KEY_ID> \\\n  --coin BTC --is-buy true --sz 0.0001 --limit-px 105726 --order-type market\n\n# 9. Check fills\nnpx @vincentai/cli@latest hyperliquid trades --key-id <KEY_ID> --coin BTC\n\n# 10. Close long — 0.5% below bid\nnpx @vincentai/cli@latest hyperliquid orderbook --key-id <KEY_ID> --coin BTC\nnpx @vincentai/cli@latest hyperliquid trade --key-id <KEY_ID> \\\n  --coin BTC --is-buy false --sz 0.0001 --limit-px 104674 --order-type market --reduce-only\n```\n\n## Output Format\n\nAll CLI commands return JSON to stdout.\n\n**balance:**\n```json\n{\n  \"walletAddress\": \"0x...\",\n  \"accountValue\": \"105.23\",\n  \"withdrawable\": \"95.00\",\n  \"positions\": [\n    {\n      \"position\": {\n        \"coin\": \"BTC\",\n        \"szi\": \"0.0001\",\n        \"entryPx\": \"105200.0\",\n        \"positionValue\": \"10.52\",\n        \"unrealizedPnl\": \"0.05\",\n        \"liquidationPx\": null,\n        \"leverage\": { \"type\": \"cross\", \"value\": 20 }\n      },\n      \"type\": \"oneWay\"\n    }\n  ],\n  \"spotBalances\": [\n    {\n      \"coin\": \"USDC\",\n      \"token\": 0,\n      \"hold\": \"0.0\",\n      \"total\": \"50.0\"\n    }\n  ]\n}\n```\n\n**markets:**\n```json\n{\n  \"BTC\": \"105234.5\",\n  \"ETH\": \"3412.0\",\n  \"SOL\": \"185.3\"\n}\n```\n\n**orderbook:**\n```json\n{\n  \"coin\": \"BTC\",\n  \"levels\": [\n    [[\"105200.0\", \"0.5\", 3], [\"105100.0\", \"1.2\", 5]],\n    [[\"105300.0\", \"0.3\", 2], [\"105400.0\", \"0.8\", 4]]\n  ]\n}\n```\n`levels[0]` = bids (descending), `levels[1]` = asks (ascending). Each entry is `[price, size, numOrders]`. Best bid: `levels[0][0][0]`, best ask: `levels[1][0][0]`.\n\n**trade (executed):**\n```json\n{\n  \"orderId\": 12345678,\n  \"status\": \"executed\",\n  \"transactionLogId\": \"clx...\",\n  \"walletAddress\": \"0x...\",\n  \"fillDetails\": {\n    \"totalSz\": \"0.0001\",\n    \"avgPx\": \"105250.0\"\n  }\n}\n```\n\n**trade (pending approval):**\n```json\n{\n  \"status\": \"pending_approval\",\n  \"transactionLogId\": \"clx...\",\n  \"walletAddress\": \"0x...\",\n  \"reason\": \"Exceeds approval threshold\"\n}\n```\n\n**trade (denied):**\n```json\n{\n  \"status\": \"denied\",\n  \"transactionLogId\": \"clx...\",\n  \"walletAddress\": \"0x...\",\n  \"reason\": \"Exceeds daily spending limit\"\n}\n```\n\n**withdraw (executed):**\n```json\n{\n  \"status\": \"executed\",\n  \"transactionLogId\": \"clx...\"\n}\n```\n\n**withdraw (pending approval):**\n```json\n{\n  \"status\": \"pending_approval\",\n  \"transactionLogId\": \"clx...\",\n  \"reason\": \"Exceeds approval threshold\"\n}\n```\n\n**withdraw (denied):**\n```json\n{\n  \"status\": \"denied\",\n  \"transactionLogId\": \"clx...\",\n  \"reason\": \"Exceeds daily spending limit\"\n}\n```\n\n**internal-transfer (executed):**\n```json\n{\n  \"status\": \"executed\",\n  \"transactionLogId\": \"clx...\"\n}\n```\n\n**internal-transfer (pending approval):**\n```json\n{\n  \"status\": \"pending_approval\",\n  \"transactionLogId\": \"clx...\",\n  \"reason\": \"Exceeds approval threshold\"\n}\n```\n\n**internal-transfer (denied):**\n```json\n{\n  \"status\": \"denied\",\n  \"transactionLogId\": \"clx...\",\n  \"reason\": \"Exceeds daily spending limit\"\n}\n```\n\n**open-orders:**\n```json\n{\n  \"walletAddress\": \"0x...\",\n  \"openOrders\": [\n    {\n      \"coin\": \"BTC\",\n      \"side\": \"B\",\n      \"limitPx\": \"100000.0\",\n      \"sz\": \"0.0001\",\n      \"oid\": 12345678,\n      \"timestamp\": 1700000000000,\n      \"origSz\": \"0.0001\"\n    }\n  ]\n}\n```\n`side`: `\"B\"` = buy/long, `\"A\"` = ask/sell.\n\n**trades (fills):**\n```json\n{\n  \"walletAddress\": \"0x...\",\n  \"fills\": [\n    {\n      \"coin\": \"BTC\",\n      \"px\": \"105200.0\",\n      \"sz\": \"0.0001\",\n      \"side\": \"B\",\n      \"time\": 1700000000000,\n      \"dir\": \"Open Long\",\n      \"closedPnl\": \"0\",\n      \"fee\": \"0.0105\",\n      \"oid\": 12345678\n    }\n  ]\n}\n```\n\n**cancel-order / cancel-all:**\n```json\n{}\n```\nEmpty object on success. Any non-zero exit code indicates failure.\n\n## Error Handling\n\n| Error | Cause | Resolution |\n|-------|-------|------------|\n| `401 Unauthorized` | Invalid or missing API key | Check key-id is correct; re-link if needed |\n| `status: \"denied\"` | Trade blocked by server-side policy | User must adjust policies at heyvincent.ai |\n| `status: \"pending_approval\"` | Trade exceeds approval threshold | Do not retry — wallet owner receives Telegram notification to approve/deny |\n| `400 Bad Request` | Invalid parameters (e.g. non-numeric oid, bad coin) | Fix the parameter values |\n| `429 Rate Limited` | Too many requests | Wait and retry with backoff |\n| `500 TRADE_FAILED` | HyperLiquid rejected the order (e.g. insufficient margin, bad price) | Check account balance and order parameters |\n| `Key not found` | API key was revoked or never created | Re-link with a new token from the wallet owner |\n\n## Important Notes\n\n- **No gas required.** HyperLiquid L1 is gasless — all perp trades settle natively.\n- **Perps and spot sub-accounts.** The generated EOA has both a perps sub-account (cross-margin) and a spot sub-account. Use `internal-transfer` to move USDC between them. Deposits via the HL bridge land in the perps account by default.\n- **Never try to access raw secret values.** The private key stays server-side.\n- Always share the claim URL with the user after creating a wallet.\n- For market orders, always set `limitPx` slightly outside the best price (`* 1.005` for buys, `* 0.995` for sells) to guarantee IoC fill at the current market price.\n- If a trade returns `status: \"pending_approval\"`, do not retry — wait for the wallet owner to respond via Telegram.\n","topics":["Wallet"],"tags":{"latest":"1.0.70"},"stats":{"comments":0,"downloads":797,"installsAllTime":30,"installsCurrent":0,"stars":0,"versions":3},"createdAt":1773086420669,"updatedAt":1779077868700},"latestVersion":{"version":"1.0.70","createdAt":1773276273684,"changelog":"- Added instructions for withdrawing USDC to another HyperLiquid address using the `withdraw` command.\n- Included parameters and response codes for the new withdrawal functionality.\n- Updated quick start workflow: \"Withdraw USDC\" is a separate step before \"Fund the Wallet\".\n- No other functional changes; help documentation expanded for more complete coverage.","license":"MIT-0"},"metadata":{"setup":[{"key":"${OPENCLAW_STATE_DIR:-$HOME/.openclaw}/credentials/agentwallet","required":true},{"key":"./agentwallet","required":true}],"os":null,"systems":null},"owner":{"handle":"glitch003","userId":"s173aadqv5xdar8hm4yg2jb52d83fv08","displayName":"Chris Cassano","image":"https://avatars.githubusercontent.com/u/1285652?v=4"},"moderation":null}