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

@liberfi.io/ui-perpetuals

v1.1.12

Published

Perpetuals for Liberfi React SDK

Downloads

5,902

Readme

@liberfi.io/ui-perpetuals

@liberfi.io/ui-perpetuals provides perpetual trading UI widgets, container hooks, and typed client contracts for the Liberfi React SDK. It is designed for host apps that want ready-to-use perpetual modules (order book, trades, place order, positions, orders, history) while still controlling networking, side effects, and provider wiring.

Design Philosophy

  • Keep data logic and presentation separated (*.script.tsx + *.ui.tsx + *.widget.tsx).
  • Keep client integration explicit via PerpetualsProvider and usePerpetualsClient.
  • Prefer typed hooks over ad-hoc data fetching to keep cache keys and API calls consistent.
  • Expose building blocks (UI + hooks + types) so consumers can compose custom flows.

Installation

pnpm add @liberfi.io/ui-perpetuals

Required peer dependencies:

  • react
  • react-dom
  • @tanstack/react-query
  • react-hook-form

API Reference

Components

  • CoinInfoWidget(props: CoinInfoWidgetProps)
  • CoinInfoUI(props: CoinInfoUIProps)
  • CoinInfoSkeletonsUI()
  • CoinInfoNotFoundUI()
  • SearchCoinsWidget(props: SearchCoinsWidgetProps)
  • SearchCoinsUI(props: SearchCoinsUIProps)
  • OrderBookWidget(props: OrderBookWidgetProps)
  • OrderBookUI(props: OrderBookUIProps)
  • TradesWidget(props: TradesWidgetProps)
  • TradesUI(props: TradesUIProps)
  • PlaceOrderFormWidget(props: PlaceOrderFormWidgetProps)
  • PlaceOrderFormUI(props: PlaceOrderFormUIProps) (uses react-hook-form UseFormReturn)
  • PositionsWidget(props: PositionsWidgetProps) — wires usePositionsScript to PositionsUI; owns sort state and the close-position mutation
  • PositionsUI(props: PositionsUIProps) — controlled, presentational positions table (div+flex layout, 9 columns, sortable headers, header tooltips, zebra striping, min-w-[1000px] + horizontal scroll). The Mark Price, Margin Used (PNL), and TP / SL columns are kept live by useAccountStateSubscription (webData2): each push re-marks every position against the venue's markPx, recomputes PnL, and re-derives the closing-side TP/SL trigger prices client-side, so the table updates at the same cadence as the order book — no extra subscription needed at the widget level.
  • PositionsSkeleton()
  • PositionsEmpty()
  • OpenOrdersWidget(props: OpenOrdersWidgetProps) — wires useOpenOrdersScript to OpenOrdersUI; owns sort state, the per-row cancel mutation, and a confirmation dialog for the destructive Cancel All action
  • OpenOrdersUI(props: OpenOrdersUIProps) — controlled, presentational open-orders table (div+flex layout, 12 columns mirroring Axiom 1:1, 9 sortable headers, Leverage header tooltip, zebra striping, min-w-[1100px] + horizontal scroll). The Current Price column reads each order's live mark price; TP / SL reads the parent limit order's children[] array (Hyperliquid's authoritative bundled-exit field), so the table updates at the same cadence as the order book — no extra subscription needed at the widget level.
  • OpenOrdersSkeleton()
  • OpenOrdersEmpty()
  • TradeHistoryWidget(props: TradeHistoryWidgetProps) — wires useTradeHistoryScript to TradeHistoryUI; thin pass-through (no destructive actions to gate). Defaults to all-coin display so the bottom-panel UX matches Positions / Open Orders.
  • TradeHistoryUI(props: TradeHistoryUIProps) — controlled, presentational user-fills table (div+flex layout, 7 columns mirroring Axiom 1:1 minus the Share column, all 7 headers sortable, virtualized via react-window since userFills can return thousands of records, zebra striping, min-w-[1100px] + horizontal scroll). The Description column passes through Hyperliquid's dir string ("Open Long" / "Close Short" / "Market liquidation triggered at <px>") and colours it by trade direction (buy=bullish, sell/liquidation=bearish). Closed PnL always renders the signed value (+$0.06 / -$0.06) so the dollar amount stays readable in copy-paste / high-contrast modes.
  • TradeHistorySkeleton()
  • TradeHistoryEmpty()
  • PerpetualsProvider(props: PerpetualsProviderProps)
  • DepositFormUI(props: DepositFormUIProps) — pure deposit form (amount + recipient)
  • DepositConfirmUI(props: DepositConfirmUIProps) — quote confirmation modal with expiry countdown
  • DepositStatusUI(props: DepositStatusUIProps) — terminal status modal (settled / refunded / failed)
  • DepositFlowWidget(props: DepositFlowWidgetProps) — orchestrates form + confirm + status with hooks
  • HyperliquidInitUI(props: HyperliquidInitUIProps) — first-run setup checklist (builder fee / referrer / leverage)
  • HyperliquidInitWidget(props: HyperliquidInitWidgetProps) — wires the checklist to useHyperliquidSetup

Hooks

  • Context hook:
    • usePerpetualsClient()
  • Query hooks:
    • useCoinsQuery, useMarketQuery, useMarketsQuery, useKlinesQuery
    • useOrderBookQuery, useRecentTradesQuery
    • usePositionsQuery, useOrdersQuery, useTradesQuery
  • Mutation hooks:
    • useCreateOrderMutation, useCancelOrderMutation
  • Subscription hooks:
    • useMarketDataSubscription, useCandlesSubscription, useUserDataSubscription
  • Component script hooks:
    • useCoinInfo, useSearchCoinsScript, useOrderBookScript, useTradesScript
    • usePlaceOrderFormScript, usePositionsScript, useOpenOrdersScript, useTradeHistoryScript
  • Deposit hooks (Solana → Hyperliquid USDC):
    • usePerpDepositClient — accessor for the deposit REST client from PerpetualsProvider
    • usePerpDepositQuote — TanStack Query wrapper around POST /v1/deposits/quote
    • usePerpDepositExecute — orchestrates quote → sign → broadcast → submit via the DepositState FSM
    • usePerpDepositStatus — long-poll GET /v1/deposits/{id} until terminal
  • Hyperliquid first-run setup:
    • useHyperliquidSetup — runs approveBuilderFee, setReferrer, and updateLeverage idempotently against an injected IHyperliquidSetupAdapter
  • Also exported helpers from hook modules:
    • Query keys and fetchers such as coinsQueryKey/fetchCoins, marketQueryKey/fetchMarket, ordersQueryKey/fetchOrders, etc.
    • Trade operation helpers: createOrder, cancelOrder.

Functions / Utilities

  • HyperliquidPerpetualsClient class implementing IPerpetualsClient.
  • usePerpetualsClient() as the context accessor utility.
  • LiberFiHttpTransport — shared HTTP layer (used by every LiberFi REST client; injectable for testing).
  • LiberFiPerpetualsClient — REST client over LiberFi-managed perpetuals (talks to perpetuals-server).
  • LiberFiPerpDepositClient — REST client over /v1/deposits/* (quote / submit / status / refresh).
  • Deposit state machine (pure functions) — reduceDepositState, initialDepositState, isDepositTerminal, isDepositPolling, currentDepositStatus, currentDepositBreakdown, isTerminalDepositLifecycle.
  • Hyperliquid setup state machine (pure functions) — reduceSetupState, initialSetupState, classifyStep, nextRunnableStep.

Types & Enums

  • Client-related:
    • IPerpetualsClient, HyperliquidClientConfig, HyperliquidEnvironment, HyperliquidApiError
    • PerpetualsContextValue, PerpetualsProviderProps
    • LiberFiHttpTransportConfig, LiberFiHttpMethod, LiberFiHttpRequestOptions, LiberFiApiError
    • LiberFiPerpetualsClientConfig, SignTypedDataFn
    • IPerpDepositClient, LiberFiPerpDepositClientConfig
  • Deposit (Solana → Hyperliquid):
    • DepositSource, DepositStatus, DepositErrorInfo, DepositStatusTransition, DepositBreakdown
    • DepositQuoteRequest, DepositQuoteResponse, DepositSubmitRequest, DepositSubmitResponse, DepositStatusResponse
    • DepositPhase, DepositState, DepositEvent
    • TERMINAL_DEPOSIT_STATUSES
  • Hyperliquid setup:
    • IHyperliquidSetupAdapter, HyperliquidAccountState, HyperliquidSetupActionResult
    • ApproveBuilderFeeParams, SetReferrerParams, UpdateLeverageParams
    • SetupStep, SetupStepId, StepRecord, StepStatus, SetupPhase, SetupState, SetupAction
    • UseHyperliquidSetupOptions, UseHyperliquidSetupResult
  • Domain enums/types:
    • Symbol, TradingProvider, OrderSide, OrderType, OrderStatus, KlineInterval, TradeSide
  • Domain entities:
    • Coin, MarketData, Kline, OrderBookLevel, OrderBook, Trade, Account
    • Position, Order, TradeHistory
  • Request/response contracts:
    • PlaceOrderParams, CancelOrderParams, GetPositionsParams, GetOpenOrdersParams, GetTradesParams
    • PlaceOrderResult, CancelOrderResult, GetPositionsResult, GetOpenOrdersResult, GetTradesResult
  • UI and script props/result types:
    • All *Props, Use*Params, Use*Result types re-exported by each component/hook index.
  • Positions table sort:
    • PositionSortKey — discriminated string union of the seven sortable columns (asset, position, value, entry, mark, liq, marginPnl)
    • SortDirection"asc" | "desc"
  • Trade History table sort:
    • TradeHistorySortKey — discriminated string union of the seven sortable columns (time, size, asset, description, price, tradeValue, closedPnl)
    • SortDirection"asc" | "desc"

Constants

  • version (package version string).

Usage Examples

import {
  HyperliquidPerpetualsClient,
  PerpetualsProvider,
  PlaceOrderFormWidget,
  OrderBookWidget,
  TradesWidget,
} from "@liberfi.io/ui-perpetuals";

const client = new HyperliquidPerpetualsClient({ environment: "testnet" });

export function PerpsPanel() {
  return (
    <PerpetualsProvider client={client}>
      <OrderBookWidget symbol="BTC-USDC" />
      <TradesWidget symbol="BTC-USDC" />
      <PlaceOrderFormWidget symbol="BTC-USDC" userAddress="0x..." />
    </PerpetualsProvider>
  );
}
import { useForm } from "react-hook-form";
import {
  PlaceOrderFormUI,
  type PlaceOrderFormData,
} from "@liberfi.io/ui-perpetuals";

const methods = useForm<PlaceOrderFormData>({
  defaultValues: {
    amount: 0,
    leverage: 1,
    takeProfitPercent: 0,
    stopLossPercent: 0,
  },
});

// Pass methods directly to PlaceOrderFormUI if you build your own container.

Deposit (Solana → Hyperliquid USDC)

The deposit flow is a single end-to-end widget plus three presentational components for callers that want a custom layout. The widget consumes the deposit client via PerpetualsProvider and delegates wallet signing to the host application.

import {
  DepositFlowWidget,
  HyperliquidPerpetualsClient,
  LiberFiHttpTransport,
  LiberFiPerpDepositClient,
  PerpetualsProvider,
} from "@liberfi.io/ui-perpetuals";

const transport = new LiberFiHttpTransport({
  baseUrl: process.env.NEXT_PUBLIC_PERPETUALS_API!,
});

const perpetualsClient = new HyperliquidPerpetualsClient({
  environment: "mainnet",
});
const depositClient = new LiberFiPerpDepositClient({ transport });

export function DepositPanel({ wallet }: { wallet: SolanaWalletAdapter }) {
  return (
    <PerpetualsProvider client={perpetualsClient} depositClient={depositClient}>
      <DepositFlowWidget
        userSolanaAddress={wallet.publicKey.toBase58()}
        userId={user.id}
        source="dex"
        defaultRecipient={user.evmAddress}
        signAndBroadcast={async (txBase64) => wallet.signAndSend(txBase64)}
        buildSolanaExplorerUrl={(h) => `https://solscan.io/tx/${h}`}
        buildHyperliquidExplorerUrl={(h) =>
          `https://app.hyperliquid.xyz/explorer/tx/${h}`
        }
        onSettled={(intentId) => console.log("settled", intentId)}
      />
    </PerpetualsProvider>
  );
}

For a fully custom layout, drive the lower-level UI components with usePerpDepositQuote, usePerpDepositExecute, and usePerpDepositStatus directly. The state-machine pure functions (reduceDepositState, etc.) are also exported for tooling and tests.

Hyperliquid first-run setup

HyperliquidInitWidget orchestrates the three idempotent setup actions Hyperliquid expects on a fresh account: approve a builder fee, set a referrer, and pin a default leverage. Wallet signing is delegated to a consumer-supplied adapter so this SDK does not pin a specific Hyperliquid client library.

import {
  HyperliquidInitWidget,
  type IHyperliquidSetupAdapter,
} from "@liberfi.io/ui-perpetuals";

const adapter: IHyperliquidSetupAdapter = buildPrivyAdapter(/* … */);

