JSPM

  • Created
  • Published
  • Downloads 719
  • Score
    100M100P100Q111330F
  • License MIT

React SDK for Pear Protocol Hyperliquid API integration

Package Exports

  • @pear-protocol/hyperliquid-sdk

Readme

Pear Hyperliquid SDK

A comprehensive React SDK for integrating with the Pear Protocol Hyperliquid API. This SDK provides a complete toolkit for building trading applications with real-time WebSocket data, authentication, position management, order execution, and market data access.

Features

  • React Context Provider - Easy integration with React applications
  • Real-time WebSocket Connections - Dual WebSocket support (Pear API + HyperLiquid native)
  • Authentication - EIP-712 signature and Privy token authentication
  • Position Management - Create, adjust, and close trading positions
  • Order Management - Place, modify, and cancel orders (MARKET, LIMIT, TWAP, TP/SL)
  • Market Data - Access real-time price feeds, asset information, and candle data
  • Agent Wallet - Manage agent wallet creation and status
  • TypeScript - Full type safety with comprehensive type definitions
  • Zustand State Management - Efficient state management for market and user data

Installation

npm install @pear-protocol/hyperliquid-sdk
# or
yarn add @pear-protocol/hyperliquid-sdk

Peer Dependencies

This SDK requires React 18 or higher:

npm install react react-dom
# or
yarn add react react-dom

Quick Start

1. Wrap your application with the Provider

import { PearHyperliquidProvider } from "@pear-protocol/hyperliquid-sdk";

function App() {
  return (
    <PearHyperliquidProvider
      apiBaseUrl="https://hl-v2.pearprotocol.io"
      wsUrl="wss://hl-v2.pearprotocol.io/ws"
      clientId="YOUR_CLIENT_ID"
    >
      <YourApp />
    </PearHyperliquidProvider>
  );
}

2. Use hooks in your components

import {
  usePearAuth,
  usePearHyperliquid,
  usePosition,
  useOrders,
} from "@pear-protocol/hyperliquid-sdk";

function TradingComponent() {
  const { address, setAddress } = usePearHyperliquid();
  const { isAuthenticated, loginWithSignedMessage } = usePearAuth();
  const { openPositions, createPosition } = usePosition();
  const { openOrders, cancelOrder } = useOrders();

  // Your component logic
}

Core Concepts

Provider Configuration

The PearHyperliquidProvider accepts the following props:

Prop Type Default Description
apiBaseUrl string https://hl-v2.pearprotocol.io Pear API base URL
wsUrl string wss://hl-v2.pearprotocol.io/ws Pear WebSocket URL
clientId string PEARPROTOCOLUI Client identifier for authentication

Authentication

The SDK supports two authentication methods:

EIP-712 Signature Authentication

import { usePearAuth } from "@pear-protocol/hyperliquid-sdk";

function LoginComponent() {
  const { getEip712, loginWithSignedMessage, isAuthenticated } = usePearAuth();

  const handleLogin = async (address: string, signer: any) => {
    // Get EIP-712 message
    const eip712Data = await getEip712(address);

    // Sign with wallet
    const signature = await signer.signTypedData(
      eip712Data.domain,
      eip712Data.types,
      eip712Data.message
    );

    // Authenticate
    await loginWithSignedMessage(address, signature, eip712Data.timestamp);
  };

  return <div>{isAuthenticated ? "Logged In" : "Logged Out"}</div>;
}

Privy Token Authentication

import { usePearAuth } from "@pear-protocol/hyperliquid-sdk";

function PrivyLoginComponent() {
  const { loginWithPrivyToken, isAuthenticated } = usePearAuth();

  const handlePrivyLogin = async (
    address: string,
    appId: string,
    accessToken: string
  ) => {
    await loginWithPrivyToken(address, appId, accessToken);
  };
}

API Reference

Hooks

Core Hooks

usePearHyperliquid()

Access the entire SDK context. Prefer using more specific hooks when possible.

const {
  apiBaseUrl,
  wsUrl,
  address,
  setAddress,
  connectionStatus,
  isConnected,
  nativeConnectionStatus,
  nativeIsConnected,
  authStatus,
  isAuthenticated,
  accessToken,
  user,
  // ... and more
} = usePearHyperliquid();
usePearAuth()

Authentication state and actions.

const {
  status, // AuthStatus enum
  isAuthenticated, // boolean
  user, // UserProfile | null
  error, // string | null
  getEip712, // (address: string) => Promise<EIP712MessageResponse>
  loginWithSignedMessage, // (address, signature, timestamp) => Promise<void>
  loginWithPrivyToken, // (address, appId, accessToken) => Promise<void>
  refreshTokens, // () => Promise<any>
  logout, // () => Promise<void>
} = usePearAuth();
usePearAgentWallet()

Agent wallet management.

const {
  agentWallet, // AgentWalletState
  isReady, // boolean
  loading, // boolean
  error, // string | null
  refreshAgentWalletStatus, // () => Promise<any>
  createAgentWallet, // () => Promise<any>
  notifyAgentWalletApproved, // () => Promise<any>
} = usePearAgentWallet();

Position Management

usePosition()

Manage trading positions.

const {
  createPosition, // (payload) => Promise<ApiResponse<CreatePositionResponseDto>>
  updateRiskParameters, // (positionId, payload) => Promise<ApiResponse<UpdateRiskParametersResponseDto>>
  closePosition, // (positionId, payload) => Promise<ApiResponse<ClosePositionResponseDto>>
  closeAllPositions, // (payload) => Promise<ApiResponse<CloseAllPositionsResponseDto>>
  adjustPosition, // (positionId, payload) => Promise<ApiResponse<AdjustPositionResponseDto>>
  openPositions, // OpenPositionDto[] | null
  isLoading, // boolean
} = usePosition();

Example: Create a Position

const { createPosition } = usePosition();

const handleCreatePosition = async () => {
  try {
    const response = await createPosition({
      leverage: 5,
      usdValue: 1000,
      longAssets: [{ asset: "ETH", weight: 1 }],
      shortAssets: [{ asset: "BTC", weight: 1 }],
      orderType: "MARKET",
    });
    console.log("Position created:", response.data);
  } catch (error) {
    console.error("Failed to create position:", error);
  }
};

Example: Close a Position

const { closePosition } = usePosition();

const handleClosePosition = async (positionId: string) => {
  try {
    const response = await closePosition(positionId, {
      orderType: "MARKET",
    });
    console.log("Position closed:", response.data);
  } catch (error) {
    console.error("Failed to close position:", error);
  }
};

Order Management

useOrders()

Manage orders (LIMIT, TP/SL, TWAP).

const {
  adjustOrder, // (orderId, payload) => Promise<ApiResponse<AdjustOrderResponseDto>>
  cancelOrder, // (orderId) => Promise<ApiResponse<CancelOrderResponseDto>>
  cancelTwapOrder, // (orderId) => Promise<ApiResponse<CancelTwapResponseDto>>
  openOrders, // OpenLimitOrderDto[] | null
  isLoading, // boolean
} = useOrders();

Example: Cancel an Order

const { cancelOrder } = useOrders();

const handleCancelOrder = async (orderId: string) => {
  try {
    await cancelOrder(orderId);
    console.log("Order cancelled successfully");
  } catch (error) {
    console.error("Failed to cancel order:", error);
  }
};

Trading Data

useTradeHistories()

Access trade history data.

const { data, isLoading } = useTradeHistories();
useOpenOrders()

Access open orders with loading state.

const { data, isLoading } = useOpenOrders();
useAccountSummary()

Access account summary with real-time calculations.

const { data, isLoading } = useAccountSummary();
// data: AccountSummaryResponseDto | null

Market Data

useMarketData()

Access real-time market data from Zustand store.

import { useMarketData } from "@pear-protocol/hyperliquid-sdk";

function MarketDataComponent() {
  const activeAssets = useMarketData((state) => state.activeAssets);

  return (
    <div>
      {activeAssets?.active.map((asset, idx) => (
        <div key={idx}>
          Long: {asset.longAssets.map((a) => a.asset).join(", ")} vs Short:{" "}
          {asset.shortAssets.map((a) => a.asset).join(", ")}
        </div>
      ))}
    </div>
  );
}
useHistoricalPriceData()

Fetch and manage historical price data for tokens.

import { useHistoricalPriceData } from "@pear-protocol/hyperliquid-sdk";

function ChartComponent() {
  const { fetchHistoricalData, getTokenData } = useHistoricalPriceData();

  useEffect(() => {
    fetchHistoricalData("ETH", "1d"); // 1 day range
  }, []);

  const ethData = getTokenData("ETH");
}
useBasketCandles()

Get candle data for basket (multi-asset) positions.

import { useBasketCandles } from "@pear-protocol/hyperliquid-sdk";

function BasketChartComponent() {
  const { candles, isLoading, error } = useBasketCandles({
    longAssets: [
      { symbol: "ETH", weight: 0.5 },
      { symbol: "BTC", weight: 0.5 },
    ],
    shortAssets: [{ symbol: "SOL", weight: 1 }],
    interval: "1h",
    lookbackHours: 24,
  });
}
useTokenSelectionMetadata()

Get metadata for selected tokens including prices, funding, and leverage info.

import { useTokenSelectionMetadata } from "@pear-protocol/hyperliquid-sdk";

function TokenSelector() {
  const { getMetadata, isLoading } = useTokenSelectionMetadata();

  const ethMetadata = getMetadata("ETH");
  // ethMetadata: { currentPrice, priceChange24hPercent, maxLeverage, ... }
}

WebSocket Hooks

useHyperliquidWebSocket()

Access Pear API WebSocket connection (managed by provider).

useHyperliquidNativeWebSocket()

Access HyperLiquid native WebSocket connection (managed by provider).

TWAP Orders

useTwap()

Access TWAP (Time-Weighted Average Price) order monitoring.

import { useTwap } from "@pear-protocol/hyperliquid-sdk";

function TwapMonitor() {
  const { twapOrders, isLoading } = useTwap();

  return (
    <div>
      {twapOrders?.map((order) => (
        <div key={order.orderId}>
          Status: {order.status}
          Progress: {(order.filledUsdValue / order.totalUsdValue) * 100}%
        </div>
      ))}
    </div>
  );
}

Notifications

useNotifications()

Access user notifications.

import { useNotifications } from "@pear-protocol/hyperliquid-sdk";

function NotificationCenter() {
  const { notifications, isLoading, markAsRead, markAllAsRead } =
    useNotifications();

  return (
    <div>
      {notifications?.map((notif) => (
        <div key={notif.id} onClick={() => markAsRead(notif.id)}>
          {notif.category}: {JSON.stringify(notif.parameters)}
        </div>
      ))}
    </div>
  );
}

Utility Classes

AccountSummaryCalculator

Calculate account summary with real-time data.

import { AccountSummaryCalculator } from "@pear-protocol/hyperliquid-sdk";

const calculator = new AccountSummaryCalculator(webData2);
const summary = calculator.calculateAccountSummary(
  accountSummary,
  openOrders,
  agentWalletAddress,
  agentWalletStatus
);

ConflictDetector

Detect position conflicts for new trades.

import { ConflictDetector } from "@pear-protocol/hyperliquid-sdk";

const conflicts = ConflictDetector.detectConflicts(
  longTokens,
  shortTokens,
  existingPositions
);

TokenMetadataExtractor

Extract token metadata from WebSocket data.

import { TokenMetadataExtractor } from "@pear-protocol/hyperliquid-sdk";

const metadata = TokenMetadataExtractor.extractMetadata(
  "ETH",
  webData2,
  allMids,
  activeAssetData
);

Direct API Clients

For advanced use cases, you can import and use API clients directly:

import {
  createPosition,
  updateRiskParameters,
  closePosition,
  adjustOrder,
  cancelOrder,
} from "@pear-protocol/hyperliquid-sdk";

// All client functions require baseUrl and accessToken
const response = await createPosition(baseUrl, accessToken, {
  leverage: 5,
  usdValue: 1000,
  longAssets: [{ asset: "ETH", weight: 1 }],
  shortAssets: [{ asset: "BTC", weight: 1 }],
  orderType: "MARKET",
});

TypeScript Support

The SDK is written in TypeScript and provides comprehensive type definitions. All hooks, functions, and data structures are fully typed.

import type {
  OpenPositionDto,
  OpenLimitOrderDto,
  TradeHistoryDataDto,
  AccountSummaryResponseDto,
  WebSocketChannel,
  CandleInterval,
  TokenMetadata,
  // ... and many more
} from "@pear-protocol/hyperliquid-sdk";

WebSocket Data Flow

The SDK manages two WebSocket connections:

  1. Pear API WebSocket - User-specific data (positions, orders, trade history, account summary)
  2. HyperLiquid Native WebSocket - Market data (prices, asset info, candles)

Data is automatically stored in Zustand stores and accessible via hooks:

  • useUserData store - User positions, orders, and account data
  • useHyperliquidData store - Market data (webData2, allMids, activeAssetData)
  • useHistoricalPriceDataStore - Historical price data
  • useMarketData store - Active assets and market overview

Error Handling

All API functions return promises and throw errors on failure. Always wrap API calls in try-catch blocks:

