@pear-protocol/hyperliquid-sdk 0.0.7-2.1 → 0.0.7-3.beta

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
@@ -1,6 +1,5 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
- import { useState, useRef, useCallback, useEffect, useMemo, useContext, createContext } from 'react';
3
- import { create } from 'zustand';
2
+ import React, { useState, useRef, useCallback, useEffect, useMemo, useContext, createContext } from 'react';
4
3
 
5
4
  // Browser-compatible WebSocket ready state enum (mirrors native values)
6
5
  var ReadyState;
@@ -11,10 +10,52 @@ var ReadyState;
11
10
  ReadyState[ReadyState["CLOSED"] = 3] = "CLOSED";
12
11
  })(ReadyState || (ReadyState = {}));
13
12
 
13
+ const createStoreImpl = (createState) => {
14
+ let state;
15
+ const listeners = /* @__PURE__ */ new Set();
16
+ const setState = (partial, replace) => {
17
+ const nextState = typeof partial === "function" ? partial(state) : partial;
18
+ if (!Object.is(nextState, state)) {
19
+ const previousState = state;
20
+ state = (replace != null ? replace : typeof nextState !== "object" || nextState === null) ? nextState : Object.assign({}, state, nextState);
21
+ listeners.forEach((listener) => listener(state, previousState));
22
+ }
23
+ };
24
+ const getState = () => state;
25
+ const getInitialState = () => initialState;
26
+ const subscribe = (listener) => {
27
+ listeners.add(listener);
28
+ return () => listeners.delete(listener);
29
+ };
30
+ const api = { setState, getState, getInitialState, subscribe };
31
+ const initialState = state = createState(setState, getState, api);
32
+ return api;
33
+ };
34
+ const createStore = ((createState) => createState ? createStoreImpl(createState) : createStoreImpl);
35
+
36
+ const identity = (arg) => arg;
37
+ function useStore(api, selector = identity) {
38
+ const slice = React.useSyncExternalStore(
39
+ api.subscribe,
40
+ React.useCallback(() => selector(api.getState()), [api, selector]),
41
+ React.useCallback(() => selector(api.getInitialState()), [api, selector])
42
+ );
43
+ React.useDebugValue(slice);
44
+ return slice;
45
+ }
46
+ const createImpl = (createState) => {
47
+ const api = createStore(createState);
48
+ const useBoundStore = (selector) => useStore(api, selector);
49
+ Object.assign(useBoundStore, api);
50
+ return useBoundStore;
51
+ };
52
+ const create = ((createState) => createState ? createImpl(createState) : createImpl);
53
+
14
54
  const useUserData = create((set) => ({
15
55
  accessToken: null,
16
56
  refreshToken: null,
17
57
  isAuthenticated: false,
58
+ isReady: false,
18
59
  address: null,
19
60
  tradeHistories: null,
20
61
  rawOpenPositions: null,
@@ -23,40 +64,38 @@ const useUserData = create((set) => ({
23
64
  twapDetails: null,
24
65
  notifications: null,
25
66
  userExtraAgents: null,
26
- spotState: null,
27
67
  setAccessToken: (token) => set({ accessToken: token }),
28
68
  setRefreshToken: (token) => set({ refreshToken: token }),
29
69
  setIsAuthenticated: (value) => set({ isAuthenticated: value }),
30
- setAddress: (address) => set(() => {
31
- if (typeof window !== 'undefined') {
32
- if (address) {
33
- window.localStorage.setItem('address', address);
34
- }
35
- else {
36
- window.localStorage.removeItem('address');
37
- }
38
- }
39
- return { address };
40
- }),
70
+ setIsReady: (value) => set({ isReady: value }),
71
+ setAddress: (address) => {
72
+ // if (typeof window !== "undefined") {
73
+ // if (address) {
74
+ // window.localStorage.setItem("address", address);
75
+ // } else {
76
+ // window.localStorage.removeItem("address");
77
+ // }
78
+ // }
79
+ set({ address });
80
+ },
41
81
  setTradeHistories: (value) => set({ tradeHistories: value }),
42
82
  setRawOpenPositions: (value) => set({ rawOpenPositions: value }),
43
83
  setOpenOrders: (value) => set({ openOrders: value }),
44
84
  setAccountSummary: (value) => set({ accountSummary: value }),
45
85
  setTwapDetails: (value) => set({ twapDetails: value }),
46
86
  setNotifications: (value) => set({ notifications: value }),
47
- setSpotState: (value) => set({ spotState: value }),
48
87
  clean: () => set({
49
- accessToken: null,
50
- refreshToken: null,
51
- isAuthenticated: false,
52
- address: null,
88
+ // accessToken: null,
89
+ // refreshToken: null,
90
+ // isAuthenticated: false,
91
+ // isReady: false,
92
+ // address: null,
53
93
  tradeHistories: null,
54
94
  rawOpenPositions: null,
55
95
  openOrders: null,
56
96
  accountSummary: null,
57
97
  twapDetails: null,
58
98
  notifications: null,
59
- spotState: null,
60
99
  }),
61
100
  setUserExtraAgents: (value) => set({ userExtraAgents: value }),
62
101
  }));
@@ -74,71 +113,18 @@ const useMarketData = create((set) => ({
74
113
  * Convert a full/prefixed symbol (e.g., "xyz:XYZ100") to a display symbol (e.g., "XYZ100").
75
114
  */
76
115
  function toDisplaySymbol(symbol) {
77
- const parts = symbol.split(':');
116
+ const parts = symbol.split(":");
78
117
  return parts.length > 1 ? parts.slice(-1)[0] : symbol;
79
118
  }
80
119
  /**
81
120
  * Convert a display symbol back to backend form using a provided map.
82
121
  * If mapping is missing, returns the original symbol.
83
- * For multi-market assets, returns the first available market.
84
- * @param displaySymbol e.g., "TSLA"
85
- * @param hip3Assets map of display -> all full market names (e.g., "TSLA" -> ["xyz:TSLA", "flx:TSLA"])
86
- */
87
- function toBackendSymbol(displaySymbol, hip3Assets) {
88
- const markets = hip3Assets.get(displaySymbol);
89
- // Return first market if available, otherwise return original symbol
90
- return markets && markets.length > 0 ? markets[0] : displaySymbol;
91
- }
92
- /**
93
- * Convert a display symbol to backend form for a specific market prefix.
94
- * This is useful when an asset is available on multiple markets (e.g., xyz:TSLA and flx:TSLA).
95
- * @param displaySymbol e.g., "TSLA"
96
- * @param marketPrefix e.g., "xyz" or "flx"
97
- * @param hip3Assets map of display -> all full market names
98
- * @returns Full market name if found, null if prefix not specified for multi-market asset, otherwise displaySymbol with prefix
99
- */
100
- function toBackendSymbolWithMarket(displaySymbol, marketPrefix, hip3Assets) {
101
- const availableMarkets = hip3Assets.get(displaySymbol);
102
- if (!availableMarkets || availableMarkets.length === 0) {
103
- // Not a HIP-3 asset, return as-is or with prefix if provided
104
- return marketPrefix ? `${marketPrefix}:${displaySymbol}` : displaySymbol;
105
- }
106
- if (marketPrefix) {
107
- // Find the market with the specified prefix
108
- const targetMarket = availableMarkets.find((market) => market.toLowerCase().startsWith(`${marketPrefix.toLowerCase()}:`));
109
- if (targetMarket) {
110
- return targetMarket;
111
- }
112
- }
113
- // No prefix specified or not found, return null to force explicit market selection
114
- return null;
115
- }
116
- /**
117
- * Get all available markets for a display symbol.
118
- * @param displaySymbol e.g., "TSLA"
119
- * @param hip3Assets map of display -> all full market names
120
- * @returns Array of full market names, e.g., ["xyz:TSLA", "flx:TSLA"]
122
+ * @param displaySymbol e.g., "XYZ100"
123
+ * @param displayToFull map of display -> full (e.g., "XYZ100" -> "xyz:XYZ100")
121
124
  */
122
- function getAvailableMarkets(displaySymbol, hip3Assets) {
125
+ function toBackendSymbol(displaySymbol, displayToFull) {
123
126
  var _a;
124
- return (_a = hip3Assets.get(displaySymbol)) !== null && _a !== void 0 ? _a : [];
125
- }
126
- /**
127
- * Extract the market prefix from a full market name.
128
- * @param fullSymbol e.g., "xyz:TSLA"
129
- * @returns The prefix (e.g., "xyz") or undefined if no prefix
130
- */
131
- function getMarketPrefix(fullSymbol) {
132
- const parts = fullSymbol.split(':');
133
- return parts.length > 1 ? parts[0] : undefined;
134
- }
135
- /**
136
- * Check if a symbol is a HIP-3 market (has a prefix).
137
- * @param symbol e.g., "xyz:TSLA" or "TSLA"
138
- * @returns true if the symbol has a market prefix
139
- */
140
- function isHip3Market(symbol) {
141
- return symbol.includes(':');
127
+ return (_a = displayToFull.get(displaySymbol)) !== null && _a !== void 0 ? _a : displaySymbol;
142
128
  }
143
129
 
144
130
  const useHyperliquidWebSocket = ({ wsUrl, address, enabled = true, }) => {
@@ -155,8 +141,7 @@ const useHyperliquidWebSocket = ({ wsUrl, address, enabled = true, }) => {
155
141
  try {
156
142
  const message = JSON.parse(event.data);
157
143
  // Handle subscription responses (only if they don't have channel data)
158
- if (('success' in message || 'error' in message) &&
159
- !('channel' in message)) {
144
+ if (('success' in message || 'error' in message) && !('channel' in message)) {
160
145
  if (message.error) {
161
146
  setLastError(message.error);
162
147
  }
@@ -175,21 +160,12 @@ const useHyperliquidWebSocket = ({ wsUrl, address, enabled = true, }) => {
175
160
  switch (dataMessage.channel) {
176
161
  case 'trade-histories':
177
162
  {
178
- const mapAsset = (a) => {
179
- var _a, _b;
180
- const extractedPrefix = getMarketPrefix(a.coin);
181
- return {
182
- ...a,
183
- coin: toDisplaySymbol(a.coin),
184
- marketPrefix: (_b = (_a = a.marketPrefix) !== null && _a !== void 0 ? _a : extractedPrefix) !== null && _b !== void 0 ? _b : null,
185
- };
186
- };
187
163
  const list = dataMessage.data.map((item) => {
188
164
  var _a, _b;
189
165
  return ({
190
166
  ...item,
191
- closedLongAssets: item.closedLongAssets.map(mapAsset),
192
- closedShortAssets: item.closedShortAssets.map(mapAsset),
167
+ closedLongAssets: item.closedLongAssets.map((a) => ({ ...a, coin: toDisplaySymbol(a.coin) })),
168
+ closedShortAssets: item.closedShortAssets.map((a) => ({ ...a, coin: toDisplaySymbol(a.coin) })),
193
169
  positionLongAssets: (_a = item.positionLongAssets) === null || _a === void 0 ? void 0 : _a.map((a) => toDisplaySymbol(a)),
194
170
  positionShortAssets: (_b = item.positionShortAssets) === null || _b === void 0 ? void 0 : _b.map((a) => toDisplaySymbol(a)),
195
171
  });
@@ -199,19 +175,10 @@ const useHyperliquidWebSocket = ({ wsUrl, address, enabled = true, }) => {
199
175
  break;
200
176
  case 'open-positions':
201
177
  {
202
- const enrichAsset = (a) => {
203
- var _a, _b;
204
- const extractedPrefix = getMarketPrefix(a.coin);
205
- return {
206
- ...a,
207
- coin: toDisplaySymbol(a.coin),
208
- marketPrefix: (_b = (_a = a.marketPrefix) !== null && _a !== void 0 ? _a : extractedPrefix) !== null && _b !== void 0 ? _b : null,
209
- };
210
- };
211
178
  const list = dataMessage.data.map((pos) => ({
212
179
  ...pos,
213
- longAssets: pos.longAssets.map(enrichAsset),
214
- shortAssets: pos.shortAssets.map(enrichAsset),
180
+ longAssets: pos.longAssets.map((a) => ({ ...a, coin: toDisplaySymbol(a.coin) })),
181
+ shortAssets: pos.shortAssets.map((a) => ({ ...a, coin: toDisplaySymbol(a.coin) })),
215
182
  }));
216
183
  setRawOpenPositions(list);
217
184
  }
@@ -220,14 +187,8 @@ const useHyperliquidWebSocket = ({ wsUrl, address, enabled = true, }) => {
220
187
  {
221
188
  const list = dataMessage.data.map((order) => ({
222
189
  ...order,
223
- longAssets: order.longAssets.map((a) => ({
224
- ...a,
225
- asset: toDisplaySymbol(a.asset),
226
- })),
227
- shortAssets: order.shortAssets.map((a) => ({
228
- ...a,
229
- asset: toDisplaySymbol(a.asset),
230
- })),
190
+ longAssets: order.longAssets.map((a) => ({ ...a, asset: toDisplaySymbol(a.asset) })),
191
+ shortAssets: order.shortAssets.map((a) => ({ ...a, asset: toDisplaySymbol(a.asset) })),
231
192
  }));
232
193
  setOpenOrders(list);
233
194
  }
@@ -237,20 +198,10 @@ const useHyperliquidWebSocket = ({ wsUrl, address, enabled = true, }) => {
237
198
  break;
238
199
  case 'twap-details':
239
200
  {
240
- const mapTwapAsset = (a) => {
241
- var _a, _b, _c;
242
- const extractedPrefix = getMarketPrefix(a.asset);
243
- return {
244
- ...a,
245
- asset: toDisplaySymbol(a.asset),
246
- marketPrefix: (_b = (_a = a.marketPrefix) !== null && _a !== void 0 ? _a : extractedPrefix) !== null && _b !== void 0 ? _b : null,
247
- collateralToken: (_c = a.collateralToken) !== null && _c !== void 0 ? _c : undefined,
248
- };
249
- };
250
201
  const list = dataMessage.data.map((twap) => ({
251
202
  ...twap,
252
- longAssets: twap.longAssets.map(mapTwapAsset),
253
- shortAssets: twap.shortAssets.map(mapTwapAsset),
203
+ longAssets: twap.longAssets.map((a) => ({ ...a, asset: toDisplaySymbol(a.asset) })),
204
+ shortAssets: twap.shortAssets.map((a) => ({ ...a, asset: toDisplaySymbol(a.asset) })),
254
205
  }));
255
206
  setTwapDetails(list);
256
207
  }
@@ -263,14 +214,8 @@ const useHyperliquidWebSocket = ({ wsUrl, address, enabled = true, }) => {
263
214
  const md = dataMessage.data;
264
215
  const mapGroup = (g) => ({
265
216
  ...g,
266
- longAssets: g.longAssets.map((a) => ({
267
- ...a,
268
- asset: toDisplaySymbol(a.asset),
269
- })),
270
- shortAssets: g.shortAssets.map((a) => ({
271
- ...a,
272
- asset: toDisplaySymbol(a.asset),
273
- })),
217
+ longAssets: g.longAssets.map((a) => ({ ...a, asset: toDisplaySymbol(a.asset) })),
218
+ shortAssets: g.shortAssets.map((a) => ({ ...a, asset: toDisplaySymbol(a.asset) })),
274
219
  });
275
220
  const mapped = {
276
221
  active: md.active.map(mapGroup),
@@ -288,15 +233,7 @@ const useHyperliquidWebSocket = ({ wsUrl, address, enabled = true, }) => {
288
233
  catch (error) {
289
234
  setLastError(`Failed to parse message: ${error instanceof Error ? error.message : String(error)}`);
290
235
  }
291
- }, [
292
- setTradeHistories,
293
- setRawOpenPositions,
294
- setOpenOrders,
295
- setAccountSummary,
296
- setTwapDetails,
297
- setNotifications,
298
- setMarketData,
299
- ]);
236
+ }, [setTradeHistories, setRawOpenPositions, setOpenOrders, setAccountSummary, setTwapDetails, setNotifications, setMarketData]);
300
237
  const connect = useCallback(() => {
301
238
  if (!enabled || !wsUrl)
302
239
  return;
@@ -365,7 +302,7 @@ const useHyperliquidWebSocket = ({ wsUrl, address, enabled = true, }) => {
365
302
  'open-orders',
366
303
  'twap-details',
367
304
  'fills-checkpoint',
368
- 'notifications',
305
+ 'notifications'
369
306
  ];
370
307
  const globalChannels = ['market-data'];
371
308
  if (address && address !== lastSubscribedAddress) {
@@ -374,14 +311,14 @@ const useHyperliquidWebSocket = ({ wsUrl, address, enabled = true, }) => {
374
311
  sendMessage(JSON.stringify({
375
312
  action: 'unsubscribe',
376
313
  address: lastSubscribedAddress,
377
- channels: addressSpecificChannels,
314
+ channels: addressSpecificChannels
378
315
  }));
379
316
  }
380
317
  // Subscribe to all channels (global + address-specific)
381
318
  sendMessage(JSON.stringify({
382
319
  action: 'subscribe',
383
320
  address: address,
384
- channels: [...globalChannels, ...addressSpecificChannels],
321
+ channels: [...globalChannels, ...addressSpecificChannels]
385
322
  }));
386
323
  setLastSubscribedAddress(address);
387
324
  setLastError(null);
@@ -391,7 +328,7 @@ const useHyperliquidWebSocket = ({ wsUrl, address, enabled = true, }) => {
391
328
  sendMessage(JSON.stringify({
392
329
  action: 'unsubscribe',
393
330
  address: lastSubscribedAddress,
394
- channels: addressSpecificChannels,
331
+ channels: addressSpecificChannels
395
332
  }));
396
333
  setLastSubscribedAddress(null);
397
334
  }
@@ -399,7 +336,7 @@ const useHyperliquidWebSocket = ({ wsUrl, address, enabled = true, }) => {
399
336
  // If no address but connected, subscribe to global channels only
400
337
  sendMessage(JSON.stringify({
401
338
  action: 'subscribe',
402
- channels: globalChannels,
339
+ channels: globalChannels
403
340
  }));
404
341
  }
405
342
  }, [isConnected, address, lastSubscribedAddress, sendMessage]);
@@ -422,14 +359,11 @@ const useHyperliquidData = create((set, get) => ({
422
359
  finalAssetContexts: null,
423
360
  finalAtOICaps: null,
424
361
  aggregatedClearingHouseState: null,
425
- rawClearinghouseStates: null,
426
362
  perpMetaAssets: null,
427
- allPerpMetaAssets: null,
428
- hip3Assets: new Map(),
429
- hip3MarketPrefixes: new Map(),
363
+ hip3DisplayToFull: new Map(),
430
364
  setAllMids: (value) => set({ allMids: value }),
431
365
  setActiveAssetData: (value) => set((state) => ({
432
- activeAssetData: typeof value === 'function' ? value(state.activeAssetData) : value,
366
+ activeAssetData: typeof value === 'function' ? value(state.activeAssetData) : value
433
367
  })),
434
368
  deleteActiveAssetData: (key) => {
435
369
  set((state) => {
@@ -464,16 +398,13 @@ const useHyperliquidData = create((set, get) => ({
464
398
  activeAssetData: {
465
399
  ...state.activeAssetData,
466
400
  [key]: value,
467
- },
401
+ }
468
402
  })),
469
403
  setFinalAssetContexts: (value) => set({ finalAssetContexts: value }),
470
404
  setFinalAtOICaps: (value) => set({ finalAtOICaps: value }),
471
405
  setAggregatedClearingHouseState: (value) => set({ aggregatedClearingHouseState: value }),
472
- setRawClearinghouseStates: (value) => set({ rawClearinghouseStates: value }),
473
406
  setPerpMetaAssets: (value) => set({ perpMetaAssets: value }),
474
- setAllPerpMetaAssets: (value) => set({ allPerpMetaAssets: value }),
475
- setHip3Assets: (value) => set({ hip3Assets: value }),
476
- setHip3MarketPrefixes: (value) => set({ hip3MarketPrefixes: value }),
407
+ setHip3DisplayToFull: (value) => set({ hip3DisplayToFull: value })
477
408
  }));
478
409
 
479
410
  /**
@@ -736,8 +667,7 @@ const useUserSelection$1 = create((set, get) => ({
736
667
  }));
737
668
 
738
669
  const useHyperliquidNativeWebSocket = ({ address, enabled = true, }) => {
739
- const { setAllMids, setActiveAssetData, upsertActiveAssetData, setCandleData, deleteCandleSymbol, deleteActiveAssetData, addCandleData, setFinalAssetContexts, setFinalAtOICaps, setAggregatedClearingHouseState, setRawClearinghouseStates, } = useHyperliquidData();
740
- const { setSpotState } = useUserData();
670
+ const { setAllMids, setActiveAssetData, upsertActiveAssetData, setCandleData, deleteCandleSymbol, deleteActiveAssetData, addCandleData, setFinalAssetContexts, setFinalAtOICaps, setAggregatedClearingHouseState, } = useHyperliquidData();
741
671
  const { candleInterval } = useUserSelection$1();
742
672
  const longTokens = useUserSelection$1((s) => s.longTokens);
743
673
  const shortTokens = useUserSelection$1((s) => s.shortTokens);
@@ -756,9 +686,9 @@ const useHyperliquidNativeWebSocket = ({ address, enabled = true, }) => {
756
686
  try {
757
687
  const message = JSON.parse(event.data);
758
688
  // Handle subscription responses
759
- if ('success' in message || 'error' in message) {
689
+ if ("success" in message || "error" in message) {
760
690
  if (message.error) {
761
- console.error('[HyperLiquid WS] Subscription error:', message.error);
691
+ console.error("[HyperLiquid WS] Subscription error:", message.error);
762
692
  setLastError(message.error);
763
693
  }
764
694
  else {
@@ -767,44 +697,30 @@ const useHyperliquidNativeWebSocket = ({ address, enabled = true, }) => {
767
697
  return;
768
698
  }
769
699
  // Handle channel data messages
770
- if ('channel' in message && 'data' in message) {
700
+ if ("channel" in message && "data" in message) {
771
701
  const response = message;
772
702
  switch (response.channel) {
773
- case 'webData3':
703
+ case "webData3":
774
704
  const webData3 = response.data;
775
705
  // finalAssetContexts now sourced from allDexsAssetCtxs channel
776
706
  const finalAtOICaps = webData3.perpDexStates.flatMap((dex) => dex.perpsAtOpenInterestCap);
777
707
  setFinalAtOICaps(finalAtOICaps);
778
708
  break;
779
- case 'allDexsAssetCtxs':
709
+ case "allDexsAssetCtxs":
780
710
  {
781
711
  const data = response.data;
782
- // Filter out hyna to match perpMetaAssets filtering
783
- const FILTERED_DEX_PREFIXES = ['hyna'];
784
- const filtered = (data.ctxs || [])
785
- .filter(([prefix]) => !FILTERED_DEX_PREFIXES.includes((prefix || '').toLowerCase()))
786
- .sort((a, b) => {
787
- // Sort to match perpMetaAssets order: default market first, then alphabetically
788
- const prefixA = a[0] || '';
789
- const prefixB = b[0] || '';
790
- if (prefixA === '' && prefixB !== '')
791
- return -1;
792
- if (prefixA !== '' && prefixB === '')
793
- return 1;
794
- return prefixA.localeCompare(prefixB);
795
- });
796
- const finalAssetContexts = filtered.flatMap(([, ctxs]) => ctxs || []);
712
+ const finalAssetContexts = (data.ctxs || []).flatMap(([, ctxs]) => ctxs || []);
797
713
  setFinalAssetContexts(finalAssetContexts);
798
714
  }
799
715
  break;
800
- case 'allDexsClearinghouseState':
716
+ case "allDexsClearinghouseState":
801
717
  {
802
718
  const data = response.data;
803
719
  const states = (data.clearinghouseStates || [])
804
720
  .map(([, s]) => s)
805
721
  .filter(Boolean);
806
- const sum = (values) => values.reduce((acc, v) => acc + (parseFloat(v || '0') || 0), 0);
807
- const toStr = (n) => Number.isFinite(n) ? n.toString() : '0';
722
+ const sum = (values) => values.reduce((acc, v) => acc + (parseFloat(v || "0") || 0), 0);
723
+ const toStr = (n) => Number.isFinite(n) ? n.toString() : "0";
808
724
  const assetPositions = states.flatMap((s) => s.assetPositions || []);
809
725
  const crossMaintenanceMarginUsed = toStr(sum(states.map((s) => s.crossMaintenanceMarginUsed)));
810
726
  const crossMarginSummary = {
@@ -830,41 +746,22 @@ const useHyperliquidNativeWebSocket = ({ address, enabled = true, }) => {
830
746
  withdrawable,
831
747
  };
832
748
  setAggregatedClearingHouseState(aggregatedClearingHouseState);
833
- setRawClearinghouseStates(data.clearinghouseStates || null);
834
749
  }
835
750
  break;
836
- case 'allMids':
751
+ case "allMids":
837
752
  {
838
753
  const data = response.data;
839
- // Keep BOTH normalized prefixed keys AND display symbol keys
840
- // This ensures xyz:TSLA and flx:TSLA are stored separately,
841
- // while also maintaining backward compatibility with non-prefixed lookups
842
- const mids = {};
843
- Object.entries(data.mids || {}).forEach(([k, v]) => {
844
- // Normalize prefixed keys to lowercase prefix (e.g., "XYZ:TSLA" -> "xyz:TSLA")
845
- // This matches how we look up tokens in the SDK
846
- let normalizedKey = k;
847
- if (k.includes(':')) {
848
- const [prefix, ...rest] = k.split(':');
849
- normalizedKey = `${prefix.toLowerCase()}:${rest.join(':')}`;
850
- }
851
- // Store with normalized key
852
- mids[normalizedKey] = v;
853
- // Also store with original key for backward compatibility
854
- if (k !== normalizedKey) {
855
- mids[k] = v;
856
- }
857
- // Also store with display symbol for backward compatibility
858
- const displayKey = toDisplaySymbol(k);
859
- // Only set display key if it doesn't already exist (avoid overwriting market-specific prices)
860
- if (!(displayKey in mids)) {
861
- mids[displayKey] = v;
862
- }
863
- });
864
- setAllMids({ mids });
754
+ const remapped = {
755
+ mids: Object.fromEntries(
756
+ // only support non hip-3 and xyz market
757
+ Object.entries(data.mids || {})
758
+ .filter(([k, v]) => !k.includes(":") || k.includes("xyz:"))
759
+ .map(([k, v]) => [toDisplaySymbol(k), v])),
760
+ };
761
+ setAllMids(remapped);
865
762
  }
866
763
  break;
867
- case 'activeAssetData':
764
+ case "activeAssetData":
868
765
  {
869
766
  const assetData = response.data;
870
767
  const symbol = toDisplaySymbol(assetData.coin);
@@ -875,22 +772,14 @@ const useHyperliquidNativeWebSocket = ({ address, enabled = true, }) => {
875
772
  upsertActiveAssetData(symbol, normalized);
876
773
  }
877
774
  break;
878
- case 'candle':
775
+ case "candle":
879
776
  {
880
777
  const candleDataItem = response.data;
881
- const symbol = toDisplaySymbol(candleDataItem.s || '');
778
+ const symbol = toDisplaySymbol(candleDataItem.s || "");
882
779
  const normalized = { ...candleDataItem, s: symbol };
883
780
  addCandleData(symbol, normalized);
884
781
  }
885
782
  break;
886
- case 'spotState':
887
- {
888
- const spotStateData = response.data;
889
- if (spotStateData === null || spotStateData === void 0 ? void 0 : spotStateData.spotState) {
890
- setSpotState(spotStateData.spotState);
891
- }
892
- }
893
- break;
894
783
  default:
895
784
  console.warn(`[HyperLiquid WS] Unknown channel: ${response.channel}`);
896
785
  }
@@ -898,7 +787,7 @@ const useHyperliquidNativeWebSocket = ({ address, enabled = true, }) => {
898
787
  }
899
788
  catch (error) {
900
789
  const errorMessage = `Failed to parse message: ${error instanceof Error ? error.message : String(error)}`;
901
- console.error('[HyperLiquid WS] Parse error:', errorMessage, 'Raw message:', event.data);
790
+ console.error("[HyperLiquid WS] Parse error:", errorMessage, "Raw message:", event.data);
902
791
  setLastError(errorMessage);
903
792
  }
904
793
  }, [
@@ -908,8 +797,6 @@ const useHyperliquidNativeWebSocket = ({ address, enabled = true, }) => {
908
797
  setFinalAssetContexts,
909
798
  setFinalAtOICaps,
910
799
  setAggregatedClearingHouseState,
911
- setRawClearinghouseStates,
912
- setSpotState,
913
800
  ]);
914
801
  const connect = useCallback(() => {
915
802
  if (!enabled)
@@ -940,7 +827,7 @@ const useHyperliquidNativeWebSocket = ({ address, enabled = true, }) => {
940
827
  if (!manualCloseRef.current && reconnectAttemptsRef.current < 5) {
941
828
  reconnectAttemptsRef.current += 1;
942
829
  if (reconnectAttemptsRef.current === 5) {
943
- console.error('[HyperLiquid WS] Reconnection stopped after 5 attempts');
830
+ console.error("[HyperLiquid WS] Reconnection stopped after 5 attempts");
944
831
  }
945
832
  setTimeout(() => connect(), 3000);
946
833
  }
@@ -1008,17 +895,6 @@ const useHyperliquidNativeWebSocket = ({ address, enabled = true, }) => {
1008
895
  },
1009
896
  };
1010
897
  sendJsonMessage(unsubscribeMessage);
1011
- // Unsubscribe from spotState for previous address
1012
- if (subscribedAddress !== DEFAULT_ADDRESS) {
1013
- const unsubscribeSpotState = {
1014
- method: 'unsubscribe',
1015
- subscription: {
1016
- type: 'spotState',
1017
- user: subscribedAddress,
1018
- },
1019
- };
1020
- sendJsonMessage(unsubscribeSpotState);
1021
- }
1022
898
  const unsubscribeAllDexsClearinghouseState = {
1023
899
  method: "unsubscribe",
1024
900
  subscription: {
@@ -1062,26 +938,11 @@ const useHyperliquidNativeWebSocket = ({ address, enabled = true, }) => {
1062
938
  sendJsonMessage(subscribeAllDexsClearinghouseState);
1063
939
  sendJsonMessage(subscribeAllMids);
1064
940
  sendJsonMessage(subscribeAllDexsAssetCtxs);
1065
- // Subscribe to spotState for real-time spot balances (USDH, USDC, etc.)
1066
- // Only subscribe if we have a real user address (not the default)
1067
- if (userAddress !== DEFAULT_ADDRESS) {
1068
- const subscribeSpotState = {
1069
- method: 'subscribe',
1070
- subscription: {
1071
- type: 'spotState',
1072
- user: userAddress,
1073
- },
1074
- };
1075
- sendJsonMessage(subscribeSpotState);
1076
- }
1077
941
  setSubscribedAddress(userAddress);
1078
942
  // Clear previous data when address changes
1079
943
  if (subscribedAddress && subscribedAddress !== userAddress) {
1080
944
  // clear aggregatedClearingHouseState
1081
945
  setAggregatedClearingHouseState(null);
1082
- setRawClearinghouseStates(null);
1083
- // clear spotState
1084
- setSpotState(null);
1085
946
  }
1086
947
  }, [
1087
948
  isConnected,
@@ -1089,8 +950,6 @@ const useHyperliquidNativeWebSocket = ({ address, enabled = true, }) => {
1089
950
  subscribedAddress,
1090
951
  sendJsonMessage,
1091
952
  setAggregatedClearingHouseState,
1092
- setRawClearinghouseStates,
1093
- setSpotState,
1094
953
  ]);
1095
954
  // Handle token subscriptions for activeAssetData
1096
955
  useEffect(() => {
@@ -1287,112 +1146,20 @@ const useAccountSummary = () => {
1287
1146
  return { data: calculated, isLoading };
1288
1147
  };
1289
1148
 
1290
- function findAssetMeta$4(coinName, perpMetaAssets, knownPrefix, desiredCollateral) {
1291
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
1292
- if (!perpMetaAssets) {
1293
- return { collateralToken: 'USDC', marketPrefix: null };
1294
- }
1295
- if (desiredCollateral) {
1296
- const collateralMatch = perpMetaAssets.find((a) => a.name === coinName && a.collateralToken === desiredCollateral);
1297
- if (collateralMatch) {
1298
- return {
1299
- collateralToken: (_a = collateralMatch.collateralToken) !== null && _a !== void 0 ? _a : 'USDC',
1300
- marketPrefix: (_b = collateralMatch.marketPrefix) !== null && _b !== void 0 ? _b : null,
1301
- };
1302
- }
1303
- }
1304
- if (coinName.includes(':')) {
1305
- const [prefix, symbol] = coinName.split(':');
1306
- const exactMatch = perpMetaAssets.find((a) => {
1307
- var _a;
1308
- return a.name === symbol &&
1309
- ((_a = a.marketPrefix) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === prefix.toLowerCase();
1310
- });
1311
- if (exactMatch) {
1312
- return {
1313
- collateralToken: (_c = exactMatch.collateralToken) !== null && _c !== void 0 ? _c : 'USDC',
1314
- marketPrefix: (_d = exactMatch.marketPrefix) !== null && _d !== void 0 ? _d : null,
1315
- };
1316
- }
1317
- }
1318
- if (knownPrefix) {
1319
- const exactMatch = perpMetaAssets.find((a) => {
1320
- var _a;
1321
- return a.name === coinName &&
1322
- ((_a = a.marketPrefix) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === knownPrefix.toLowerCase();
1323
- });
1324
- if (exactMatch) {
1325
- return {
1326
- collateralToken: (_e = exactMatch.collateralToken) !== null && _e !== void 0 ? _e : 'USDC',
1327
- marketPrefix: (_f = exactMatch.marketPrefix) !== null && _f !== void 0 ? _f : null,
1328
- };
1329
- }
1330
- }
1331
- const exactMatch = perpMetaAssets.find((a) => a.name === coinName && !a.marketPrefix);
1332
- if (exactMatch) {
1333
- return {
1334
- collateralToken: (_g = exactMatch.collateralToken) !== null && _g !== void 0 ? _g : 'USDC',
1335
- marketPrefix: (_h = exactMatch.marketPrefix) !== null && _h !== void 0 ? _h : null,
1336
- };
1337
- }
1338
- const hip3Matches = perpMetaAssets.filter((a) => a.name === coinName && a.marketPrefix);
1339
- if (hip3Matches.length > 0) {
1340
- if (desiredCollateral) {
1341
- const collateralMatch = hip3Matches.find((a) => a.collateralToken === desiredCollateral);
1342
- if (collateralMatch) {
1343
- return {
1344
- collateralToken: (_j = collateralMatch.collateralToken) !== null && _j !== void 0 ? _j : 'USDC',
1345
- marketPrefix: (_k = collateralMatch.marketPrefix) !== null && _k !== void 0 ? _k : null,
1346
- };
1347
- }
1348
- }
1349
- const usdHMatch = hip3Matches.find((a) => a.collateralToken === 'USDH');
1350
- const chosen = usdHMatch !== null && usdHMatch !== void 0 ? usdHMatch : hip3Matches[0];
1351
- return {
1352
- collateralToken: (_l = chosen.collateralToken) !== null && _l !== void 0 ? _l : 'USDC',
1353
- marketPrefix: (_m = chosen.marketPrefix) !== null && _m !== void 0 ? _m : null,
1354
- };
1355
- }
1356
- return { collateralToken: 'USDC', marketPrefix: null };
1357
- }
1358
- function enrichTradeHistoryAssets(assets, perpMetaAssets) {
1359
- return assets.map((asset) => {
1360
- var _a;
1361
- if (asset.marketPrefix && asset.collateralToken) {
1362
- return asset;
1363
- }
1364
- const meta = findAssetMeta$4(asset.coin, perpMetaAssets, asset.marketPrefix, asset.collateralToken);
1365
- return {
1366
- ...asset,
1367
- marketPrefix: asset.marketPrefix || meta.marketPrefix,
1368
- collateralToken: (_a = asset.collateralToken) !== null && _a !== void 0 ? _a : meta.collateralToken,
1369
- };
1370
- });
1371
- }
1372
- function enrichTradeHistories(histories, perpMetaAssets) {
1373
- return histories.map((history) => ({
1374
- ...history,
1375
- closedLongAssets: enrichTradeHistoryAssets(history.closedLongAssets, perpMetaAssets),
1376
- closedShortAssets: enrichTradeHistoryAssets(history.closedShortAssets, perpMetaAssets),
1377
- }));
1378
- }
1379
1149
  const useTradeHistories = () => {
1380
1150
  const context = useContext(PearHyperliquidContext);
1381
1151
  if (!context) {
1382
1152
  throw new Error('useTradeHistories must be used within a PearHyperliquidProvider');
1383
1153
  }
1384
1154
  const tradeHistories = useUserData((state) => state.tradeHistories);
1385
- const allPerpMetaAssets = useHyperliquidData((state) => state.allPerpMetaAssets);
1386
1155
  const isLoading = useMemo(() => {
1387
1156
  return tradeHistories === null && context.isConnected;
1388
1157
  }, [tradeHistories, context.isConnected]);
1389
- const enrichedTradeHistories = useMemo(() => {
1390
- if (!tradeHistories)
1391
- return null;
1392
- return enrichTradeHistories(tradeHistories, allPerpMetaAssets);
1393
- }, [tradeHistories, allPerpMetaAssets]);
1394
- return { data: enrichedTradeHistories, isLoading };
1158
+ return { data: tradeHistories, isLoading };
1395
1159
  };
1160
+ /**
1161
+ * Hook to access open orders with loading state
1162
+ */
1396
1163
  const useOpenOrders = () => {
1397
1164
  const context = useContext(PearHyperliquidContext);
1398
1165
  if (!context) {
@@ -1421,51 +1188,21 @@ const useWebData = () => {
1421
1188
  const perpMetaAssets = useHyperliquidData((state) => state.perpMetaAssets);
1422
1189
  const aggregatedClearinghouseState = useHyperliquidData((state) => state.aggregatedClearingHouseState);
1423
1190
  const finalAtOICaps = useHyperliquidData((state) => state.finalAtOICaps);
1424
- const hip3Assets = useHyperliquidData((state) => state.hip3Assets);
1425
- const hip3MarketPrefixes = useHyperliquidData((state) => state.hip3MarketPrefixes);
1191
+ const hip3Assets = useHyperliquidData((state) => state.hip3DisplayToFull);
1426
1192
  let marketDataBySymbol = {};
1427
1193
  if (finalAssetContexts && perpMetaAssets) {
1428
1194
  const result = {};
1429
- // Build a map of display name -> asset context index (for unique display names)
1430
- const displayNameToContextIndex = new Map();
1431
- const seenNames = new Set();
1432
- let contextIndex = 0;
1433
- // First pass: map unique display names to their context index
1434
1195
  for (let index = 0; index < perpMetaAssets.length; index++) {
1435
1196
  const name = perpMetaAssets[index].name;
1436
- if (!seenNames.has(name)) {
1437
- seenNames.add(name);
1438
- if (contextIndex < finalAssetContexts.length) {
1439
- displayNameToContextIndex.set(name, contextIndex);
1440
- contextIndex++;
1441
- }
1442
- }
1443
- }
1444
- // Second pass: create nested entries for all market variants
1445
- for (let index = 0; index < perpMetaAssets.length; index++) {
1446
- const universeAsset = perpMetaAssets[index];
1447
- const displayName = universeAsset.name;
1448
- const marketPrefix = universeAsset.marketPrefix;
1449
- const ctxIndex = displayNameToContextIndex.get(displayName);
1450
- if (ctxIndex !== undefined) {
1451
- const assetContext = finalAssetContexts[ctxIndex];
1452
- // Initialize the symbol entry if it doesn't exist
1453
- if (!result[displayName]) {
1454
- result[displayName] = {};
1455
- }
1456
- // Use marketPrefix as key for HIP-3 assets, "default" for regular assets
1457
- const variantKey = marketPrefix || 'default';
1458
- result[displayName][variantKey] = {
1459
- asset: assetContext,
1460
- universe: universeAsset,
1461
- };
1462
- }
1197
+ result[name] = {
1198
+ asset: finalAssetContexts[index],
1199
+ universe: perpMetaAssets[index],
1200
+ };
1463
1201
  }
1464
1202
  marketDataBySymbol = result;
1465
1203
  }
1466
1204
  return {
1467
1205
  hip3Assets,
1468
- hip3MarketPrefixes,
1469
1206
  clearinghouseState: aggregatedClearinghouseState,
1470
1207
  perpsAtOpenInterestCap: finalAtOICaps,
1471
1208
  marketDataBySymbol,
@@ -1480,30 +1217,19 @@ const useWebData = () => {
1480
1217
  class TokenMetadataExtractor {
1481
1218
  /**
1482
1219
  * Extracts comprehensive token metadata
1483
- * @param symbol - Token symbol (base symbol without prefix, e.g., "TSLA")
1220
+ * @param symbol - Token symbol
1484
1221
  * @param perpMetaAssets - Aggregated universe assets (flattened across dexes)
1485
1222
  * @param finalAssetContexts - Aggregated asset contexts (flattened across dexes)
1486
1223
  * @param allMids - AllMids data containing current prices
1487
1224
  * @param activeAssetData - Optional active asset data containing leverage information
1488
- * @param marketPrefix - Optional market prefix (e.g., "xyz", "flx") for HIP3 multi-market assets
1489
1225
  * @returns TokenMetadata or null if token not found
1490
1226
  */
1491
- static extractTokenMetadata(symbol, perpMetaAssets, finalAssetContexts, allMids, activeAssetData, marketPrefix) {
1227
+ static extractTokenMetadata(symbol, perpMetaAssets, finalAssetContexts, allMids, activeAssetData) {
1492
1228
  if (!perpMetaAssets || !finalAssetContexts || !allMids) {
1493
1229
  return null;
1494
1230
  }
1495
1231
  // Find token index in aggregated universe
1496
- // For HIP3 assets, match both name AND marketPrefix
1497
- const universeIndex = perpMetaAssets.findIndex((asset) => {
1498
- if (asset.name !== symbol)
1499
- return false;
1500
- // If marketPrefix is specified, match it; otherwise match assets without prefix
1501
- if (marketPrefix) {
1502
- return asset.marketPrefix === marketPrefix;
1503
- }
1504
- // No prefix specified - match non-HIP3 asset (no marketPrefix) or first matching asset
1505
- return !asset.marketPrefix;
1506
- });
1232
+ const universeIndex = perpMetaAssets.findIndex(asset => asset.name === symbol);
1507
1233
  if (universeIndex === -1) {
1508
1234
  return null;
1509
1235
  }
@@ -1512,20 +1238,9 @@ class TokenMetadataExtractor {
1512
1238
  if (!assetCtx) {
1513
1239
  return null;
1514
1240
  }
1515
- // Get current price - prefer assetCtx.midPx as it's already index-matched,
1516
- // fall back to allMids lookup if midPx is null
1517
- const prefixedKeyColon = marketPrefix ? `${marketPrefix}:${symbol}` : null;
1518
- let currentPrice = 0;
1519
- // Primary source: assetCtx.midPx (already properly indexed)
1520
- if (assetCtx.midPx) {
1521
- currentPrice = parseFloat(assetCtx.midPx);
1522
- }
1523
- // Fallback: allMids lookup with multiple key formats for HIP3 markets
1524
- if (!currentPrice || isNaN(currentPrice)) {
1525
- const currentPriceStr = (prefixedKeyColon && allMids.mids[prefixedKeyColon]) ||
1526
- allMids.mids[symbol];
1527
- currentPrice = currentPriceStr ? parseFloat(currentPriceStr) : 0;
1528
- }
1241
+ // Get current price from allMids
1242
+ const currentPriceStr = allMids.mids[symbol];
1243
+ const currentPrice = currentPriceStr ? parseFloat(currentPriceStr) : 0;
1529
1244
  // Get previous day price
1530
1245
  const prevDayPrice = parseFloat(assetCtx.prevDayPx);
1531
1246
  // Calculate 24h price change
@@ -1536,11 +1251,7 @@ class TokenMetadataExtractor {
1536
1251
  const markPrice = parseFloat(assetCtx.markPx);
1537
1252
  const oraclePrice = parseFloat(assetCtx.oraclePx);
1538
1253
  // Extract leverage info from activeAssetData if available
1539
- // Try prefixed key first (e.g., "xyz:TSLA"), then fall back to plain symbol
1540
- const activeDataKey = prefixedKeyColon && (activeAssetData === null || activeAssetData === void 0 ? void 0 : activeAssetData[prefixedKeyColon])
1541
- ? prefixedKeyColon
1542
- : symbol;
1543
- const tokenActiveData = activeAssetData === null || activeAssetData === void 0 ? void 0 : activeAssetData[activeDataKey];
1254
+ const tokenActiveData = activeAssetData === null || activeAssetData === void 0 ? void 0 : activeAssetData[symbol];
1544
1255
  const leverage = tokenActiveData === null || tokenActiveData === void 0 ? void 0 : tokenActiveData.leverage;
1545
1256
  const maxTradeSzs = tokenActiveData === null || tokenActiveData === void 0 ? void 0 : tokenActiveData.maxTradeSzs;
1546
1257
  const availableToTrade = tokenActiveData === null || tokenActiveData === void 0 ? void 0 : tokenActiveData.availableToTrade;
@@ -1558,27 +1269,21 @@ class TokenMetadataExtractor {
1558
1269
  leverage,
1559
1270
  maxTradeSzs,
1560
1271
  availableToTrade,
1561
- collateralToken: universeAsset.collateralToken,
1562
1272
  };
1563
1273
  }
1564
1274
  /**
1565
1275
  * Extracts metadata for multiple tokens
1566
- * @param tokens - Array of token objects with symbol and optional marketPrefix
1276
+ * @param symbols - Array of token symbols
1567
1277
  * @param perpMetaAssets - Aggregated universe assets
1568
1278
  * @param finalAssetContexts - Aggregated asset contexts
1569
1279
  * @param allMids - AllMids data
1570
1280
  * @param activeAssetData - Optional active asset data containing leverage information
1571
- * @returns Record of unique key to TokenMetadata. Key is "{prefix}:{symbol}" for HIP3 assets, or just "{symbol}" otherwise
1281
+ * @returns Record of symbol to TokenMetadata
1572
1282
  */
1573
- static extractMultipleTokensMetadata(tokens, perpMetaAssets, finalAssetContexts, allMids, activeAssetData) {
1283
+ static extractMultipleTokensMetadata(symbols, perpMetaAssets, finalAssetContexts, allMids, activeAssetData) {
1574
1284
  const result = {};
1575
- for (const token of tokens) {
1576
- // Use a unique key that includes the prefix for HIP3 assets
1577
- // This ensures xyz:TSLA and flx:TSLA get separate entries
1578
- const resultKey = token.marketPrefix
1579
- ? `${token.marketPrefix}:${token.symbol}`
1580
- : token.symbol;
1581
- result[resultKey] = this.extractTokenMetadata(token.symbol, perpMetaAssets, finalAssetContexts, allMids, activeAssetData, token.marketPrefix);
1285
+ for (const symbol of symbols) {
1286
+ result[symbol] = this.extractTokenMetadata(symbol, perpMetaAssets, finalAssetContexts, allMids, activeAssetData);
1582
1287
  }
1583
1288
  return result;
1584
1289
  }
@@ -1591,30 +1296,10 @@ class TokenMetadataExtractor {
1591
1296
  static isTokenAvailable(symbol, perpMetaAssets) {
1592
1297
  if (!perpMetaAssets)
1593
1298
  return false;
1594
- return perpMetaAssets.some((asset) => asset.name === symbol);
1299
+ return perpMetaAssets.some(asset => asset.name === symbol);
1595
1300
  }
1596
1301
  }
1597
1302
 
1598
- /**
1599
- * Parse a token string that may have a market prefix (e.g., "xyz:GOOGL" -> { prefix: "xyz", symbol: "GOOGL" })
1600
- * This allows us to keep the full name (xyz:GOOGL) for URLs/tags while extracting just the symbol for SDK lookups.
1601
- */
1602
- function parseTokenWithPrefix(token) {
1603
- if (token.includes(':')) {
1604
- const [prefix, ...rest] = token.split(':');
1605
- const symbol = rest.join(':').toUpperCase();
1606
- return {
1607
- prefix: prefix.toLowerCase(),
1608
- symbol,
1609
- fullName: `${prefix.toLowerCase()}:${symbol}`,
1610
- };
1611
- }
1612
- return {
1613
- prefix: null,
1614
- symbol: token.toUpperCase(),
1615
- fullName: token.toUpperCase(),
1616
- };
1617
- }
1618
1303
  const useTokenSelectionMetadataStore = create((set) => ({
1619
1304
  isPriceDataReady: false,
1620
1305
  isLoading: true,
@@ -1624,65 +1309,23 @@ const useTokenSelectionMetadataStore = create((set) => ({
1624
1309
  weightedRatio24h: 1,
1625
1310
  priceRatio: 1,
1626
1311
  priceRatio24h: 1,
1627
- openInterest: '0',
1628
- volume: '0',
1312
+ openInterest: "0",
1313
+ volume: "0",
1629
1314
  sumNetFunding: 0,
1630
1315
  maxLeverage: 0,
1631
1316
  minMargin: 0,
1632
1317
  leverageMatched: true,
1633
- recompute: ({ perpMetaAssets, finalAssetContexts, allMids, activeAssetData, marketData, longTokens, shortTokens, }) => {
1634
- const isPriceDataReady = !!(perpMetaAssets &&
1635
- finalAssetContexts &&
1636
- allMids);
1637
- // Parse tokens - handle prefixed tokens like "xyz:GOOGL" by extracting the symbol and market prefix
1638
- // The full name (xyz:GOOGL) is kept as the metadata key for UI consistency
1639
- const parsedLongTokens = longTokens.map((t) => ({
1640
- ...t,
1641
- parsed: parseTokenWithPrefix(t.symbol),
1642
- }));
1643
- const parsedShortTokens = shortTokens.map((t) => ({
1644
- ...t,
1645
- parsed: parseTokenWithPrefix(t.symbol),
1646
- }));
1647
- // Extract base symbols with their market prefixes for SDK lookups
1648
- // This ensures xyz:TSLA and flx:TSLA get different market data
1649
- const longTokensForLookup = parsedLongTokens.map((t) => ({
1650
- symbol: t.parsed.symbol,
1651
- marketPrefix: t.parsed.prefix,
1652
- }));
1653
- const shortTokensForLookup = parsedShortTokens.map((t) => ({
1654
- symbol: t.parsed.symbol,
1655
- marketPrefix: t.parsed.prefix,
1656
- }));
1657
- // Also extract just the base symbols (without prefix) for lookups that don't support prefixes
1658
- const longBaseSymbols = longTokensForLookup.map((t) => t.symbol);
1659
- const shortBaseSymbols = shortTokensForLookup.map((t) => t.symbol);
1660
- // Get metadata using base symbols with market prefix for proper market differentiation
1661
- const longBaseMetadata = isPriceDataReady
1662
- ? TokenMetadataExtractor.extractMultipleTokensMetadata(longTokensForLookup, perpMetaAssets, finalAssetContexts, allMids, activeAssetData)
1318
+ recompute: ({ perpMetaAssets, finalAssetContexts, allMids, activeAssetData, marketData, longTokens, shortTokens }) => {
1319
+ const isPriceDataReady = !!(perpMetaAssets && finalAssetContexts && allMids);
1320
+ // Compute metadata when ready
1321
+ const longSymbols = longTokens.map((t) => t.symbol);
1322
+ const shortSymbols = shortTokens.map((t) => t.symbol);
1323
+ const longTokensMetadata = isPriceDataReady
1324
+ ? TokenMetadataExtractor.extractMultipleTokensMetadata(longSymbols, perpMetaAssets, finalAssetContexts, allMids, activeAssetData)
1663
1325
  : {};
1664
- const shortBaseMetadata = isPriceDataReady
1665
- ? TokenMetadataExtractor.extractMultipleTokensMetadata(shortTokensForLookup, perpMetaAssets, finalAssetContexts, allMids, activeAssetData)
1326
+ const shortTokensMetadata = isPriceDataReady
1327
+ ? TokenMetadataExtractor.extractMultipleTokensMetadata(shortSymbols, perpMetaAssets, finalAssetContexts, allMids, activeAssetData)
1666
1328
  : {};
1667
- // Re-map metadata using original full names (with prefix) as keys for UI consistency
1668
- // The extractor now keys by "{prefix}:{symbol}" for prefixed tokens, which matches our parsed.fullName
1669
- const longTokensMetadata = {};
1670
- parsedLongTokens.forEach((t) => {
1671
- var _a;
1672
- // Use the full name (e.g., "xyz:TSLA") as the lookup key since extractor uses the same format
1673
- const lookupKey = t.parsed.prefix
1674
- ? `${t.parsed.prefix}:${t.parsed.symbol}`
1675
- : t.parsed.symbol;
1676
- longTokensMetadata[t.symbol] = (_a = longBaseMetadata[lookupKey]) !== null && _a !== void 0 ? _a : null;
1677
- });
1678
- const shortTokensMetadata = {};
1679
- parsedShortTokens.forEach((t) => {
1680
- var _a;
1681
- const lookupKey = t.parsed.prefix
1682
- ? `${t.parsed.prefix}:${t.parsed.symbol}`
1683
- : t.parsed.symbol;
1684
- shortTokensMetadata[t.symbol] = (_a = shortBaseMetadata[lookupKey]) !== null && _a !== void 0 ? _a : null;
1685
- });
1686
1329
  // Determine loading state
1687
1330
  const allTokens = [...longTokens, ...shortTokens];
1688
1331
  const isLoading = (() => {
@@ -1690,33 +1333,26 @@ const useTokenSelectionMetadataStore = create((set) => ({
1690
1333
  return true;
1691
1334
  if (allTokens.length === 0)
1692
1335
  return false;
1693
- const allMetadata = {
1694
- ...longTokensMetadata,
1695
- ...shortTokensMetadata,
1696
- };
1336
+ const allMetadata = { ...longTokensMetadata, ...shortTokensMetadata };
1697
1337
  return allTokens.some((token) => !allMetadata[token.symbol]);
1698
1338
  })();
1699
1339
  // Open interest and volume (from market data for matching asset basket)
1700
- // Use base symbols (without prefix) for matching against market data
1701
1340
  const { openInterest, volume } = (() => {
1702
- const empty = { openInterest: '0', volume: '0' };
1341
+ const empty = { openInterest: "0", volume: "0" };
1703
1342
  if (!(marketData === null || marketData === void 0 ? void 0 : marketData.active) || (!longTokens.length && !shortTokens.length))
1704
1343
  return empty;
1705
- const selectedLong = longBaseSymbols.slice().sort();
1706
- const selectedShort = shortBaseSymbols.slice().sort();
1344
+ const selectedLong = longTokens.map((t) => t.symbol).sort();
1345
+ const selectedShort = shortTokens.map((t) => t.symbol).sort();
1707
1346
  const match = marketData.active.find((item) => {
1708
1347
  const longs = [...item.longAssets].sort();
1709
1348
  const shorts = [...item.shortAssets].sort();
1710
- if (longs.length !== selectedLong.length ||
1711
- shorts.length !== selectedShort.length)
1349
+ if (longs.length !== selectedLong.length || shorts.length !== selectedShort.length)
1712
1350
  return false;
1713
1351
  const longsEqual = longs.every((s, i) => s.asset === selectedLong[i]);
1714
1352
  const shortsEqual = shorts.every((s, i) => s.asset === selectedShort[i]);
1715
1353
  return longsEqual && shortsEqual;
1716
1354
  });
1717
- return match
1718
- ? { openInterest: match.openInterest, volume: match.volume }
1719
- : empty;
1355
+ return match ? { openInterest: match.openInterest, volume: match.volume } : empty;
1720
1356
  })();
1721
1357
  // Price ratio (only when exactly one long and one short)
1722
1358
  const { priceRatio, priceRatio24h } = (() => {
@@ -1795,30 +1431,20 @@ const useTokenSelectionMetadataStore = create((set) => ({
1795
1431
  });
1796
1432
  return totalFunding;
1797
1433
  })();
1798
- // Max leverage (minimum across all tokens)
1799
- // Use tokens with their market prefixes for proper lookup in perpMetaAssets
1434
+ // Max leverage (maximum across all tokens)
1800
1435
  const maxLeverage = (() => {
1801
1436
  if (!perpMetaAssets)
1802
1437
  return 0;
1803
- const allTokensForLookup = [
1804
- ...longTokensForLookup,
1805
- ...shortTokensForLookup,
1806
- ];
1807
- if (allTokensForLookup.length === 0)
1438
+ const allTokenSymbols = [...longTokens, ...shortTokens].map((t) => t.symbol);
1439
+ if (allTokenSymbols.length === 0)
1808
1440
  return 0;
1809
- let minLev = Infinity;
1810
- allTokensForLookup.forEach(({ symbol, marketPrefix }) => {
1811
- // Match by both name AND marketPrefix for HIP3 assets
1812
- const tokenUniverse = perpMetaAssets.find((u) => u.name === symbol &&
1813
- (marketPrefix
1814
- ? u.marketPrefix === marketPrefix
1815
- : !u.marketPrefix));
1816
- // Fallback to just matching by name if no exact match
1817
- const fallbackUniverse = tokenUniverse || perpMetaAssets.find((u) => u.name === symbol);
1818
- if (fallbackUniverse === null || fallbackUniverse === void 0 ? void 0 : fallbackUniverse.maxLeverage)
1819
- minLev = Math.min(minLev, fallbackUniverse.maxLeverage);
1441
+ let maxLev = 0;
1442
+ allTokenSymbols.forEach((symbol) => {
1443
+ const tokenUniverse = perpMetaAssets.find((u) => u.name === symbol);
1444
+ if (tokenUniverse === null || tokenUniverse === void 0 ? void 0 : tokenUniverse.maxLeverage)
1445
+ maxLev = Math.max(maxLev, tokenUniverse.maxLeverage);
1820
1446
  });
1821
- return minLev === Infinity ? 0 : minLev;
1447
+ return maxLev;
1822
1448
  })();
1823
1449
  // Min margin (10 * total number of tokens)
1824
1450
  const minMargin = (() => {
@@ -1828,10 +1454,7 @@ const useTokenSelectionMetadataStore = create((set) => ({
1828
1454
  // Whether all tokens have matching leverage
1829
1455
  const leverageMatched = (() => {
1830
1456
  const allTokensArr = [...longTokens, ...shortTokens];
1831
- const allMetadata = {
1832
- ...longTokensMetadata,
1833
- ...shortTokensMetadata,
1834
- };
1457
+ const allMetadata = { ...longTokensMetadata, ...shortTokensMetadata };
1835
1458
  if (allTokensArr.length === 0)
1836
1459
  return true;
1837
1460
  const tokensWithLev = allTokensArr.filter((token) => { var _a; return (_a = allMetadata[token.symbol]) === null || _a === void 0 ? void 0 : _a.leverage; });
@@ -6016,8 +5639,8 @@ function addAuthInterceptors(params) {
6016
5639
  /**
6017
5640
  * Fetch historical candle data from HyperLiquid API
6018
5641
  */
6019
- const fetchHistoricalCandles = async (coin, startTime, endTime, interval, hip3Assets) => {
6020
- const backendCoin = toBackendSymbol(coin, hip3Assets);
5642
+ const fetchHistoricalCandles = async (coin, startTime, endTime, interval, displayToFull) => {
5643
+ const backendCoin = toBackendSymbol(coin, displayToFull);
6021
5644
  const request = {
6022
5645
  req: { coin: backendCoin, startTime, endTime, interval },
6023
5646
  type: 'candleSnapshot',
@@ -6176,10 +5799,10 @@ const useHistoricalPriceData = () => {
6176
5799
  setTokenLoading(token.symbol, true);
6177
5800
  });
6178
5801
  try {
6179
- const hip3Assets = useHyperliquidData.getState().hip3Assets;
5802
+ const displayToFull = useHyperliquidData.getState().hip3DisplayToFull;
6180
5803
  const fetchPromises = tokensToFetch.map(async (token) => {
6181
5804
  try {
6182
- const response = await fetchHistoricalCandles(token.symbol, startTime, endTime, interval, hip3Assets);
5805
+ const response = await fetchHistoricalCandles(token.symbol, startTime, endTime, interval, displayToFull);
6183
5806
  addHistoricalPriceData(token.symbol, interval, response.data, { start: startTime, end: endTime });
6184
5807
  return { symbol: token.symbol, candles: response.data, success: true };
6185
5808
  }
@@ -6868,14 +6491,14 @@ function useAutoSyncFills(options) {
6868
6491
  * @throws MinimumPositionSizeError if any asset has less than $11 USD value
6869
6492
  * @throws MaxAssetsPerLegError if any leg exceeds the maximum allowed assets (15)
6870
6493
  */
6871
- async function createPosition(baseUrl, payload, hip3Assets) {
6494
+ async function createPosition(baseUrl, payload, displayToFull) {
6872
6495
  // Validate maximum assets per leg before creating position
6873
6496
  validateMaxAssetsPerLeg(payload.longAssets, payload.shortAssets);
6874
6497
  // Validate minimum asset size before creating position
6875
6498
  validateMinimumAssetSize(payload.usdValue, payload.longAssets, payload.shortAssets);
6876
6499
  const url = joinUrl(baseUrl, "/positions");
6877
6500
  // Translate display symbols to backend format
6878
- const mapAssets = (arr) => arr === null || arr === void 0 ? void 0 : arr.map((a) => ({ ...a, asset: toBackendSymbol(a.asset, hip3Assets) }));
6501
+ const mapAssets = (arr) => arr === null || arr === void 0 ? void 0 : arr.map((a) => ({ ...a, asset: toBackendSymbol(a.asset, displayToFull) }));
6879
6502
  const translatedPayload = {
6880
6503
  ...payload,
6881
6504
  longAssets: mapAssets(payload.longAssets),
@@ -6974,9 +6597,9 @@ async function adjustPosition(baseUrl, positionId, payload) {
6974
6597
  throw toApiError(error);
6975
6598
  }
6976
6599
  }
6977
- async function adjustAdvancePosition(baseUrl, positionId, payload, hip3Assets) {
6600
+ async function adjustAdvancePosition(baseUrl, positionId, payload, displayToFull) {
6978
6601
  const url = joinUrl(baseUrl, `/positions/${positionId}/adjust-advance`);
6979
- const mapAssets = (arr) => arr === null || arr === void 0 ? void 0 : arr.map((a) => ({ ...a, asset: toBackendSymbol(a.asset, hip3Assets) }));
6602
+ const mapAssets = (arr) => arr === null || arr === void 0 ? void 0 : arr.map((a) => ({ ...a, asset: toBackendSymbol(a.asset, displayToFull) }));
6980
6603
  const translatedPayload = (payload || []).map((item) => ({
6981
6604
  longAssets: mapAssets(item.longAssets),
6982
6605
  shortAssets: mapAssets(item.shortAssets),
@@ -7059,11 +6682,10 @@ const calculatePositionAsset = (asset, currentPrice, totalInitialPositionSize, l
7059
6682
  positionValue: currentNotional,
7060
6683
  unrealizedPnl: unrealizedPnl,
7061
6684
  entryPositionValue: entryNotional,
7062
- initialWeight: totalInitialPositionSize > 0 ? entryNotional / totalInitialPositionSize : 0,
6685
+ initialWeight: totalInitialPositionSize > 0
6686
+ ? entryNotional / totalInitialPositionSize
6687
+ : 0,
7063
6688
  fundingPaid: (_a = asset.fundingPaid) !== null && _a !== void 0 ? _a : 0,
7064
- // Preserve market metadata from raw asset (if provided by backend)
7065
- marketPrefix: asset.marketPrefix,
7066
- collateralToken: asset.collateralToken,
7067
6689
  };
7068
6690
  };
7069
6691
  const buildPositionValue = (rawPositions, clearinghouseState, allMids) => {
@@ -7152,108 +6774,36 @@ const buildPositionValue = (rawPositions, clearinghouseState, allMids) => {
7152
6774
  });
7153
6775
  };
7154
6776
 
7155
- function findAssetMeta$3(coinName, perpMetaAssets, knownPrefix, desiredCollateral) {
7156
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
7157
- if (!perpMetaAssets) {
7158
- return { collateralToken: 'USDC', marketPrefix: null };
7159
- }
7160
- if (desiredCollateral) {
7161
- const collateralMatch = perpMetaAssets.find((a) => a.name === coinName && a.collateralToken === desiredCollateral);
7162
- if (collateralMatch) {
7163
- return {
7164
- collateralToken: (_a = collateralMatch.collateralToken) !== null && _a !== void 0 ? _a : 'USDC',
7165
- marketPrefix: (_b = collateralMatch.marketPrefix) !== null && _b !== void 0 ? _b : null,
7166
- };
7167
- }
7168
- }
7169
- if (coinName.includes(':')) {
7170
- const [prefix, symbol] = coinName.split(':');
7171
- const exactMatch = perpMetaAssets.find((a) => {
7172
- var _a;
7173
- return a.name === symbol &&
7174
- ((_a = a.marketPrefix) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === prefix.toLowerCase();
7175
- });
7176
- if (exactMatch) {
7177
- return {
7178
- collateralToken: (_c = exactMatch.collateralToken) !== null && _c !== void 0 ? _c : 'USDC',
7179
- marketPrefix: (_d = exactMatch.marketPrefix) !== null && _d !== void 0 ? _d : null,
7180
- };
7181
- }
7182
- }
7183
- if (knownPrefix) {
7184
- const exactMatch = perpMetaAssets.find((a) => {
7185
- var _a;
7186
- return a.name === coinName &&
7187
- ((_a = a.marketPrefix) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === knownPrefix.toLowerCase();
7188
- });
7189
- if (exactMatch) {
7190
- return {
7191
- collateralToken: (_e = exactMatch.collateralToken) !== null && _e !== void 0 ? _e : 'USDC',
7192
- marketPrefix: (_f = exactMatch.marketPrefix) !== null && _f !== void 0 ? _f : null,
7193
- };
7194
- }
7195
- }
7196
- const regularAsset = perpMetaAssets.find((a) => a.name === coinName && !a.marketPrefix);
7197
- if (regularAsset) {
7198
- return {
7199
- collateralToken: (_g = regularAsset.collateralToken) !== null && _g !== void 0 ? _g : 'USDC',
7200
- marketPrefix: null,
7201
- };
7202
- }
7203
- const hip3Asset = perpMetaAssets.find((a) => a.name === coinName && a.marketPrefix);
7204
- if (hip3Asset) {
7205
- return {
7206
- collateralToken: (_h = hip3Asset.collateralToken) !== null && _h !== void 0 ? _h : 'USDC',
7207
- marketPrefix: (_j = hip3Asset.marketPrefix) !== null && _j !== void 0 ? _j : null,
7208
- };
7209
- }
7210
- return { collateralToken: 'USDC', marketPrefix: null };
7211
- }
7212
- function enrichPositionAssets(assets, perpMetaAssets) {
7213
- return assets.map((asset) => {
7214
- var _a;
7215
- if (asset.marketPrefix && asset.collateralToken) {
7216
- return asset;
7217
- }
7218
- const meta = findAssetMeta$3(asset.coin, perpMetaAssets, asset.marketPrefix, asset.collateralToken);
7219
- return {
7220
- ...asset,
7221
- marketPrefix: asset.marketPrefix || meta.marketPrefix,
7222
- collateralToken: (_a = asset.collateralToken) !== null && _a !== void 0 ? _a : meta.collateralToken,
7223
- };
7224
- });
7225
- }
7226
- function enrichPositions(positions, perpMetaAssets) {
7227
- return positions.map((position) => ({
7228
- ...position,
7229
- longAssets: enrichPositionAssets(position.longAssets, perpMetaAssets),
7230
- shortAssets: enrichPositionAssets(position.shortAssets, perpMetaAssets),
7231
- }));
7232
- }
7233
6777
  function usePosition() {
7234
6778
  const context = useContext(PearHyperliquidContext);
7235
6779
  if (!context) {
7236
6780
  throw new Error('usePosition must be used within a PearHyperliquidProvider');
7237
6781
  }
7238
6782
  const { apiBaseUrl, isConnected } = context;
7239
- const hip3Assets = useHyperliquidData((s) => s.hip3Assets);
6783
+ const displayToFull = useHyperliquidData((s) => s.hip3DisplayToFull);
6784
+ // Create position API action
7240
6785
  const createPosition$1 = async (payload) => {
7241
- return createPosition(apiBaseUrl, payload, hip3Assets);
6786
+ return createPosition(apiBaseUrl, payload, displayToFull);
7242
6787
  };
6788
+ // Update TP/SL risk parameters for a position
7243
6789
  const updateRiskParameters$1 = async (positionId, payload) => {
7244
6790
  return updateRiskParameters(apiBaseUrl, positionId, payload);
7245
6791
  };
6792
+ // Close a position (MARKET or TWAP)
7246
6793
  const closePosition$1 = async (positionId, payload) => {
7247
6794
  return closePosition(apiBaseUrl, positionId, payload);
7248
6795
  };
6796
+ // Close all positions (MARKET or TWAP)
7249
6797
  const closeAllPositions$1 = async (payload) => {
7250
6798
  return closeAllPositions(apiBaseUrl, payload);
7251
6799
  };
6800
+ // Adjust a position (REDUCE/INCREASE by %; MARKET or LIMIT)
7252
6801
  const adjustPosition$1 = async (positionId, payload) => {
7253
6802
  return adjustPosition(apiBaseUrl, positionId, payload);
7254
6803
  };
6804
+ // Adjust to absolute target sizes per asset, optionally adding new assets
7255
6805
  const adjustAdvancePosition$1 = async (positionId, payload) => {
7256
- return adjustAdvancePosition(apiBaseUrl, positionId, payload, hip3Assets);
6806
+ return adjustAdvancePosition(apiBaseUrl, positionId, payload, displayToFull);
7257
6807
  };
7258
6808
  const updateLeverage$1 = async (positionId, leverage) => {
7259
6809
  return updateLeverage(apiBaseUrl, positionId, { leverage });
@@ -7262,46 +6812,22 @@ function usePosition() {
7262
6812
  const userOpenPositions = useUserData((state) => state.rawOpenPositions);
7263
6813
  const aggregatedClearingHouseState = useHyperliquidData((state) => state.aggregatedClearingHouseState);
7264
6814
  const allMids = useHyperliquidData((state) => state.allMids);
7265
- const allPerpMetaAssets = useHyperliquidData((state) => state.allPerpMetaAssets);
7266
6815
  const isLoading = useMemo(() => {
7267
6816
  return userOpenPositions === null && isConnected;
7268
6817
  }, [userOpenPositions, isConnected]);
7269
6818
  const openPositions = useMemo(() => {
7270
6819
  if (!userOpenPositions || !aggregatedClearingHouseState || !allMids)
7271
6820
  return null;
7272
- const positions = buildPositionValue(userOpenPositions, aggregatedClearingHouseState, allMids);
7273
- return enrichPositions(positions, allPerpMetaAssets);
7274
- }, [
7275
- userOpenPositions,
7276
- aggregatedClearingHouseState,
7277
- allMids,
7278
- allPerpMetaAssets,
7279
- ]);
7280
- return {
7281
- createPosition: createPosition$1,
7282
- updateRiskParameters: updateRiskParameters$1,
7283
- closePosition: closePosition$1,
7284
- closeAllPositions: closeAllPositions$1,
7285
- adjustPosition: adjustPosition$1,
7286
- adjustAdvancePosition: adjustAdvancePosition$1,
7287
- updateLeverage: updateLeverage$1,
7288
- openPositions,
7289
- isLoading,
7290
- };
6821
+ return buildPositionValue(userOpenPositions, aggregatedClearingHouseState, allMids);
6822
+ }, [userOpenPositions, aggregatedClearingHouseState, allMids]);
6823
+ return { createPosition: createPosition$1, updateRiskParameters: updateRiskParameters$1, closePosition: closePosition$1, closeAllPositions: closeAllPositions$1, adjustPosition: adjustPosition$1, adjustAdvancePosition: adjustAdvancePosition$1, updateLeverage: updateLeverage$1, openPositions, isLoading };
7291
6824
  }
7292
6825
 
7293
6826
  async function adjustOrder(baseUrl, orderId, payload) {
7294
6827
  const url = joinUrl(baseUrl, `/orders/${orderId}/adjust`);
7295
6828
  try {
7296
- const resp = await apiClient.put(url, payload, {
7297
- headers: { 'Content-Type': 'application/json' },
7298
- timeout: 60000,
7299
- });
7300
- return {
7301
- data: resp.data,
7302
- status: resp.status,
7303
- headers: resp.headers,
7304
- };
6829
+ const resp = await apiClient.put(url, payload, { headers: { 'Content-Type': 'application/json' }, timeout: 60000 });
6830
+ return { data: resp.data, status: resp.status, headers: resp.headers };
7305
6831
  }
7306
6832
  catch (error) {
7307
6833
  throw toApiError(error);
@@ -7310,14 +6836,8 @@ async function adjustOrder(baseUrl, orderId, payload) {
7310
6836
  async function cancelOrder(baseUrl, orderId) {
7311
6837
  const url = joinUrl(baseUrl, `/orders/${orderId}/cancel`);
7312
6838
  try {
7313
- const resp = await apiClient.delete(url, {
7314
- timeout: 60000,
7315
- });
7316
- return {
7317
- data: resp.data,
7318
- status: resp.status,
7319
- headers: resp.headers,
7320
- };
6839
+ const resp = await apiClient.delete(url, { timeout: 60000 });
6840
+ return { data: resp.data, status: resp.status, headers: resp.headers };
7321
6841
  }
7322
6842
  catch (error) {
7323
6843
  throw toApiError(error);
@@ -7327,129 +6847,19 @@ async function cancelTwapOrder(baseUrl, orderId) {
7327
6847
  const url = joinUrl(baseUrl, `/orders/${orderId}/twap/cancel`);
7328
6848
  try {
7329
6849
  const resp = await apiClient.post(url, {}, { headers: { 'Content-Type': 'application/json' }, timeout: 60000 });
7330
- return {
7331
- data: resp.data,
7332
- status: resp.status,
7333
- headers: resp.headers,
7334
- };
7335
- }
7336
- catch (error) {
7337
- throw toApiError(error);
7338
- }
7339
- }
7340
- /**
7341
- * Execute a spot order (swap) using Pear Hyperliquid service
7342
- * POST /orders/spot
7343
- */
7344
- async function executeSpotOrder(baseUrl, payload) {
7345
- const url = joinUrl(baseUrl, '/orders/spot');
7346
- try {
7347
- const resp = await apiClient.post(url, payload, {
7348
- headers: { 'Content-Type': 'application/json' },
7349
- timeout: 60000,
7350
- });
7351
- return {
7352
- data: resp.data,
7353
- status: resp.status,
7354
- headers: resp.headers,
7355
- };
6850
+ return { data: resp.data, status: resp.status, headers: resp.headers };
7356
6851
  }
7357
6852
  catch (error) {
7358
6853
  throw toApiError(error);
7359
6854
  }
7360
6855
  }
7361
6856
 
7362
- function findAssetMeta$2(assetName, perpMetaAssets, knownPrefix, desiredCollateral) {
7363
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
7364
- if (!perpMetaAssets) {
7365
- return { collateralToken: 'USDC', marketPrefix: null };
7366
- }
7367
- if (desiredCollateral) {
7368
- const collateralMatch = perpMetaAssets.find((a) => a.name === assetName && a.collateralToken === desiredCollateral);
7369
- if (collateralMatch) {
7370
- return {
7371
- collateralToken: (_a = collateralMatch.collateralToken) !== null && _a !== void 0 ? _a : 'USDC',
7372
- marketPrefix: (_b = collateralMatch.marketPrefix) !== null && _b !== void 0 ? _b : null,
7373
- };
7374
- }
7375
- }
7376
- if (assetName.includes(':')) {
7377
- const [prefix, symbol] = assetName.split(':');
7378
- const exactMatch = perpMetaAssets.find((a) => {
7379
- var _a;
7380
- return a.name === symbol &&
7381
- ((_a = a.marketPrefix) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === prefix.toLowerCase();
7382
- });
7383
- if (exactMatch) {
7384
- return {
7385
- collateralToken: (_c = exactMatch.collateralToken) !== null && _c !== void 0 ? _c : 'USDC',
7386
- marketPrefix: (_d = exactMatch.marketPrefix) !== null && _d !== void 0 ? _d : null,
7387
- };
7388
- }
7389
- }
7390
- if (knownPrefix) {
7391
- const exactMatch = perpMetaAssets.find((a) => {
7392
- var _a;
7393
- return a.name === assetName &&
7394
- ((_a = a.marketPrefix) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === knownPrefix.toLowerCase();
7395
- });
7396
- if (exactMatch) {
7397
- return {
7398
- collateralToken: (_e = exactMatch.collateralToken) !== null && _e !== void 0 ? _e : 'USDC',
7399
- marketPrefix: (_f = exactMatch.marketPrefix) !== null && _f !== void 0 ? _f : null,
7400
- };
7401
- }
7402
- }
7403
- const regularAsset = perpMetaAssets.find((a) => a.name === assetName && !a.marketPrefix);
7404
- if (regularAsset) {
7405
- return {
7406
- collateralToken: (_g = regularAsset.collateralToken) !== null && _g !== void 0 ? _g : 'USDC',
7407
- marketPrefix: null,
7408
- };
7409
- }
7410
- const hip3Assets = perpMetaAssets.filter((a) => a.name === assetName && a.marketPrefix);
7411
- if (hip3Assets.length > 0) {
7412
- if (desiredCollateral) {
7413
- const collateralMatch = hip3Assets.find((a) => a.collateralToken === desiredCollateral);
7414
- if (collateralMatch) {
7415
- return {
7416
- collateralToken: (_h = collateralMatch.collateralToken) !== null && _h !== void 0 ? _h : 'USDC',
7417
- marketPrefix: (_j = collateralMatch.marketPrefix) !== null && _j !== void 0 ? _j : null,
7418
- };
7419
- }
7420
- }
7421
- const usdHMatch = hip3Assets.find((a) => a.collateralToken === 'USDH');
7422
- const chosen = usdHMatch !== null && usdHMatch !== void 0 ? usdHMatch : hip3Assets[0];
7423
- return {
7424
- collateralToken: (_k = chosen.collateralToken) !== null && _k !== void 0 ? _k : 'USDC',
7425
- marketPrefix: (_l = chosen.marketPrefix) !== null && _l !== void 0 ? _l : null,
7426
- };
7427
- }
7428
- return { collateralToken: 'USDC', marketPrefix: null };
7429
- }
7430
- function enrichOrderAssets$1(assets, perpMetaAssets) {
7431
- if (!assets)
7432
- return [];
7433
- return assets.map((asset) => {
7434
- var _a;
7435
- if (asset.marketPrefix && asset.collateralToken) {
7436
- return asset;
7437
- }
7438
- const meta = findAssetMeta$2(asset.asset, perpMetaAssets, asset.marketPrefix, asset.collateralToken);
7439
- return {
7440
- ...asset,
7441
- marketPrefix: asset.marketPrefix || meta.marketPrefix,
7442
- collateralToken: (_a = asset.collateralToken) !== null && _a !== void 0 ? _a : meta.collateralToken,
7443
- };
7444
- });
7445
- }
7446
6857
  function useOrders() {
7447
6858
  const context = useContext(PearHyperliquidContext);
7448
6859
  if (!context)
7449
6860
  throw new Error('useOrders must be used within a PearHyperliquidProvider');
7450
6861
  const { apiBaseUrl } = context;
7451
6862
  const openOrders = useUserData((state) => state.openOrders);
7452
- const allPerpMetaAssets = useHyperliquidData((state) => state.allPerpMetaAssets);
7453
6863
  const isLoading = useMemo(() => openOrders === null && context.isConnected, [openOrders, context.isConnected]);
7454
6864
  const { openPositions } = usePosition();
7455
6865
  const positionsById = useMemo(() => {
@@ -7468,27 +6878,19 @@ function useOrders() {
7468
6878
  const isTpSl = ord.orderType === 'TP' || ord.orderType === 'SL';
7469
6879
  const hasAssets = ((_b = (_a = ord.longAssets) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) > 0 || ((_d = (_c = ord.shortAssets) === null || _c === void 0 ? void 0 : _c.length) !== null && _d !== void 0 ? _d : 0) > 0;
7470
6880
  const pos = positionsById.get((_e = ord.positionId) !== null && _e !== void 0 ? _e : '');
7471
- let enrichedOrd = {
7472
- ...ord,
7473
- longAssets: enrichOrderAssets$1(ord.longAssets, allPerpMetaAssets),
7474
- shortAssets: enrichOrderAssets$1(ord.shortAssets, allPerpMetaAssets),
7475
- };
7476
- if (isTpSl && !hasAssets && pos) {
7477
- const mapAssets = (arr) => arr.map((a) => ({
7478
- asset: a.coin,
7479
- weight: a.initialWeight,
7480
- marketPrefix: a.marketPrefix,
7481
- collateralToken: a.collateralToken,
7482
- }));
7483
- enrichedOrd = {
7484
- ...enrichedOrd,
6881
+ if (!isTpSl || !pos)
6882
+ return ord;
6883
+ const mapAssets = (arr) => arr.map((a) => ({ asset: a.coin, weight: a.initialWeight }));
6884
+ if (!hasAssets) {
6885
+ return {
6886
+ ...ord,
7485
6887
  longAssets: mapAssets(pos.longAssets),
7486
6888
  shortAssets: mapAssets(pos.shortAssets),
7487
6889
  };
7488
6890
  }
7489
- return enrichedOrd;
6891
+ return ord;
7490
6892
  });
7491
- }, [openOrders, positionsById, allPerpMetaAssets]);
6893
+ }, [openOrders, positionsById]);
7492
6894
  const adjustOrder$1 = async (orderId, payload) => {
7493
6895
  return adjustOrder(apiBaseUrl, orderId, payload);
7494
6896
  };
@@ -7498,156 +6900,16 @@ function useOrders() {
7498
6900
  const cancelTwapOrder$1 = async (orderId) => {
7499
6901
  return cancelTwapOrder(apiBaseUrl, orderId);
7500
6902
  };
7501
- return {
7502
- adjustOrder: adjustOrder$1,
7503
- cancelOrder: cancelOrder$1,
7504
- cancelTwapOrder: cancelTwapOrder$1,
7505
- openOrders: enrichedOpenOrders,
7506
- isLoading,
7507
- };
6903
+ return { adjustOrder: adjustOrder$1, cancelOrder: cancelOrder$1, cancelTwapOrder: cancelTwapOrder$1, openOrders: enrichedOpenOrders, isLoading };
7508
6904
  }
7509
6905
 
7510
- /**
7511
- * Hook for executing spot orders (swaps) on Hyperliquid
7512
- * Use this to swap between USDC and USDH or other spot assets
7513
- */
7514
- function useSpotOrder() {
7515
- const context = useContext(PearHyperliquidContext);
7516
- if (!context) {
7517
- throw new Error('useSpotOrder must be used within a PearHyperliquidProvider');
7518
- }
7519
- const { apiBaseUrl } = context;
7520
- const [isLoading, setIsLoading] = useState(false);
7521
- const [error, setError] = useState(null);
7522
- const resetError = useCallback(() => {
7523
- setError(null);
7524
- }, []);
7525
- const executeSpotOrder$1 = useCallback(async (payload) => {
7526
- setIsLoading(true);
7527
- setError(null);
7528
- try {
7529
- const response = await executeSpotOrder(apiBaseUrl, payload);
7530
- return response;
7531
- }
7532
- catch (err) {
7533
- const apiError = err;
7534
- setError(apiError);
7535
- throw apiError;
7536
- }
7537
- finally {
7538
- setIsLoading(false);
7539
- }
7540
- }, [apiBaseUrl]);
7541
- return {
7542
- executeSpotOrder: executeSpotOrder$1,
7543
- isLoading,
7544
- error,
7545
- resetError,
7546
- };
7547
- }
7548
-
7549
- function findAssetMeta$1(assetName, perpMetaAssets, knownPrefix, desiredCollateral) {
7550
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
7551
- if (!perpMetaAssets) {
7552
- return { collateralToken: 'USDC', marketPrefix: null };
7553
- }
7554
- if (desiredCollateral) {
7555
- const collateralMatch = perpMetaAssets.find((a) => a.name === assetName && a.collateralToken === desiredCollateral);
7556
- if (collateralMatch) {
7557
- return {
7558
- collateralToken: (_a = collateralMatch.collateralToken) !== null && _a !== void 0 ? _a : 'USDC',
7559
- marketPrefix: (_b = collateralMatch.marketPrefix) !== null && _b !== void 0 ? _b : null,
7560
- };
7561
- }
7562
- }
7563
- if (assetName.includes(':')) {
7564
- const [prefix, symbol] = assetName.split(':');
7565
- const exactMatch = perpMetaAssets.find((a) => {
7566
- var _a;
7567
- return a.name === symbol &&
7568
- ((_a = a.marketPrefix) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === prefix.toLowerCase();
7569
- });
7570
- if (exactMatch) {
7571
- return {
7572
- collateralToken: (_c = exactMatch.collateralToken) !== null && _c !== void 0 ? _c : 'USDC',
7573
- marketPrefix: (_d = exactMatch.marketPrefix) !== null && _d !== void 0 ? _d : null,
7574
- };
7575
- }
7576
- }
7577
- if (knownPrefix) {
7578
- const exactMatch = perpMetaAssets.find((a) => {
7579
- var _a;
7580
- return a.name === assetName &&
7581
- ((_a = a.marketPrefix) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === knownPrefix.toLowerCase();
7582
- });
7583
- if (exactMatch) {
7584
- return {
7585
- collateralToken: (_e = exactMatch.collateralToken) !== null && _e !== void 0 ? _e : 'USDC',
7586
- marketPrefix: (_f = exactMatch.marketPrefix) !== null && _f !== void 0 ? _f : null,
7587
- };
7588
- }
7589
- }
7590
- const regularAsset = perpMetaAssets.find((a) => a.name === assetName && !a.marketPrefix);
7591
- if (regularAsset) {
7592
- return {
7593
- collateralToken: (_g = regularAsset.collateralToken) !== null && _g !== void 0 ? _g : 'USDC',
7594
- marketPrefix: null,
7595
- };
7596
- }
7597
- const hip3Assets = perpMetaAssets.filter((a) => a.name === assetName && a.marketPrefix);
7598
- if (hip3Assets.length > 0) {
7599
- if (desiredCollateral) {
7600
- const collateralMatch = hip3Assets.find((a) => a.collateralToken === desiredCollateral);
7601
- if (collateralMatch) {
7602
- return {
7603
- collateralToken: (_h = collateralMatch.collateralToken) !== null && _h !== void 0 ? _h : 'USDC',
7604
- marketPrefix: (_j = collateralMatch.marketPrefix) !== null && _j !== void 0 ? _j : null,
7605
- };
7606
- }
7607
- }
7608
- const usdHMatch = hip3Assets.find((a) => a.collateralToken === 'USDH');
7609
- const chosen = usdHMatch !== null && usdHMatch !== void 0 ? usdHMatch : hip3Assets[0];
7610
- return {
7611
- collateralToken: (_k = chosen.collateralToken) !== null && _k !== void 0 ? _k : 'USDC',
7612
- marketPrefix: (_l = chosen.marketPrefix) !== null && _l !== void 0 ? _l : null,
7613
- };
7614
- }
7615
- return { collateralToken: 'USDC', marketPrefix: null };
7616
- }
7617
- function enrichOrderAssets(assets, perpMetaAssets) {
7618
- if (!assets)
7619
- return [];
7620
- return assets.map((asset) => {
7621
- var _a;
7622
- if (asset.marketPrefix && asset.collateralToken) {
7623
- return asset;
7624
- }
7625
- const meta = findAssetMeta$1(asset.asset, perpMetaAssets, asset.marketPrefix, asset.collateralToken);
7626
- return {
7627
- ...asset,
7628
- marketPrefix: asset.marketPrefix || meta.marketPrefix,
7629
- collateralToken: (_a = asset.collateralToken) !== null && _a !== void 0 ? _a : meta.collateralToken,
7630
- };
7631
- });
7632
- }
7633
- function enrichTwapOrders(orders, perpMetaAssets) {
7634
- return orders.map((order) => ({
7635
- ...order,
7636
- longAssets: enrichOrderAssets(order.longAssets, perpMetaAssets),
7637
- shortAssets: enrichOrderAssets(order.shortAssets, perpMetaAssets),
7638
- }));
7639
- }
7640
6906
  function useTwap() {
7641
- const twapDetails = useUserData((state) => state.twapDetails);
7642
- const allPerpMetaAssets = useHyperliquidData((state) => state.allPerpMetaAssets);
6907
+ const twapDetails = useUserData(state => state.twapDetails);
7643
6908
  const context = useContext(PearHyperliquidContext);
7644
6909
  if (!context)
7645
6910
  throw new Error('useTwap must be used within a PearHyperliquidProvider');
7646
6911
  const { apiBaseUrl } = context;
7647
- const orders = useMemo(() => {
7648
- const rawOrders = twapDetails !== null && twapDetails !== void 0 ? twapDetails : [];
7649
- return enrichTwapOrders(rawOrders, allPerpMetaAssets);
7650
- }, [twapDetails, allPerpMetaAssets]);
6912
+ const orders = useMemo(() => twapDetails !== null && twapDetails !== void 0 ? twapDetails : [], [twapDetails]);
7651
6913
  const cancelTwap$1 = async (orderId) => {
7652
6914
  return cancelTwap(apiBaseUrl, orderId);
7653
6915
  };
@@ -7730,170 +6992,59 @@ function useNotifications() {
7730
6992
  };
7731
6993
  }
7732
6994
 
7733
- // Helper to find asset metadata from perpMetaAssets
7734
- function findAssetMeta(assetName, perpMetaAssets) {
7735
- var _a, _b, _c, _d;
7736
- if (!perpMetaAssets) {
7737
- return { collateralToken: 'USDC', marketPrefix: null };
7738
- }
7739
- // Try exact match first (for prefixed assets like "xyz:TSLA")
7740
- const exactMatch = perpMetaAssets.find((a) => a.name === assetName);
7741
- if (exactMatch) {
7742
- return {
7743
- collateralToken: (_a = exactMatch.collateralToken) !== null && _a !== void 0 ? _a : 'USDC',
7744
- marketPrefix: (_b = exactMatch.marketPrefix) !== null && _b !== void 0 ? _b : null,
7745
- };
7746
- }
7747
- // Try matching by base symbol (for non-prefixed names in data)
7748
- const baseMatch = perpMetaAssets.find((a) => {
7749
- const baseName = a.name.includes(':') ? a.name.split(':')[1] : a.name;
7750
- return baseName === assetName;
7751
- });
7752
- if (baseMatch) {
7753
- return {
7754
- collateralToken: (_c = baseMatch.collateralToken) !== null && _c !== void 0 ? _c : 'USDC',
7755
- marketPrefix: (_d = baseMatch.marketPrefix) !== null && _d !== void 0 ? _d : null,
7756
- };
7757
- }
7758
- return { collateralToken: 'USDC', marketPrefix: null };
7759
- }
7760
- // Enrich a single asset with metadata
7761
- function enrichAsset(asset, perpMetaAssets) {
7762
- const meta = findAssetMeta(asset.asset, perpMetaAssets);
7763
- return {
7764
- ...asset,
7765
- collateralToken: meta.collateralToken,
7766
- marketPrefix: meta.marketPrefix,
7767
- };
7768
- }
7769
- // Enrich a basket item with collateral info
7770
- function enrichBasketItem(item, perpMetaAssets) {
7771
- const enrichedLongs = item.longAssets.map((a) => enrichAsset(a, perpMetaAssets));
7772
- const enrichedShorts = item.shortAssets.map((a) => enrichAsset(a, perpMetaAssets));
7773
- // Determine collateral type
7774
- const allAssets = [...enrichedLongs, ...enrichedShorts];
7775
- const hasUsdc = allAssets.some((a) => a.collateralToken === 'USDC');
7776
- const hasUsdh = allAssets.some((a) => a.collateralToken === 'USDH');
7777
- let collateralType = 'USDC';
7778
- if (hasUsdc && hasUsdh) {
7779
- collateralType = 'MIXED';
7780
- }
7781
- else if (hasUsdh) {
7782
- collateralType = 'USDH';
7783
- }
7784
- return {
7785
- ...item,
7786
- longAssets: enrichedLongs,
7787
- shortAssets: enrichedShorts,
7788
- collateralType,
7789
- };
7790
- }
7791
- /**
7792
- * Filter baskets by collateral type
7793
- * - 'USDC': Only baskets where ALL assets use USDC (collateralType === 'USDC')
7794
- * - 'USDH': Only baskets where ALL assets use USDH (collateralType === 'USDH')
7795
- * - 'ALL' or undefined: No filtering, returns all baskets
7796
- */
7797
- function filterByCollateral(baskets, filter) {
7798
- if (!filter || filter === 'ALL') {
7799
- return baskets;
7800
- }
7801
- return baskets.filter((basket) => {
7802
- if (filter === 'USDC') {
7803
- // Include baskets that are purely USDC or have USDC assets
7804
- return (basket.collateralType === 'USDC' || basket.collateralType === 'MIXED');
7805
- }
7806
- if (filter === 'USDH') {
7807
- // Include baskets that are purely USDH or have USDH assets
7808
- return (basket.collateralType === 'USDH' || basket.collateralType === 'MIXED');
7809
- }
7810
- return true;
7811
- });
7812
- }
7813
- // Base selector for the full market-data payload (raw from WS)
6995
+ // Base selector for the full market-data payload
7814
6996
  const useMarketDataPayload = () => {
7815
6997
  return useMarketData((s) => s.marketData);
7816
6998
  };
7817
- // Full payload for 'market-data-all' channel (raw from WS)
6999
+ // Full payload for 'market-data-all' channel
7818
7000
  const useMarketDataAllPayload = () => {
7819
7001
  return useMarketData((s) => s.marketDataAll);
7820
7002
  };
7821
- // Access perpMetaAssets for enrichment
7822
- const usePerpMetaAssets = () => {
7823
- return useHyperliquidData((s) => s.perpMetaAssets);
7824
- };
7825
- // Active baskets (with collateral and market prefix info)
7826
- const useActiveBaskets = (collateralFilter) => {
7003
+ // Active baskets
7004
+ const useActiveBaskets = () => {
7005
+ var _a;
7827
7006
  const data = useMarketDataPayload();
7828
- const perpMetaAssets = usePerpMetaAssets();
7829
- return useMemo(() => {
7830
- if (!(data === null || data === void 0 ? void 0 : data.active))
7831
- return [];
7832
- const enriched = data.active.map((item) => enrichBasketItem(item, perpMetaAssets));
7833
- return filterByCollateral(enriched, collateralFilter);
7834
- }, [data, perpMetaAssets, collateralFilter]);
7007
+ return (_a = data === null || data === void 0 ? void 0 : data.active) !== null && _a !== void 0 ? _a : [];
7835
7008
  };
7836
- // Top gainers (with collateral and market prefix info)
7837
- const useTopGainers = (limit, collateralFilter) => {
7009
+ // Top gainers (optional limit override)
7010
+ const useTopGainers = (limit) => {
7838
7011
  const data = useMarketDataPayload();
7839
- const perpMetaAssets = usePerpMetaAssets();
7840
7012
  return useMemo(() => {
7841
7013
  var _a;
7842
7014
  const list = (_a = data === null || data === void 0 ? void 0 : data.topGainers) !== null && _a !== void 0 ? _a : [];
7843
- const limited = typeof limit === 'number' ? list.slice(0, Math.max(0, limit)) : list;
7844
- const enriched = limited.map((item) => enrichBasketItem(item, perpMetaAssets));
7845
- return filterByCollateral(enriched, collateralFilter);
7846
- }, [data, perpMetaAssets, limit, collateralFilter]);
7015
+ return typeof limit === 'number' ? list.slice(0, Math.max(0, limit)) : list;
7016
+ }, [data, limit]);
7847
7017
  };
7848
- // Top losers (with collateral and market prefix info)
7849
- const useTopLosers = (limit, collateralFilter) => {
7018
+ // Top losers (optional limit override)
7019
+ const useTopLosers = (limit) => {
7850
7020
  const data = useMarketDataPayload();
7851
- const perpMetaAssets = usePerpMetaAssets();
7852
7021
  return useMemo(() => {
7853
7022
  var _a;
7854
7023
  const list = (_a = data === null || data === void 0 ? void 0 : data.topLosers) !== null && _a !== void 0 ? _a : [];
7855
- const limited = typeof limit === 'number' ? list.slice(0, Math.max(0, limit)) : list;
7856
- const enriched = limited.map((item) => enrichBasketItem(item, perpMetaAssets));
7857
- return filterByCollateral(enriched, collateralFilter);
7858
- }, [data, perpMetaAssets, limit, collateralFilter]);
7024
+ return typeof limit === 'number' ? list.slice(0, Math.max(0, limit)) : list;
7025
+ }, [data, limit]);
7859
7026
  };
7860
- // Highlighted baskets (with collateral and market prefix info)
7861
- const useHighlightedBaskets = (collateralFilter) => {
7027
+ // Highlighted baskets
7028
+ const useHighlightedBaskets = () => {
7029
+ var _a;
7862
7030
  const data = useMarketDataPayload();
7863
- const perpMetaAssets = usePerpMetaAssets();
7864
- return useMemo(() => {
7865
- if (!(data === null || data === void 0 ? void 0 : data.highlighted))
7866
- return [];
7867
- const enriched = data.highlighted.map((item) => enrichBasketItem(item, perpMetaAssets));
7868
- return filterByCollateral(enriched, collateralFilter);
7869
- }, [data, perpMetaAssets, collateralFilter]);
7031
+ return (_a = data === null || data === void 0 ? void 0 : data.highlighted) !== null && _a !== void 0 ? _a : [];
7870
7032
  };
7871
- // Watchlist baskets (with collateral and market prefix info)
7872
- const useWatchlistBaskets = (collateralFilter) => {
7033
+ // Watchlist baskets (from market-data payload when subscribed with address)
7034
+ const useWatchlistBaskets = () => {
7035
+ var _a;
7873
7036
  const data = useMarketDataPayload();
7874
- const perpMetaAssets = usePerpMetaAssets();
7875
- return useMemo(() => {
7876
- if (!(data === null || data === void 0 ? void 0 : data.watchlist))
7877
- return [];
7878
- const enriched = data.watchlist.map((item) => enrichBasketItem(item, perpMetaAssets));
7879
- return filterByCollateral(enriched, collateralFilter);
7880
- }, [data, perpMetaAssets, collateralFilter]);
7037
+ return (_a = data === null || data === void 0 ? void 0 : data.watchlist) !== null && _a !== void 0 ? _a : [];
7881
7038
  };
7882
- // All baskets (with collateral and market prefix info)
7883
- const useAllBaskets = (collateralFilter) => {
7039
+ // All baskets (from market-data-all)
7040
+ const useAllBaskets = () => {
7041
+ var _a;
7884
7042
  const dataAll = useMarketDataAllPayload();
7885
- const perpMetaAssets = usePerpMetaAssets();
7886
- return useMemo(() => {
7887
- if (!(dataAll === null || dataAll === void 0 ? void 0 : dataAll.all))
7888
- return [];
7889
- const enriched = dataAll.all.map((item) => enrichBasketItem(item, perpMetaAssets));
7890
- return filterByCollateral(enriched, collateralFilter);
7891
- }, [dataAll, perpMetaAssets, collateralFilter]);
7043
+ return (_a = dataAll === null || dataAll === void 0 ? void 0 : dataAll.all) !== null && _a !== void 0 ? _a : [];
7892
7044
  };
7893
7045
  // Find a basket by its exact asset composition (order-insensitive)
7894
7046
  const useFindBasket = (longs, shorts) => {
7895
7047
  const data = useMarketDataPayload();
7896
- const perpMetaAssets = usePerpMetaAssets();
7897
7048
  return useMemo(() => {
7898
7049
  if (!data)
7899
7050
  return undefined;
@@ -7907,28 +7058,17 @@ const useFindBasket = (longs, shorts) => {
7907
7058
  : '';
7908
7059
  const lKey = normalize(longs);
7909
7060
  const sKey = normalize(shorts);
7910
- const match = (item) => normalize(item.longAssets) === lKey &&
7911
- normalize(item.shortAssets) === sKey;
7912
- const found = data.active.find(match) || data.highlighted.find(match);
7913
- return found
7914
- ? enrichBasketItem(found, perpMetaAssets)
7915
- : undefined;
7916
- }, [data, longs, shorts, perpMetaAssets]);
7061
+ const match = (item) => normalize(item.longAssets) === lKey && normalize(item.shortAssets) === sKey;
7062
+ return data.active.find(match) || data.highlighted.find(match);
7063
+ }, [data, longs, shorts]);
7917
7064
  };
7918
7065
 
7919
- async function toggleWatchlist(baseUrl, longAssets, shortAssets, hip3Assets) {
7066
+ async function toggleWatchlist(baseUrl, longAssets, shortAssets, displayToFull) {
7920
7067
  const url = joinUrl(baseUrl, '/watchlist');
7921
- const mapAssets = (arr) => arr.map((a) => ({ ...a, asset: toBackendSymbol(a.asset, hip3Assets) }));
7068
+ const mapAssets = (arr) => arr.map(a => ({ ...a, asset: toBackendSymbol(a.asset, displayToFull) }));
7922
7069
  try {
7923
- const response = await apiClient.post(url, {
7924
- longAssets: mapAssets(longAssets),
7925
- shortAssets: mapAssets(shortAssets),
7926
- }, { headers: { 'Content-Type': 'application/json' } });
7927
- return {
7928
- data: response.data,
7929
- status: response.status,
7930
- headers: response.headers,
7931
- };
7070
+ const response = await apiClient.post(url, { longAssets: mapAssets(longAssets), shortAssets: mapAssets(shortAssets) }, { headers: { 'Content-Type': 'application/json' } });
7071
+ return { data: response.data, status: response.status, headers: response.headers };
7932
7072
  }
7933
7073
  catch (error) {
7934
7074
  throw toApiError(error);
@@ -7940,11 +7080,11 @@ function useWatchlist() {
7940
7080
  if (!context)
7941
7081
  throw new Error('useWatchlist must be used within a PearHyperliquidProvider');
7942
7082
  const { apiBaseUrl, isConnected } = context;
7943
- const hip3Assets = useHyperliquidData((s) => s.hip3Assets);
7083
+ const displayToFull = useHyperliquidData((s) => s.hip3DisplayToFull);
7944
7084
  const marketData = useMarketDataPayload();
7945
7085
  const isLoading = useMemo(() => !marketData && isConnected, [marketData, isConnected]);
7946
7086
  const toggle = async (longAssets, shortAssets) => {
7947
- const resp = await toggleWatchlist(apiBaseUrl, longAssets, shortAssets, hip3Assets);
7087
+ const resp = await toggleWatchlist(apiBaseUrl, longAssets, shortAssets, displayToFull);
7948
7088
  // Server will push updated market-data over WS; nothing to set here
7949
7089
  return resp;
7950
7090
  };
@@ -8066,38 +7206,46 @@ async function logout(baseUrl, refreshTokenVal) {
8066
7206
  function useAuth() {
8067
7207
  const context = useContext(PearHyperliquidContext);
8068
7208
  if (!context) {
8069
- throw new Error("usePortfolio must be used within a PearHyperliquidProvider");
7209
+ throw new Error("useAuth must be used within a PearHyperliquidProvider");
8070
7210
  }
8071
7211
  const { apiBaseUrl, clientId } = context;
8072
- const [isReady, setIsReady] = useState(false);
8073
7212
  const accessToken = useUserData((s) => s.accessToken);
8074
7213
  const refreshToken$1 = useUserData((s) => s.refreshToken);
7214
+ const isReady = useUserData((s) => s.isReady);
7215
+ const isAuthenticated = useUserData((s) => s.isAuthenticated);
7216
+ const address = useUserData((s) => s.address);
8075
7217
  const setAccessToken = useUserData((s) => s.setAccessToken);
8076
7218
  const setRefreshToken = useUserData((s) => s.setRefreshToken);
8077
- const isAuthenticated = useUserData((s) => s.isAuthenticated);
7219
+ const setIsReady = useUserData((s) => s.setIsReady);
8078
7220
  const setIsAuthenticated = useUserData((s) => s.setIsAuthenticated);
8079
7221
  const setAddress = useUserData((s) => s.setAddress);
8080
7222
  useEffect(() => {
8081
7223
  if (typeof window == "undefined") {
8082
7224
  return;
8083
7225
  }
8084
- const access = localStorage.getItem("accessToken");
8085
- const refresh = localStorage.getItem("refreshToken");
8086
- const addr = localStorage.getItem("address");
8087
- setAccessToken(access);
8088
- setRefreshToken(refresh);
8089
- setAddress(addr);
8090
- const authed = Boolean(access && addr);
8091
- setIsAuthenticated(authed);
7226
+ if (address) {
7227
+ // If we already have an address in state, use it to load the session
7228
+ const accessTokenKey = `${address}_accessToken`;
7229
+ const refreshTokenKey = `${address}_refreshToken`;
7230
+ const storedAccessToken = localStorage.getItem(accessTokenKey);
7231
+ const storedRefreshToken = localStorage.getItem(refreshTokenKey);
7232
+ console.log({ storedAccessToken, storedRefreshToken });
7233
+ if (storedAccessToken && storedRefreshToken) {
7234
+ setAccessToken(storedAccessToken);
7235
+ setRefreshToken(storedRefreshToken);
7236
+ setIsAuthenticated(true);
7237
+ }
7238
+ }
8092
7239
  setIsReady(true);
8093
- }, [setAccessToken, setRefreshToken, setIsAuthenticated, setAddress]);
7240
+ }, [address]);
8094
7241
  useEffect(() => {
8095
7242
  const cleanup = addAuthInterceptors({
8096
7243
  apiBaseUrl,
8097
7244
  getAccessToken: () => {
8098
- return typeof window !== "undefined"
8099
- ? window.localStorage.getItem("accessToken")
8100
- : null;
7245
+ if (typeof window === "undefined")
7246
+ return null;
7247
+ // Read from Zustand state as single source of truth
7248
+ return useUserData.getState().accessToken;
8101
7249
  },
8102
7250
  refreshTokens: async () => {
8103
7251
  const data = await refreshTokens();
@@ -8123,12 +7271,12 @@ function useAuth() {
8123
7271
  clientId,
8124
7272
  details: { signature, timestamp },
8125
7273
  });
8126
- window.localStorage.setItem("accessToken", data.accessToken);
8127
- window.localStorage.setItem("refreshToken", data.refreshToken);
8128
- window.localStorage.setItem("address", address);
7274
+ const accessTokenKey = `${address}_accessToken`;
7275
+ const refreshTokenKey = `${address}_refreshToken`;
7276
+ window.localStorage.setItem(accessTokenKey, data.accessToken);
7277
+ window.localStorage.setItem(refreshTokenKey, data.refreshToken);
8129
7278
  setAccessToken(data.accessToken);
8130
7279
  setRefreshToken(data.refreshToken);
8131
- setAddress(address);
8132
7280
  setIsAuthenticated(true);
8133
7281
  }
8134
7282
  catch (e) {
@@ -8143,12 +7291,12 @@ function useAuth() {
8143
7291
  appId,
8144
7292
  accessToken: privyAccessToken,
8145
7293
  });
8146
- window.localStorage.setItem("accessToken", data.accessToken);
8147
- window.localStorage.setItem("refreshToken", data.refreshToken);
8148
- window.localStorage.setItem("address", address);
7294
+ const accessTokenKey = `${address}_accessToken`;
7295
+ const refreshTokenKey = `${address}_refreshToken`;
7296
+ window.localStorage.setItem(accessTokenKey, data.accessToken);
7297
+ window.localStorage.setItem(refreshTokenKey, data.refreshToken);
8149
7298
  setAccessToken(data.accessToken);
8150
7299
  setRefreshToken(data.refreshToken);
8151
- setAddress(address);
8152
7300
  setIsAuthenticated(true);
8153
7301
  }
8154
7302
  catch (e) {
@@ -8156,30 +7304,38 @@ function useAuth() {
8156
7304
  }
8157
7305
  }
8158
7306
  async function refreshTokens() {
8159
- const refresh = window.localStorage.getItem("refreshToken");
8160
- if (!refresh)
7307
+ const currentAddress = address;
7308
+ const currentRefresh = refreshToken$1;
7309
+ if (!currentRefresh || !currentAddress)
8161
7310
  throw new Error("No refresh token");
8162
- const { data } = await refreshToken(apiBaseUrl, refresh);
8163
- window.localStorage.setItem("accessToken", data.accessToken);
8164
- window.localStorage.setItem("refreshToken", data.refreshToken);
7311
+ const { data } = await refreshToken(apiBaseUrl, currentRefresh);
7312
+ // Update tokens in localStorage
7313
+ const accessTokenKey = `${currentAddress}_accessToken`;
7314
+ const refreshTokenKey = `${currentAddress}_refreshToken`;
7315
+ window.localStorage.setItem(accessTokenKey, data.accessToken);
7316
+ window.localStorage.setItem(refreshTokenKey, data.refreshToken);
8165
7317
  setAccessToken(data.accessToken);
8166
7318
  setRefreshToken(data.refreshToken);
8167
7319
  setIsAuthenticated(true);
8168
7320
  return data;
8169
7321
  }
8170
7322
  async function logout$1() {
8171
- const refresh = window.localStorage.getItem("refreshToken");
8172
- if (refresh) {
7323
+ const currentAddress = address;
7324
+ const currentRefresh = refreshToken$1;
7325
+ if (currentRefresh) {
8173
7326
  try {
8174
- await logout(apiBaseUrl, refresh);
7327
+ await logout(apiBaseUrl, currentRefresh);
8175
7328
  }
8176
7329
  catch (_a) {
8177
7330
  /* ignore */
8178
7331
  }
8179
7332
  }
8180
- window.localStorage.removeItem("accessToken");
8181
- window.localStorage.removeItem("refreshToken");
8182
- window.localStorage.removeItem("address");
7333
+ if (currentAddress) {
7334
+ const accessTokenKey = `${currentAddress}_accessToken`;
7335
+ const refreshTokenKey = `${currentAddress}_refreshToken`;
7336
+ window.localStorage.removeItem(accessTokenKey);
7337
+ window.localStorage.removeItem(refreshTokenKey);
7338
+ }
8183
7339
  setAccessToken(null);
8184
7340
  setRefreshToken(null);
8185
7341
  setAddress(null);
@@ -8195,114 +7351,20 @@ function useAuth() {
8195
7351
  loginWithPrivyToken,
8196
7352
  refreshTokens,
8197
7353
  logout: logout$1,
7354
+ setAddress,
7355
+ address,
8198
7356
  };
8199
7357
  }
8200
7358
 
8201
- const useAllUserBalances = () => {
8202
- const spotState = useUserData((state) => state.spotState);
8203
- const aggregatedClearingHouseState = useHyperliquidData((state) => state.aggregatedClearingHouseState);
8204
- const rawClearinghouseStates = useHyperliquidData((state) => state.rawClearinghouseStates);
8205
- const activeAssetData = useHyperliquidData((state) => state.activeAssetData);
8206
- const { longTokensMetadata, shortTokensMetadata } = useTokenSelectionMetadata();
8207
- return useMemo(() => {
8208
- const isLoading = !spotState || !aggregatedClearingHouseState;
8209
- // Helper function to truncate to 2 decimal places without rounding
8210
- const truncateToTwoDecimals = (value) => {
8211
- return Math.floor(value * 100) / 100;
8212
- };
8213
- // Get spot balances from spotState
8214
- let spotUsdcBal = undefined;
8215
- let spotUsdhBal = undefined;
8216
- if (spotState) {
8217
- const balances = spotState.balances || [];
8218
- for (const balance of balances) {
8219
- const total = parseFloat(balance.total || '0');
8220
- if (balance.coin === 'USDC') {
8221
- spotUsdcBal = truncateToTwoDecimals(total);
8222
- }
8223
- if (balance.coin === 'USDH') {
8224
- spotUsdhBal = truncateToTwoDecimals(total);
8225
- }
8226
- }
8227
- }
8228
- let availableToTradeUsdhFromAsset = 0;
8229
- // This activeAssetData only contains data for SELECTED tokens (user's long and short Tokens)
8230
- // It does NOT contain data for all tokens, so we cannot reliably use it for available to trade as used on hl trade page
8231
- // so intead, we rely on rawClearinghouseStates which provides market-specific data
8232
- // if (activeAssetData) {
8233
- // Object.values(activeAssetData).forEach((assetData) => {
8234
- // if (!assetData.availableToTrade) return;
8235
- // const coinSymbol = assetData.coin;
8236
- // const availableValue = truncateToTwoDecimals(
8237
- // parseFloat(assetData.availableToTrade[0] || '0'),
8238
- // );
8239
- // // Determine collateral type based on market prefix
8240
- // // HIP3 markets have prefix: "xyz:SYMBOL", "flx:SYMBOL", "vntl:SYMBOL", etc.
8241
- // if (coinSymbol.includes(':')) {
8242
- // const prefix = coinSymbol.split(':')[0];
8243
- // if (prefix === 'xyz') {
8244
- // // xyz markets use USDC
8245
- // availableToTradeUsdcFromAsset = availableValue;
8246
- // } else {
8247
- // // flx, vntl, hyna and other markets use USDH
8248
- // availableToTradeUsdhFromAsset = availableValue;
8249
- // }
8250
- // } else {
8251
- // // Regular markets without prefix are automatically USDC
8252
- // availableToTradeUsdcFromAsset = availableValue;
8253
- // }
8254
- // });
8255
- // }
8256
- // Calculate USDC available to trade
8257
- // Priority 1: Use value from activeAssetData if available (> 0)
8258
- // Priority 2: Calculate from USDC-specific clearinghouseState (empty prefix)
8259
- let availableToTradeUsdcValue = undefined;
8260
- if (rawClearinghouseStates) {
8261
- // Find USDC market (empty prefix)
8262
- const usdcMarket = rawClearinghouseStates.find(([prefix]) => prefix === '');
8263
- const usdcState = usdcMarket === null || usdcMarket === void 0 ? void 0 : usdcMarket[1];
8264
- if (usdcState === null || usdcState === void 0 ? void 0 : usdcState.marginSummary) {
8265
- const accountValue = parseFloat(usdcState.marginSummary.accountValue || '0');
8266
- const totalMarginUsed = parseFloat(usdcState.marginSummary.totalMarginUsed || '0');
8267
- const calculatedValue = Math.max(0, accountValue - totalMarginUsed);
8268
- availableToTradeUsdcValue = truncateToTwoDecimals(calculatedValue);
8269
- }
8270
- }
8271
- // Calculate USDH available to trade
8272
- // Priority 1: Use value from activeAssetData if available (> 0)
8273
- // Priority 2: Use spot USDH balance
8274
- const availableToTradeUsdhValue = availableToTradeUsdhFromAsset > 0
8275
- ? availableToTradeUsdhFromAsset
8276
- : spotUsdhBal;
8277
- return {
8278
- spotUsdcBalance: spotUsdcBal,
8279
- availableToTradeUsdc: availableToTradeUsdcValue,
8280
- spotUsdhBalance: spotUsdhBal,
8281
- availableToTradeUsdh: availableToTradeUsdhValue,
8282
- isLoading,
8283
- };
8284
- }, [
8285
- spotState,
8286
- aggregatedClearingHouseState,
8287
- rawClearinghouseStates,
8288
- activeAssetData,
8289
- longTokensMetadata,
8290
- shortTokensMetadata,
8291
- ]);
8292
- };
8293
-
8294
7359
  const PearHyperliquidContext = createContext(undefined);
8295
7360
  /**
8296
7361
  * React Provider for PearHyperliquidClient
8297
7362
  */
8298
- const PearHyperliquidProvider = ({ children, apiBaseUrl = 'https://hl-ui.pearprotocol.io', clientId = 'PEARPROTOCOLUI', wsUrl = 'wss://hl-ui.pearprotocol.io/ws', }) => {
7363
+ const PearHyperliquidProvider = ({ children, apiBaseUrl = "https://hl-ui.pearprotocol.io", clientId = "PEARPROTOCOLUI", wsUrl = "wss://hl-ui.pearprotocol.io/ws", }) => {
8299
7364
  const address = useUserData((s) => s.address);
8300
- const setAddress = useUserData((s) => s.setAddress);
8301
7365
  const perpsMetaAssets = useHyperliquidData((state) => state.perpMetaAssets);
8302
7366
  const setPerpMetaAssets = useHyperliquidData((state) => state.setPerpMetaAssets);
8303
- const setAllPerpMetaAssets = useHyperliquidData((state) => state.setAllPerpMetaAssets);
8304
- const setHip3Assets = useHyperliquidData((state) => state.setHip3Assets);
8305
- const setHip3MarketPrefixes = useHyperliquidData((state) => state.setHip3MarketPrefixes);
7367
+ const setHip3DisplayToFull = useHyperliquidData((state) => state.setHip3DisplayToFull);
8306
7368
  const websocketsEnabled = useMemo(() => Array.isArray(perpsMetaAssets) && perpsMetaAssets.length > 0, [perpsMetaAssets]);
8307
7369
  const { isConnected, lastError } = useHyperliquidWebSocket({
8308
7370
  wsUrl,
@@ -8317,107 +7379,32 @@ const PearHyperliquidProvider = ({ children, apiBaseUrl = 'https://hl-ui.pearpro
8317
7379
  if (perpsMetaAssets === null) {
8318
7380
  fetchAllPerpMetas()
8319
7381
  .then((res) => {
8320
- const assetToMarkets = new Map();
8321
- const marketPrefixes = new Map();
8322
- const FILTERED_PREFIXES = ['hyna'];
8323
- // Group assets by market prefix to match WebSocket flattening order
8324
- // WebSocket sends in order: "", "flx", "hyna", "vntl", "xyz" (we filter out hyna)
8325
- const assetsByPrefix = new Map();
8326
- const allAssetsByPrefix = new Map();
8327
- res.data.forEach((item) => {
8328
- const collateralToken = item.collateralToken === 360 ? 'USDH' : 'USDC';
8329
- item.universe.forEach((asset) => {
8330
- var _a;
8331
- const [maybePrefix, maybeMarket] = asset.name.split(':');
8332
- if (maybeMarket) {
8333
- // HIP3 asset with market prefix
8334
- const prefix = maybePrefix.toLowerCase();
8335
- const displayName = maybeMarket;
8336
- const fullName = `${prefix}:${displayName}`;
8337
- marketPrefixes.set(fullName, prefix);
8338
- if (!FILTERED_PREFIXES.includes(prefix)) {
8339
- const existingMarkets = (_a = assetToMarkets.get(displayName)) !== null && _a !== void 0 ? _a : [];
8340
- if (!existingMarkets.includes(fullName)) {
8341
- assetToMarkets.set(displayName, [
8342
- ...existingMarkets,
8343
- fullName,
8344
- ]);
8345
- }
8346
- }
8347
- const assetWithMeta = {
8348
- ...asset,
8349
- name: displayName,
8350
- marketPrefix: prefix,
8351
- collateralToken,
8352
- };
8353
- // Group by market prefix
8354
- const allList = allAssetsByPrefix.get(prefix) || [];
8355
- allList.push(assetWithMeta);
8356
- allAssetsByPrefix.set(prefix, allList);
8357
- if (!FILTERED_PREFIXES.includes(prefix)) {
8358
- const cleanedList = assetsByPrefix.get(prefix) || [];
8359
- cleanedList.push(assetWithMeta);
8360
- assetsByPrefix.set(prefix, cleanedList);
8361
- }
8362
- }
8363
- else {
8364
- // Default market asset (no prefix)
8365
- const assetWithMeta = {
8366
- ...asset,
8367
- collateralToken,
8368
- };
8369
- // Add to default market group ("")
8370
- const defaultList = assetsByPrefix.get('') || [];
8371
- defaultList.push(assetWithMeta);
8372
- assetsByPrefix.set('', defaultList);
8373
- const allDefaultList = allAssetsByPrefix.get('') || [];
8374
- allDefaultList.push(assetWithMeta);
8375
- allAssetsByPrefix.set('', allDefaultList);
8376
- }
8377
- });
8378
- });
8379
- // Flatten in consistent order: default market first, then HIP3 markets alphabetically
8380
- // This ensures both REST API and WebSocket data align properly
8381
- const cleanedPrefixes = Array.from(assetsByPrefix.keys()).sort((a, b) => {
8382
- // Empty prefix (default market) always comes first
8383
- if (a === '' && b !== '')
8384
- return -1;
8385
- if (a !== '' && b === '')
8386
- return 1;
8387
- // HIP3 markets sorted alphabetically
8388
- return a.localeCompare(b);
8389
- });
8390
- const allPrefixes = Array.from(allAssetsByPrefix.keys()).sort((a, b) => {
8391
- if (a === '' && b !== '')
8392
- return -1;
8393
- if (a !== '' && b === '')
8394
- return 1;
8395
- return a.localeCompare(b);
8396
- });
8397
- const cleanedPerpMetas = [];
8398
- const allPerpMetas = [];
8399
- cleanedPrefixes.forEach((prefix) => {
8400
- const assets = assetsByPrefix.get(prefix) || [];
8401
- cleanedPerpMetas.push(...assets);
8402
- });
8403
- allPrefixes.forEach((prefix) => {
8404
- const assets = allAssetsByPrefix.get(prefix) || [];
8405
- allPerpMetas.push(...assets);
7382
+ // Only show HL and XYZ for now as other are using USDH collateral and need more work
7383
+ const aggregatedPerpMetas = res.data
7384
+ .slice(0, 2)
7385
+ .flatMap((item) => item.universe);
7386
+ const hip3Map = new Map();
7387
+ const displayToFull = new Map();
7388
+ const cleanedPerpMetas = aggregatedPerpMetas.map((asset) => {
7389
+ var _a;
7390
+ const [maybePrefix, maybeMarket] = asset.name.split(":");
7391
+ if (maybeMarket) {
7392
+ const prefix = maybePrefix.toLowerCase();
7393
+ const market = maybeMarket;
7394
+ const existing = (_a = hip3Map.get(prefix)) !== null && _a !== void 0 ? _a : [];
7395
+ hip3Map.set(prefix, [...existing, market]);
7396
+ displayToFull.set(market, `${prefix}:${market}`);
7397
+ return { ...asset, name: market };
7398
+ }
7399
+ return asset;
8406
7400
  });
8407
- setHip3Assets(assetToMarkets);
8408
- setHip3MarketPrefixes(marketPrefixes);
7401
+ setHip3DisplayToFull(displayToFull);
8409
7402
  setPerpMetaAssets(cleanedPerpMetas);
8410
- setAllPerpMetaAssets(allPerpMetas);
8411
7403
  })
8412
7404
  .catch(() => { });
8413
7405
  }
8414
- }, [
8415
- perpsMetaAssets,
8416
- setPerpMetaAssets,
8417
- setAllPerpMetaAssets,
8418
- setHip3Assets,
8419
- setHip3MarketPrefixes,
8420
- ]);
7406
+ }, [perpsMetaAssets, setPerpMetaAssets, setHip3DisplayToFull]);
7407
+ // Auth methods now sourced from useAuth hook
8421
7408
  useAutoSyncFills({
8422
7409
  baseUrl: apiBaseUrl,
8423
7410
  address,
@@ -8439,8 +7426,6 @@ const PearHyperliquidProvider = ({ children, apiBaseUrl = 'https://hl-ui.pearpro
8439
7426
  }), [
8440
7427
  apiBaseUrl,
8441
7428
  wsUrl,
8442
- address,
8443
- setAddress,
8444
7429
  isConnected,
8445
7430
  lastError,
8446
7431
  nativeIsConnected,
@@ -8455,7 +7440,7 @@ const PearHyperliquidProvider = ({ children, apiBaseUrl = 'https://hl-ui.pearpro
8455
7440
  function usePearHyperliquid() {
8456
7441
  const ctx = useContext(PearHyperliquidContext);
8457
7442
  if (!ctx)
8458
- throw new Error('usePearHyperliquid must be used within a PearHyperliquidProvider');
7443
+ throw new Error("usePearHyperliquid must be used within a PearHyperliquidProvider");
8459
7444
  return ctx;
8460
7445
  }
8461
7446
 
@@ -8546,4 +7531,4 @@ function mapCandleIntervalToTradingViewInterval(interval) {
8546
7531
  }
8547
7532
  }
8548
7533
 
8549
- export { AccountSummaryCalculator, ConflictDetector, MAX_ASSETS_PER_LEG, MINIMUM_ASSET_USD_VALUE, MaxAssetsPerLegError, MinimumPositionSizeError, PearHyperliquidProvider, TokenMetadataExtractor, adjustAdvancePosition, adjustOrder, adjustPosition, calculateMinimumPositionValue, calculateWeightedRatio, cancelOrder, cancelTwap, cancelTwapOrder, closeAllPositions, closePosition, computeBasketCandles, createCandleLookups, createPosition, executeSpotOrder, getAvailableMarkets, getCompleteTimestamps, getMarketPrefix, getPortfolio, isHip3Market, mapCandleIntervalToTradingViewInterval, mapTradingViewIntervalToCandleInterval, markNotificationReadById, markNotificationsRead, toBackendSymbol, toBackendSymbolWithMarket, toDisplaySymbol, toggleWatchlist, updateLeverage, updateRiskParameters, useAccountSummary, useActiveBaskets, useAgentWallet, useAllBaskets, useAllUserBalances, useAuth, useAutoSyncFills, useBasketCandles, useFindBasket, useHighlightedBaskets, useHistoricalPriceData, useHistoricalPriceDataStore, useHyperliquidNativeWebSocket, useHyperliquidWebSocket, useMarketData, useMarketDataAllPayload, useMarketDataPayload, useNotifications, useOpenOrders, useOrders, usePearHyperliquid, usePerformanceOverlays, usePerpMetaAssets, usePortfolio, usePosition, useSpotOrder, useTokenSelectionMetadata, useTopGainers, useTopLosers, useTradeHistories, useTwap, useUserSelection, useWatchlist, useWatchlistBaskets, useWebData, validateMaxAssetsPerLeg, validateMinimumAssetSize, validatePositionSize };
7534
+ export { AccountSummaryCalculator, ConflictDetector, MAX_ASSETS_PER_LEG, MINIMUM_ASSET_USD_VALUE, MaxAssetsPerLegError, MinimumPositionSizeError, PearHyperliquidProvider, TokenMetadataExtractor, adjustAdvancePosition, adjustOrder, adjustPosition, calculateMinimumPositionValue, calculateWeightedRatio, cancelOrder, cancelTwap, cancelTwapOrder, closeAllPositions, closePosition, computeBasketCandles, createCandleLookups, createPosition, getCompleteTimestamps, getPortfolio, mapCandleIntervalToTradingViewInterval, mapTradingViewIntervalToCandleInterval, markNotificationReadById, markNotificationsRead, toggleWatchlist, updateLeverage, updateRiskParameters, useAccountSummary, useActiveBaskets, useAgentWallet, useAllBaskets, useAuth, useAutoSyncFills, useBasketCandles, useFindBasket, useHighlightedBaskets, useHistoricalPriceData, useHistoricalPriceDataStore, useHyperliquidNativeWebSocket, useHyperliquidWebSocket, useMarketData, useMarketDataAllPayload, useMarketDataPayload, useNotifications, useOpenOrders, useOrders, usePearHyperliquid, usePerformanceOverlays, usePortfolio, usePosition, useTokenSelectionMetadata, useTopGainers, useTopLosers, useTradeHistories, useTwap, useUserSelection, useWatchlist, useWatchlistBaskets, useWebData, validateMaxAssetsPerLeg, validateMinimumAssetSize, validatePositionSize };