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:
- Pear API WebSocket - User-specific data (positions, orders, trade history, account summary)
- 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 datauseHyperliquidData
store - Market data (webData2, allMids, activeAssetData)useHistoricalPriceDataStore
- Historical price datauseMarketData
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.