@pear-protocol/hyperliquid-sdk 0.0.49 → 0.0.50

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/index.js CHANGED
@@ -26,6 +26,7 @@ const useUserData = create((set) => ({
26
26
  accountSummary: null,
27
27
  twapDetails: null,
28
28
  notifications: null,
29
+ userExtraAgents: null,
29
30
  setTradeHistories: (value) => set({ tradeHistories: value }),
30
31
  setRawOpenPositions: (value) => set({ rawOpenPositions: value }),
31
32
  setOpenOrders: (value) => set({ openOrders: value }),
@@ -40,6 +41,7 @@ const useUserData = create((set) => ({
40
41
  twapDetails: null,
41
42
  notifications: null,
42
43
  }),
44
+ setUserExtraAgents: (value) => set({ userExtraAgents: value }),
43
45
  }));
44
46
 
45
47
  const useMarketData = create((set) => ({
@@ -50,9 +52,28 @@ const useMarketData = create((set) => ({
50
52
  clean: () => set({ marketData: null, marketDataAll: null }),
51
53
  }));
52
54
 
53
- const useHyperliquidWebSocket = ({ wsUrl, address }) => {
55
+ // Utilities for translating between display symbols and backend (prefixed) symbols
56
+ /**
57
+ * Convert a full/prefixed symbol (e.g., "xyz:XYZ100") to a display symbol (e.g., "XYZ100").
58
+ */
59
+ function toDisplaySymbol(symbol) {
60
+ const parts = symbol.split(":");
61
+ return parts.length > 1 ? parts.slice(-1)[0] : symbol;
62
+ }
63
+ /**
64
+ * Convert a display symbol back to backend form using a provided map.
65
+ * If mapping is missing, returns the original symbol.
66
+ * @param displaySymbol e.g., "XYZ100"
67
+ * @param displayToFull map of display -> full (e.g., "XYZ100" -> "xyz:XYZ100")
68
+ */
69
+ function toBackendSymbol(displaySymbol, displayToFull) {
70
+ var _a;
71
+ return (_a = displayToFull.get(displaySymbol)) !== null && _a !== void 0 ? _a : displaySymbol;
72
+ }
73
+
74
+ const useHyperliquidWebSocket = ({ wsUrl, address, enabled = true, }) => {
54
75
  const { setTradeHistories, setRawOpenPositions, setOpenOrders, setAccountSummary, setTwapDetails, setNotifications, clean, } = useUserData();
55
- const { setMarketData, setMarketDataAll } = useMarketData();
76
+ const { setMarketData } = useMarketData();
56
77
  const [lastError, setLastError] = useState(null);
57
78
  const [lastSubscribedAddress, setLastSubscribedAddress] = useState(null);
58
79
  // Native WebSocket connection with basic reconnection
@@ -82,30 +103,69 @@ const useHyperliquidWebSocket = ({ wsUrl, address }) => {
82
103
  }
83
104
  switch (dataMessage.channel) {
84
105
  case 'trade-histories':
85
- setTradeHistories(dataMessage.data);
106
+ {
107
+ const list = dataMessage.data.map((item) => ({
108
+ ...item,
109
+ longAssets: item.longAssets.map((a) => ({ ...a, coin: toDisplaySymbol(a.coin) })),
110
+ shortAssets: item.shortAssets.map((a) => ({ ...a, coin: toDisplaySymbol(a.coin) })),
111
+ }));
112
+ setTradeHistories(list);
113
+ }
86
114
  break;
87
115
  case 'open-positions':
88
- setRawOpenPositions(dataMessage.data);
116
+ {
117
+ const list = dataMessage.data.map((pos) => ({
118
+ ...pos,
119
+ longAssets: pos.longAssets.map((a) => ({ ...a, coin: toDisplaySymbol(a.coin) })),
120
+ shortAssets: pos.shortAssets.map((a) => ({ ...a, coin: toDisplaySymbol(a.coin) })),
121
+ }));
122
+ setRawOpenPositions(list);
123
+ }
89
124
  break;
90
125
  case 'open-orders':
91
- setOpenOrders(dataMessage.data);
126
+ {
127
+ const list = dataMessage.data.map((order) => ({
128
+ ...order,
129
+ longAssets: order.longAssets.map((a) => ({ ...a, asset: toDisplaySymbol(a.asset) })),
130
+ shortAssets: order.shortAssets.map((a) => ({ ...a, asset: toDisplaySymbol(a.asset) })),
131
+ }));
132
+ setOpenOrders(list);
133
+ }
92
134
  break;
93
135
  case 'account-summary':
94
136
  setAccountSummary(dataMessage.data);
95
137
  break;
96
138
  case 'twap-details':
97
- setTwapDetails(dataMessage.data);
139
+ {
140
+ const list = dataMessage.data.map((twap) => ({
141
+ ...twap,
142
+ longAssets: twap.longAssets.map((a) => ({ ...a, asset: toDisplaySymbol(a.asset) })),
143
+ shortAssets: twap.shortAssets.map((a) => ({ ...a, asset: toDisplaySymbol(a.asset) })),
144
+ }));
145
+ setTwapDetails(list);
146
+ }
98
147
  break;
99
148
  case 'notifications':
100
149
  setNotifications(dataMessage.data);
101
150
  break;
102
151
  case 'market-data':
103
- setMarketData(dataMessage.data);
104
- break;
105
- case 'market-data-all':
106
- setMarketDataAll(dataMessage.data);
152
+ {
153
+ const md = dataMessage.data;
154
+ const mapGroup = (g) => ({
155
+ ...g,
156
+ longAssets: g.longAssets.map((a) => ({ ...a, asset: toDisplaySymbol(a.asset) })),
157
+ shortAssets: g.shortAssets.map((a) => ({ ...a, asset: toDisplaySymbol(a.asset) })),
158
+ });
159
+ const mapped = {
160
+ active: md.active.map(mapGroup),
161
+ topGainers: md.topGainers.map(mapGroup),
162
+ topLosers: md.topLosers.map(mapGroup),
163
+ highlighted: md.highlighted.map(mapGroup),
164
+ watchlist: md.watchlist.map(mapGroup),
165
+ };
166
+ setMarketData(mapped);
167
+ }
107
168
  break;
108
- // 'fills-checkpoint' is intentionally ignored here
109
169
  }
110
170
  }
111
171
  }
@@ -114,9 +174,15 @@ const useHyperliquidWebSocket = ({ wsUrl, address }) => {
114
174
  }
115
175
  }, [setTradeHistories, setRawOpenPositions, setOpenOrders, setAccountSummary, setTwapDetails, setNotifications, setMarketData]);
116
176
  const connect = useCallback(() => {
117
- if (!wsUrl)
177
+ if (!enabled || !wsUrl)
118
178
  return;
119
179
  try {
180
+ // Avoid opening multiple sockets if one is already active or connecting
181
+ if (wsRef.current &&
182
+ (wsRef.current.readyState === WebSocket.OPEN ||
183
+ wsRef.current.readyState === WebSocket.CONNECTING)) {
184
+ return;
185
+ }
120
186
  manualCloseRef.current = false;
121
187
  setReadyState(ReadyState.CONNECTING);
122
188
  const ws = new WebSocket(wsUrl);
@@ -141,7 +207,7 @@ const useHyperliquidWebSocket = ({ wsUrl, address }) => {
141
207
  catch (e) {
142
208
  setLastError(`WebSocket connection failed: ${e instanceof Error ? e.message : String(e)}`);
143
209
  }
144
- }, [wsUrl, handleMessage]);
210
+ }, [wsUrl, handleMessage, enabled]);
145
211
  useEffect(() => {
146
212
  connect();
147
213
  return () => {
@@ -175,7 +241,7 @@ const useHyperliquidWebSocket = ({ wsUrl, address }) => {
175
241
  'fills-checkpoint',
176
242
  'notifications'
177
243
  ];
178
- const globalChannels = ['market-data', 'market-data-all'];
244
+ const globalChannels = ['market-data'];
179
245
  if (address && address !== lastSubscribedAddress) {
180
246
  // Unsubscribe from previous address-specific channels if exists
181
247
  if (lastSubscribedAddress) {
@@ -225,11 +291,14 @@ const useHyperliquidWebSocket = ({ wsUrl, address }) => {
225
291
  };
226
292
 
227
293
  const useHyperliquidData = create((set, get) => ({
228
- webData2: null,
229
294
  allMids: null,
230
295
  activeAssetData: null,
231
296
  candleData: null,
232
- setWebData2: (value) => set({ webData2: value }),
297
+ finalAssetContexts: null,
298
+ finalAtOICaps: null,
299
+ aggregatedClearingHouseState: null,
300
+ perpMetaAssets: null,
301
+ hip3DisplayToFull: new Map(),
233
302
  setAllMids: (value) => set({ allMids: value }),
234
303
  setActiveAssetData: (value) => set((state) => ({
235
304
  activeAssetData: typeof value === 'function' ? value(state.activeAssetData) : value
@@ -268,7 +337,12 @@ const useHyperliquidData = create((set, get) => ({
268
337
  ...state.activeAssetData,
269
338
  [key]: value,
270
339
  }
271
- }))
340
+ })),
341
+ setFinalAssetContexts: (value) => set({ finalAssetContexts: value }),
342
+ setFinalAtOICaps: (value) => set({ finalAtOICaps: value }),
343
+ setAggregatedClearingHouseState: (value) => set({ aggregatedClearingHouseState: value }),
344
+ setPerpMetaAssets: (value) => set({ perpMetaAssets: value }),
345
+ setHip3DisplayToFull: (value) => set({ hip3DisplayToFull: value })
272
346
  }));
273
347
 
274
348
  const DEFAULT_STATE = {
@@ -408,8 +482,8 @@ const useUserSelection$1 = create((set, get) => ({
408
482
  resetToDefaults: () => set((prev) => ({ ...prev, ...DEFAULT_STATE })),
409
483
  }));
410
484
 
411
- const useHyperliquidNativeWebSocket = ({ address, }) => {
412
- const { setWebData2, setAllMids, setActiveAssetData, upsertActiveAssetData, setCandleData, deleteCandleSymbol, deleteActiveAssetData, addCandleData } = useHyperliquidData();
485
+ const useHyperliquidNativeWebSocket = ({ address, enabled = true, }) => {
486
+ const { setAllMids, setActiveAssetData, upsertActiveAssetData, setCandleData, deleteCandleSymbol, deleteActiveAssetData, addCandleData, setFinalAssetContexts, setFinalAtOICaps, setAggregatedClearingHouseState } = useHyperliquidData();
413
487
  const { candleInterval } = useUserSelection$1();
414
488
  const longTokens = useUserSelection$1((s) => s.longTokens);
415
489
  const shortTokens = useUserSelection$1((s) => s.shortTokens);
@@ -442,19 +516,69 @@ const useHyperliquidNativeWebSocket = ({ address, }) => {
442
516
  if ('channel' in message && 'data' in message) {
443
517
  const response = message;
444
518
  switch (response.channel) {
445
- case 'webData2':
446
- setWebData2(response.data);
519
+ case 'webData3':
520
+ const webData3 = response.data;
521
+ const finalAssetContexts = webData3.perpDexStates.flatMap((dex) => dex.assetCtxs);
522
+ const finalAtOICaps = webData3.perpDexStates.flatMap((dex) => dex.perpsAtOpenInterestCap);
523
+ const aggregatedClearingHouseState = (() => {
524
+ const states = webData3.perpDexStates
525
+ .map((dex) => dex.clearinghouseState)
526
+ .filter(Boolean);
527
+ const sum = (values) => values.reduce((acc, v) => acc + (parseFloat(v || '0') || 0), 0);
528
+ const toStr = (n) => (Number.isFinite(n) ? n.toString() : '0');
529
+ const assetPositions = states.flatMap((s) => s.assetPositions || []);
530
+ const crossMaintenanceMarginUsed = toStr(sum(states.map((s) => s.crossMaintenanceMarginUsed)));
531
+ const crossMarginSummary = {
532
+ accountValue: toStr(sum(states.map((s) => { var _a; return (_a = s.crossMarginSummary) === null || _a === void 0 ? void 0 : _a.accountValue; }))),
533
+ totalMarginUsed: toStr(sum(states.map((s) => { var _a; return (_a = s.crossMarginSummary) === null || _a === void 0 ? void 0 : _a.totalMarginUsed; }))),
534
+ totalNtlPos: toStr(sum(states.map((s) => { var _a; return (_a = s.crossMarginSummary) === null || _a === void 0 ? void 0 : _a.totalNtlPos; }))),
535
+ totalRawUsd: toStr(sum(states.map((s) => { var _a; return (_a = s.crossMarginSummary) === null || _a === void 0 ? void 0 : _a.totalRawUsd; }))),
536
+ };
537
+ const marginSummary = {
538
+ accountValue: toStr(sum(states.map((s) => { var _a; return (_a = s.marginSummary) === null || _a === void 0 ? void 0 : _a.accountValue; }))),
539
+ totalMarginUsed: toStr(sum(states.map((s) => { var _a; return (_a = s.marginSummary) === null || _a === void 0 ? void 0 : _a.totalMarginUsed; }))),
540
+ totalNtlPos: toStr(sum(states.map((s) => { var _a; return (_a = s.marginSummary) === null || _a === void 0 ? void 0 : _a.totalNtlPos; }))),
541
+ totalRawUsd: toStr(sum(states.map((s) => { var _a; return (_a = s.marginSummary) === null || _a === void 0 ? void 0 : _a.totalRawUsd; }))),
542
+ };
543
+ const withdrawable = toStr(sum(states.map((s) => s.withdrawable)));
544
+ const time = Math.max(0, ...states.map((s) => s.time || 0));
545
+ return {
546
+ assetPositions,
547
+ crossMaintenanceMarginUsed,
548
+ crossMarginSummary,
549
+ marginSummary,
550
+ time,
551
+ withdrawable,
552
+ };
553
+ })();
554
+ setFinalAssetContexts(finalAssetContexts);
555
+ setFinalAtOICaps(finalAtOICaps);
556
+ setAggregatedClearingHouseState(aggregatedClearingHouseState);
447
557
  break;
448
558
  case 'allMids':
449
- setAllMids(response.data);
559
+ {
560
+ const data = response.data;
561
+ const remapped = {
562
+ mids: Object.fromEntries(Object.entries(data.mids || {}).map(([k, v]) => [toDisplaySymbol(k), v]))
563
+ };
564
+ setAllMids(remapped);
565
+ }
450
566
  break;
451
567
  case 'activeAssetData':
452
- const assetData = response.data;
453
- upsertActiveAssetData(assetData.coin, assetData);
568
+ {
569
+ const assetData = response.data;
570
+ const symbol = toDisplaySymbol(assetData.coin);
571
+ const normalized = { ...assetData, coin: symbol };
572
+ upsertActiveAssetData(symbol, normalized);
573
+ }
454
574
  break;
455
575
  case 'candle':
456
- const candleDataItem = response.data;
457
- addCandleData(candleDataItem.s, candleDataItem);
576
+ {
577
+ const candleDataItem = response.data;
578
+ const symbol = toDisplaySymbol(candleDataItem.s || '');
579
+ const normalized = { ...candleDataItem, s: symbol };
580
+ addCandleData(symbol, normalized);
581
+ }
458
582
  break;
459
583
  default:
460
584
  console.warn(`[HyperLiquid WS] Unknown channel: ${response.channel}`);
@@ -466,9 +590,17 @@ const useHyperliquidNativeWebSocket = ({ address, }) => {
466
590
  console.error('[HyperLiquid WS] Parse error:', errorMessage, 'Raw message:', event.data);
467
591
  setLastError(errorMessage);
468
592
  }
469
- }, [setWebData2, setAllMids, upsertActiveAssetData, addCandleData]);
593
+ }, [setAllMids, upsertActiveAssetData, addCandleData, setFinalAssetContexts, setFinalAtOICaps, setAggregatedClearingHouseState]);
470
594
  const connect = useCallback(() => {
595
+ if (!enabled)
596
+ return;
471
597
  try {
598
+ // Avoid opening multiple sockets if one is already active or connecting
599
+ if (wsRef.current &&
600
+ (wsRef.current.readyState === WebSocket.OPEN ||
601
+ wsRef.current.readyState === WebSocket.CONNECTING)) {
602
+ return;
603
+ }
472
604
  manualCloseRef.current = false;
473
605
  setReadyState(ReadyState.CONNECTING);
474
606
  const ws = new WebSocket('wss://api.hyperliquid.xyz/ws');
@@ -497,7 +629,7 @@ const useHyperliquidNativeWebSocket = ({ address, }) => {
497
629
  catch (e) {
498
630
  setLastError(`WebSocket connection failed: ${e instanceof Error ? e.message : String(e)}`);
499
631
  }
500
- }, [handleMessage]);
632
+ }, [handleMessage, enabled]);
501
633
  useEffect(() => {
502
634
  connect();
503
635
  return () => {
@@ -551,17 +683,17 @@ const useHyperliquidNativeWebSocket = ({ address, }) => {
551
683
  const unsubscribeMessage = {
552
684
  method: 'unsubscribe',
553
685
  subscription: {
554
- type: 'webData2',
686
+ type: 'webData3',
555
687
  user: subscribedAddress,
556
688
  },
557
689
  };
558
690
  sendJsonMessage(unsubscribeMessage);
559
691
  }
560
- // Subscribe to webData2 with new address
561
- const subscribeWebData2 = {
692
+ // Subscribe to webData3 with new address
693
+ const subscribeWebData3 = {
562
694
  method: 'subscribe',
563
695
  subscription: {
564
- type: 'webData2',
696
+ type: 'webData3',
565
697
  user: userAddress,
566
698
  },
567
699
  };
@@ -570,16 +702,18 @@ const useHyperliquidNativeWebSocket = ({ address, }) => {
570
702
  method: 'subscribe',
571
703
  subscription: {
572
704
  type: 'allMids',
705
+ dex: 'ALL_DEXS',
573
706
  },
574
707
  };
575
- sendJsonMessage(subscribeWebData2);
708
+ sendJsonMessage(subscribeWebData3);
576
709
  sendJsonMessage(subscribeAllMids);
577
710
  setSubscribedAddress(userAddress);
578
711
  // Clear previous data when address changes
579
712
  if (subscribedAddress && subscribedAddress !== userAddress) {
580
- setWebData2(null);
713
+ // clear aggregatedClearingHouseState
714
+ setAggregatedClearingHouseState(null);
581
715
  }
582
- }, [isConnected, address, subscribedAddress, sendJsonMessage, setWebData2]);
716
+ }, [isConnected, address, subscribedAddress, sendJsonMessage, setAggregatedClearingHouseState]);
583
717
  // Handle token subscriptions for activeAssetData
584
718
  useEffect(() => {
585
719
  if (!isConnected || !address)
@@ -4590,196 +4724,79 @@ async function logout(baseUrl, refreshTokenVal) {
4590
4724
  }
4591
4725
  }
4592
4726
 
4593
- async function getAgentWallet(baseUrl, accessToken) {
4594
- const url = joinUrl(baseUrl, '/agentWallet');
4595
- try {
4596
- const resp = await axios$1.get(url, { headers: { Authorization: `Bearer ${accessToken}` }, timeout: 30000 });
4597
- return { data: resp.data, status: resp.status, headers: resp.headers };
4598
- }
4599
- catch (error) {
4600
- throw toApiError(error);
4601
- }
4602
- }
4603
- async function createAgentWallet(baseUrl, accessToken) {
4604
- const url = joinUrl(baseUrl, '/agentWallet');
4605
- try {
4606
- const resp = await axios$1.post(url, undefined, { headers: { Authorization: `Bearer ${accessToken}` }, timeout: 30000 });
4607
- return { data: resp.data, status: resp.status, headers: resp.headers };
4608
- }
4609
- catch (error) {
4610
- throw toApiError(error);
4611
- }
4612
- }
4613
-
4614
- function useAgentWallet({ baseUrl }) {
4615
- var _a, _b, _c;
4616
- const accountSummary = useUserData((state) => state.accountSummary);
4617
- const setAccountSummary = useUserData((state) => state.setAccountSummary);
4618
- const agentWallet = {
4619
- address: ((_a = accountSummary === null || accountSummary === void 0 ? void 0 : accountSummary.agentWallet) === null || _a === void 0 ? void 0 : _a.address) || null,
4620
- name: 'Pear Protocol',
4621
- status: ((_b = accountSummary === null || accountSummary === void 0 ? void 0 : accountSummary.agentWallet) === null || _b === void 0 ? void 0 : _b.status) || null,
4622
- isActive: ((_c = accountSummary === null || accountSummary === void 0 ? void 0 : accountSummary.agentWallet) === null || _c === void 0 ? void 0 : _c.status) === 'ACTIVE',
4623
- };
4624
- // Derive loading/error locally for now
4625
- let error = null;
4626
- let loading = false;
4627
- const getAuthHeader = () => {
4628
- const token = localStorage.getItem('accessToken');
4629
- if (!token)
4630
- throw new Error('Not authenticated');
4631
- return token;
4632
- };
4633
- const refreshAgentWalletStatus = useCallback(async () => {
4634
- loading = true;
4635
- error = null;
4636
- try {
4637
- const token = getAuthHeader();
4638
- const { data } = await getAgentWallet(baseUrl, token);
4639
- // Update store account summary's agentWallet
4640
- const current = useUserData.getState().accountSummary;
4641
- const updated = current
4642
- ? { ...current, agentWallet: { address: data.agentWalletAddress || '', status: data.status } }
4643
- : { balanceSummary: { crossMaintenanceMarginUsed: '0', crossMarginSummary: { accountValue: '0', totalMarginUsed: '0', totalNtlPos: '0', totalRawUsd: '0' }, marginSummary: { accountValue: '0', totalMarginUsed: '0', totalNtlPos: '0', totalRawUsd: '0' }, time: Date.now(), withdrawable: '0' }, agentWallet: { address: data.agentWalletAddress || '', status: data.status } };
4644
- setAccountSummary(updated);
4645
- return data;
4646
- }
4647
- catch (e) {
4648
- error = (e === null || e === void 0 ? void 0 : e.message) || 'Failed to fetch agent wallet';
4649
- throw e;
4650
- }
4651
- finally {
4652
- loading = false;
4653
- }
4654
- }, [baseUrl]);
4655
- const createAgentWallet$1 = useCallback(async () => {
4656
- loading = true;
4657
- error = null;
4658
- try {
4659
- const token = getAuthHeader();
4660
- const { data } = await createAgentWallet(baseUrl, token);
4661
- // Update store account summary's agentWallet to reflect newly created address
4662
- const current = useUserData.getState().accountSummary;
4663
- const updated = current
4664
- ? { ...current, agentWallet: { address: data.agentWalletAddress, status: 'ACTIVE' } }
4665
- : { balanceSummary: { crossMaintenanceMarginUsed: '0', crossMarginSummary: { accountValue: '0', totalMarginUsed: '0', totalNtlPos: '0', totalRawUsd: '0' }, marginSummary: { accountValue: '0', totalMarginUsed: '0', totalNtlPos: '0', totalRawUsd: '0' }, time: Date.now(), withdrawable: '0' }, agentWallet: { address: data.agentWalletAddress, status: 'ACTIVE' } };
4666
- setAccountSummary(updated);
4667
- return data;
4668
- }
4669
- catch (e) {
4670
- error = (e === null || e === void 0 ? void 0 : e.message) || 'Failed to create agent wallet';
4671
- throw e;
4672
- }
4673
- finally {
4674
- loading = false;
4675
- }
4676
- }, [baseUrl]);
4677
- // For user to notify that approvals are done; we re-check status
4678
- const notifyAgentWalletApproved = useCallback(async () => {
4679
- return refreshAgentWalletStatus();
4680
- }, [refreshAgentWalletStatus]);
4681
- return {
4682
- agentWallet,
4683
- isReady: agentWallet.isActive,
4684
- loading,
4685
- error,
4686
- refreshAgentWalletStatus,
4687
- createAgentWallet: createAgentWallet$1,
4688
- notifyAgentWalletApproved,
4689
- };
4690
- }
4691
-
4692
- /**
4693
- * Hook to manage address (login/logout functionality)
4694
- */
4695
- const useAddress = () => {
4696
- const context = useContext(PearHyperliquidContext);
4697
- if (!context) {
4698
- throw new Error('useAddress must be used within a PearHyperliquidProvider');
4699
- }
4700
- return {
4701
- address: context.address,
4702
- setAddress: context.setAddress,
4703
- clearAddress: () => context.setAddress(null),
4704
- isLoggedIn: !!context.address,
4705
- };
4706
- };
4707
-
4708
4727
  /**
4709
4728
  * Account summary calculation utility class
4710
4729
  */
4711
4730
  class AccountSummaryCalculator {
4712
- constructor(webData2) {
4713
- this.webData2 = webData2;
4731
+ constructor(clearinghouseState) {
4732
+ this.clearinghouseState = clearinghouseState;
4714
4733
  }
4715
4734
  /**
4716
- * Calculate account summary from webData2 and platform orders
4735
+ * Calculate account summary from real-time clearinghouse state and platform orders
4717
4736
  */
4718
- calculateAccountSummary(platformAccountSummary, platformOpenOrders, agentWalletAddress, agentWalletStatus) {
4719
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
4720
- // If we don't have webData2, return platform data as-is
4721
- if (!((_a = this.webData2) === null || _a === void 0 ? void 0 : _a.clearinghouseState)) {
4722
- return platformAccountSummary;
4737
+ calculateAccountSummary(platformAccountSummary, registeredAgentWallets) {
4738
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
4739
+ if (!this.clearinghouseState) {
4740
+ return null;
4723
4741
  }
4724
- const clearinghouseState = this.webData2.clearinghouseState;
4725
- // Calculate total limit order value from platform orders
4726
- const totalLimitOrderValue = this.calculateTotalLimitOrderValue(platformOpenOrders || []);
4727
- // Use real-time data from webData2 clearinghouseState
4742
+ const clearinghouseState = this.clearinghouseState;
4728
4743
  const withdrawableAmount = parseFloat(clearinghouseState.withdrawable || '0');
4729
- const adjustedWithdrawable = Math.max(0, withdrawableAmount - totalLimitOrderValue);
4744
+ const adjustedWithdrawable = Math.max(0, withdrawableAmount - ((_a = platformAccountSummary === null || platformAccountSummary === void 0 ? void 0 : platformAccountSummary.totalTwapChunkUsdValue) !== null && _a !== void 0 ? _a : 0) - ((_b = platformAccountSummary === null || platformAccountSummary === void 0 ? void 0 : platformAccountSummary.totalLimitOrderUsdValue) !== null && _b !== void 0 ? _b : 0));
4730
4745
  const accountSummary = {
4731
4746
  balanceSummary: {
4732
4747
  crossMaintenanceMarginUsed: clearinghouseState.crossMaintenanceMarginUsed || '0',
4733
4748
  crossMarginSummary: {
4734
- accountValue: ((_b = clearinghouseState.crossMarginSummary) === null || _b === void 0 ? void 0 : _b.accountValue) || '0',
4735
- totalMarginUsed: ((_c = clearinghouseState.crossMarginSummary) === null || _c === void 0 ? void 0 : _c.totalMarginUsed) || '0',
4736
- totalNtlPos: ((_d = clearinghouseState.crossMarginSummary) === null || _d === void 0 ? void 0 : _d.totalNtlPos) || '0',
4737
- totalRawUsd: ((_e = clearinghouseState.crossMarginSummary) === null || _e === void 0 ? void 0 : _e.totalRawUsd) || '0'
4749
+ accountValue: ((_c = clearinghouseState.crossMarginSummary) === null || _c === void 0 ? void 0 : _c.accountValue) || '0',
4750
+ totalMarginUsed: ((_d = clearinghouseState.crossMarginSummary) === null || _d === void 0 ? void 0 : _d.totalMarginUsed) || '0',
4751
+ totalNtlPos: ((_e = clearinghouseState.crossMarginSummary) === null || _e === void 0 ? void 0 : _e.totalNtlPos) || '0',
4752
+ totalRawUsd: ((_f = clearinghouseState.crossMarginSummary) === null || _f === void 0 ? void 0 : _f.totalRawUsd) || '0'
4738
4753
  },
4739
4754
  marginSummary: {
4740
- accountValue: ((_f = clearinghouseState.marginSummary) === null || _f === void 0 ? void 0 : _f.accountValue) || '0',
4741
- totalMarginUsed: ((_g = clearinghouseState.marginSummary) === null || _g === void 0 ? void 0 : _g.totalMarginUsed) || '0',
4742
- totalNtlPos: ((_h = clearinghouseState.marginSummary) === null || _h === void 0 ? void 0 : _h.totalNtlPos) || '0',
4743
- totalRawUsd: ((_j = clearinghouseState.marginSummary) === null || _j === void 0 ? void 0 : _j.totalRawUsd) || '0'
4755
+ accountValue: ((_g = clearinghouseState.marginSummary) === null || _g === void 0 ? void 0 : _g.accountValue) || '0',
4756
+ totalMarginUsed: ((_h = clearinghouseState.marginSummary) === null || _h === void 0 ? void 0 : _h.totalMarginUsed) || '0',
4757
+ totalNtlPos: ((_j = clearinghouseState.marginSummary) === null || _j === void 0 ? void 0 : _j.totalNtlPos) || '0',
4758
+ totalRawUsd: ((_k = clearinghouseState.marginSummary) === null || _k === void 0 ? void 0 : _k.totalRawUsd) || '0'
4744
4759
  },
4745
4760
  time: clearinghouseState.time || Date.now(),
4746
4761
  withdrawable: adjustedWithdrawable.toString()
4747
- },
4748
- agentWallet: {
4749
- address: agentWalletAddress || ((_k = platformAccountSummary === null || platformAccountSummary === void 0 ? void 0 : platformAccountSummary.agentWallet) === null || _k === void 0 ? void 0 : _k.address) || '',
4750
- status: agentWalletStatus || ((_l = platformAccountSummary === null || platformAccountSummary === void 0 ? void 0 : platformAccountSummary.agentWallet) === null || _l === void 0 ? void 0 : _l.status) || 'UNKNOWN'
4751
4762
  }
4752
4763
  };
4753
- return accountSummary;
4754
- }
4755
- /**
4756
- * Calculate total USD value of open limit orders
4757
- */
4758
- calculateTotalLimitOrderValue(openOrders) {
4759
- if (!(openOrders === null || openOrders === void 0 ? void 0 : openOrders.length)) {
4760
- return 0;
4764
+ if (platformAccountSummary === null || platformAccountSummary === void 0 ? void 0 : platformAccountSummary.agentWalletAddress) {
4765
+ accountSummary.agentWallet = {
4766
+ address: platformAccountSummary.agentWalletAddress,
4767
+ status: registeredAgentWallets.find((agent) => { var _a; return agent.address.toLowerCase() === ((_a = platformAccountSummary.agentWalletAddress) === null || _a === void 0 ? void 0 : _a.toLowerCase()); }) ? 'ACTIVE' : 'EXPIRED'
4768
+ };
4761
4769
  }
4762
- const totalValue = openOrders
4763
- .filter(order => order.status === 'OPEN' || order.status === 'PROCESSING')
4764
- .reduce((sum, order) => sum + order.usdValue / order.leverage, 0);
4765
- return totalValue;
4770
+ return accountSummary;
4766
4771
  }
4767
- /**
4768
- * Get real-time clearinghouse state from webData2
4769
- */
4770
4772
  getClearinghouseState() {
4771
- var _a;
4772
- return ((_a = this.webData2) === null || _a === void 0 ? void 0 : _a.clearinghouseState) || null;
4773
+ return this.clearinghouseState || null;
4773
4774
  }
4774
4775
  /**
4775
4776
  * Check if real-time data is available
4776
4777
  */
4777
4778
  hasRealTimeData() {
4778
- var _a;
4779
- return !!((_a = this.webData2) === null || _a === void 0 ? void 0 : _a.clearinghouseState);
4779
+ return !!this.clearinghouseState;
4780
4780
  }
4781
4781
  }
4782
4782
 
4783
+ const useAccountSummary = () => {
4784
+ const context = useContext(PearHyperliquidContext);
4785
+ if (!context) {
4786
+ throw new Error('useAccountSummary must be used within a PearHyperliquidProvider');
4787
+ }
4788
+ const platformAccountSummary = useUserData((state) => state.accountSummary);
4789
+ const aggregatedClearingHouseState = useHyperliquidData((state) => state.aggregatedClearingHouseState);
4790
+ const registeredAgentWallets = useUserData((state) => state.userExtraAgents);
4791
+ const isLoading = useMemo(() => {
4792
+ return platformAccountSummary === null && context.isConnected && registeredAgentWallets === null && aggregatedClearingHouseState === null;
4793
+ }, [platformAccountSummary, context.isConnected, registeredAgentWallets, aggregatedClearingHouseState]);
4794
+ // Create calculator and compute account summary
4795
+ const calculator = new AccountSummaryCalculator(aggregatedClearingHouseState);
4796
+ const calculated = calculator.calculateAccountSummary(platformAccountSummary, registeredAgentWallets || []);
4797
+ return { data: calculated, isLoading };
4798
+ };
4799
+
4783
4800
  const useTradeHistories = () => {
4784
4801
  const context = useContext(PearHyperliquidContext);
4785
4802
  if (!context) {
@@ -4805,29 +4822,7 @@ const useOpenOrders = () => {
4805
4822
  }, [openOrders, context.isConnected]);
4806
4823
  return { data: openOrders, isLoading };
4807
4824
  };
4808
- /**
4809
- * Hook to access account summary with real-time calculations and loading state
4810
- */
4811
- const useAccountSummary = () => {
4812
- var _a, _b;
4813
- const context = useContext(PearHyperliquidContext);
4814
- if (!context) {
4815
- throw new Error('useAccountSummary must be used within a PearHyperliquidProvider');
4816
- }
4817
- const openOrders = useUserData((state) => state.openOrders);
4818
- const accountSummary = useUserData((state) => state.accountSummary);
4819
- const webData2 = useHyperliquidData((state) => state.webData2);
4820
- const isLoading = useMemo(() => {
4821
- // Loading is true initially and becomes false once we get the first data
4822
- return accountSummary === null && context.isConnected;
4823
- }, [accountSummary, context.isConnected]);
4824
- // Create calculator and compute account summary
4825
- const calculator = new AccountSummaryCalculator(webData2);
4826
- const calculated = calculator.calculateAccountSummary(accountSummary, openOrders, (_a = accountSummary === null || accountSummary === void 0 ? void 0 : accountSummary.agentWallet) === null || _a === void 0 ? void 0 : _a.address, (_b = accountSummary === null || accountSummary === void 0 ? void 0 : accountSummary.agentWallet) === null || _b === void 0 ? void 0 : _b.status);
4827
- return { data: calculated, isLoading };
4828
- };
4829
4825
 
4830
- // Re-expose as a React hook without Zustand's selector signature
4831
4826
  const useUserSelection = () => {
4832
4827
  return useUserSelection$1();
4833
4828
  };
@@ -4836,28 +4831,31 @@ const useUserSelection = () => {
4836
4831
  * Hook to access webData and native WebSocket state
4837
4832
  */
4838
4833
  const useWebData = () => {
4839
- var _a;
4840
4834
  const context = useContext(PearHyperliquidContext);
4841
4835
  if (!context) {
4842
4836
  throw new Error('useWebData must be used within a PearHyperliquidProvider');
4843
4837
  }
4844
- const webData2 = useHyperliquidData((state) => state.webData2);
4838
+ const finalAssetContexts = useHyperliquidData((state) => state.finalAssetContexts);
4839
+ const perpMetaAssets = useHyperliquidData((state) => state.perpMetaAssets);
4840
+ const aggregatedClearinghouseState = useHyperliquidData((state) => state.aggregatedClearingHouseState);
4841
+ const finalAtOICaps = useHyperliquidData((state) => state.finalAtOICaps);
4842
+ const hip3Assets = useHyperliquidData((state) => state.hip3DisplayToFull);
4845
4843
  let marketDataBySymbol = {};
4846
- if ((webData2 === null || webData2 === void 0 ? void 0 : webData2.assetCtxs) && ((_a = webData2 === null || webData2 === void 0 ? void 0 : webData2.meta) === null || _a === void 0 ? void 0 : _a.universe)) {
4847
- const { assetCtxs, meta: { universe } } = webData2;
4844
+ if (finalAssetContexts && perpMetaAssets && finalAssetContexts.length === perpMetaAssets.length) {
4848
4845
  const result = {};
4849
- for (let index = 0; index < universe.length; index++) {
4850
- const name = universe[index].name;
4846
+ for (let index = 0; index < perpMetaAssets.length; index++) {
4847
+ const name = perpMetaAssets[index].name;
4851
4848
  result[name] = {
4852
- asset: assetCtxs[index],
4853
- universe: universe[index],
4849
+ asset: finalAssetContexts[index],
4850
+ universe: perpMetaAssets[index],
4854
4851
  };
4855
4852
  }
4856
4853
  marketDataBySymbol = result;
4857
4854
  }
4858
4855
  return {
4859
- clearinghouseState: webData2 === null || webData2 === void 0 ? void 0 : webData2.clearinghouseState,
4860
- perpsAtOpenInterestCap: webData2 === null || webData2 === void 0 ? void 0 : webData2.perpsAtOpenInterestCap,
4856
+ hip3Assets,
4857
+ clearinghouseState: aggregatedClearinghouseState,
4858
+ perpsAtOpenInterestCap: finalAtOICaps,
4861
4859
  marketDataBySymbol,
4862
4860
  isConnected: context.nativeIsConnected,
4863
4861
  error: context.nativeLastError,
@@ -4865,28 +4863,29 @@ const useWebData = () => {
4865
4863
  };
4866
4864
 
4867
4865
  /**
4868
- * Extracts token metadata from WebData2 and AllMids data
4866
+ * Extracts token metadata from aggregated WebData3 contexts and AllMids data
4869
4867
  */
4870
4868
  class TokenMetadataExtractor {
4871
4869
  /**
4872
4870
  * Extracts comprehensive token metadata
4873
4871
  * @param symbol - Token symbol
4874
- * @param webData2 - WebData2 response containing asset context and universe data
4872
+ * @param perpMetaAssets - Aggregated universe assets (flattened across dexes)
4873
+ * @param finalAssetContexts - Aggregated asset contexts (flattened across dexes)
4875
4874
  * @param allMids - AllMids data containing current prices
4876
4875
  * @param activeAssetData - Optional active asset data containing leverage information
4877
4876
  * @returns TokenMetadata or null if token not found
4878
4877
  */
4879
- static extractTokenMetadata(symbol, webData2, allMids, activeAssetData) {
4880
- if (!webData2 || !allMids) {
4878
+ static extractTokenMetadata(symbol, perpMetaAssets, finalAssetContexts, allMids, activeAssetData) {
4879
+ if (!perpMetaAssets || !finalAssetContexts || !allMids) {
4881
4880
  return null;
4882
4881
  }
4883
- // Find token index in universe
4884
- const universeIndex = webData2.meta.universe.findIndex(asset => asset.name === symbol);
4882
+ // Find token index in aggregated universe
4883
+ const universeIndex = perpMetaAssets.findIndex(asset => asset.name === symbol);
4885
4884
  if (universeIndex === -1) {
4886
4885
  return null;
4887
4886
  }
4888
- const universeAsset = webData2.meta.universe[universeIndex];
4889
- const assetCtx = webData2.assetCtxs[universeIndex];
4887
+ const universeAsset = perpMetaAssets[universeIndex];
4888
+ const assetCtx = finalAssetContexts[universeIndex];
4890
4889
  if (!assetCtx) {
4891
4890
  return null;
4892
4891
  }
@@ -4926,28 +4925,29 @@ class TokenMetadataExtractor {
4926
4925
  /**
4927
4926
  * Extracts metadata for multiple tokens
4928
4927
  * @param symbols - Array of token symbols
4929
- * @param webData2 - WebData2 response
4928
+ * @param perpMetaAssets - Aggregated universe assets
4929
+ * @param finalAssetContexts - Aggregated asset contexts
4930
4930
  * @param allMids - AllMids data
4931
4931
  * @param activeAssetData - Optional active asset data containing leverage information
4932
4932
  * @returns Record of symbol to TokenMetadata
4933
4933
  */
4934
- static extractMultipleTokensMetadata(symbols, webData2, allMids, activeAssetData) {
4934
+ static extractMultipleTokensMetadata(symbols, perpMetaAssets, finalAssetContexts, allMids, activeAssetData) {
4935
4935
  const result = {};
4936
4936
  for (const symbol of symbols) {
4937
- result[symbol] = this.extractTokenMetadata(symbol, webData2, allMids, activeAssetData);
4937
+ result[symbol] = this.extractTokenMetadata(symbol, perpMetaAssets, finalAssetContexts, allMids, activeAssetData);
4938
4938
  }
4939
4939
  return result;
4940
4940
  }
4941
4941
  /**
4942
- * Checks if token data is available in WebData2
4942
+ * Checks if token data is available in aggregated universe assets
4943
4943
  * @param symbol - Token symbol
4944
- * @param webData2 - WebData2 response
4944
+ * @param perpMetaAssets - Aggregated universe assets
4945
4945
  * @returns boolean indicating if token exists in universe
4946
4946
  */
4947
- static isTokenAvailable(symbol, webData2) {
4948
- if (!webData2)
4947
+ static isTokenAvailable(symbol, perpMetaAssets) {
4948
+ if (!perpMetaAssets)
4949
4949
  return false;
4950
- return webData2.meta.universe.some(asset => asset.name === symbol);
4950
+ return perpMetaAssets.some(asset => asset.name === symbol);
4951
4951
  }
4952
4952
  }
4953
4953
 
@@ -4966,16 +4966,16 @@ const useTokenSelectionMetadataStore = create((set) => ({
4966
4966
  maxLeverage: 0,
4967
4967
  minMargin: 0,
4968
4968
  leverageMatched: true,
4969
- recompute: ({ webData2, allMids, activeAssetData, marketData, longTokens, shortTokens }) => {
4970
- const isPriceDataReady = !!(webData2 && allMids);
4969
+ recompute: ({ perpMetaAssets, finalAssetContexts, allMids, activeAssetData, marketData, longTokens, shortTokens }) => {
4970
+ const isPriceDataReady = !!(perpMetaAssets && finalAssetContexts && allMids);
4971
4971
  // Compute metadata when ready
4972
4972
  const longSymbols = longTokens.map((t) => t.symbol);
4973
4973
  const shortSymbols = shortTokens.map((t) => t.symbol);
4974
4974
  const longTokensMetadata = isPriceDataReady
4975
- ? TokenMetadataExtractor.extractMultipleTokensMetadata(longSymbols, webData2, allMids, activeAssetData)
4975
+ ? TokenMetadataExtractor.extractMultipleTokensMetadata(longSymbols, perpMetaAssets, finalAssetContexts, allMids, activeAssetData)
4976
4976
  : {};
4977
4977
  const shortTokensMetadata = isPriceDataReady
4978
- ? TokenMetadataExtractor.extractMultipleTokensMetadata(shortSymbols, webData2, allMids, activeAssetData)
4978
+ ? TokenMetadataExtractor.extractMultipleTokensMetadata(shortSymbols, perpMetaAssets, finalAssetContexts, allMids, activeAssetData)
4979
4979
  : {};
4980
4980
  // Determine loading state
4981
4981
  const allTokens = [...longTokens, ...shortTokens];
@@ -5084,15 +5084,14 @@ const useTokenSelectionMetadataStore = create((set) => ({
5084
5084
  })();
5085
5085
  // Max leverage (minimum across all tokens)
5086
5086
  const maxLeverage = (() => {
5087
- var _a;
5088
- if (!((_a = webData2 === null || webData2 === void 0 ? void 0 : webData2.meta) === null || _a === void 0 ? void 0 : _a.universe))
5087
+ if (!perpMetaAssets)
5089
5088
  return 0;
5090
5089
  const allTokenSymbols = [...longTokens, ...shortTokens].map((t) => t.symbol);
5091
5090
  if (allTokenSymbols.length === 0)
5092
5091
  return 0;
5093
5092
  let minLev = Infinity;
5094
5093
  allTokenSymbols.forEach((symbol) => {
5095
- const tokenUniverse = webData2.meta.universe.find((u) => u.name === symbol);
5094
+ const tokenUniverse = perpMetaAssets.find((u) => u.name === symbol);
5096
5095
  if (tokenUniverse === null || tokenUniverse === void 0 ? void 0 : tokenUniverse.maxLeverage)
5097
5096
  minLev = Math.min(minLev, tokenUniverse.maxLeverage);
5098
5097
  });
@@ -5144,7 +5143,8 @@ const useTokenSelectionMetadata = () => {
5144
5143
  if (!context) {
5145
5144
  throw new Error('useTokenSelection must be used within PearHyperliquidProvider');
5146
5145
  }
5147
- const webData2 = useHyperliquidData((state) => state.webData2);
5146
+ const perpMetaAssets = useHyperliquidData((state) => state.perpMetaAssets);
5147
+ const finalAssetContexts = useHyperliquidData((state) => state.finalAssetContexts);
5148
5148
  const allMids = useHyperliquidData((state) => state.allMids);
5149
5149
  const activeAssetData = useHyperliquidData((state) => state.activeAssetData);
5150
5150
  const marketData = useMarketData((state) => state.marketData);
@@ -5153,7 +5153,8 @@ const useTokenSelectionMetadata = () => {
5153
5153
  // Recompute derived metadata when inputs change
5154
5154
  useEffect(() => {
5155
5155
  recompute({
5156
- webData2,
5156
+ perpMetaAssets,
5157
+ finalAssetContexts,
5157
5158
  allMids,
5158
5159
  activeAssetData: activeAssetData || null,
5159
5160
  marketData: marketData || null,
@@ -5162,7 +5163,7 @@ const useTokenSelectionMetadata = () => {
5162
5163
  });
5163
5164
  // We want to recompute when token lists or upstream data change
5164
5165
  // eslint-disable-next-line react-hooks/exhaustive-deps
5165
- }, [webData2, allMids, activeAssetData, JSON.stringify(longTokens), JSON.stringify(shortTokens)]);
5166
+ }, [perpMetaAssets, finalAssetContexts, allMids, activeAssetData, JSON.stringify(longTokens), JSON.stringify(shortTokens)]);
5166
5167
  return {
5167
5168
  // Loading states
5168
5169
  isLoading,
@@ -5307,9 +5308,10 @@ const useHistoricalPriceDataStore = create((set, get) => ({
5307
5308
  /**
5308
5309
  * Fetch historical candle data from HyperLiquid API
5309
5310
  */
5310
- const fetchHistoricalCandles = async (coin, startTime, endTime, interval) => {
5311
+ const fetchHistoricalCandles = async (coin, startTime, endTime, interval, displayToFull) => {
5312
+ const backendCoin = toBackendSymbol(coin, displayToFull);
5311
5313
  const request = {
5312
- req: { coin, startTime, endTime, interval },
5314
+ req: { coin: backendCoin, startTime, endTime, interval },
5313
5315
  type: 'candleSnapshot',
5314
5316
  };
5315
5317
  try {
@@ -5337,6 +5339,40 @@ const fetchUserFillsFromHyperliquid = async (user, startTime, aggregateByTime =
5337
5339
  throw toApiError(error);
5338
5340
  }
5339
5341
  };
5342
+ /**
5343
+ * Fetch all perp metas from HyperLiquid API
5344
+ * Endpoint: https://api.hyperliquid.xyz/info
5345
+ * Payload: { "type": "allPerpMetas" }
5346
+ */
5347
+ const fetchAllPerpMetas = async () => {
5348
+ const request = { type: 'allPerpMetas' };
5349
+ try {
5350
+ const response = await axios$1.post('https://api.hyperliquid.xyz/info', request, {
5351
+ headers: { 'Content-Type': 'application/json' },
5352
+ });
5353
+ return { data: response.data, status: response.status, headers: response.headers };
5354
+ }
5355
+ catch (error) {
5356
+ throw toApiError(error);
5357
+ }
5358
+ };
5359
+ /**
5360
+ * Fetch extra agent approvals for a given user from HyperLiquid API
5361
+ * Endpoint: https://api.hyperliquid.xyz/info
5362
+ * Payload: { "type": "extraAgents", "user": "0x..." }
5363
+ */
5364
+ const fetchExtraAgents = async (user) => {
5365
+ const request = { type: 'extraAgents', user };
5366
+ try {
5367
+ const response = await axios$1.post('https://api.hyperliquid.xyz/info', request, {
5368
+ headers: { 'Content-Type': 'application/json' },
5369
+ });
5370
+ return { data: response.data, status: response.status, headers: response.headers };
5371
+ }
5372
+ catch (error) {
5373
+ throw toApiError(error);
5374
+ }
5375
+ };
5340
5376
 
5341
5377
  const useHistoricalPriceData = () => {
5342
5378
  const context = useContext(PearHyperliquidContext);
@@ -5417,9 +5453,10 @@ const useHistoricalPriceData = () => {
5417
5453
  setTokenLoading(token.symbol, true);
5418
5454
  });
5419
5455
  try {
5456
+ const displayToFull = useHyperliquidData.getState().hip3DisplayToFull;
5420
5457
  const fetchPromises = tokensToFetch.map(async (token) => {
5421
5458
  try {
5422
- const response = await fetchHistoricalCandles(token.symbol, startTime, endTime, interval);
5459
+ const response = await fetchHistoricalCandles(token.symbol, startTime, endTime, interval, displayToFull);
5423
5460
  addHistoricalPriceData(token.symbol, interval, response.data, { start: startTime, end: endTime });
5424
5461
  return { symbol: token.symbol, candles: response.data, success: true };
5425
5462
  }
@@ -5907,6 +5944,50 @@ const usePerformanceOverlays = () => {
5907
5944
  };
5908
5945
  };
5909
5946
 
5947
+ async function createAgentWallet(baseUrl, accessToken) {
5948
+ const url = joinUrl(baseUrl, '/agentWallet');
5949
+ try {
5950
+ const resp = await axios$1.post(url, undefined, { headers: { Authorization: `Bearer ${accessToken}` }, timeout: 30000 });
5951
+ return { data: resp.data, status: resp.status, headers: resp.headers };
5952
+ }
5953
+ catch (error) {
5954
+ throw toApiError(error);
5955
+ }
5956
+ }
5957
+
5958
+ function useAgentWallet() {
5959
+ const context = useContext(PearHyperliquidContext);
5960
+ if (!context) {
5961
+ throw new Error('usePortfolio must be used within a PearHyperliquidProvider');
5962
+ }
5963
+ const { apiBaseUrl, address, accessToken, isAuthenticated } = context;
5964
+ const setAgentWallets = useUserData((state) => state.setUserExtraAgents);
5965
+ const refreshAgentWalletStatus = useCallback(async () => {
5966
+ const hlAgentWallets = await fetchExtraAgents(address);
5967
+ setAgentWallets((hlAgentWallets === null || hlAgentWallets === void 0 ? void 0 : hlAgentWallets.data) || []);
5968
+ }, [address]);
5969
+ useEffect(() => {
5970
+ if (!address)
5971
+ return;
5972
+ refreshAgentWalletStatus();
5973
+ }, [address, refreshAgentWalletStatus]);
5974
+ const createAgentWallet$1 = useCallback(async () => {
5975
+ if (!isAuthenticated || !accessToken) {
5976
+ throw new Error('Not authenticated');
5977
+ }
5978
+ const response = await createAgentWallet(apiBaseUrl, accessToken);
5979
+ return response.data;
5980
+ }, [apiBaseUrl, accessToken, isAuthenticated]);
5981
+ const notifyAgentWalletApproved = useCallback(async () => {
5982
+ return refreshAgentWalletStatus();
5983
+ }, [refreshAgentWalletStatus]);
5984
+ return {
5985
+ refreshAgentWalletStatus,
5986
+ createAgentWallet: createAgentWallet$1,
5987
+ notifyAgentWalletApproved,
5988
+ };
5989
+ }
5990
+
5910
5991
  /**
5911
5992
  * Sync external fills into Pear Hyperliquid service (POST /sync/fills)
5912
5993
  */
@@ -5926,8 +6007,8 @@ const syncFills = async (baseUrl, accessToken, payload) => {
5926
6007
  /**
5927
6008
  * Convenience: fetch user fills from HyperLiquid, then sync them to Pear backend
5928
6009
  */
5929
- const syncUserFillsFromHyperliquid = async (baseUrl, accessToken, user, aggregateByTime = true) => {
5930
- const firstStartTime = 1735660800000; // 1 January 2025
6010
+ const syncUserFillsFromHyperliquid = async (baseUrl, accessToken, user, aggregateByTime = true, lastSyncAt = null) => {
6011
+ const firstStartTime = lastSyncAt ? Number(lastSyncAt) : 1735660800000;
5931
6012
  const allFills = [];
5932
6013
  const seenTids = new Set();
5933
6014
  let startTime = firstStartTime;
@@ -5964,6 +6045,7 @@ function useAutoSyncFills(options) {
5964
6045
  const [isSyncing, setIsSyncing] = useState(false);
5965
6046
  const mountedRef = useRef(true);
5966
6047
  const runningRef = useRef(null);
6048
+ const lastSyncedAt = useUserData((state) => { var _a; return (_a = state.accountSummary) === null || _a === void 0 ? void 0 : _a.lastSyncedAt; });
5967
6049
  useEffect(() => {
5968
6050
  mountedRef.current = true;
5969
6051
  return () => { mountedRef.current = false; };
@@ -5975,13 +6057,15 @@ function useAutoSyncFills(options) {
5975
6057
  if (!canRun)
5976
6058
  return;
5977
6059
  if (runningRef.current)
5978
- return; // avoid overlap
6060
+ return;
6061
+ if (!useUserData.getState().accountSummary)
6062
+ return;
5979
6063
  setIsSyncing(true);
5980
6064
  setError(null);
5981
6065
  const promise = (async () => {
5982
6066
  var _a;
5983
6067
  try {
5984
- const { data } = await syncUserFillsFromHyperliquid(baseUrl, accessToken, address, aggregateByTime);
6068
+ const { data } = await syncUserFillsFromHyperliquid(baseUrl, accessToken, address, aggregateByTime, lastSyncedAt);
5985
6069
  if (!mountedRef.current)
5986
6070
  return;
5987
6071
  setLastResult(data);
@@ -6000,7 +6084,7 @@ function useAutoSyncFills(options) {
6000
6084
  })();
6001
6085
  runningRef.current = promise;
6002
6086
  await promise;
6003
- }, [canRun, baseUrl, accessToken, address, aggregateByTime]);
6087
+ }, [canRun, baseUrl, accessToken, address, aggregateByTime, lastSyncedAt]);
6004
6088
  useEffect(() => {
6005
6089
  if (!canRun)
6006
6090
  return;
@@ -6106,12 +6190,19 @@ function validatePositionSize(usdValue, longAssets, shortAssets) {
6106
6190
  * Caller should supply an accessToken from localStorage.getItem('accessToken')
6107
6191
  * @throws MinimumPositionSizeError if any asset has less than $11 USD value
6108
6192
  */
6109
- async function createPosition(baseUrl, accessToken, payload) {
6193
+ async function createPosition(baseUrl, accessToken, payload, displayToFull) {
6110
6194
  // Validate minimum asset size before creating position
6111
6195
  validateMinimumAssetSize(payload.usdValue, payload.longAssets, payload.shortAssets);
6112
6196
  const url = joinUrl(baseUrl, "/positions");
6197
+ // Translate display symbols to backend format
6198
+ const mapAssets = (arr) => arr === null || arr === void 0 ? void 0 : arr.map((a) => ({ ...a, asset: toBackendSymbol(a.asset, displayToFull) }));
6199
+ const translatedPayload = {
6200
+ ...payload,
6201
+ longAssets: mapAssets(payload.longAssets),
6202
+ shortAssets: mapAssets(payload.shortAssets),
6203
+ };
6113
6204
  try {
6114
- const resp = await axios$1.post(url, payload, {
6205
+ const resp = await axios$1.post(url, translatedPayload, {
6115
6206
  headers: {
6116
6207
  "Content-Type": "application/json",
6117
6208
  Authorization: `Bearer ${accessToken}`,
@@ -6250,7 +6341,7 @@ const calculatePositionAsset = (asset, currentPrice, totalInitialPositionSize, l
6250
6341
  initialWeight: totalInitialPositionSize > 0 ? entryNotional / totalInitialPositionSize : 0,
6251
6342
  };
6252
6343
  };
6253
- const buildPositionValue = (rawPositions, webData2, allMids) => {
6344
+ const buildPositionValue = (rawPositions, clearinghouseState, allMids) => {
6254
6345
  return rawPositions.map((position) => {
6255
6346
  let mappedPosition = {
6256
6347
  positionId: position.positionId,
@@ -6269,7 +6360,7 @@ const buildPositionValue = (rawPositions, webData2, allMids) => {
6269
6360
  mappedPosition.longAssets = position.longAssets.map(longAsset => {
6270
6361
  var _a, _b, _c;
6271
6362
  const currentPrice = parseFloat(allMids.mids[longAsset.coin]);
6272
- const assetState = (_a = webData2.clearinghouseState.assetPositions.find(ap => ap.position.coin === longAsset.coin)) === null || _a === void 0 ? void 0 : _a.position;
6363
+ const assetState = (_a = clearinghouseState.assetPositions.find(ap => toDisplaySymbol(ap.position.coin) === longAsset.coin)) === null || _a === void 0 ? void 0 : _a.position;
6273
6364
  const leverage = (_c = (_b = assetState === null || assetState === void 0 ? void 0 : assetState.leverage) === null || _b === void 0 ? void 0 : _b.value) !== null && _c !== void 0 ? _c : 0;
6274
6365
  const mappedPositionAssets = calculatePositionAsset(longAsset, currentPrice, totalInitialPositionSize, leverage, true);
6275
6366
  mappedPosition.entryPositionValue += mappedPositionAssets.entryPositionValue;
@@ -6283,7 +6374,7 @@ const buildPositionValue = (rawPositions, webData2, allMids) => {
6283
6374
  mappedPosition.shortAssets = position.shortAssets.map(shortAsset => {
6284
6375
  var _a, _b, _c;
6285
6376
  const currentPrice = parseFloat(allMids.mids[shortAsset.coin]);
6286
- const assetState = (_a = webData2.clearinghouseState.assetPositions.find(ap => ap.position.coin === shortAsset.coin)) === null || _a === void 0 ? void 0 : _a.position;
6377
+ const assetState = (_a = clearinghouseState.assetPositions.find(ap => toDisplaySymbol(ap.position.coin) === shortAsset.coin)) === null || _a === void 0 ? void 0 : _a.position;
6287
6378
  const leverage = (_c = (_b = assetState === null || assetState === void 0 ? void 0 : assetState.leverage) === null || _b === void 0 ? void 0 : _b.value) !== null && _c !== void 0 ? _c : 0;
6288
6379
  const mappedPositionAssets = calculatePositionAsset(shortAsset, currentPrice, totalInitialPositionSize, leverage, false);
6289
6380
  mappedPosition.entryPositionValue += mappedPositionAssets.entryPositionValue;
@@ -6316,11 +6407,12 @@ function usePosition() {
6316
6407
  throw new Error('usePosition must be used within a PearHyperliquidProvider');
6317
6408
  }
6318
6409
  const { apiBaseUrl, accessToken, isConnected } = context;
6410
+ const displayToFull = useHyperliquidData((s) => s.hip3DisplayToFull);
6319
6411
  // Create position API action
6320
6412
  const createPosition$1 = async (payload) => {
6321
6413
  if (!accessToken)
6322
6414
  throw new Error('Not authenticated');
6323
- return createPosition(apiBaseUrl, accessToken, payload);
6415
+ return createPosition(apiBaseUrl, accessToken, payload, displayToFull);
6324
6416
  };
6325
6417
  // Update TP/SL risk parameters for a position
6326
6418
  const updateRiskParameters$1 = async (positionId, payload) => {
@@ -6348,16 +6440,16 @@ function usePosition() {
6348
6440
  };
6349
6441
  // Open positions using WS data, with derived values
6350
6442
  const userOpenPositions = useUserData((state) => state.rawOpenPositions);
6351
- const webData2 = useHyperliquidData((state) => state.webData2);
6443
+ const aggregatedClearingHouseState = useHyperliquidData((state) => state.aggregatedClearingHouseState);
6352
6444
  const allMids = useHyperliquidData((state) => state.allMids);
6353
6445
  const isLoading = useMemo(() => {
6354
6446
  return userOpenPositions === null && isConnected;
6355
6447
  }, [userOpenPositions, isConnected]);
6356
6448
  const openPositions = useMemo(() => {
6357
- if (!userOpenPositions || !webData2 || !allMids)
6449
+ if (!userOpenPositions || !aggregatedClearingHouseState || !allMids)
6358
6450
  return null;
6359
- return buildPositionValue(userOpenPositions, webData2, allMids);
6360
- }, [userOpenPositions, webData2, allMids]);
6451
+ return buildPositionValue(userOpenPositions, aggregatedClearingHouseState, allMids);
6452
+ }, [userOpenPositions, aggregatedClearingHouseState, allMids]);
6361
6453
  return { createPosition: createPosition$1, updateRiskParameters: updateRiskParameters$1, closePosition: closePosition$1, closeAllPositions: closeAllPositions$1, adjustPosition: adjustPosition$1, openPositions, isLoading };
6362
6454
  }
6363
6455
 
@@ -6418,7 +6510,6 @@ function useOrders() {
6418
6510
  const pos = positionsById.get((_e = ord.positionId) !== null && _e !== void 0 ? _e : '');
6419
6511
  if (!isTpSl || !pos)
6420
6512
  return ord;
6421
- // Build order assets from position weights when TP/SL has no assets
6422
6513
  const mapAssets = (arr) => arr.map((a) => ({ asset: a.coin, weight: a.initialWeight }));
6423
6514
  if (!hasAssets) {
6424
6515
  return {
@@ -6427,7 +6518,6 @@ function useOrders() {
6427
6518
  shortAssets: mapAssets(pos.shortAssets),
6428
6519
  };
6429
6520
  }
6430
- // Leverage is now tracked per-asset in positions; keep order leverage as-is
6431
6521
  return ord;
6432
6522
  });
6433
6523
  }, [openOrders, positionsById]);
@@ -6511,7 +6601,6 @@ function useNotifications() {
6511
6601
  if (!isAuthenticated || !accessToken)
6512
6602
  throw new Error('Not authenticated');
6513
6603
  const { data } = await markNotificationsRead(apiBaseUrl, accessToken, timestampMs);
6514
- // Optimistic local update for immediate UI feedback
6515
6604
  if (notifications) {
6516
6605
  const updated = notifications.map((n) => {
6517
6606
  const created = Date.parse(n.created_at);
@@ -6608,10 +6697,11 @@ const useFindBasket = (longs, shorts) => {
6608
6697
  }, [data, longs, shorts]);
6609
6698
  };
6610
6699
 
6611
- async function toggleWatchlist(baseUrl, accessToken, longAssets, shortAssets) {
6700
+ async function toggleWatchlist(baseUrl, accessToken, longAssets, shortAssets, displayToFull) {
6612
6701
  const url = joinUrl(baseUrl, '/watchlist');
6702
+ const mapAssets = (arr) => arr.map(a => ({ ...a, asset: toBackendSymbol(a.asset, displayToFull) }));
6613
6703
  try {
6614
- const response = await axios$1.post(url, { longAssets, shortAssets }, { headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${accessToken}` } });
6704
+ const response = await axios$1.post(url, { longAssets: mapAssets(longAssets), shortAssets: mapAssets(shortAssets) }, { headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${accessToken}` } });
6615
6705
  return { data: response.data, status: response.status, headers: response.headers };
6616
6706
  }
6617
6707
  catch (error) {
@@ -6624,12 +6714,13 @@ function useWatchlist() {
6624
6714
  if (!context)
6625
6715
  throw new Error('useWatchlist must be used within a PearHyperliquidProvider');
6626
6716
  const { apiBaseUrl, accessToken, isConnected } = context;
6717
+ const displayToFull = useHyperliquidData((s) => s.hip3DisplayToFull);
6627
6718
  const marketData = useMarketDataPayload();
6628
6719
  const isLoading = useMemo(() => !marketData && isConnected, [marketData, isConnected]);
6629
6720
  const toggle = async (longAssets, shortAssets) => {
6630
6721
  if (!accessToken)
6631
6722
  throw new Error('Not authenticated');
6632
- const resp = await toggleWatchlist(apiBaseUrl, accessToken, longAssets, shortAssets);
6723
+ const resp = await toggleWatchlist(apiBaseUrl, accessToken, longAssets, shortAssets, displayToFull);
6633
6724
  // Server will push updated market-data over WS; nothing to set here
6634
6725
  return resp;
6635
6726
  };
@@ -6656,7 +6747,7 @@ async function getPortfolio(baseUrl, accessToken) {
6656
6747
  /**
6657
6748
  * Hook to fetch and manage portfolio data
6658
6749
  * Returns bucketed volume, open interest snapshot, win/loss trade counts,
6659
- * and overall metrics filtered to PEAR fills (cloid LIKE 0x50454152%)
6750
+ * and overall metrics
6660
6751
  */
6661
6752
  function usePortfolio() {
6662
6753
  const context = useContext(PearHyperliquidContext);
@@ -6700,23 +6791,51 @@ const PearHyperliquidContext = createContext(undefined);
6700
6791
  */
6701
6792
  const PearHyperliquidProvider = ({ children, apiBaseUrl = 'https://hl-v2.pearprotocol.io', clientId = 'PEARPROTOCOLUI', wsUrl = 'wss://hl-v2.pearprotocol.io/ws', }) => {
6702
6793
  const [address, setAddress] = useState(null);
6794
+ const perpsMetaAssets = useHyperliquidData((state) => state.perpMetaAssets);
6795
+ const setPerpMetaAssets = useHyperliquidData((state) => state.setPerpMetaAssets);
6796
+ const setHip3DisplayToFull = useHyperliquidData((state) => state.setHip3DisplayToFull);
6797
+ const websocketsEnabled = useMemo(() => Array.isArray(perpsMetaAssets) && perpsMetaAssets.length > 0, [perpsMetaAssets]);
6703
6798
  // WebSocket connection and data (Pear API)
6704
6799
  const { isConnected, lastError } = useHyperliquidWebSocket({
6705
6800
  wsUrl,
6706
6801
  address,
6802
+ enabled: websocketsEnabled,
6707
6803
  });
6708
6804
  // HyperLiquid native WebSocket connection
6709
6805
  const { isConnected: nativeIsConnected, lastError: nativeLastError } = useHyperliquidNativeWebSocket({
6710
6806
  address,
6807
+ enabled: websocketsEnabled,
6711
6808
  });
6712
6809
  // Auth hook
6713
- // Auth state inside provider (replaces useAuth internal state)
6714
6810
  const [authStatus, setAuthStatus] = useState(AuthStatus.Idle);
6715
6811
  const [user, setUser] = useState(null);
6716
6812
  const [authError, setAuthError] = useState(null);
6717
6813
  const [accessToken, setAccessToken] = useState(null);
6718
6814
  const isAuthenticated = useMemo(() => !!accessToken, [accessToken]);
6719
- // Hydrate from existing token
6815
+ useEffect(() => {
6816
+ if (perpsMetaAssets === null) {
6817
+ fetchAllPerpMetas().then(res => {
6818
+ const aggregatedPerpMetas = res.data.flatMap(item => item.universe);
6819
+ const hip3Map = new Map();
6820
+ const displayToFull = new Map();
6821
+ const cleanedPerpMetas = aggregatedPerpMetas.map((asset) => {
6822
+ var _a;
6823
+ const [maybePrefix, maybeMarket] = asset.name.split(":");
6824
+ if (maybeMarket) {
6825
+ const prefix = maybePrefix.toLowerCase();
6826
+ const market = maybeMarket;
6827
+ const existing = (_a = hip3Map.get(prefix)) !== null && _a !== void 0 ? _a : [];
6828
+ hip3Map.set(prefix, [...existing, market]);
6829
+ displayToFull.set(market, `${prefix}:${market}`);
6830
+ return { ...asset, name: market };
6831
+ }
6832
+ return asset;
6833
+ });
6834
+ setHip3DisplayToFull(displayToFull);
6835
+ setPerpMetaAssets(cleanedPerpMetas);
6836
+ }).catch(() => { });
6837
+ }
6838
+ }, [perpsMetaAssets, setPerpMetaAssets, setHip3DisplayToFull]);
6720
6839
  useEffect(() => {
6721
6840
  const access = localStorage.getItem('accessToken');
6722
6841
  if (access) {
@@ -6807,8 +6926,6 @@ const PearHyperliquidProvider = ({ children, apiBaseUrl = 'https://hl-v2.pearpro
6807
6926
  setAuthError(null);
6808
6927
  setAddress(null);
6809
6928
  }, [apiBaseUrl]);
6810
- // Agent wallet hook
6811
- const { agentWallet, isReady: isAgentWalletReady, loading: agentWalletLoading, error: agentWalletError, refreshAgentWalletStatus, createAgentWallet, notifyAgentWalletApproved, } = useAgentWallet({ baseUrl: apiBaseUrl });
6812
6929
  useAutoSyncFills({
6813
6930
  baseUrl: apiBaseUrl,
6814
6931
  accessToken: accessToken || '',
@@ -6842,23 +6959,13 @@ const PearHyperliquidProvider = ({ children, apiBaseUrl = 'https://hl-v2.pearpro
6842
6959
  loginWithPrivyToken,
6843
6960
  refreshTokens,
6844
6961
  logout: logout$1,
6845
- // Agent wallet
6846
- agentWallet,
6847
- isAgentWalletReady,
6848
- agentWalletError,
6849
- agentWalletLoading,
6850
- refreshAgentWalletStatus,
6851
- createAgentWallet,
6852
- notifyAgentWalletApproved,
6853
6962
  }), [
6854
6963
  apiBaseUrl, wsUrl,
6855
6964
  address, setAddress,
6856
6965
  isConnected, lastError,
6857
6966
  nativeIsConnected, nativeLastError,
6858
6967
  authStatus, isAuthenticated, user, authError,
6859
- agentWallet, isAgentWalletReady, agentWalletError, agentWalletLoading,
6860
6968
  getEip712, loginWithSignedMessage, refreshTokens, logout$1,
6861
- refreshAgentWalletStatus, createAgentWallet, notifyAgentWalletApproved,
6862
6969
  ]);
6863
6970
  return (jsx(PearHyperliquidContext.Provider, { value: contextValue, children: children }));
6864
6971
  };
@@ -6890,21 +6997,6 @@ function usePearAuth() {
6890
6997
  logout: ctx.logout,
6891
6998
  };
6892
6999
  }
6893
- /**
6894
- * Provider-aware Agent Wallet hook. Uses agent wallet state/actions provided by PearHyperliquidProvider.
6895
- */
6896
- function usePearAgentWallet() {
6897
- const ctx = usePearHyperliquid();
6898
- return {
6899
- agentWallet: ctx.agentWallet,
6900
- isReady: ctx.isAgentWalletReady,
6901
- loading: ctx.agentWalletLoading,
6902
- error: ctx.agentWalletError,
6903
- refreshAgentWalletStatus: ctx.refreshAgentWalletStatus,
6904
- createAgentWallet: ctx.createAgentWallet,
6905
- notifyAgentWalletApproved: ctx.notifyAgentWalletApproved,
6906
- };
6907
- }
6908
7000
 
6909
7001
  /**
6910
7002
  * Detects conflicts between selected tokens and existing positions
@@ -6993,4 +7085,4 @@ function mapCandleIntervalToTradingViewInterval(interval) {
6993
7085
  }
6994
7086
  }
6995
7087
 
6996
- export { AccountSummaryCalculator, AuthStatus, ConflictDetector, MINIMUM_ASSET_USD_VALUE, MinimumPositionSizeError, PearHyperliquidProvider, TokenMetadataExtractor, adjustOrder, adjustPosition, calculateMinimumPositionValue, calculateWeightedRatio, cancelOrder, cancelTwap, cancelTwapOrder, closeAllPositions, closePosition, computeBasketCandles, createCandleLookups, createPosition, getCompleteTimestamps, getPortfolio, mapCandleIntervalToTradingViewInterval, mapTradingViewIntervalToCandleInterval, markNotificationReadById, markNotificationsRead, toggleWatchlist, updateRiskParameters, useAccountSummary, useActiveBaskets, useAddress, useAgentWallet, useAllBaskets, useAutoSyncFills, useBasketCandles, useFindBasket, useHighlightedBaskets, useHistoricalPriceData, useHistoricalPriceDataStore, useHyperliquidNativeWebSocket, useHyperliquidWebSocket, useMarketData, useMarketDataAllPayload, useMarketDataPayload, useNotifications, useOpenOrders, useOrders, usePearAgentWallet, usePearAuth, usePearHyperliquid, usePerformanceOverlays, usePortfolio, usePosition, useTokenSelectionMetadata, useTopGainers, useTopLosers, useTradeHistories, useTwap, useUserSelection, useWatchlist, useWatchlistBaskets, useWebData, validateMinimumAssetSize, validatePositionSize };
7088
+ export { AccountSummaryCalculator, AuthStatus, ConflictDetector, MINIMUM_ASSET_USD_VALUE, MinimumPositionSizeError, PearHyperliquidProvider, TokenMetadataExtractor, adjustOrder, adjustPosition, calculateMinimumPositionValue, calculateWeightedRatio, cancelOrder, cancelTwap, cancelTwapOrder, closeAllPositions, closePosition, computeBasketCandles, createCandleLookups, createPosition, getCompleteTimestamps, getPortfolio, mapCandleIntervalToTradingViewInterval, mapTradingViewIntervalToCandleInterval, markNotificationReadById, markNotificationsRead, toggleWatchlist, updateRiskParameters, useAccountSummary, useActiveBaskets, useAgentWallet, useAllBaskets, useAutoSyncFills, useBasketCandles, useFindBasket, useHighlightedBaskets, useHistoricalPriceData, useHistoricalPriceDataStore, useHyperliquidNativeWebSocket, useHyperliquidWebSocket, useMarketData, useMarketDataAllPayload, useMarketDataPayload, useNotifications, useOpenOrders, useOrders, usePearAuth, usePearHyperliquid, usePerformanceOverlays, usePortfolio, usePosition, useTokenSelectionMetadata, useTopGainers, useTopLosers, useTradeHistories, useTwap, useUserSelection, useWatchlist, useWatchlistBaskets, useWebData, validateMinimumAssetSize, validatePositionSize };