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

@outcome.xyz/hip4

v1.0.0-beta

Published

TypeScript SDK for Hyperliquid HIP-4

Readme


TypeScript SDK for Hyperliquid HIP-4 prediction markets. Zero runtime dependencies.

Built for developers

The SDK is structured around a single adapter with typed sub-modules for each domain - events, market data, account state, trading, wallet, and auth. Everything returns typed responses, WebSocket subscriptions return unsubscribe functions, and all signing (L1 agent + EIP-712) is handled internally with no external crypto dependencies.

pnpm add @outcome.xyz/hip4
import { createHIP4Adapter } from "@outcome.xyz/hip4";

const hip4 = createHIP4Adapter({ testnet: true });
await hip4.initialize();

Examples

API

hip4.events

| Method | Description | | -------------------------------- | ------------------------------------------------------------------------ | | fetchEvents(params?) | List events. Filters: category, active, limit, offset, query | | fetchEvent(eventId) | Single event by ID | | fetchCategories() | Available categories | | fetchMarkets(params?) | Typed HIP-4 markets with optional grouping by type or question | | fetchSettledOutcome(outcomeId) | Settlement details for a resolved outcome. Returns null if not settled |

hip4.marketData

| Method | Description | | ------------------------------------------------- | --------------------------------------------- | | fetchOrderBook(marketId, sideIndex?) | L2 snapshot | | fetchPrice(marketId) | Both sides, 5s cache | | fetchTrades(marketId, limit?) | Recent trades | | fetchCandles(marketId, interval?, start?, end?) | OHLCV candles | | subscribeOrderBook(marketId, cb) | Real-time L2 book | | subscribePrice(marketId, cb) | Real-time prices | | subscribeTrades(marketId, cb) | Real-time trades | | subscribeAllMids(cb) | All mid-prices across every market | | subscribeActiveAssetCtx(coin, cb) | Per-spot-coin context (vol, OI, mark) | | subscribeSpotAssetCtxs(cb) | Bulk spot-asset context updates | | subscribePerpAssetCtx(coin, cb) | Per-perp-coin context (mark, oracle, funding) |

hip4.account

| Method | Description | | --------------------------------- | ------------------------------------------ | | fetchPositions(address) | Outcome positions with resolved side names | | fetchActivity(address) | Fills, last 30 days | | fetchBalance(address) | Spot balances | | fetchOpenOrders(address) | Resting orders | | subscribePositions(address, cb) | Polling at 10s |

hip4.trading

| Method | Description | | ----------------------- | --------------------------------------------------------------------------------------------------------------------------- | | placeOrder(params) | Place market or limit order. Returns { success, orderId?, error? } | | placeOrders(params[]) | Batch place orders in a single signed request | | modifyOrder(params) | Modify a resting order (price and/or size); preserves queue priority on size-only edits | | cancelOrder(params[]) | Cancel one or more resting orders. Returns HLCancelResponse | | scheduleCancel(time) | Dead-man's switch - registers a future timestamp at which HL cancels every open order from this agent. Pass null to clear | | splitOutcome(params) | Split X quote tokens into X Yes + X No shares of one outcome | | mergeOutcome(params) | Merge X paired Yes+No shares back into X quote tokens | | mergeQuestion(params) | Merge X Yes shares from every outcome of a question into X quote tokens | | negateOutcome(params) | Convert X No shares of one outcome into X Yes shares of every other outcome in the question |

hip4.wallet

| Method | Signing | Description | | ----------------------------------- | -------- | ------------------------------- | | setSigner(signer) | - | Set user wallet for EIP-712 ops | | buyUsdh(amount) | L1 agent | Buy USDH on spot | | sellUsdh(amount) | L1 agent | Sell USDH on spot | | transferToSpot(amount) | EIP-712 | Perp -> Spot | | transferToPerps(amount) | EIP-712 | Spot -> Perp | | withdraw({ destination, amount }) | EIP-712 | Withdraw to external address | | usdSend({ destination, amount }) | EIP-712 | Send to another HL address |

hip4.auth