try {
  await createPosition(payload);
} catch (error) {
  if (error instanceof Error) {
    console.error("Error:", error.message);
  }
}

Environment Variables

When using the SDK, you may want to configure different environments:

// Production
<PearHyperliquidProvider
  apiBaseUrl="https://hl-v2.pearprotocol.io"
  wsUrl="wss://hl-v2.pearprotocol.io/ws"
/>

// Beta
<PearHyperliquidProvider
  apiBaseUrl="https://hl-v2-beta.pearprotocol.io"
  wsUrl="wss://hl-v2-beta.pearprotocol.io/ws"
/>

Examples

Complete Trading Component

import { useState } from "react";
import {
  usePearAuth,
  usePearHyperliquid,
  usePosition,
  useOrders,
  useAccountSummary,
} from "@pear-protocol/hyperliquid-sdk";

function TradingDashboard() {
  const { address, setAddress, isConnected } = usePearHyperliquid();
  const { isAuthenticated, loginWithSignedMessage } = usePearAuth();
  const { openPositions, createPosition, closePosition } = usePosition();
  const { openOrders, cancelOrder } = useOrders();
  const { data: accountSummary } = useAccountSummary();

  const handleCreatePosition = async () => {
    try {
      await createPosition({
        leverage: 3,
        usdValue: 500,
        longAssets: [{ asset: "ETH", weight: 1 }],
        shortAssets: [{ asset: "BTC", weight: 1 }],
        orderType: "MARKET",
      });
    } catch (error) {
      console.error("Failed to create position:", error);
    }
  };

  return (
    <div>
      <h1>Trading Dashboard</h1>

      <div>
        <h2>Account</h2>
        <p>Address: {address || "Not connected"}</p>
        <p>Status: {isAuthenticated ? "Authenticated" : "Not authenticated"}</p>
        <p>WebSocket: {isConnected ? "Connected" : "Disconnected"}</p>
      </div>

      <div>
        <h2>Account Summary</h2>
        <p>
          Account Value: $
          {accountSummary?.balanceSummary.marginSummary.accountValue}
        </p>
        <p>Withdrawable: ${accountSummary?.balanceSummary.withdrawable}</p>
      </div>

      <div>
        <h2>Open Positions</h2>
        {openPositions?.map((pos) => (
          <div key={pos.positionId}>
            <p>PNL: ${pos.unrealizedPnl.toFixed(2)}</p>
            <p>Value: ${pos.positionValue.toFixed(2)}</p>
            <button
              onClick={() =>
                closePosition(pos.positionId, { orderType: "MARKET" })
              }
            >
              Close
            </button>
          </div>
        ))}
      </div>

      <div>
        <h2>Open Orders</h2>
        {openOrders?.map((order) => (
          <div key={order.orderId}>
            <p>Type: {order.orderType}</p>
            <p>Value: ${order.usdValue}</p>
            <button onClick={() => cancelOrder(order.orderId)}>Cancel</button>
          </div>
        ))}
      </div>

      <button onClick={handleCreatePosition}>Create New Position</button>
    </div>
  );
}

export default TradingDashboard;

Market Data Component

import {
  useMarketData,
  useTokenSelectionMetadata,
  useHyperliquidWebSocket,
} from "@pear-protocol/hyperliquid-sdk";

function MarketOverview() {
  const activeAssets = useMarketData((state) => state.activeAssets);
  const { getMetadata } = useTokenSelectionMetadata();

  return (
    <div>
      <h2>Top Gainers</h2>
      {activeAssets?.topGainers.slice(0, 5).map((asset, idx) => {
        const longAsset = asset.longAssets[0]?.asset;
        const metadata = longAsset ? getMetadata(longAsset) : null;

        return (
          <div key={idx}>
            <p>
              {longAsset}: {metadata?.priceChange24hPercent.toFixed(2)}%
            </p>
          </div>
        );
      })}

      <h2>Top Losers</h2>
      {activeAssets?.topLosers.slice(0, 5).map((asset, idx) => {
        const shortAsset = asset.shortAssets[0]?.asset;
        const metadata = shortAsset ? getMetadata(shortAsset) : null;

        return (
          <div key={idx}>
            <p>
              {shortAsset}: {metadata?.priceChange24hPercent.toFixed(2)}%
            </p>
          </div>
        );
      })}
    </div>
  );
}

License

MIT

Repository

GitHub: https://github.com/pear-protocol/hyperliquid

Support

For issues and questions, please visit the GitHub Issues page.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.