• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

nktkas / hyperliquid / 21190802342

20 Jan 2026 10:10PM UTC coverage: 95.464% (+0.01%) from 95.453%
21190802342

push

github

web-flow
feat(info/userNonFundingLedgerUpdates): add new update types for UserNonFundingLedgerUpdatesResponse (#112)

655 of 874 branches covered (74.94%)

Branch coverage included in aggregate %.

42 of 42 new or added lines in 1 file covered. (100.0%)

32 existing lines in 5 files now uncovered.

13276 of 13719 relevant lines covered (96.77%)

1187.37 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

79.22
/bin/cli.ts
1
#!/usr/bin/env node
2
// deno-lint-ignore-file no-console
3

4
/**
5
 * Command-line interface for interacting with Hyperliquid API.
6
 *
7
 * @example
8
 * ```sh
9
 * npx @nktkas/hyperliquid <endpoint> <method> [options]
10
 * ```
11
 *
12
 * @example Info Endpoint
13
 * ```sh
14
 * npx @nktkas/hyperliquid info clearinghouseState --user 0x...
15
 * ```
16
 *
17
 * @example Exchange Endpoint
18
 * ```sh
19
 * npx @nktkas/hyperliquid exchange withdraw3 --private-key 0x... --destination 0x... --amount 100.5
20
 * ```
21
 */
22

23
// @ts-ignore: Ignore missing TS types when building npm
24
import process from "node:process";
233✔
25
import { type Args, extractArgs, transformArgs } from "./_utils.ts";
233✔
26
import { ExchangeClient, HttpTransport, InfoClient } from "../src/mod.ts";
233✔
27
import { PrivateKeySigner } from "../src/signing/mod.ts";
233✔
28

29
// ============================================================
30
// Execute
31
// ============================================================
32

33
function transformParams(method: string, params: Args<false>): Record<string, unknown> {
350✔
34
  switch (method) {
350✔
35
    case "spotUser": {
701✔
36
      return { toggleSpotDusting: { ...params } };
1,755✔
37
    }
351✔
38
    case "twapOrder": {
701✔
39
      return { twap: { ...params } };
1,755✔
40
    }
351✔
41
    default: {
815✔
42
      return params;
465✔
43
    }
465✔
44
  }
350✔
45
}
350✔
46

47
class EchoTransport extends HttpTransport {
233✔
48
  constructor(isTestnet: boolean) {
233✔
49
    super({ isTestnet });
1,050✔
50
  }
350✔
51
  override request<T>(_: string, payload: unknown): Promise<T> {
233✔
52
    return new Promise((resolve) => resolve({ status: "ok", response: payload } as T));
1,634✔
53
  }
350✔
54
}
233✔
55

56
/** Execute CLI command on info/exchange endpoint */
57
async function executeEndpointMethod(endpoint: string, method: string, args: Args<false>): Promise<unknown> {
233✔
58
  // Parse CLI flags
59
  const isTestnet = "testnet" in args;
350✔
60
  const timeout = Number(args.timeout) || undefined;
350✔
61
  const isOffline = "offline" in args;
350✔
62

63
  // Create transport (echo for offline, http for online)
64
  const transport = isOffline ? new EchoTransport(isTestnet) : new HttpTransport({ isTestnet, timeout });
×
65
  let client: InfoClient | ExchangeClient;
350✔
66

67
  // Create client based on endpoint
68
  switch (endpoint) {
350✔
69
    case "info":
350✔
70
      client = new InfoClient({ transport });
1,263✔
71
      break;
421✔
72
    case "exchange": {
746✔
73
      const wallet = new PrivateKeySigner(args["private-key"] as `0x${string}`);
396✔
74
      delete args["private-key"]; // remove before uncontrolled transfer of arguments (just in case)
396✔
75

76
      const defaultVaultAddress = args.vault as `0x${string}` | undefined;
396✔
77

78
      client = new ExchangeClient({ transport, wallet, defaultVaultAddress });
1,980✔
79
      break;
396✔
80
    }
396✔
81
    default:
×
82
      throw new Error(`Invalid endpoint "${endpoint}". Use "info" or "exchange"`);
×
83
  }
350✔
84

85
  // Check if method exists on client
86
  if (!(method in client)) throw new Error(`Unknown "${method}" method for "${endpoint}" endpoint`);
×
87

88
  // Execute method and return result
89
  const params = transformParams(method, args);
350✔
90
  // @ts-expect-error: dynamic method access
91
  const response = await client[method](params);
350✔
92
  return isOffline ? response.response : response; // for offline mode, we want to see the request payload, not the wrapper
×
93
}
350✔
94

95
// ============================================================
96
// CLI
97
// ============================================================
98

99
function printHelp(): void {
×
100
  console.log(`Hyperliquid CLI
×
101

102
Usage:
103
  npx @nktkas/hyperliquid <endpoint> <method> [options]
104

105
Endpoints:
106
  info      - Query blockchain and market information
107
  exchange  - Execute trading operations (requires --private-key)
108

109
Common Options:
110
  --testnet               Use testnet instead of mainnet
111
  --timeout <number>      Request timeout in milliseconds (default: 10000)
112
  --help, -h              Show this help message
113
  --offline               Generate transactions offline without broadcasting
114

115
Exchange Options:
116
  --private-key <key>     Private key for exchange operations (required)
117
  --vault <address>       Vault address for operations
118

119
=============================================================================
120
INFO ENDPOINT METHODS
121
=============================================================================
122

123
Market Data:
124
  alignedQuoteTokenInfo   --token <number>
125
  allMids                 [--dex <string>]
126
  allPerpMetas            (no params)
127
  candleSnapshot          --coin <string> --interval <1m|3m|5m|15m|30m|1h|2h|4h|8h|12h|1d|3d|1w|1M>
128
                          --startTime <number> [--endTime <number>]
129
  fundingHistory          --coin <string> --startTime <number> [--endTime <number>]
130
  l2Book                  --coin <string> [--nSigFigs <2|3|4|5>] [--mantissa <2|5>]
131
  liquidatable            (no params)
132
  marginTable             --id <number>
133
  maxMarketOrderNtls      (no params)
134
  meta                    [--dex <string>]
135
  metaAndAssetCtxs        [--dex <string>]
136
  perpsAtOpenInterestCap  [--dex <string>]
137
  predictedFundings       (no params)
138
  recentTrades            --coin <string>
139
  spotMeta                (no params)
140
  spotMetaAndAssetCtxs    (no params)
141

142
User Account:
143
  activeAssetData         --user <address> --coin <string>
144
  clearinghouseState      --user <address> [--dex <string>]
145
  extraAgents             --user <address>
146
  isVip                   --user <address>
147
  legalCheck              --user <address>
148
  maxBuilderFee           --user <address> --builder <address>
149
  portfolio               --user <address>
150
  preTransferCheck        --user <address> --source <address>
151
  referral                --user <address>
152
  spotClearinghouseState  --user <address> [--dex <string>]
153
  subAccounts             --user <address>
154
  subAccounts2            --user <address>
155
  userDexAbstraction      --user <address>
156
  userFees                --user <address>
157
  userFunding             --user <address> --startTime <number> [--endTime <number>]
158
  userNonFundingLedgerUpdates  --user <address> --startTime <number> [--endTime <number>]
159
  userRateLimit           --user <address>
160
  userRole                --user <address>
161
  userToMultiSigSigners   --user <address>
162
  webData2                --user <address>
163

164
Orders & TWAP & Position:
165
  frontendOpenOrders      --user <address> [--dex <string>]
166
  historicalOrders        --user <address>
167
  openOrders              --user <address> [--dex <string>]
168
  orderStatus             --user <address> --oid <number|hex>
169
  twapHistory             --user <address>
170
  userFills               --user <address> [--aggregateByTime <bool>]
171
  userFillsByTime         --user <address> --startTime <number>
172
                          [--endTime <number>] [--aggregateByTime <bool>]
173
  userTwapSliceFills           --user <address>
174
  userTwapSliceFillsByTime     --user <address> --startTime <number>
175
                               [--endTime <number>] [--aggregateByTime <bool>]
176

177
Delegation & Validators:
178
  delegations             --user <address>
179
  delegatorHistory        --user <address>
180
  delegatorRewards        --user <address>
181
  delegatorSummary        --user <address>
182
  gossipRootIps           (no params)
183
  validatorL1Votes        (no params)
184
  validatorSummaries      (no params)
185

186
Vault:
187
  leadingVaults           --user <address>
188
  userVaultEquities       --user <address>
189
  vaultDetails            --vaultAddress <address> [--user <address>]
190
  vaultSummaries          (no params)
191

192
DEX:
193
  perpDexLimits           --dex <string>
194
  perpDexs                (no params)
195
  perpDexStatus           --dex <string>
196

197
Deploy Market:
198
  perpDeployAuctionStatus      (no params)
199
  spotDeployState              --user <address>
200
  spotPairDeployAuctionStatus  (no params)
201

202
Earn:
203
  allBorrowLendReserveStates   (no params)
204
  borrowLendReserveState       --token <number>
205
  borrowLendUserState          --user <address>
206
  userBorrowLendInterest       --user <address> --startTime <number> [--endTime <number>]
207

208
Other:
209
  exchangeStatus          (no params)
210

211
Transaction & Block Details:
212
  blockDetails            --height <number>
213
  tokenDetails            --tokenId <hex>
214
  txDetails               --hash <hex>
215
  userDetails             --user <address>
216

217
=============================================================================
218
EXCHANGE ENDPOINT METHODS
219
=============================================================================
220

221
Order & TWAP & Position:
222
  batchModify             --modifies <json>
223
  cancel                  --cancels <json>
224
  cancelByCloid           --cancels <json>
225
  modify                  --oid <number|hex> --order <json>
226
  order                   --orders <json> [--grouping <na|normalTpsl|positionTpsl>] [--builder <json>]
227
  scheduleCancel          [--time <number>]
228
  twapCancel              --a <number> --t <number>
229
  twapOrder               --a <number> --b <bool> --s <number> --r <bool> --m <number> --t <bool>
230
  updateIsolatedMargin    --asset <number> --isBuy <bool> --ntli <number>
231
  updateLeverage          --asset <number> --isCross <bool> --leverage <number>
232

233
Account:
234
  agentEnableDexAbstraction  (no params)
235
  approveAgent            --agentAddress <address> [--agentName <string>]
236
  approveBuilderFee       --maxFeeRate <number> --builder <address>
237
  evmUserModify           --usingBigBlocks <bool>
238
  noop                    (no params)
239
  reserveRequestWeight    --weight <number>
240
  setDisplayName          --displayName <string>
241
  spotUser                --optOut <bool>
242
  userDexAbstraction      --user <address> --enabled <bool>
243
  userPortfolioMargin     --user <address> --enabled <bool>
244

245
Fund Transfers:
246
  sendAsset               --destination <address> --token <name:address> --amount <number>
247
                          --sourceDex <string> --destinationDex <string> [--fromSubAccount <address>]
248
  spotSend                --destination <address> --token <name:address> --amount <number>
249
  usdClassTransfer        --amount <number> --toPerp <bool>
250
  usdSend                 --destination <address> --amount <number>
251
  withdraw3               --destination <address> --amount <number>
252

253
Sub-Account:
254
  createSubAccount        --name <string>
255
  subAccountModify        --subAccountUser <address> --name <string>
256
  subAccountSpotTransfer  --subAccountUser <address> --isDeposit <bool>
257
                          --token <name:address> --amount <number>
258
  subAccountTransfer      --subAccountUser <address> --isDeposit <bool> --usd <number>
259

260
Referrer:
261
  claimRewards            (no params)
262
  registerReferrer        --code <string>
263
  setReferrer             --code <string>
264

265
Staking & Delegation:
266
  cDeposit                --wei <number>
267
  cWithdraw               --wei <number>
268
  linkStakingUser         --user <address> --isFinalize <bool>
269
  tokenDelegate           --validator <address> --wei <number> --isUndelegate <bool>
270

271
Vault:
272
  createVault             --name <string> --description <string> --initialUsd <number>
273
  vaultDistribute         --vaultAddress <address> --usd <number>
274
  vaultModify             --vaultAddress <address> [--allowDeposits <bool>]
275
                          [--alwaysCloseOnWithdraw <bool>]
276
  vaultTransfer           --vaultAddress <address> --isDeposit <bool> --usd <number>
277

278
Deploy Market:
279
  perpDeploy              --<action> <json>
280
  spotDeploy              --<action> <json>
281

282
Validator Actions:
283
  cSignerAction           --jailSelf null | --unjailSelf null
284
  cValidatorAction        --<action> <json>
285
  validatorL1Stream       --riskFreeRate <number>
286

287
Earn:
288
  borrowLend              --operation <supply|withdraw> --token <number> --amount <number|null>
289

290
Other:
291
  convertToMultiSigUser   --authorizedUsers <json> --threshold <number>
292

293
=============================================================================
294

295
Examples:
296
  # Get all mid prices
297
  npx @nktkas/hyperliquid info allMids
298

299
  # Get ETH order book with 3 significant figures
300
  npx @nktkas/hyperliquid info l2Book --coin ETH --nSigFigs 3
301

302
  # Get user's portfolio
303
  npx @nktkas/hyperliquid info portfolio --user 0x...
304

305
  # Get candle data for BTC
306
  npx @nktkas/hyperliquid info candleSnapshot --coin BTC --interval 1h --startTime 1700000000000
307

308
  # Place a limit order
309
  npx @nktkas/hyperliquid exchange order --private-key 0x... --orders '[{\"a\":0,\"b\":true,\"p\":30000,\"s\":0.1,\"r\":false,\"t\":{\"limit\":{\"tif\":\"Gtc\"}}}]'
310

311
  # Modify an existing order
312
  npx @nktkas/hyperliquid exchange modify --private-key 0x... --oid 12345 --order '{\"a\":0,\"b\":true,\"p\":31000,\"s\":0.1,\"r\":false,\"t\":{\"limit\":{\"tif\":\"Gtc\"}}}'
313

314
  # Cancel orders
315
  npx @nktkas/hyperliquid exchange cancel --private-key 0x... --cancels '[{\"a\":0,\"o\":12345}]'
316

317
  # Update leverage
318
  npx @nktkas/hyperliquid exchange updateLeverage --private-key 0x... --asset 0 --isCross true --leverage 5
319

320
  # Withdraw funds
321
  npx @nktkas/hyperliquid exchange withdraw3 --private-key 0x... --destination 0x... --amount 100.5
322

323
  # Send USD to another user
324
  npx @nktkas/hyperliquid exchange usdSend --private-key 0x... --destination 0x... --amount 50
325

326
  # Create a vault
UNCOV
327
  npx @nktkas/hyperliquid exchange createVault --private-key 0x... --name "My Vault" --description "Test vault" --initialUsd 1000`);
×
UNCOV
328
}
×
329

330
// ============================================================
331
// Entry
332
// ============================================================
333

334
const rawArgs = extractArgs(process.argv.slice(2), {
233✔
335
  flags: ["testnet", "help", "h", "offline"],
1,398✔
336
  collect: false,
233✔
337
});
233✔
338
const args = transformArgs(rawArgs, { number: "string" });
699✔
339
const [endpoint, method] = args._;
233✔
340
if (args.help || args.h || !endpoint || !method) {
233✔
341
  printHelp();
465✔
342
} else {
233✔
UNCOV
343
  executeEndpointMethod(endpoint, method, args)
×
UNCOV
344
    .then((result) => console.log(JSON.stringify(result)))
×
UNCOV
345
    .catch((error) => console.error(error));
×
346
}
233✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc