npm package: @liberfi.io/ui-predict
Description: Predict Components for Liberfi React SDK
Author: liberfi.io
Latest version: 0.1.138

# @liberfi.io/ui-predict

Prediction market UI components, data hooks, and client for the Liberfi React SDK. Provides a full-stack prediction market experience — from event browsing and detail views to trading, order management, and real-time price feeds. Consumed by template apps (e.g. `dex-nextjs-template`) and composed with `@liberfi.io/ui` base components.

## Design Philosophy

- **Script / UI / Widget separation** — Each feature area (events, trade-form, order-book, etc.) is split into a `.script` (data hook), `.ui` (pure presentation), and `.widget` (wiring) layer. Presentational components are reusable without the full data stack.
- **Inversion of Control** — Navigation, side effects, and framework-specific behaviour (e.g. Next.js `<Link>`) are injected via callbacks and component props. The package never imports a router or framework directly.
- **V1 / V2 coexistence** — Legacy DFlow-backed components coexist with the prediction-server v2 client. Consumers migrate at their own pace; both APIs are stable and exported.
- **Provider-based client injection** — `PredictProvider` / `PredictV2Provider` supply the API client via React Context. Hooks pull the client from context, keeping components testable and decoupled from concrete HTTP implementations.

## Installation

```bash
pnpm add @liberfi.io/ui-predict
```

### Peer dependencies

The consumer must provide:

| Package                     | Version                          |
| --------------------------- | -------------------------------- |
| `react`                     | >= 18                            |
| `react-dom`                 | >= 18                            |
| `@tanstack/react-query`     | ^5.90.2                          |
| `@liberfi.io/react-predict` | workspace / matching SDK version |

## API Reference

### Providers

| Provider              | Props                                     | Description                                                                  |
| --------------------- | ----------------------------------------- | ---------------------------------------------------------------------------- |
| `PredictProvider`     | `client: IPredictClient`                  | Supplies the legacy DFlow predict client to all descendant hooks/components. |
| `PredictV2Provider`   | `client: PredictClientV2`                 | Supplies the v2 prediction-server client.                                    |
| `UserPredictProvider` | `walletAddress: string, enabled: boolean` | Provides user-specific prediction context (positions, orders).               |

### Components — Events

| Component            | Key Props                                                                                                                             | Description                                                                                                             |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| `EventsPage`         | `onSelect`, `onSelectOutcome`, `getEventHref`, `LinkComponent`, `onHover`                                                             | Full events page with categories, toolbar, filters, and grid.                                                           |
| `EventsWidget`       | `tagSlugSelection`, `limit`, `status`, `sort_by`, `source`, `onSelect`, `onSelectOutcome`, `getEventHref`, `LinkComponent`, `onHover` | Container that wires `useEventsInfinite` data to `EventsUI`.                                                            |
| `EventsUI`           | `events`, `hasMore`, `onFetchMore`, `onSelect`, `onSelectOutcome`, `getEventHref`, `LinkComponent`, `onHover`                         | Virtualized grid (react-window) rendering `EventItem` cards.                                                            |
| `EventItem`          | `event`, `href`, `LinkComponent`, `onSelect`, `onSelectOutcome`, `onHover`                                                            | Single event card. Uses `Linkable` from `@liberfi.io/ui` — renders as a `<Link>` when `href` is set, `<div>` otherwise. |
| `EventsToolbarUI`    | Sort + filter button props                                                                                                            | Toolbar for sort preset and filter modal trigger.                                                                       |
| `EventsFilterUI`     | Modal filter state props                                                                                                              | Filter modal (platform, time, volume, liquidity).                                                                       |
| `EventsSkeleton`     | `count?`                                                                                                                              | Grid skeleton used while events cards are loading.                                                                      |
| `EventsPageSkeleton` | `count?`                                                                                                                              | Page-level skeleton including category/toolbar placeholders + events grid skeleton.                                     |
| `CategoriesWidget`   | `onSelect`, `trailing`                                                                                                                | Category/tag navigation (slug-based).                                                                                   |

#### Link integration props

These props enable framework-agnostic route link rendering and prefetching:

- **`getEventHref?: (event: PredictEvent) => string`** — Generates the URL for each event card. When provided, cards render as link elements instead of plain divs.
- **`LinkComponent?: LinkComponentType`** — A custom link component (e.g. `next/link`). Falls back to `<a>` when `href` is set without this prop. Import `LinkComponentType` from `@liberfi.io/ui`.
- **`onHover?: (event: PredictEvent) => void`** — Called when a card is hovered (`onMouseEnter`). Use this to trigger data prefetching (e.g. `queryClient.prefetchQuery`).

### Components — Event Detail

| Component             | Key Props                                                               | Description                                          |
| --------------------- | ----------------------------------------------------------------------- | ---------------------------------------------------- |
| `EventDetailPage`     | `eventId`, `onTradeAction`                                              | Full detail page composing detail + trade form.      |
| `EventDetailWidget`   | `eventId`, `initialMarketTickers`, `initialChartRange`, `onTradeAction` | Event detail with candlestick chart and market list. |
| `EventDetailUI`       | `event`, `series`, `candlesticks`, `chartRange`, ...                    | Pure presentation for event detail.                  |
| `EventDetailSkeleton` | `marketCount?`                                                          | Loading skeleton for the detail page.                |

### Components — Trading

| Component            | Description                                          |
| -------------------- | ---------------------------------------------------- |
| `TradeFormWidget`    | Trade form wiring (market, side, amount, execution). |
| `OrderBookWidget`    | Live order book with depth visualization.            |
| `OpenOrdersWidget`   | User's open orders with cancel support.              |
| `TradeHistoryWidget` | Recent trade history.                                |
| `PositionsWidget`    | User's prediction market positions.                  |

### Hooks — Events

| Hook                     | Params                       | Return                    | Description                                                                                  |
| ------------------------ | ---------------------------- | ------------------------- | -------------------------------------------------------------------------------------------- |
| `useEventsInfinite`      | `UseEventsInfiniteParams`    | `UseEventsInfiniteResult` | Infinite-scroll events list (flattened pages, cursor-based via `@liberfi.io/react-predict`). |
| `useEventByIdQuery`      | `{ id, withNestedMarkets? }` | TanStack Query result     | Single event by ID/slug.                                                                     |
| `useEventsQuery`         | `EventQueryParams`           | TanStack Query result     | Legacy paginated events.                                                                     |
| `useEventsInfiniteQuery` | `EventQueryParams`           | TanStack infinite query   | Legacy infinite-scroll events.                                                               |

### Hooks — Markets & Data

| Hook                                                      | Description                     |
| --------------------------------------------------------- | ------------------------------- |
| `useMarketsQuery`                                         | Markets by event.               |
| `useMarketByIdQuery`                                      | Single market by ticker.        |
| `useMarketByMintQuery`                                    | Market lookup by mint address.  |
| `useMarketsBatchQuery`                                    | Batch market lookup.            |
| `useOrderBookQuery`                                       | Order book for a market.        |
| `useTradesQuery`                                          | Recent trades.                  |
| `useOnchainTradesQuery` / `useOnchainTradesInfiniteQuery` | On-chain trade history.         |
| `usePriceHistoryQuery`                                    | Candlestick data.               |
| `useForecastHistoryQuery`                                 | AI forecast percentile history. |
| `useLiveDataQuery`                                        | Real-time market data.          |
| `useSeriesQuery`                                          | Series metadata.                |
| `useCategoriesQuery`                                      | Tag/category list.              |
| `useSearchQuery`                                          | Search events.                  |

### Hooks — User & Trading

| Hook                        | Description                      |
| --------------------------- | -------------------------------- |
| `usePositionsByWalletQuery` | User positions by wallet.        |
| `useMarketPositions`        | Positions for a specific market. |
| `useQuoteQuery`             | Trade quote.                     |
| `useSwapMutation`           | Execute a swap/trade.            |
| `useOrderQuery`             | Place a limit order.             |
| `useIntentQuery`            | Intent-based trading.            |
| `useOutcomeMintsQuery`      | Outcome token mints.             |
| `useTokensQuery`            | Token list.                      |
| `useVenuesQuery`            | Venue list.                      |

### Hooks — WebSocket

| Hook                       | Description                               |
| -------------------------- | ----------------------------------------- |
| `useWsConnection`          | WebSocket connection lifecycle.           |
| `useWsClient`              | Access the WS client instance.            |
| `usePricesSubscription`    | Subscribe to real-time price updates.     |
| `useTradesSubscription`    | Subscribe to real-time trade updates.     |
| `useOrderbookSubscription` | Subscribe to real-time orderbook updates. |

### Hooks — V2

| Hook                 | Description                                                   |
| -------------------- | ------------------------------------------------------------- |
| `usePredictV2Client` | Access the v2 prediction-server client.                       |
| `useEvents`          | Events query (single page) — see `@liberfi.io/react-predict`. |
| `useEventV2Query`    | V2 single event query.                                        |

### Functions / Utilities

