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

@usdh-kit/sdk

v0.2.0

Published

TypeScript SDK for USDH on Hyperliquid

Downloads

72

Readme

@usdh-kit/sdk

CI npm License: MIT

Current SDK version: 0.1.0

TypeScript SDK for USDH on Hyperliquid.

USDH is the native stablecoin on Hyperliquid, issued by Bridge and designed by Native Markets, with 50% of reserve revenue routed to the Hyperliquid Assistance Fund. @usdh-kit/sdk ships the retail-side plumbing (pair resolution, signing, transport) so apps and bots can convert into USDH without writing the Hyperliquid action layer themselves.

Contributors: Yaugourt · Sumfxn

Status

Pre-release. Public API is unstable until 1.0.0.

What works today:

  • getQuote() and swap() for USDC → USDH end to end (signing + msgpack + IOC limit submission)
  • bridgeToCore() for moving USDC from HyperEVM to HyperCore, with credit polling
  • getHypercoreBalance() for spendable HyperCore balances (total - hold)
  • getRoute() / preflightSwap() for HyperCore-vs-HyperEVM source selection
  • bridgeAndSwap() for route → optional bridge → swap orchestration
  • Read-only InfoClient (spotMeta, spotClearinghouseState, L2 book)

Deferred to follow-up PRs: USDT pricing/swap, reverse direction (USDH → USDC), multi-chain source.

Install

pnpm add @usdh-kit/sdk

Quickstart

import { BridgeTimeoutError, createUsdhKit, isBridgeAndSwapError } from '@usdh-kit/sdk'

const kit = createUsdhKit({ network: 'mainnet', signer, evmWallet, slippageBps: 30 })
const amount = 11_000_000n // 11 USDC; Hyperliquid spot orders must be >10 USDC

try {
  const result = await kit.bridgeAndSwap({
    from: 'USDC',
    amount,
    onProgress: (event) => console.log(event.phase),
  })

  console.log(`got ${result.swap.received} USDH for ${result.swap.spent} USDC`)
} catch (err) {
  if (isBridgeAndSwapError(err)) {
    console.error(`${err.phase} failed`, err.cause)
    if (err.cause instanceof BridgeTimeoutError) {
      console.log(`bridge tx ${err.cause.txHash} is still pending HyperCore credit`)
    }
  }
  throw err
}

swap() submits an IOC limit order priced slippageBps above the mid (max slippage is enforced pre-fill by Hyperliquid's matcher). The returned result.slippageBps is the realised slippage versus mid; tighten the tolerance and retry if it's higher than you expected.

Agent wallets

Browser wallets can reject Hyperliquid L1 order signatures because orders use Hyperliquid's Exchange typed-data domain (chainId: 1337), not the connected HyperEVM chain. The recommended production pattern is a Hyperliquid API/agent wallet:

  • the master wallet approves the agent once with approveAgent()
  • the agent signs L1 trading actions
  • reads, routing, balances, and bridge ownership still use the master account via accountAddress
import { approveAgent, createUsdhKit } from '@usdh-kit/sdk'

await approveAgent({
  network: 'mainnet',
  signer: masterWalletSigner,
  agentAddress: agentSigner.address,
  agentName: 'my-app-usdh',
  signatureChainId: 999, // match the connected HyperEVM chain for browser wallets
})

const kit = createUsdhKit({
  network: 'mainnet',
  signer: agentSigner,
  accountAddress: masterWalletSigner.address,
  evmWallet: masterEvmWallet,
  slippageBps: 30,
})

Backend and bot builders can provide an already-approved agent signer from a private key or key-management system. Frontend builders should keep any generated browser agent short-lived, scoped to the current account/network, and avoid logging private keys, raw signatures, or full typed-data payloads.

Quote a swap

getQuote() returns a mid-price snapshot with a 30-second validity window.

const quote = await kit.getQuote({ from: 'USDC', amount: 11_000_000n })
if (Date.now() < quote.validUntil) {
  console.log(`mid-price on ${quote.pair}: ${quote.midPrice}`)
  console.log(`would receive ~${quote.estimatedReceived} USDH`)
}

Route and preflight

getHypercoreBalance() returns total, held, and spendable HyperCore balance for a source stable. getRoute() decides whether the user can swap directly from HyperCore or needs to bridge from HyperEVM first. It checks spendable HyperCore source balance (total - hold), applies the configured slippage plus a small HC fee buffer, and returns a quote alongside the route decision.

const balance = await kit.getHypercoreBalance({ asset: 'USDC' })
console.log(`spendable HC USDC: ${balance.available}`)

const route = await kit.preflightSwap({ from: 'USDC', amount: 11_000_000n })

if (!route.canSwap) {
  console.log(route.blockReason)
}

if (route.requiresBridge) {
  console.log('will bridge from HyperEVM before swapping')
}

getRoute() does not inspect the user's HyperEVM ERC20 balance. If it selects the bridge route, canSwap only means the kit has an evmWallet configured; the wallet/RPC will still reject an underfunded bridge transaction.

Bridge and swap

bridgeAndSwap() composes the common retail flow:

  1. route/preflight
  2. bridge from HyperEVM when required
  3. swap on HyperCore

It returns both legs when a bridge happened and emits progress events that can directly drive UI state:

const result = await kit.bridgeAndSwap({
  from: 'USDC',
  amount: 11_000_000n,
  onProgress: (event) => {
    if (event.phase === 'bridging') showBridgeSpinner()
    if (event.phase === 'swapping') showSwapSpinner()
  },
})

console.log(result.route.sourceChain)
console.log(result.bridge?.txHash)
console.log(result.swap.orderId)

Unexpected route, bridge, or swap failures are wrapped in BridgeAndSwapError. Use isBridgeAndSwapError(err) to narrow the type, then inspect phase, route, optional bridge, and cause so apps can show accurate recovery copy without parsing strings. If cause is BridgeTimeoutError, the EVM transfer was sent and you can show cause.txHash while waiting/retrying for HyperCore credit. Preflight blockers still throw their specific errors (MissingEvmWalletError, InsufficientBalanceError).

Features (V1)

  • USDC → USDH quote and swap via the canonical HL spot pair
  • HyperEVM → HyperCore bridge with credit polling (bridgeToCore)
  • getRoute() / preflightSwap() route selection and preflight metadata
  • bridgeAndSwap() high-level orchestration with progress callbacks
  • Wallet-agnostic Signer interface (works with viem, ethers, Privy, Turnkey, raw private key)
  • Read-only InfoClient (spotMeta, spot clearinghouse state, L2 book)
  • Typed error hierarchy rooted at UsdhKitError, including BridgeAndSwapError phase/cause context and isBridgeAndSwapError() narrowing
  • npm provenance on every release
  • Mainnet and testnet support, no signing on read paths

Runtime support

  • Node.js >= 18.18 (native fetch, AbortController, bigint)
  • Bun >= 1.1
  • Modern evergreen browsers (Chrome >= 107, Safari >= 16, Firefox >= 104)
  • Edge runtimes (Cloudflare Workers, Vercel Edge)

License

MIT