npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

hotstuff-market-cli

v0.1.3

Published

Hotstuff market + trading CLI powered by the official TypeScript SDK.

Readme

Hotstuff CLI

Terminal Preview

Features

  • Prompted credential setup stored in credentials.json in the current working directory
  • Market data commands for price discovery and monitoring
  • Trade commands for place/cancel/order tracking
  • Mainnet/testnet switching via env vars
  • SDK-compatible transport and signing wrappers that mirror the latest request shapes

Install

npm install -g hotstuff-market-cli

Aliases available after install:

  • hotstuff
  • hotstuff-market
  • cli

Quick Start

# 1) Configure API credentials once
node ./cli.mjs auth setup

# 2) Confirm auth is ready
node ./cli.mjs auth status

# 3) Inspect market
node ./cli.mjs market price BTC

# 4) Place an order
node ./cli.mjs trade buy BTC 0.01 70000

# 5) Check account state
node ./cli.mjs trade orders --limit 20
node ./cli.mjs trade positions

If credentials are missing or the signer is not authorized, the CLI stops before placing the order and shows the next auth step to run. auth setup always asks for the main account address and agent private key, then overwrites credentials.json in the current working directory.

Commands

Auth

node ./cli.mjs auth setup
node ./cli.mjs auth setup --private-key 0x... --address 0x...
node ./cli.mjs auth status
node ./cli.mjs auth clear

Recommended order:

  1. Run node ./cli.mjs auth setup and enter the main account address plus agent key when prompted
  2. Run node ./cli.mjs auth status
  3. Trade only after the status output shows the expected account and signer

Market

node ./cli.mjs market list [--type all|perps|spot]
node ./cli.mjs market price <SYMBOL>
node ./cli.mjs market tickers [--market perp|spot|all] [--limit N]
node ./cli.mjs market candles <SYMBOL> [--period SECONDS] [--from UNIX] [--to UNIX] [--type mark|ltp|index]
node ./cli.mjs market orderbook <SYMBOL> [--depth N]
node ./cli.mjs market instruments [perps|spot|all]
node ./cli.mjs market ticker <SYMBOL>
node ./cli.mjs market oracle <ASSET>
node ./cli.mjs market supported-collateral <ASSET>
node ./cli.mjs market bbo <SYMBOL>
node ./cli.mjs market mids <SYMBOL>
node ./cli.mjs market trades <SYMBOL> [LIMIT]
node ./cli.mjs market chart <SYMBOL> <RES> <TYPE> <FROM_UNIX> <TO_UNIX>

Trade

node ./cli.mjs trade buy <SYMBOL> <SIZE> <PRICE> [--position LONG|SHORT|BOTH] [--tif GTC|IOC|FOK] [--reduce-only] [--post-only] [--cloid ID] [--expires EPOCH_MS]
node ./cli.mjs trade sell <SYMBOL> <SIZE> <PRICE> [--position LONG|SHORT|BOTH] [--tif GTC|IOC|FOK] [--reduce-only] [--post-only] [--cloid ID] [--expires EPOCH_MS]
node ./cli.mjs trade cancel <SYMBOL> (--oid ORDER_ID | --cloid CLIENT_ID) [--expires EPOCH_MS]
node ./cli.mjs trade cancel-instrument <SYMBOL> [--expires EPOCH_MS]
node ./cli.mjs trade cancel-all [--expires EPOCH_MS]
node ./cli.mjs trade orders [--limit N] [--page N]
node ./cli.mjs trade positions

For troubleshooting signer mismatches, add --debug or set HOTSTUFF_DEBUG=1 on trade commands.

CLI ↔ SDK Sync

The CLI uses SDK-compatible transport and signing wrappers:

  • createInfoClient() and createExplorerClient() are thin RPC proxies to the SDK info/explorer endpoints
  • createExchangeClient() signs exchange actions with the SDK's signAction, NonceManager, and EXCHANGE_OP_CODES utilities
  • createWebSocketTransport() and createHttpTransport() mirror the SDK transport behavior

Market command mapping:

