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

@zofai/trading-widget

v0.1.1

Published

Embeddable perpetuals trading UI for ZO Finance on Sui. Partners can drop the full widget into their dapp or compose custom layouts from sub-components.

Readme

@zo/trading-widget

Embeddable perpetuals trading UI for ZO Finance on Sui. Partners can drop the full widget into their dapp or compose custom layouts from sub-components.

Features

  • Market header – Symbol selector, mark price, funding rate
  • Price chart – Pyth-powered OHLC + live updates (lightweight-charts)
  • Recent trades – Live trade feed
  • Trade panel – Open/close positions (market & limit), ZLP/SLP/USDZ
  • Positions / Orders / History – Bottom tabs with countdown to next refresh
  • RPC settings – Predefined or custom RPC URL
  • Wallet – Sui connect via @mysten/dapp-kit-react; custom connect button and account sidebar

Peer dependencies

Your app must install:

  • react & react-dom (≥18)
  • jotai (≥2)
  • @tanstack/react-query (≥5)
  • @mysten/dapp-kit-react (≥1) & @mysten/sui (≥2)
  • zo-sdk (≥0.1)

The widget uses Tailwind-compatible utility classes (e.g. flex, text-white, rounded-lg). Either:

  • Use Tailwind CSS or UnoCSS in your app so those classes resolve, or
  • Import the bundled CSS once in your app: import '@zo/trading-widget/style.css' (or @zofai/trading-widget/style.css). This file contains the compiled UnoCSS used by the widget.

Quick start: full widget

  1. Wrap your app with the required providers (order matters):
import { appStore } from '@zo/trading-widget'
import { Provider as JotaiProvider } from 'jotai'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { DAppKitProvider } from '@mysten/dapp-kit-react'

// Your dapp-kit instance (Sui wallet + network)
import { dAppKit } from './dapp-kit'

const queryClient = new QueryClient({
  defaultOptions: {
    queries: { staleTime: 60_000, retry: 2 },
  },
})

export function Root() {
  return (
    <JotaiProvider store={appStore}>
      <QueryClientProvider client={queryClient}>
        <DAppKitProvider dAppKit={dAppKit}>
          <App />
        </DAppKitProvider>
      </QueryClientProvider>
    </JotaiProvider>
  )
}
  1. Render the widget where you want the trading UI:
import { TradingWidget } from '@zo/trading-widget'

export function App() {
  return (
    <div className="h-screen flex flex-col">
      <header>{/* Your navbar, connect button, etc. */}</header>
      <main className="min-h-0 flex-1">
        <TradingWidget className="h-full" />
      </main>
    </div>
  )
}

TradingWidget props

| Prop | Type | Description | | ---------- | -------- | ------------------------------------ | | symbol | string | Initial symbol (default "BTC") | | className| string | Extra class on the widget container |


Components

All-in-one

  • TradingWidget – Full layout: header, chart, recent trades, trade panel, bottom tabs (positions/orders/history), dialogs and toasts.

Layout & header

  • TradingWidgetProvider – Sui + React Query + Jotai setup. Use when building a custom layout so sub-components have the same context.
  • MarketHeader – Symbol dropdown (from ZLP/SLP index tokens), mark price, funding rate.

Market data

  • PriceChart – Pyth-backed candlestick chart (history + streaming).
  • RecentTrades – Recent trades for the selected symbol.

Trading & account

  • TradePanel – Long/short, market/limit, leverage, collateral selector; opens positions on ZLP/SLP/USDZ.
  • CustomConnectButton – Connect wallet; when connected opens the account sidebar instead of a dropdown.

Tables (bottom section)

  • BottomTabs – Tabs: Positions, Orders, History; each shows a circular countdown to next refresh.
  • PositionsList – Open positions with PnL, adjust/close.
  • OrdersList – Open orders with cancel.
  • HistoryList – Trade history.

Settings

  • RpcSettings – Dropdown: choose predefined RPC or enter custom URL; shows latency. Persists to localStorage so the widget’s provider uses the selected RPC.

Custom layout

Use TradingWidgetProvider and the sub-components to build your own layout:

import {
  TradingWidgetProvider,
  MarketHeader,
  PriceChart,
  RecentTrades,
  TradePanel,
  BottomTabs,
  CustomConnectButton,
  RpcSettings,
} from '@zo/trading-widget'

export function CustomTradePage() {
  return (
    <TradingWidgetProvider>
      <div className="flex flex-col h-full bg-gray-950 text-white">
        <header className="flex items-center gap-3 border-b border-gray-800 px-4 py-2">
          <MarketHeader />
          <div className="flex-1" />
          <RpcSettings />
          <CustomConnectButton />
        </header>
        <div className="flex flex-1 overflow-hidden">
          <div className="flex-1 min-w-0">
            <PriceChart />
          </div>
          <aside className="w-48 shrink-0">
            <RecentTrades />
          </aside>
          <aside className="w-72 shrink-0">
            <TradePanel />
          </aside>
        </div>
        <div className="h-52 shrink-0 border-t border-gray-800">
          <BottomTabs />
        </div>
      </div>
    </TradingWidgetProvider>
  )
}

Ensure your app is wrapped with Jotai (appStore), React Query, and DAppKit as in Quick start.


Hooks & store

For custom UIs that need widget data or actions:

Hooks

  • useEssential() – wallet, network, consts (zo/sudo/usdz), accountData, refreshAccount
  • useWallet(), useNetwork() – wallet and current network
  • usePosition(address, network) – positions list, refresh, dataUpdatedAt
  • useOrder(address, network) – orders list, refresh, dataUpdatedAt
  • useHistories(address, network) – trade history
  • useFundingRate(symbol, network, lpToken) – funding rate
  • usePositionConfig(network, { symbols }) – position config (fees, etc.)
  • useSymbolInfo(network) – symbol info map (ZLP/SLP/USDZ)
  • useRpc() – RPC list, custom URL, latency; used by RpcSettings
  • useSponsoredGasAvailability(address, network) – gas sponsorship

Store (Jotai)

  • appStore – same store instance must be used for the widget and your app (see Quick start).
  • currentSymbolAtom{ symbolId, unit, icon }; set when user picks a market.
  • tokenPriceAtom{ tokenPrice: Record<string, number>, isLoading, error } (Pyth oracle prices).

RPC and wallet

  • RPC – The widget reads RPC from localStorage: is-custom-rpc, custom-rpc-url, custom-rpc-index. Use RpcSettings in your header (or elsewhere) so users can pick a predefined RPC or set a custom URL. After changing RPC, a full page refresh is recommended.
  • Wallet – Uses Sui dapp-kit. Your app must create a dAppKit (e.g. with createDAppKit) and wrap the tree in DAppKitProvider. CustomConnectButton triggers the kit’s connect flow; when connected, it opens the widget’s account sidebar.

Example app

The repo includes an example app that integrates the widget:

  • Apps/example – Minimal shell: navbar (brand, RPC settings, connect), then full-width TradingWidget. See apps/example/src/App.tsx and apps/example/src/main.tsx for provider setup and dAppKit registration.

Run it (from monorepo root):

pnpm install
pnpm --filter example dev

Build

From the repo root:

pnpm --filter @zo/trading-widget build

Output: packages/trading-widget/dist/ (ESM + types). Consume from your app as @zo/trading-widget (workspace or published package).