@pear-protocol/hyperliquid-sdk 0.0.49 → 0.0.51
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/clients/hyperliquid.d.ts +14 -2
- package/dist/clients/positions.d.ts +1 -1
- package/dist/clients/sync.d.ts +1 -1
- package/dist/clients/watchlist.d.ts +1 -1
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/useAccountSummary.d.ts +5 -0
- package/dist/hooks/useAgentWallet.d.ts +4 -9
- package/dist/hooks/usePortfolio.d.ts +1 -1
- package/dist/hooks/useTrading.d.ts +1 -8
- package/dist/hooks/useWebData.d.ts +3 -2
- package/dist/hyperliquid-websocket.d.ts +2 -1
- package/dist/index.d.ts +84 -96
- package/dist/index.js +400 -310
- package/dist/provider.d.ts +0 -20
- package/dist/store/tokenSelectionMetadataStore.d.ts +3 -2
- package/dist/types.d.ts +69 -21
- package/dist/utils/account-summary-calculator.d.ts +6 -13
- package/dist/utils/position-processor.d.ts +2 -2
- package/dist/utils/symbol-translator.d.ts +11 -0
- package/dist/utils/token-metadata-extractor.d.ts +11 -9
- package/dist/websocket.d.ts +2 -1
- package/package.json +1 -1
- package/README.md +0 -735
- package/dist/hooks/useAddress.d.ts +0 -9
package/README.md
DELETED
|
@@ -1,735 +0,0 @@
|
|
|
1
|
-
# Pear Hyperliquid SDK
|
|
2
|
-
|
|
3
|
-
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.
|
|
4
|
-
|
|
5
|
-
## Features
|
|
6
|
-
|
|
7
|
-
- **React Context Provider** - Easy integration with React applications
|
|
8
|
-
- **Real-time WebSocket Connections** - Dual WebSocket support (Pear API + HyperLiquid native)
|
|
9
|
-
- **Authentication** - EIP-712 signature and Privy token authentication
|
|
10
|
-
- **Position Management** - Create, adjust, and close trading positions
|
|
11
|
-
- **Order Management** - Place, modify, and cancel orders (MARKET, LIMIT, TWAP, TP/SL)
|
|
12
|
-
- **Market Data** - Access real-time price feeds, asset information, and candle data
|
|
13
|
-
- **Agent Wallet** - Manage agent wallet creation and status
|
|
14
|
-
- **TypeScript** - Full type safety with comprehensive type definitions
|
|
15
|
-
- **Zustand State Management** - Efficient state management for market and user data
|
|
16
|
-
|
|
17
|
-
## Installation
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
npm install @pear-protocol/hyperliquid-sdk
|
|
21
|
-
# or
|
|
22
|
-
yarn add @pear-protocol/hyperliquid-sdk
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
### Peer Dependencies
|
|
26
|
-
|
|
27
|
-
This SDK requires React 18 or higher:
|
|
28
|
-
|
|
29
|
-
```bash
|
|
30
|
-
npm install react react-dom
|
|
31
|
-
# or
|
|
32
|
-
yarn add react react-dom
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
## Quick Start
|
|
36
|
-
|
|
37
|
-
### 1. Wrap your application with the Provider
|
|
38
|
-
|
|
39
|
-
```tsx
|
|
40
|
-
import { PearHyperliquidProvider } from "@pear-protocol/hyperliquid-sdk";
|
|
41
|
-
|
|
42
|
-
function App() {
|
|
43
|
-
return (
|
|
44
|
-
<PearHyperliquidProvider
|
|
45
|
-
apiBaseUrl="https://hl-v2.pearprotocol.io"
|
|
46
|
-
wsUrl="wss://hl-v2.pearprotocol.io/ws"
|
|
47
|
-
clientId="YOUR_CLIENT_ID"
|
|
48
|
-
>
|
|
49
|
-
<YourApp />
|
|
50
|
-
</PearHyperliquidProvider>
|
|
51
|
-
);
|
|
52
|
-
}
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
### 2. Use hooks in your components
|
|
56
|
-
|
|
57
|
-
```tsx
|
|
58
|
-
import {
|
|
59
|
-
usePearAuth,
|
|
60
|
-
usePearHyperliquid,
|
|
61
|
-
usePosition,
|
|
62
|
-
useOrders,
|
|
63
|
-
} from "@pear-protocol/hyperliquid-sdk";
|
|
64
|
-
|
|
65
|
-
function TradingComponent() {
|
|
66
|
-
const { address, setAddress } = usePearHyperliquid();
|
|
67
|
-
const { isAuthenticated, loginWithSignedMessage } = usePearAuth();
|
|
68
|
-
const { openPositions, createPosition } = usePosition();
|
|
69
|
-
const { openOrders, cancelOrder } = useOrders();
|
|
70
|
-
|
|
71
|
-
// Your component logic
|
|
72
|
-
}
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
## Core Concepts
|
|
76
|
-
|
|
77
|
-
### Provider Configuration
|
|
78
|
-
|
|
79
|
-
The `PearHyperliquidProvider` accepts the following props:
|
|
80
|
-
|
|
81
|
-
| Prop | Type | Default | Description |
|
|
82
|
-
| ------------ | -------- | -------------------------------- | ------------------------------------ |
|
|
83
|
-
| `apiBaseUrl` | `string` | `https://hl-v2.pearprotocol.io` | Pear API base URL |
|
|
84
|
-
| `wsUrl` | `string` | `wss://hl-v2.pearprotocol.io/ws` | Pear WebSocket URL |
|
|
85
|
-
| `clientId` | `string` | `PEARPROTOCOLUI` | Client identifier for authentication |
|
|
86
|
-
|
|
87
|
-
### Authentication
|
|
88
|
-
|
|
89
|
-
The SDK supports two authentication methods:
|
|
90
|
-
|
|
91
|
-
#### EIP-712 Signature Authentication
|
|
92
|
-
|
|
93
|
-
```tsx
|
|
94
|
-
import { usePearAuth } from "@pear-protocol/hyperliquid-sdk";
|
|
95
|
-
|
|
96
|
-
function LoginComponent() {
|
|
97
|
-
const { getEip712, loginWithSignedMessage, isAuthenticated } = usePearAuth();
|
|
98
|
-
|
|
99
|
-
const handleLogin = async (address: string, signer: any) => {
|
|
100
|
-
// Get EIP-712 message
|
|
101
|
-
const eip712Data = await getEip712(address);
|
|
102
|
-
|
|
103
|
-
// Sign with wallet
|
|
104
|
-
const signature = await signer.signTypedData(
|
|
105
|
-
eip712Data.domain,
|
|
106
|
-
eip712Data.types,
|
|
107
|
-
eip712Data.message
|
|
108
|
-
);
|
|
109
|
-
|
|
110
|
-
// Authenticate
|
|
111
|
-
await loginWithSignedMessage(address, signature, eip712Data.timestamp);
|
|
112
|
-
};
|
|
113
|
-
|
|
114
|
-
return <div>{isAuthenticated ? "Logged In" : "Logged Out"}</div>;
|
|
115
|
-
}
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
#### Privy Token Authentication
|
|
119
|
-
|
|
120
|
-
```tsx
|
|
121
|
-
import { usePearAuth } from "@pear-protocol/hyperliquid-sdk";
|
|
122
|
-
|
|
123
|
-
function PrivyLoginComponent() {
|
|
124
|
-
const { loginWithPrivyToken, isAuthenticated } = usePearAuth();
|
|
125
|
-
|
|
126
|
-
const handlePrivyLogin = async (
|
|
127
|
-
address: string,
|
|
128
|
-
appId: string,
|
|
129
|
-
accessToken: string
|
|
130
|
-
) => {
|
|
131
|
-
await loginWithPrivyToken(address, appId, accessToken);
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
## API Reference
|
|
137
|
-
|
|
138
|
-
### Hooks
|
|
139
|
-
|
|
140
|
-
#### Core Hooks
|
|
141
|
-
|
|
142
|
-
##### `usePearHyperliquid()`
|
|
143
|
-
|
|
144
|
-
Access the entire SDK context. Prefer using more specific hooks when possible.
|
|
145
|
-
|
|
146
|
-
```tsx
|
|
147
|
-
const {
|
|
148
|
-
apiBaseUrl,
|
|
149
|
-
wsUrl,
|
|
150
|
-
address,
|
|
151
|
-
setAddress,
|
|
152
|
-
connectionStatus,
|
|
153
|
-
isConnected,
|
|
154
|
-
nativeConnectionStatus,
|
|
155
|
-
nativeIsConnected,
|
|
156
|
-
authStatus,
|
|
157
|
-
isAuthenticated,
|
|
158
|
-
accessToken,
|
|
159
|
-
user,
|
|
160
|
-
// ... and more
|
|
161
|
-
} = usePearHyperliquid();
|
|
162
|
-
```
|
|
163
|
-
|
|
164
|
-
##### `usePearAuth()`
|
|
165
|
-
|
|
166
|
-
Authentication state and actions.
|
|
167
|
-
|
|
168
|
-
```tsx
|
|
169
|
-
const {
|
|
170
|
-
status, // AuthStatus enum
|
|
171
|
-
isAuthenticated, // boolean
|
|
172
|
-
user, // UserProfile | null
|
|
173
|
-
error, // string | null
|
|
174
|
-
getEip712, // (address: string) => Promise<EIP712MessageResponse>
|
|
175
|
-
loginWithSignedMessage, // (address, signature, timestamp) => Promise<void>
|
|
176
|
-
loginWithPrivyToken, // (address, appId, accessToken) => Promise<void>
|
|
177
|
-
refreshTokens, // () => Promise<any>
|
|
178
|
-
logout, // () => Promise<void>
|
|
179
|
-
} = usePearAuth();
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
##### `usePearAgentWallet()`
|
|
183
|
-
|
|
184
|
-
Agent wallet management.
|
|
185
|
-
|
|
186
|
-
```tsx
|
|
187
|
-
const {
|
|
188
|
-
agentWallet, // AgentWalletState
|
|
189
|
-
isReady, // boolean
|
|
190
|
-
loading, // boolean
|
|
191
|
-
error, // string | null
|
|
192
|
-
refreshAgentWalletStatus, // () => Promise<any>
|
|
193
|
-
createAgentWallet, // () => Promise<any>
|
|
194
|
-
notifyAgentWalletApproved, // () => Promise<any>
|
|
195
|
-
} = usePearAgentWallet();
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
#### Position Management
|
|
199
|
-
|
|
200
|
-
##### `usePosition()`
|
|
201
|
-
|
|
202
|
-
Manage trading positions.
|
|
203
|
-
|
|
204
|
-
```tsx
|
|
205
|
-
const {
|
|
206
|
-
createPosition, // (payload) => Promise<ApiResponse<CreatePositionResponseDto>>
|
|
207
|
-
updateRiskParameters, // (positionId, payload) => Promise<ApiResponse<UpdateRiskParametersResponseDto>>
|
|
208
|
-
closePosition, // (positionId, payload) => Promise<ApiResponse<ClosePositionResponseDto>>
|
|
209
|
-
closeAllPositions, // (payload) => Promise<ApiResponse<CloseAllPositionsResponseDto>>
|
|
210
|
-
adjustPosition, // (positionId, payload) => Promise<ApiResponse<AdjustPositionResponseDto>>
|
|
211
|
-
openPositions, // OpenPositionDto[] | null
|
|
212
|
-
isLoading, // boolean
|
|
213
|
-
} = usePosition();
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
**Example: Create a Position**
|
|
217
|
-
|
|
218
|
-
```tsx
|
|
219
|
-
const { createPosition } = usePosition();
|
|
220
|
-
|
|
221
|
-
const handleCreatePosition = async () => {
|
|
222
|
-
try {
|
|
223
|
-
const response = await createPosition({
|
|
224
|
-
leverage: 5,
|
|
225
|
-
usdValue: 1000,
|
|
226
|
-
longAssets: [{ asset: "ETH", weight: 1 }],
|
|
227
|
-
shortAssets: [{ asset: "BTC", weight: 1 }],
|
|
228
|
-
orderType: "MARKET",
|
|
229
|
-
});
|
|
230
|
-
console.log("Position created:", response.data);
|
|
231
|
-
} catch (error) {
|
|
232
|
-
console.error("Failed to create position:", error);
|
|
233
|
-
}
|
|
234
|
-
};
|
|
235
|
-
```
|
|
236
|
-
|
|
237
|
-
**Example: Close a Position**
|
|
238
|
-
|
|
239
|
-
```tsx
|
|
240
|
-
const { closePosition } = usePosition();
|
|
241
|
-
|
|
242
|
-
const handleClosePosition = async (positionId: string) => {
|
|
243
|
-
try {
|
|
244
|
-
const response = await closePosition(positionId, {
|
|
245
|
-
orderType: "MARKET",
|
|
246
|
-
});
|
|
247
|
-
console.log("Position closed:", response.data);
|
|
248
|
-
} catch (error) {
|
|
249
|
-
console.error("Failed to close position:", error);
|
|
250
|
-
}
|
|
251
|
-
};
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
#### Order Management
|
|
255
|
-
|
|
256
|
-
##### `useOrders()`
|
|
257
|
-
|
|
258
|
-
Manage orders (LIMIT, TP/SL, TWAP).
|
|
259
|
-
|
|
260
|
-
```tsx
|
|
261
|
-
const {
|
|
262
|
-
adjustOrder, // (orderId, payload) => Promise<ApiResponse<AdjustOrderResponseDto>>
|
|
263
|
-
cancelOrder, // (orderId) => Promise<ApiResponse<CancelOrderResponseDto>>
|
|
264
|
-
cancelTwapOrder, // (orderId) => Promise<ApiResponse<CancelTwapResponseDto>>
|
|
265
|
-
openOrders, // OpenLimitOrderDto[] | null
|
|
266
|
-
isLoading, // boolean
|
|
267
|
-
} = useOrders();
|
|
268
|
-
```
|
|
269
|
-
|
|
270
|
-
**Example: Cancel an Order**
|
|
271
|
-
|
|
272
|
-
```tsx
|
|
273
|
-
const { cancelOrder } = useOrders();
|
|
274
|
-
|
|
275
|
-
const handleCancelOrder = async (orderId: string) => {
|
|
276
|
-
try {
|
|
277
|
-
await cancelOrder(orderId);
|
|
278
|
-
console.log("Order cancelled successfully");
|
|
279
|
-
} catch (error) {
|
|
280
|
-
console.error("Failed to cancel order:", error);
|
|
281
|
-
}
|
|
282
|
-
};
|
|
283
|
-
```
|
|
284
|
-
|
|
285
|
-
#### Trading Data
|
|
286
|
-
|
|
287
|
-
##### `useTradeHistories()`
|
|
288
|
-
|
|
289
|
-
Access trade history data.
|
|
290
|
-
|
|
291
|
-
```tsx
|
|
292
|
-
const { data, isLoading } = useTradeHistories();
|
|
293
|
-
```
|
|
294
|
-
|
|
295
|
-
##### `useOpenOrders()`
|
|
296
|
-
|
|
297
|
-
Access open orders with loading state.
|
|
298
|
-
|
|
299
|
-
```tsx
|
|
300
|
-
const { data, isLoading } = useOpenOrders();
|
|
301
|
-
```
|
|
302
|
-
|
|
303
|
-
##### `useAccountSummary()`
|
|
304
|
-
|
|
305
|
-
Access account summary with real-time calculations.
|
|
306
|
-
|
|
307
|
-
```tsx
|
|
308
|
-
const { data, isLoading } = useAccountSummary();
|
|
309
|
-
// data: AccountSummaryResponseDto | null
|
|
310
|
-
```
|
|
311
|
-
|
|
312
|
-
#### Market Data
|
|
313
|
-
|
|
314
|
-
##### `useMarketData()`
|
|
315
|
-
|
|
316
|
-
Access real-time market data from Zustand store.
|
|
317
|
-
|
|
318
|
-
```tsx
|
|
319
|
-
import { useMarketData } from "@pear-protocol/hyperliquid-sdk";
|
|
320
|
-
|
|
321
|
-
function MarketDataComponent() {
|
|
322
|
-
const activeAssets = useMarketData((state) => state.activeAssets);
|
|
323
|
-
|
|
324
|
-
return (
|
|
325
|
-
<div>
|
|
326
|
-
{activeAssets?.active.map((asset, idx) => (
|
|
327
|
-
<div key={idx}>
|
|
328
|
-
Long: {asset.longAssets.map((a) => a.asset).join(", ")} vs Short:{" "}
|
|
329
|
-
{asset.shortAssets.map((a) => a.asset).join(", ")}
|
|
330
|
-
</div>
|
|
331
|
-
))}
|
|
332
|
-
</div>
|
|
333
|
-
);
|
|
334
|
-
}
|
|
335
|
-
```
|
|
336
|
-
|
|
337
|
-
##### `useHistoricalPriceData()`
|
|
338
|
-
|
|
339
|
-
Fetch and manage historical price data for tokens.
|
|
340
|
-
|
|
341
|
-
```tsx
|
|
342
|
-
import { useHistoricalPriceData } from "@pear-protocol/hyperliquid-sdk";
|
|
343
|
-
|
|
344
|
-
function ChartComponent() {
|
|
345
|
-
const { fetchHistoricalData, getTokenData } = useHistoricalPriceData();
|
|
346
|
-
|
|
347
|
-
useEffect(() => {
|
|
348
|
-
fetchHistoricalData("ETH", "1d"); // 1 day range
|
|
349
|
-
}, []);
|
|
350
|
-
|
|
351
|
-
const ethData = getTokenData("ETH");
|
|
352
|
-
}
|
|
353
|
-
```
|
|
354
|
-
|
|
355
|
-
##### `useBasketCandles()`
|
|
356
|
-
|
|
357
|
-
Get candle data for basket (multi-asset) positions.
|
|
358
|
-
|
|
359
|
-
```tsx
|
|
360
|
-
import { useBasketCandles } from "@pear-protocol/hyperliquid-sdk";
|
|
361
|
-
|
|
362
|
-
function BasketChartComponent() {
|
|
363
|
-
const { candles, isLoading, error } = useBasketCandles({
|
|
364
|
-
longAssets: [
|
|
365
|
-
{ symbol: "ETH", weight: 0.5 },
|
|
366
|
-
{ symbol: "BTC", weight: 0.5 },
|
|
367
|
-
],
|
|
368
|
-
shortAssets: [{ symbol: "SOL", weight: 1 }],
|
|
369
|
-
interval: "1h",
|
|
370
|
-
lookbackHours: 24,
|
|
371
|
-
});
|
|
372
|
-
}
|
|
373
|
-
```
|
|
374
|
-
|
|
375
|
-
##### `useTokenSelectionMetadata()`
|
|
376
|
-
|
|
377
|
-
Get metadata for selected tokens including prices, funding, and leverage info.
|
|
378
|
-
|
|
379
|
-
```tsx
|
|
380
|
-
import { useTokenSelectionMetadata } from "@pear-protocol/hyperliquid-sdk";
|
|
381
|
-
|
|
382
|
-
function TokenSelector() {
|
|
383
|
-
const { getMetadata, isLoading } = useTokenSelectionMetadata();
|
|
384
|
-
|
|
385
|
-
const ethMetadata = getMetadata("ETH");
|
|
386
|
-
// ethMetadata: { currentPrice, priceChange24hPercent, maxLeverage, ... }
|
|
387
|
-
}
|
|
388
|
-
```
|
|
389
|
-
|
|
390
|
-
#### WebSocket Hooks
|
|
391
|
-
|
|
392
|
-
##### `useHyperliquidWebSocket()`
|
|
393
|
-
|
|
394
|
-
Access Pear API WebSocket connection (managed by provider).
|
|
395
|
-
|
|
396
|
-
##### `useHyperliquidNativeWebSocket()`
|
|
397
|
-
|
|
398
|
-
Access HyperLiquid native WebSocket connection (managed by provider).
|
|
399
|
-
|
|
400
|
-
#### TWAP Orders
|
|
401
|
-
|
|
402
|
-
##### `useTwap()`
|
|
403
|
-
|
|
404
|
-
Access TWAP (Time-Weighted Average Price) order monitoring.
|
|
405
|
-
|
|
406
|
-
```tsx
|
|
407
|
-
import { useTwap } from "@pear-protocol/hyperliquid-sdk";
|
|
408
|
-
|
|
409
|
-
function TwapMonitor() {
|
|
410
|
-
const { twapOrders, isLoading } = useTwap();
|
|
411
|
-
|
|
412
|
-
return (
|
|
413
|
-
<div>
|
|
414
|
-
{twapOrders?.map((order) => (
|
|
415
|
-
<div key={order.orderId}>
|
|
416
|
-
Status: {order.status}
|
|
417
|
-
Progress: {(order.filledUsdValue / order.totalUsdValue) * 100}%
|
|
418
|
-
</div>
|
|
419
|
-
))}
|
|
420
|
-
</div>
|
|
421
|
-
);
|
|
422
|
-
}
|
|
423
|
-
```
|
|
424
|
-
|
|
425
|
-
#### Notifications
|
|
426
|
-
|
|
427
|
-
##### `useNotifications()`
|
|
428
|
-
|
|
429
|
-
Access user notifications.
|
|
430
|
-
|
|
431
|
-
```tsx
|
|
432
|
-
import { useNotifications } from "@pear-protocol/hyperliquid-sdk";
|
|
433
|
-
|
|
434
|
-
function NotificationCenter() {
|
|
435
|
-
const { notifications, isLoading, markAsRead, markAllAsRead } =
|
|
436
|
-
useNotifications();
|
|
437
|
-
|
|
438
|
-
return (
|
|
439
|
-
<div>
|
|
440
|
-
{notifications?.map((notif) => (
|
|
441
|
-
<div key={notif.id} onClick={() => markAsRead(notif.id)}>
|
|
442
|
-
{notif.category}: {JSON.stringify(notif.parameters)}
|
|
443
|
-
</div>
|
|
444
|
-
))}
|
|
445
|
-
</div>
|
|
446
|
-
);
|
|
447
|
-
}
|
|
448
|
-
```
|
|
449
|
-
|
|
450
|
-
### Utility Classes
|
|
451
|
-
|
|
452
|
-
#### `AccountSummaryCalculator`
|
|
453
|
-
|
|
454
|
-
Calculate account summary with real-time data.
|
|
455
|
-
|
|
456
|
-
```tsx
|
|
457
|
-
import { AccountSummaryCalculator } from "@pear-protocol/hyperliquid-sdk";
|
|
458
|
-
|
|
459
|
-
const calculator = new AccountSummaryCalculator(webData2);
|
|
460
|
-
const summary = calculator.calculateAccountSummary(
|
|
461
|
-
accountSummary,
|
|
462
|
-
openOrders,
|
|
463
|
-
agentWalletAddress,
|
|
464
|
-
agentWalletStatus
|
|
465
|
-
);
|
|
466
|
-
```
|
|
467
|
-
|
|
468
|
-
#### `ConflictDetector`
|
|
469
|
-
|
|
470
|
-
Detect position conflicts for new trades.
|
|
471
|
-
|
|
472
|
-
```tsx
|
|
473
|
-
import { ConflictDetector } from "@pear-protocol/hyperliquid-sdk";
|
|
474
|
-
|
|
475
|
-
const conflicts = ConflictDetector.detectConflicts(
|
|
476
|
-
longTokens,
|
|
477
|
-
shortTokens,
|
|
478
|
-
existingPositions
|
|
479
|
-
);
|
|
480
|
-
```
|
|
481
|
-
|
|
482
|
-
#### `TokenMetadataExtractor`
|
|
483
|
-
|
|
484
|
-
Extract token metadata from WebSocket data.
|
|
485
|
-
|
|
486
|
-
```tsx
|
|
487
|
-
import { TokenMetadataExtractor } from "@pear-protocol/hyperliquid-sdk";
|
|
488
|
-
|
|
489
|
-
const metadata = TokenMetadataExtractor.extractMetadata(
|
|
490
|
-
"ETH",
|
|
491
|
-
webData2,
|
|
492
|
-
allMids,
|
|
493
|
-
activeAssetData
|
|
494
|
-
);
|
|
495
|
-
```
|
|
496
|
-
|
|
497
|
-
### Direct API Clients
|
|
498
|
-
|
|
499
|
-
For advanced use cases, you can import and use API clients directly:
|
|
500
|
-
|
|
501
|
-
```tsx
|
|
502
|
-
import {
|
|
503
|
-
createPosition,
|
|
504
|
-
updateRiskParameters,
|
|
505
|
-
closePosition,
|
|
506
|
-
adjustOrder,
|
|
507
|
-
cancelOrder,
|
|
508
|
-
} from "@pear-protocol/hyperliquid-sdk";
|
|
509
|
-
|
|
510
|
-
// All client functions require baseUrl and accessToken
|
|
511
|
-
const response = await createPosition(baseUrl, accessToken, {
|
|
512
|
-
leverage: 5,
|
|
513
|
-
usdValue: 1000,
|
|
514
|
-
longAssets: [{ asset: "ETH", weight: 1 }],
|
|
515
|
-
shortAssets: [{ asset: "BTC", weight: 1 }],
|
|
516
|
-
orderType: "MARKET",
|
|
517
|
-
});
|
|
518
|
-
```
|
|
519
|
-
|
|
520
|
-
## TypeScript Support
|
|
521
|
-
|
|
522
|
-
The SDK is written in TypeScript and provides comprehensive type definitions. All hooks, functions, and data structures are fully typed.
|
|
523
|
-
|
|
524
|
-
```tsx
|
|
525
|
-
import type {
|
|
526
|
-
OpenPositionDto,
|
|
527
|
-
OpenLimitOrderDto,
|
|
528
|
-
TradeHistoryDataDto,
|
|
529
|
-
AccountSummaryResponseDto,
|
|
530
|
-
WebSocketChannel,
|
|
531
|
-
CandleInterval,
|
|
532
|
-
TokenMetadata,
|
|
533
|
-
// ... and many more
|
|
534
|
-
} from "@pear-protocol/hyperliquid-sdk";
|
|
535
|
-
```
|
|
536
|
-
|
|
537
|
-
## WebSocket Data Flow
|
|
538
|
-
|
|
539
|
-
The SDK manages two WebSocket connections:
|
|
540
|
-
|
|
541
|
-
1. **Pear API WebSocket** - User-specific data (positions, orders, trade history, account summary)
|
|
542
|
-
2. **HyperLiquid Native WebSocket** - Market data (prices, asset info, candles)
|
|
543
|
-
|
|
544
|
-
Data is automatically stored in Zustand stores and accessible via hooks:
|
|
545
|
-
|
|
546
|
-
- `useUserData` store - User positions, orders, and account data
|
|
547
|
-
- `useHyperliquidData` store - Market data (webData2, allMids, activeAssetData)
|
|
548
|
-
- `useHistoricalPriceDataStore` - Historical price data
|
|
549
|
-
- `useMarketData` store - Active assets and market overview
|
|
550
|
-
|
|
551
|
-
## Error Handling
|
|
552
|
-
|
|
553
|
-
All API functions return promises and throw errors on failure. Always wrap API calls in try-catch blocks:
|
|
554
|
-
|
|
555
|
-
```tsx
|
|
556
|
-
try {
|
|
557
|
-
await createPosition(payload);
|
|
558
|
-
} catch (error) {
|
|
559
|
-
if (error instanceof Error) {
|
|
560
|
-
console.error("Error:", error.message);
|
|
561
|
-
}
|
|
562
|
-
}
|
|
563
|
-
```
|
|
564
|
-
|
|
565
|
-
## Environment Variables
|
|
566
|
-
|
|
567
|
-
When using the SDK, you may want to configure different environments:
|
|
568
|
-
|
|
569
|
-
```tsx
|
|
570
|
-
// Production
|
|
571
|
-
<PearHyperliquidProvider
|
|
572
|
-
apiBaseUrl="https://hl-v2.pearprotocol.io"
|
|
573
|
-
wsUrl="wss://hl-v2.pearprotocol.io/ws"
|
|
574
|
-
/>
|
|
575
|
-
|
|
576
|
-
// Beta
|
|
577
|
-
<PearHyperliquidProvider
|
|
578
|
-
apiBaseUrl="https://hl-v2-beta.pearprotocol.io"
|
|
579
|
-
wsUrl="wss://hl-v2-beta.pearprotocol.io/ws"
|
|
580
|
-
/>
|
|
581
|
-
```
|
|
582
|
-
|
|
583
|
-
## Examples
|
|
584
|
-
|
|
585
|
-
### Complete Trading Component
|
|
586
|
-
|
|
587
|
-
```tsx
|
|
588
|
-
import { useState } from "react";
|
|
589
|
-
import {
|
|
590
|
-
usePearAuth,
|
|
591
|
-
usePearHyperliquid,
|
|
592
|
-
usePosition,
|
|
593
|
-
useOrders,
|
|
594
|
-
useAccountSummary,
|
|
595
|
-
} from "@pear-protocol/hyperliquid-sdk";
|
|
596
|
-
|
|
597
|
-
function TradingDashboard() {
|
|
598
|
-
const { address, setAddress, isConnected } = usePearHyperliquid();
|
|
599
|
-
const { isAuthenticated, loginWithSignedMessage } = usePearAuth();
|
|
600
|
-
const { openPositions, createPosition, closePosition } = usePosition();
|
|
601
|
-
const { openOrders, cancelOrder } = useOrders();
|
|
602
|
-
const { data: accountSummary } = useAccountSummary();
|
|
603
|
-
|
|
604
|
-
const handleCreatePosition = async () => {
|
|
605
|
-
try {
|
|
606
|
-
await createPosition({
|
|
607
|
-
leverage: 3,
|
|
608
|
-
usdValue: 500,
|
|
609
|
-
longAssets: [{ asset: "ETH", weight: 1 }],
|
|
610
|
-
shortAssets: [{ asset: "BTC", weight: 1 }],
|
|
611
|
-
orderType: "MARKET",
|
|
612
|
-
});
|
|
613
|
-
} catch (error) {
|
|
614
|
-
console.error("Failed to create position:", error);
|
|
615
|
-
}
|
|
616
|
-
};
|
|
617
|
-
|
|
618
|
-
return (
|
|
619
|
-
<div>
|
|
620
|
-
<h1>Trading Dashboard</h1>
|
|
621
|
-
|
|
622
|
-
<div>
|
|
623
|
-
<h2>Account</h2>
|
|
624
|
-
<p>Address: {address || "Not connected"}</p>
|
|
625
|
-
<p>Status: {isAuthenticated ? "Authenticated" : "Not authenticated"}</p>
|
|
626
|
-
<p>WebSocket: {isConnected ? "Connected" : "Disconnected"}</p>
|
|
627
|
-
</div>
|
|
628
|
-
|
|
629
|
-
<div>
|
|
630
|
-
<h2>Account Summary</h2>
|
|
631
|
-
<p>
|
|
632
|
-
Account Value: $
|
|
633
|
-
{accountSummary?.balanceSummary.marginSummary.accountValue}
|
|
634
|
-
</p>
|
|
635
|
-
<p>Withdrawable: ${accountSummary?.balanceSummary.withdrawable}</p>
|
|
636
|
-
</div>
|
|
637
|
-
|
|
638
|
-
<div>
|
|
639
|
-
<h2>Open Positions</h2>
|
|
640
|
-
{openPositions?.map((pos) => (
|
|
641
|
-
<div key={pos.positionId}>
|
|
642
|
-
<p>PNL: ${pos.unrealizedPnl.toFixed(2)}</p>
|
|
643
|
-
<p>Value: ${pos.positionValue.toFixed(2)}</p>
|
|
644
|
-
<button
|
|
645
|
-
onClick={() =>
|
|
646
|
-
closePosition(pos.positionId, { orderType: "MARKET" })
|
|
647
|
-
}
|
|
648
|
-
>
|
|
649
|
-
Close
|
|
650
|
-
</button>
|
|
651
|
-
</div>
|
|
652
|
-
))}
|
|
653
|
-
</div>
|
|
654
|
-
|
|
655
|
-
<div>
|
|
656
|
-
<h2>Open Orders</h2>
|
|
657
|
-
{openOrders?.map((order) => (
|
|
658
|
-
<div key={order.orderId}>
|
|
659
|
-
<p>Type: {order.orderType}</p>
|
|
660
|
-
<p>Value: ${order.usdValue}</p>
|
|
661
|
-
<button onClick={() => cancelOrder(order.orderId)}>Cancel</button>
|
|
662
|
-
</div>
|
|
663
|
-
))}
|
|
664
|
-
</div>
|
|
665
|
-
|
|
666
|
-
<button onClick={handleCreatePosition}>Create New Position</button>
|
|
667
|
-
</div>
|
|
668
|
-
);
|
|
669
|
-
}
|
|
670
|
-
|
|
671
|
-
export default TradingDashboard;
|
|
672
|
-
```
|
|
673
|
-
|
|
674
|
-
### Market Data Component
|
|
675
|
-
|
|
676
|
-
```tsx
|
|
677
|
-
import {
|
|
678
|
-
useMarketData,
|
|
679
|
-
useTokenSelectionMetadata,
|
|
680
|
-
useHyperliquidWebSocket,
|
|
681
|
-
} from "@pear-protocol/hyperliquid-sdk";
|
|
682
|
-
|
|
683
|
-
function MarketOverview() {
|
|
684
|
-
const activeAssets = useMarketData((state) => state.activeAssets);
|
|
685
|
-
const { getMetadata } = useTokenSelectionMetadata();
|
|
686
|
-
|
|
687
|
-
return (
|
|
688
|
-
<div>
|
|
689
|
-
<h2>Top Gainers</h2>
|
|
690
|
-
{activeAssets?.topGainers.slice(0, 5).map((asset, idx) => {
|
|
691
|
-
const longAsset = asset.longAssets[0]?.asset;
|
|
692
|
-
const metadata = longAsset ? getMetadata(longAsset) : null;
|
|
693
|
-
|
|
694
|
-
return (
|
|
695
|
-
<div key={idx}>
|
|
696
|
-
<p>
|
|
697
|
-
{longAsset}: {metadata?.priceChange24hPercent.toFixed(2)}%
|
|
698
|
-
</p>
|
|
699
|
-
</div>
|
|
700
|
-
);
|
|
701
|
-
})}
|
|
702
|
-
|
|
703
|
-
<h2>Top Losers</h2>
|
|
704
|
-
{activeAssets?.topLosers.slice(0, 5).map((asset, idx) => {
|
|
705
|
-
const shortAsset = asset.shortAssets[0]?.asset;
|
|
706
|
-
const metadata = shortAsset ? getMetadata(shortAsset) : null;
|
|
707
|
-
|
|
708
|
-
return (
|
|
709
|
-
<div key={idx}>
|
|
710
|
-
<p>
|
|
711
|
-
{shortAsset}: {metadata?.priceChange24hPercent.toFixed(2)}%
|
|
712
|
-
</p>
|
|
713
|
-
</div>
|
|
714
|
-
);
|
|
715
|
-
})}
|
|
716
|
-
</div>
|
|
717
|
-
);
|
|
718
|
-
}
|
|
719
|
-
```
|
|
720
|
-
|
|
721
|
-
## License
|
|
722
|
-
|
|
723
|
-
MIT
|
|
724
|
-
|
|
725
|
-
## Repository
|
|
726
|
-
|
|
727
|
-
GitHub: [https://github.com/pear-protocol/hyperliquid](https://github.com/pear-protocol/hyperliquid/tree/main/pear-hyperliquid-sdk)
|
|
728
|
-
|
|
729
|
-
## Support
|
|
730
|
-
|
|
731
|
-
For issues and questions, please visit the [GitHub Issues](https://github.com/pear-protocol/hyperliquid/issues) page.
|
|
732
|
-
|
|
733
|
-
## Contributing
|
|
734
|
-
|
|
735
|
-
Contributions are welcome! Please feel free to submit a Pull Request.
|