| Function                     | Signature                                                                             | Description                                                                         |
| ---------------------------- | ------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
| `eventByIdQueryKey`          | `(params: UseEventByIdQueryParams) => unknown[]`                                      | Stable query key for `useEventByIdQuery`. Useful for prefetching.                   |
| `fetchEventById`             | `(client: IPredictClient, params: UseEventByIdQueryParams) => Promise<StandardEvent>` | Standalone fetch function for event detail. Useful for `queryClient.prefetchQuery`. |
| `marketCandlesticksQueryKey` | `(params) => unknown[]`                                                               | Query key for candlestick data.                                                     |
| `fetchMarketCandlesticks`    | `(client, params) => Promise<CandlesticksResponse>`                                   | Standalone candlestick fetch.                                                       |
| `createPredictClientV2`      | `(baseURL: string) => PredictClientV2`                                                | Factory for the v2 client.                                                          |
| `createPredictWsClient`      | `(config: WsClientConfig) => PredictWsClient`                                         | Factory for the WebSocket client.                                                   |

### Key Types

| Type               | Description                                                             |
| ------------------ | ----------------------------------------------------------------------- |
| `PredictEvent`     | Event with markets, metadata, and volume (`@liberfi.io/react-predict`). |
| `PredictMarket`    | Market with outcomes, status, and pricing.                              |
| `StandardEvent`    | Legacy event model.                                                     |
| `StandardMarket`   | Legacy market model.                                                    |
| `IPredictClient`   | Interface for the prediction API client.                                |
| `IPredictWsClient` | Interface for the WebSocket client.                                     |
| `TagSlugSelection` | Category/tag selection state `{ categorySlug, tagSlug }`.               |
| `ChartRangeType`   | `"1d" \| "1w" \| "1m" \| "all"`                                         |

### Constants

| Constant                    | Value                                   | Description                          |
| --------------------------- | --------------------------------------- | ------------------------------------ |
| `DEFAULT_PAGE_SIZE`         | 48                                      | Default events per page.             |
| `MAX_PRICE_HISTORY_MARKETS` | 4                                       | Max markets for candlestick queries. |
| `ChartRange`                | `{ ONE_DAY, ONE_WEEK, ONE_MONTH, ALL }` | Chart time range enum.               |
| `CandlestickPeriod`         | `{ ONE_MINUTE, ONE_HOUR, ONE_DAY }`     | Candlestick granularity.             |

## Usage Examples

### Basic event list with Next.js Link prefetching

```tsx
import { useCallback } from "react";
import { useQueryClient } from "@tanstack/react-query";
import Link from "next/link";
import { useRouter } from "next/navigation";
import {
  EventsPage,
  eventByIdQueryKey,
  fetchEventById,
  usePredictClient,
} from "@liberfi.io/ui-predict";
import type { PredictEvent } from "@liberfi.io/ui-predict";

function PredictListPage() {
  const router = useRouter();
  const queryClient = useQueryClient();
  const predictClient = usePredictClient();

  // TanStack Query data prefetch on hover
  const handleHover = useCallback(
    (event: PredictEvent) => {
      queryClient.prefetchQuery({
        queryKey: eventByIdQueryKey({
          id: event.slug,
          withNestedMarkets: true,
        }),
        queryFn: () =>
          fetchEventById(predictClient, {
            id: event.slug,
            withNestedMarkets: true,
          }),
        staleTime: 30_000,
      });
    },
    [queryClient, predictClient],
  );

  return (
    <EventsPage
      getEventHref={(event) => `/predict/${event.slug}`}
      LinkComponent={Link}
      onHover={handleHover}
      onSelect={(event) => router.push(`/predict/${event.slug}`)}
    />
  );
}
```

### Event list without Link (callback-only, backward compatible)

```tsx
import { EventsPage } from "@liberfi.io/ui-predict";

function PredictListPage() {
  return (
    <EventsPage
      onSelect={(event) => console.log("selected", event.slug)}
      onSelectOutcome={(event, market, side) =>
        console.log("outcome", event.slug, market.slug, side)
      }
    />
  );
}
```

### Provider setup

```tsx
import {
  PredictProvider,
  PredictV2Provider,
  PredictClient,
  createPredictClientV2,
} from "@liberfi.io/ui-predict";

const legacyClient = new PredictClient("https://api.example.com");
const v2Client = createPredictClientV2("https://predict-v2.example.com");

function App({ children }) {
  return (
    <PredictProvider client={legacyClient}>
      <PredictV2Provider client={v2Client}>{children}</PredictV2Provider>
    </PredictProvider>
  );
}
```

## Future Improvements

- Migrate remaining v1 components (events list, categories) to v2 client, then deprecate v1 hooks and types.
- Add `onHover` callback support to `EventDetailWidget` for prefetching related series/candlestick data.
- Consider a `usePrefetchEventDetail` convenience hook that combines route prefetch + query prefetch in one call.
- Extract common virtualized grid logic (`EventsUI` pattern) into a shared `@liberfi.io/ui` component for reuse in token lists and channel lists.