export function FirstRunSetup({ user }: { user: { evmAddress: string } }) {
  return (
    <HyperliquidInitWidget
      adapter={adapter}
      userAddress={user.evmAddress}
      steps={[
        {
          id: "approveBuilderFee",
          params: { builder: BUILDER_ADDRESS, maxFeeRate: 45 },
        },
        { id: "setReferrer", params: { code: "LIBERFI" } },
        {
          id: "updateLeverage",
          params: { asset: "BTC", leverage: 5, isCross: true },
        },
      ]}
      onComplete={() => router.push("/perpetuals")}
    />
  );
}

The pure state machine (reduceSetupState, classifyStep, nextRunnableStep) is exported separately so apps can build their own checklist UI without reimplementing the transition rules.

Future Improvements

  • Add integration tests for order submit/cancel and subscription lifecycle.
  • Finish i18n wiring across the remaining widgets (TradesUI); positions / open-orders / trade-history tables are fully translated under their respective perpetuals.* namespaces.
  • Wire a real-time userFills push subscription into useTradeHistoryScript so new fills appear instantly (today the script polls via React Query with a 5 s staleTime). The hook surface already accepts the data path; the only missing piece is a subscribeUserData('fills') listener that prepends new fills to the React Query cache for tradesQueryKey.
  • Surface a per-position TP/SL editor behind the small Edit icon Axiom shows in the TP/SL cell. The data plumbing already lands the active trigger prices on each Position (takeProfitPrice / stopLossPrice); a popover that calls useCreateOrderMutation with reduceOnly: true triggers would complete the loop.
  • Wire a Limit close action in the positions row's Close cell. Today only the Market close button is rendered; reusing the place-order form's limit-price input from a popover would close the gap.
  • Replace placeholder account/margin values in place-order script with real account sources.
  • Surface deposit status updates over a push channel (SSE/WebSocket) once the perpetuals-server exposes one — today the client polls.
  • Ship a first-party HyperliquidSetupAdapter implementation via a dedicated @liberfi.io/wallet-connector-hyperliquid package so consumers don’t need to write their own.