| Method | Description | | --------------------------------- | --------------------------------------------------- | | initAuth(walletAddress, signer) | Accepts viem PrivateKeyAccount or ethers Signer | | getAuthStatus() | "disconnected" \| "pending_approval" \| "ready" | | clearAuth() | Reset auth state |

Market Types

fetchMarkets() classifies every HIP-4 outcome into one of four types:

| Type | Description | Parsed Fields | | ---------------- | ---------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | | defaultBinary | Recurring price markets (BTC > $67250 1d) | underlying, targetPrice, expiry, period | | labelledBinary | Standalone binary with custom sides (Hypurr vs Usain Bolt) | Custom side labels | | multiOutcome | Grouped under a question, with fallback | questionId, questionName, isFallback | | priceBucket | Recurring multi-bucket price markets (per-bucket Yes/No) | underlying, expiry, priceThresholds, period, bucketIndex, lowerBound, upperBound |

// Filter by type
const binaries = await hip4.events.fetchMarkets({ type: "defaultBinary" });

// Group by type
const grouped = await hip4.events.fetchMarkets({ groupBy: "type" });

// Group multi-outcome by question
const byQuestion = await hip4.events.fetchMarkets({ groupBy: "question" });

Configuration

const hip4 = createHIP4Adapter({
  testnet: true,
  // Builder fee - collected on every order placed by this adapter
  builderAddress: "0xYourBuilderAddress",
  builderFee: 100, // 0.1% (tenths of a basis point, 0–1000)
  logger: (level, msg, data) => console.log(level, msg, data),
});

Per-order builder address/fee can also be passed on placeOrder to override the adapter-level config.

Streams

Drop-in price feeds backed by HL's WebSocket. Each takes a callback and returns an unsubscribe function. The snapshot includes the rolling candle history plus the current mid.

import { createPriceFeed, createPerpPriceFeed } from "@outcome.xyz/hip4";

// HIP-4 outcome side (uses sideIndex 0 by default)
const unsub = createPriceFeed(
  hip4.marketData,
  "1758",
  (snapshot) => console.log(snapshot.currentMid, snapshot.candles),
  { interval: "1h" },
);
unsub();

| Helper | Use | | ---------------------------------------------------------- | ------------------------------------------------------------------ | | createPriceFeed(marketData, marketId, onSnapshot, opts?) | Live mid + tick-aggregated candle history for a HIP-4 outcome side | | createPerpPriceFeed(client, coin, onSnapshot, opts?) | Same shape for an HL perp coin | | processTick, candleBoundaryMs, intervalToMs | Lower-level candle utilities |

USDH on/off-ramp (mainnet)

Built-in fiat ↔ USDH ramp via Coinbase + Across. Buy: fiat → Coinbase onramp → USDC (Arbitrum) → Across counterfactual → USDH (HyperCore). Sell: USDH (HyperEVM) → Across swap → USDC (Arbitrum) → Coinbase offramp → fiat. See examples/usdh-ramp.ts for the full flow.

Orderbook utilities

import {
  computeTradeCost,
  computeEstimatedCost,
  computePotentialReturn,
} from "@outcome.xyz/hip4";

const cost = computeTradeCost({
  tokenAmount: 100,
  orderType: "limit",
  limitPriceCents: 55, // 0.55 in cents
});
// → { estimatedCost, potentialReturn, displayShares }

Signing

Both Hyperliquid signing flows are implemented from scratch.

L1 agent signing (orders, cancels, USDH spot):

  1. Sort action keys in canonical order
  2. MessagePack encode
  3. Append nonce as BE u64
  4. Append vault marker byte
  5. Keccak-256 hash -> connectionId
  6. EIP-712 sign with Agent type on chainId 1337

User-signed EIP-712 (transfers, withdrawals, sends):

  • Domain: HyperliquidSignTransaction, signatureChainId: 0x66eee
  • Message filtered to EIP-712 type keys only
  • Requires user wallet, agent keys rejected

Acknowledgements

Signing implementation inspired by @nktkas/hyperliquid.

License

BUSL-1.1

Builders

Dennis Furrer