| CLI command | SDK client method | Input payload | Output shape | | --- | --- | --- | --- | | market price <SYMBOL> | info.ticker, info.bbo, info.oracle | { symbol } | ticker array, bbo array, oracle object | | market supported-collateral <ASSET> | info.supportedCollateral | { symbol } | collateral array | | market mids <SYMBOL> | info.mids | { symbol } | mids array | | market candles <SYMBOL> ... | info.chart | { instrument_id, resolution, from, to, chart_type } | chart point array | | market chart <SYMBOL> ... | info.chart | { instrument_id, resolution, from, to, chart_type } | chart point array | | market orderbook <SYMBOL> | info.orderbook | { symbol, depth? } | orderbook object | | market trades <SYMBOL> | info.trades | { symbol, limit? } | trades array | | market ticker <SYMBOL> | info.ticker | { symbol } | ticker array | | market bbo <SYMBOL> | info.bbo | { symbol } | bbo array | | market oracle <ASSET> | info.oracle | { symbol } | oracle object |

Trade command mapping:

| CLI command | SDK client method | Input payload | Output shape | | --- | --- | --- | --- | | trade buy ... | exchange.placeOrder | { orders: [{ instrumentId, side, positionSide, price, size, tif, ro, po, cloid, triggerPx, isMarket, tpsl, grouping }], expiresAfter } | exchange response | | trade sell ... | exchange.placeOrder | same as buy, with side: "s" | exchange response | | trade cancel <SYMBOL> --oid | exchange.cancelByOid | { cancels: [{ oid, instrumentId }], expiresAfter } | exchange response | | trade cancel <SYMBOL> --cloid | exchange.cancelByCloid | { cancels: [{ cloid, instrumentId }], expiresAfter } | exchange response | | trade cancel-instrument <SYMBOL> | exchange.cancelByInstrument | { instrumentId, expiresAfter } | exchange response | | trade cancel-all | exchange.cancelAll | { expiresAfter } | exchange response | | trade orders | info.openOrders | { user, page?, limit? } | paginated open orders | | trade positions | info.positions | { user } | positions array |

Notes:

  • market candles and market chart resolve the symbol to an instrument_id before calling info.chart, matching the latest SDK signature.
  • market mids is now symbol-based because the latest SDK requires { symbol }.
  • The CLI keeps the helper aliases in src/sdk.mjs, but the requests and payload shapes now track the latest SDK signatures.

Network Selection

Use testnet with either variable:

export HOTSTUFF_TESTNET=1
# or
export DATA_ENV=testnet

If neither is set, mainnet is used.

Credential Storage

  • File: credentials.json in the current working directory
  • Saved and overwritten by node ./cli.mjs auth setup
  • Cleared with node ./cli.mjs auth clear
  • The account address can be the main trading account, while the private key can be an authorized agent signer.
  • auth setup asks for both values every time and overwrites the old file.
  • The CLI checks the signer against the account's authorized agents before sending a trade.
  • If the signer is missing or unauthorized, the command exits with a clear auth message instead of sending the order.
  • auth status prints both the account address and signer address so you can confirm they match the intended account context.

Security reminder:

  • Never share private keys
  • Use a dedicated API trading key where possible

Local Development

npm install
npm link
hotstuff help

Useful scripts:

npm run cli -- help
npm run pack:check

Project Structure

cli.mjs        # CLI entrypoint + top-level routing
src/sdk.mjs    # standard client layer: HTTP/WS + info/exchange/explorer/subscriptions
src/market.mjs # market command handlers
src/auth.mjs   # account + agent credential setup, status, clear, and credentials.json handling in the current working directory
src/trade.mjs  # buy/sell/cancel/order commands
src/ui.mjs     # help/cards/structured output rendering

SDK Methods

RPC methods (Info/Explorer/Exchange)

src/sdk.mjs uses a dynamic RPC proxy, so new SDK methods are callable directly without updating a local method list.

import { createInfoClient, createExplorerClient } from "./src/sdk.mjs";

const info = createInfoClient();
const explorer = createExplorerClient();

await info.someNewMethod({ ...params });
await explorer.someExplorerMethod({ ...params });

Subscription methods

Add a channel alias once in SUBSCRIPTION_METHODS:

export const SUBSCRIPTION_METHODS = {
  ...,
  myFeed: {
    channel: "my_feed",
    normalize: (params = {}) => ({ ...params }),
  },
};

Then use it directly:

const subscriptions = createSubscriptionClient();
await subscriptions.myFeed({ ...params }, (event) => {
  console.log(event.detail);
});