Files
Alex Yang 8072082fda feat: add hyperliquid-reader skill + opencli plugin (#76)
* feat: add hyperliquid-reader skill + opencli plugin

Add a read-only Hyperliquid (app.hyperliquid.xyz) reader, mirroring the
tradingview-reader pattern. Unlike TradingView's CDP attach, Hyperliquid
exposes a fully public info API (POST https://api.hyperliquid.xyz/info),
so this needs no API key, wallet, login, or desktop app.

opencli plugin (opencli-plugins/hyperliquid/) — 12 read-only commands:
- Market data: markets, spot-markets, mids, book, candles,
  funding-history, funding-compare (cross-venue HL/Binance/Bybit
  funding-arb screen).
- Account by 0x address: account, positions, spot-balances,
  open-orders, fills.

Skill (plugins/data-providers/skills/hyperliquid-reader/) — SKILL.md
(5-step + error reference), README.md, references/commands.md.

Registrations: root opencli-plugin.json, data-providers plugin.json
(description + keywords), marketplace.json, root README table.

Verification: 31 unit tests pass against captured live wire shapes;
all 12 command data paths smoke-tested end-to-end against the live API.
SKILL.md description is 1019 chars (< 1024 lint cap), no angle brackets.

No trade execution: the plugin exposes no write/exchange endpoints.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

* refactor: scope hyperliquid-reader to market data only

Drop the account-by-address commands (account, positions, spot-balances,
open-orders, fills) and their lib/account.js + lib/orders.js helpers and
tests. Remove the now-unused normalizeAddress helper from lib/api.js.

The reader is now market-data only: markets, spot-markets, mids, book,
candles, funding-history, funding-compare (7 commands). Updated SKILL.md,
both READMEs, references/commands.md, the plugin/marketplace manifests,
and the root README table accordingly.

21 unit tests pass; all 7 market-data data paths re-verified live.
2026-06-07 16:21:26 -07:00

39 lines
1.4 KiB
JavaScript

/**
* hyperliquid funding-history — historical hourly funding for a coin via
* `fundingHistory`. Returns prints from now back `--hours` hours.
*/
import { cli, Strategy } from '@jackwener/opencli/registry';
import { infoFetch } from './lib/api.js';
import { normalizeFundingHistory } from './lib/funding.js';
const HOUR_MS = 3_600_000;
cli({
site: 'hyperliquid',
name: 'funding-history',
description: 'Historical hourly funding rates (+ APR, premium) for a coin',
access: 'read',
strategy: Strategy.PUBLIC,
browser: false,
args: [
{ name: 'coin', required: true, help: 'Coin (e.g. BTC)' },
{ name: 'hours', type: 'int', default: 24, help: 'Lookback window in hours (default 24)' },
{ name: 'limit', type: 'int', help: 'Cap rows to the most recent N (omit for all in window)' },
],
columns: ['coin', 'fundingRatePct', 'fundingAprPct', 'premiumPct', 'time'],
func: async (args) => {
const coin = String(args.coin).toUpperCase().trim();
const hours = Math.max(1, Number(args.hours) || 24);
const startTime = Date.now() - hours * HOUR_MS;
const rows = await infoFetch({ type: 'fundingHistory', coin, startTime });
let out = normalizeFundingHistory(rows);
out.sort((a, b) => String(b.time).localeCompare(String(a.time))); // newest first
const limit = Number(args.limit);
if (Number.isFinite(limit) && limit > 0) out = out.slice(0, limit);
return out;
},
});