JSPM

  • Created
  • Published
  • Downloads 747
  • Score
    100M100P100Q107089F
  • 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.