@pear-protocol/hyperliquid-sdk 0.0.78 → 0.1.0

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
@@ -105,84 +105,9 @@ const useMarketData = create((set) => ({
105
105
  marketData: null,
106
106
  marketDataAll: null,
107
107
  setMarketData: (value) => set({ marketData: value }),
108
- setMarketDataAll: (value) => set({ marketDataAll: value }),
109
- clean: () => set({ marketData: null, marketDataAll: null }),
108
+ clean: () => set({ marketData: null }),
110
109
  }));
111
110
 
112
- // Utilities for translating between display symbols and backend (prefixed) symbols
113
- /**
114
- * Convert a full/prefixed symbol (e.g., "xyz:XYZ100") to a display symbol (e.g., "XYZ100").
115
- */
116
- function toDisplaySymbol(symbol) {
117
- const parts = symbol.split(":");
118
- return parts.length > 1 ? parts.slice(-1)[0] : symbol;
119
- }
120
- /**
121
- * Convert a display symbol back to backend form using a provided map.
122
- * If mapping is missing, returns the original symbol.
123
- * For multi-market assets, returns the first available market.
124
- * @param displaySymbol e.g., "TSLA"
125
- * @param hip3Assets map of display -> all full market names (e.g., "TSLA" -> ["xyz:TSLA", "flx:TSLA"])
126
- */
127
- function toBackendSymbol(displaySymbol, hip3Assets) {
128
- if (displaySymbol === "BTC")
129
- return "BTC";
130
- const markets = hip3Assets.get(displaySymbol);
131
- // Return first market if available, otherwise return original symbol
132
- return markets && markets.length > 0 ? markets[0] : displaySymbol;
133
- }
134
- /**
135
- * Convert a display symbol to backend form for a specific market prefix.
136
- * This is useful when an asset is available on multiple markets (e.g., xyz:TSLA and flx:TSLA).
137
- * @param displaySymbol e.g., "TSLA"
138
- * @param marketPrefix e.g., "xyz" or "flx"
139
- * @param hip3Assets map of display -> all full market names
140
- * @returns Full market name if found, null if prefix not specified for multi-market asset, otherwise displaySymbol with prefix
141
- */
142
- function toBackendSymbolWithMarket(displaySymbol, marketPrefix, hip3Assets) {
143
- const availableMarkets = hip3Assets.get(displaySymbol);
144
- if (!availableMarkets || availableMarkets.length === 0) {
145
- // Not a HIP-3 asset, return as-is or with prefix if provided
146
- return marketPrefix ? `${marketPrefix}:${displaySymbol}` : displaySymbol;
147
- }
148
- if (marketPrefix) {
149
- // Find the market with the specified prefix
150
- const targetMarket = availableMarkets.find((market) => market.toLowerCase().startsWith(`${marketPrefix.toLowerCase()}:`));
151
- if (targetMarket) {
152
- return targetMarket;
153
- }
154
- }
155
- // No prefix specified or not found, return null to force explicit market selection
156
- return null;
157
- }
158
- /**
159
- * Get all available markets for a display symbol.
160
- * @param displaySymbol e.g., "TSLA"
161
- * @param hip3Assets map of display -> all full market names
162
- * @returns Array of full market names, e.g., ["xyz:TSLA", "flx:TSLA"]
163
- */
164
- function getAvailableMarkets(displaySymbol, hip3Assets) {
165
- var _a;
166
- return (_a = hip3Assets.get(displaySymbol)) !== null && _a !== void 0 ? _a : [];
167
- }
168
- /**
169
- * Extract the market prefix from a full market name.
170
- * @param fullSymbol e.g., "xyz:TSLA"
171
- * @returns The prefix (e.g., "xyz") or undefined if no prefix
172
- */
173
- function getMarketPrefix(fullSymbol) {
174
- const parts = fullSymbol.split(":");
175
- return parts.length > 1 ? parts[0] : undefined;
176
- }
177
- /**
178
- * Check if a symbol is a HIP-3 market (has a prefix).
179
- * @param symbol e.g., "xyz:TSLA" or "TSLA"
180
- * @returns true if the symbol has a market prefix
181
- */
182
- function isHip3Market(symbol) {
183
- return symbol.includes(":");
184
- }
185
-
186
111
  const useHyperliquidWebSocket = ({ wsUrl, address, enabled = true, }) => {
187
112
  const { setTradeHistories, setRawOpenPositions, setOpenOrders, setAccountSummary, setTwapDetails, setNotifications, clean, } = useUserData();
188
113
  const { setMarketData } = useMarketData();
@@ -217,60 +142,19 @@ const useHyperliquidWebSocket = ({ wsUrl, address, enabled = true, }) => {
217
142
  switch (dataMessage.channel) {
218
143
  case 'trade-histories':
219
144
  {
220
- const mapAsset = (a) => {
221
- var _a, _b;
222
- const extractedPrefix = getMarketPrefix(a.coin);
223
- return {
224
- ...a,
225
- coin: toDisplaySymbol(a.coin),
226
- marketPrefix: (_b = (_a = a.marketPrefix) !== null && _a !== void 0 ? _a : extractedPrefix) !== null && _b !== void 0 ? _b : null,
227
- };
228
- };
229
- const list = dataMessage.data.map((item) => {
230
- var _a, _b;
231
- return ({
232
- ...item,
233
- closedLongAssets: item.closedLongAssets.map(mapAsset),
234
- closedShortAssets: item.closedShortAssets.map(mapAsset),
235
- positionLongAssets: (_a = item.positionLongAssets) === null || _a === void 0 ? void 0 : _a.map((a) => toDisplaySymbol(a)),
236
- positionShortAssets: (_b = item.positionShortAssets) === null || _b === void 0 ? void 0 : _b.map((a) => toDisplaySymbol(a)),
237
- });
238
- });
145
+ const list = dataMessage.data;
239
146
  setTradeHistories(list);
240
147
  }
241
148
  break;
242
149
  case 'open-positions':
243
150
  {
244
- const enrichAsset = (a) => {
245
- var _a, _b;
246
- const extractedPrefix = getMarketPrefix(a.coin);
247
- return {
248
- ...a,
249
- coin: toDisplaySymbol(a.coin),
250
- marketPrefix: (_b = (_a = a.marketPrefix) !== null && _a !== void 0 ? _a : extractedPrefix) !== null && _b !== void 0 ? _b : null,
251
- };
252
- };
253
- const list = dataMessage.data.map((pos) => ({
254
- ...pos,
255
- longAssets: pos.longAssets.map(enrichAsset),
256
- shortAssets: pos.shortAssets.map(enrichAsset),
257
- }));
151
+ const list = dataMessage.data;
258
152
  setRawOpenPositions(list);
259
153
  }
260
154
  break;
261
155
  case 'open-orders':
262
156
  {
263
- const list = dataMessage.data.map((order) => ({
264
- ...order,
265
- longAssets: order.longAssets.map((a) => ({
266
- ...a,
267
- asset: toDisplaySymbol(a.asset),
268
- })),
269
- shortAssets: order.shortAssets.map((a) => ({
270
- ...a,
271
- asset: toDisplaySymbol(a.asset),
272
- })),
273
- }));
157
+ const list = dataMessage.data;
274
158
  setOpenOrders(list);
275
159
  }
276
160
  break;
@@ -279,21 +163,7 @@ const useHyperliquidWebSocket = ({ wsUrl, address, enabled = true, }) => {
279
163
  break;
280
164
  case 'twap-details':
281
165
  {
282
- const mapTwapAsset = (a) => {
283
- var _a, _b, _c;
284
- const extractedPrefix = getMarketPrefix(a.asset);
285
- return {
286
- ...a,
287
- asset: toDisplaySymbol(a.asset),
288
- marketPrefix: (_b = (_a = a.marketPrefix) !== null && _a !== void 0 ? _a : extractedPrefix) !== null && _b !== void 0 ? _b : null,
289
- collateralToken: (_c = a.collateralToken) !== null && _c !== void 0 ? _c : undefined,
290
- };
291
- };
292
- const list = dataMessage.data.map((twap) => ({
293
- ...twap,
294
- longAssets: twap.longAssets.map(mapTwapAsset),
295
- shortAssets: twap.shortAssets.map(mapTwapAsset),
296
- }));
166
+ const list = dataMessage.data;
297
167
  setTwapDetails(list);
298
168
  }
299
169
  break;
@@ -303,25 +173,7 @@ const useHyperliquidWebSocket = ({ wsUrl, address, enabled = true, }) => {
303
173
  case 'market-data':
304
174
  {
305
175
  const md = dataMessage.data;
306
- const mapGroup = (g) => ({
307
- ...g,
308
- longAssets: g.longAssets.map((a) => ({
309
- ...a,
310
- asset: toDisplaySymbol(a.asset),
311
- })),
312
- shortAssets: g.shortAssets.map((a) => ({
313
- ...a,
314
- asset: toDisplaySymbol(a.asset),
315
- })),
316
- });
317
- const mapped = {
318
- active: md.active.map(mapGroup),
319
- topGainers: md.topGainers.map(mapGroup),
320
- topLosers: md.topLosers.map(mapGroup),
321
- highlighted: md.highlighted.map(mapGroup),
322
- watchlist: md.watchlist.map(mapGroup),
323
- };
324
- setMarketData(mapped);
176
+ setMarketData(md);
325
177
  }
326
178
  break;
327
179
  }
@@ -457,6 +309,192 @@ const useHyperliquidWebSocket = ({ wsUrl, address, enabled = true, }) => {
457
309
  };
458
310
  };
459
311
 
312
+ const getMarketInfoFromSymbol = (symbol) => {
313
+ const separatorIndex = symbol.indexOf(':');
314
+ if (separatorIndex > -1) {
315
+ const prefix = symbol.slice(0, separatorIndex);
316
+ const name = symbol.slice(separatorIndex + 1);
317
+ return {
318
+ symbolName: name || symbol,
319
+ marketName: prefix || 'hyperliquid',
320
+ };
321
+ }
322
+ return { symbolName: symbol, marketName: 'hyperliquid' };
323
+ };
324
+
325
+ /**
326
+ * Check if two symbols match, handling kPEPE/KPEPE variations
327
+ * Returns true if symbols match (case-insensitive for k-prefix tokens)
328
+ */
329
+ function symbolsMatch(assetName, searchSymbol) {
330
+ // Exact match
331
+ if (assetName === searchSymbol)
332
+ return true;
333
+ // Try case-insensitive match for k-prefix tokens (kPEPE vs KPEPE)
334
+ if (assetName.toUpperCase() === searchSymbol.toUpperCase()) {
335
+ return true;
336
+ }
337
+ return false;
338
+ }
339
+ /**
340
+ * Extracts token metadata from aggregated WebData3 contexts and AllMids data
341
+ */
342
+ class TokenMetadataExtractor {
343
+ /**
344
+ * Extracts comprehensive token metadata
345
+ * @param symbol - Token symbol (e.g., "BTC", "TSLA")
346
+ * @param perpMetaAssets - Aggregated universe assets (flattened across dexes)
347
+ * @param finalAssetContexts - Aggregated asset contexts (flattened across dexes)
348
+ * @param allMids - AllMids data containing current prices
349
+ * @param activeAssetData - Optional active asset data containing leverage information
350
+ * @returns TokenMetadata or null if token not found
351
+ */
352
+ static extractTokenMetadata(symbol, perpMetaAssets, finalAssetContexts, allMids, activeAssetData, finalAtOICaps) {
353
+ if (!perpMetaAssets || !finalAssetContexts || !allMids) {
354
+ return null;
355
+ }
356
+ const universeIndex = perpMetaAssets.findIndex((asset) => symbolsMatch(asset.name, symbol));
357
+ if (universeIndex === -1) {
358
+ return null;
359
+ }
360
+ const universeAsset = perpMetaAssets[universeIndex];
361
+ const assetCtx = finalAssetContexts[universeIndex];
362
+ if (!assetCtx) {
363
+ return null;
364
+ }
365
+ // Get current price - prefer assetCtx.midPx as it's already index-matched,
366
+ // fall back to allMids lookup if midPx is null
367
+ const actualSymbol = universeAsset.name;
368
+ let currentPrice = 0;
369
+ // Primary source: assetCtx.midPx (already properly indexed)
370
+ if (assetCtx.midPx) {
371
+ currentPrice = parseFloat(assetCtx.midPx);
372
+ }
373
+ // Fallback: allMids lookup
374
+ if (!currentPrice || isNaN(currentPrice)) {
375
+ const currentPriceStr = allMids.mids[actualSymbol] || allMids.mids[symbol];
376
+ currentPrice = currentPriceStr ? parseFloat(currentPriceStr) : 0;
377
+ }
378
+ // Get previous day price
379
+ const prevDayPrice = parseFloat(assetCtx.prevDayPx);
380
+ // Calculate 24h price change
381
+ const priceChange24h = currentPrice - prevDayPrice;
382
+ const priceChange24hPercent = prevDayPrice !== 0 ? (priceChange24h / prevDayPrice) * 100 : 0;
383
+ // Parse other metadata
384
+ const netFunding = parseFloat(assetCtx.funding) * 100;
385
+ const markPrice = parseFloat(assetCtx.markPx);
386
+ const oraclePrice = parseFloat(assetCtx.oraclePx);
387
+ // Extract leverage info from activeAssetData if available
388
+ const tokenActiveData = (activeAssetData === null || activeAssetData === void 0 ? void 0 : activeAssetData[actualSymbol]) || (activeAssetData === null || activeAssetData === void 0 ? void 0 : activeAssetData[symbol]);
389
+ const leverage = tokenActiveData === null || tokenActiveData === void 0 ? void 0 : tokenActiveData.leverage;
390
+ const maxTradeSzs = tokenActiveData === null || tokenActiveData === void 0 ? void 0 : tokenActiveData.maxTradeSzs;
391
+ const availableToTrade = tokenActiveData === null || tokenActiveData === void 0 ? void 0 : tokenActiveData.availableToTrade;
392
+ const { symbolName, marketName } = getMarketInfoFromSymbol(actualSymbol);
393
+ const assetName = symbolName;
394
+ return {
395
+ assetName,
396
+ symbolName,
397
+ marketName,
398
+ isAtOiCaps: finalAtOICaps
399
+ ? finalAtOICaps.includes(symbol)
400
+ : false,
401
+ currentPrice,
402
+ prevDayPrice,
403
+ priceChange24h,
404
+ priceChange24hPercent,
405
+ netFunding,
406
+ maxLeverage: universeAsset.maxLeverage,
407
+ markPrice,
408
+ oraclePrice,
409
+ openInterest: assetCtx.openInterest,
410
+ dayVolume: assetCtx.dayNtlVlm,
411
+ leverage,
412
+ maxTradeSzs,
413
+ availableToTrade,
414
+ collateralToken: universeAsset.collateralToken,
415
+ };
416
+ }
417
+ /**
418
+ * Extracts metadata for multiple tokens
419
+ * @param tokens - Array of token strings (e.g., "BTC", "TSLA")
420
+ * @param perpMetaAssets - Aggregated universe assets
421
+ * @param finalAssetContexts - Aggregated asset contexts
422
+ * @param allMids - AllMids data
423
+ * @param activeAssetData - Optional active asset data containing leverage information
424
+ * @returns Record of token string to TokenMetadata (keys match input tokens exactly)
425
+ */
426
+ static extractMultipleTokensMetadata(tokens, perpMetaAssets, finalAssetContexts, allMids, activeAssetData, finalAtOICaps) {
427
+ const result = {};
428
+ for (const token of tokens) {
429
+ result[token] = this.extractTokenMetadata(token, perpMetaAssets, finalAssetContexts, allMids, activeAssetData, finalAtOICaps);
430
+ }
431
+ return result;
432
+ }
433
+ /**
434
+ * Checks if token data is available in aggregated universe assets
435
+ * @param symbol - Token symbol
436
+ * @param perpMetaAssets - Aggregated universe assets
437
+ * @returns boolean indicating if token exists in universe
438
+ */
439
+ static isTokenAvailable(symbol, perpMetaAssets) {
440
+ if (!perpMetaAssets)
441
+ return false;
442
+ return perpMetaAssets.some((asset) => symbolsMatch(asset.name, symbol));
443
+ }
444
+ }
445
+
446
+ const buildOiCapSet = (finalAtOICaps) => new Set((finalAtOICaps !== null && finalAtOICaps !== void 0 ? finalAtOICaps : [])
447
+ .filter(Boolean)
448
+ .map((value) => value.toUpperCase()));
449
+ const isAtOiCaps = (symbol, symbolName, oiCapSet) => oiCapSet.has(symbol.toUpperCase()) ||
450
+ oiCapSet.has(symbolName.toUpperCase());
451
+ const applyMetadataContext = (symbol, metadata, oiCapSet) => {
452
+ if (!metadata)
453
+ return null;
454
+ const { symbolName, marketName } = getMarketInfoFromSymbol(symbol);
455
+ const assetName = symbolName;
456
+ return {
457
+ ...metadata,
458
+ assetName,
459
+ symbolName,
460
+ marketName,
461
+ isAtOiCaps: isAtOiCaps(symbol, symbolName, oiCapSet),
462
+ };
463
+ };
464
+ const applyOiCapsToMetadataMap = (tokenMetadata, finalAtOICaps) => {
465
+ if (!tokenMetadata || Object.keys(tokenMetadata).length === 0) {
466
+ return tokenMetadata;
467
+ }
468
+ const oiCapSet = buildOiCapSet(finalAtOICaps);
469
+ const next = {};
470
+ Object.entries(tokenMetadata).forEach(([symbol, metadata]) => {
471
+ next[symbol] = applyMetadataContext(symbol, metadata, oiCapSet);
472
+ });
473
+ return next;
474
+ };
475
+ const buildTokenMetadataMap = ({ perpMetaAssets, finalAssetContexts, allMids, activeAssetData, finalAtOICaps, }) => {
476
+ if (!perpMetaAssets || !finalAssetContexts || !allMids) {
477
+ return {};
478
+ }
479
+ const oiCapSet = buildOiCapSet(finalAtOICaps);
480
+ const symbols = perpMetaAssets.map((asset) => asset.name);
481
+ const metadataMap = TokenMetadataExtractor.extractMultipleTokensMetadata(symbols, perpMetaAssets, finalAssetContexts, allMids, activeAssetData, finalAtOICaps);
482
+ symbols.forEach((symbol) => {
483
+ metadataMap[symbol] = applyMetadataContext(symbol, metadataMap[symbol], oiCapSet);
484
+ });
485
+ return metadataMap;
486
+ };
487
+ const updateTokenMetadataForSymbols = (prev, symbols, { perpMetaAssets, finalAssetContexts, allMids, activeAssetData, finalAtOICaps, }) => {
488
+ if (!perpMetaAssets || !finalAssetContexts || !allMids) {
489
+ return prev;
490
+ }
491
+ const oiCapSet = buildOiCapSet(finalAtOICaps);
492
+ const next = { ...prev };
493
+ symbols.forEach((symbol) => {
494
+ next[symbol] = applyMetadataContext(symbol, TokenMetadataExtractor.extractTokenMetadata(symbol, perpMetaAssets, finalAssetContexts, allMids, activeAssetData), oiCapSet);
495
+ });
496
+ return next;
497
+ };
460
498
  const useHyperliquidData = create((set, get) => ({
461
499
  allMids: null,
462
500
  activeAssetData: null,
@@ -466,13 +504,30 @@ const useHyperliquidData = create((set, get) => ({
466
504
  aggregatedClearingHouseState: null,
467
505
  rawClearinghouseStates: null,
468
506
  perpMetaAssets: null,
469
- allPerpMetaAssets: null,
470
- hip3Assets: new Map(),
471
- hip3MarketPrefixes: new Map(),
472
- setAllMids: (value) => set({ allMids: value }),
473
- setActiveAssetData: (value) => set((state) => ({
474
- activeAssetData: typeof value === 'function' ? value(state.activeAssetData) : value,
507
+ tokenMetadata: {},
508
+ setAllMids: (value) => set((state) => ({
509
+ allMids: value,
510
+ tokenMetadata: buildTokenMetadataMap({
511
+ perpMetaAssets: state.perpMetaAssets,
512
+ finalAssetContexts: state.finalAssetContexts,
513
+ allMids: value,
514
+ activeAssetData: state.activeAssetData,
515
+ finalAtOICaps: state.finalAtOICaps,
516
+ }),
475
517
  })),
518
+ setActiveAssetData: (value) => set((state) => {
519
+ const activeAssetData = typeof value === 'function' ? value(state.activeAssetData) : value;
520
+ return {
521
+ activeAssetData,
522
+ tokenMetadata: buildTokenMetadataMap({
523
+ perpMetaAssets: state.perpMetaAssets,
524
+ finalAssetContexts: state.finalAssetContexts,
525
+ allMids: state.allMids,
526
+ activeAssetData,
527
+ finalAtOICaps: state.finalAtOICaps,
528
+ }),
529
+ };
530
+ }),
476
531
  deleteActiveAssetData: (key) => {
477
532
  set((state) => {
478
533
  if (!state.activeAssetData || !(key in state.activeAssetData)) {
@@ -480,7 +535,16 @@ const useHyperliquidData = create((set, get) => ({
480
535
  }
481
536
  const updated = { ...state.activeAssetData };
482
537
  delete updated[key];
483
- return { activeAssetData: updated };
538
+ return {
539
+ activeAssetData: updated,
540
+ tokenMetadata: updateTokenMetadataForSymbols(state.tokenMetadata, [key], {
541
+ perpMetaAssets: state.perpMetaAssets,
542
+ finalAssetContexts: state.finalAssetContexts,
543
+ allMids: state.allMids,
544
+ activeAssetData: updated,
545
+ finalAtOICaps: state.finalAtOICaps,
546
+ }),
547
+ };
484
548
  });
485
549
  },
486
550
  addCandleData(symbol, candle) {
@@ -502,20 +566,49 @@ const useHyperliquidData = create((set, get) => ({
502
566
  });
503
567
  },
504
568
  setCandleData: (value) => set({ candleData: value }),
505
- upsertActiveAssetData: (key, value) => set((state) => ({
506
- activeAssetData: {
507
- ...state.activeAssetData,
569
+ upsertActiveAssetData: (key, value) => set((state) => {
570
+ var _a;
571
+ const activeAssetData = {
572
+ ...((_a = state.activeAssetData) !== null && _a !== void 0 ? _a : {}),
508
573
  [key]: value,
509
- },
574
+ };
575
+ return {
576
+ activeAssetData,
577
+ tokenMetadata: updateTokenMetadataForSymbols(state.tokenMetadata, [key], {
578
+ perpMetaAssets: state.perpMetaAssets,
579
+ finalAssetContexts: state.finalAssetContexts,
580
+ allMids: state.allMids,
581
+ activeAssetData,
582
+ finalAtOICaps: state.finalAtOICaps,
583
+ }),
584
+ };
585
+ }),
586
+ setFinalAssetContexts: (value) => set((state) => ({
587
+ finalAssetContexts: value,
588
+ tokenMetadata: buildTokenMetadataMap({
589
+ perpMetaAssets: state.perpMetaAssets,
590
+ finalAssetContexts: value,
591
+ allMids: state.allMids,
592
+ activeAssetData: state.activeAssetData,
593
+ finalAtOICaps: state.finalAtOICaps,
594
+ }),
595
+ })),
596
+ setFinalAtOICaps: (value) => set((state) => ({
597
+ finalAtOICaps: value,
598
+ tokenMetadata: applyOiCapsToMetadataMap(state.tokenMetadata, value),
510
599
  })),
511
- setFinalAssetContexts: (value) => set({ finalAssetContexts: value }),
512
- setFinalAtOICaps: (value) => set({ finalAtOICaps: value }),
513
600
  setAggregatedClearingHouseState: (value) => set({ aggregatedClearingHouseState: value }),
514
601
  setRawClearinghouseStates: (value) => set({ rawClearinghouseStates: value }),
515
- setPerpMetaAssets: (value) => set({ perpMetaAssets: value }),
516
- setAllPerpMetaAssets: (value) => set({ allPerpMetaAssets: value }),
517
- setHip3Assets: (value) => set({ hip3Assets: value }),
518
- setHip3MarketPrefixes: (value) => set({ hip3MarketPrefixes: value }),
602
+ setPerpMetaAssets: (value) => set((state) => ({
603
+ perpMetaAssets: value,
604
+ tokenMetadata: buildTokenMetadataMap({
605
+ perpMetaAssets: value,
606
+ finalAssetContexts: state.finalAssetContexts,
607
+ allMids: state.allMids,
608
+ activeAssetData: state.activeAssetData,
609
+ finalAtOICaps: state.finalAtOICaps,
610
+ }),
611
+ }))
519
612
  }));
520
613
 
521
614
  /**
@@ -781,6 +874,7 @@ const useHyperliquidNativeWebSocket = ({ address, enabled = true, onUserFills, }
781
874
  const { setAllMids, setActiveAssetData, upsertActiveAssetData, setCandleData, deleteCandleSymbol, deleteActiveAssetData, addCandleData, setFinalAssetContexts, setFinalAtOICaps, setAggregatedClearingHouseState, setRawClearinghouseStates, } = useHyperliquidData();
782
875
  const { setSpotState } = useUserData();
783
876
  const { candleInterval } = useUserSelection$1();
877
+ const userSummary = useUserData((state) => state.accountSummary);
784
878
  const longTokens = useUserSelection$1((s) => s.longTokens);
785
879
  const shortTokens = useUserSelection$1((s) => s.shortTokens);
786
880
  const selectedTokenSymbols = useMemo(() => [...longTokens, ...shortTokens].map((t) => t.symbol), [longTokens, shortTokens]);
@@ -888,51 +982,20 @@ const useHyperliquidNativeWebSocket = ({ address, enabled = true, onUserFills, }
888
982
  case 'allMids':
889
983
  {
890
984
  const data = response.data;
891
- // Keep BOTH normalized prefixed keys AND display symbol keys
892
- // This ensures xyz:TSLA and flx:TSLA are stored separately,
893
- // while also maintaining backward compatibility with non-prefixed lookups
894
- const mids = {};
895
- Object.entries(data.mids || {}).forEach(([k, v]) => {
896
- // Normalize prefixed keys to lowercase prefix (e.g., "XYZ:TSLA" -> "xyz:TSLA")
897
- // This matches how we look up tokens in the SDK
898
- let normalizedKey = k;
899
- if (k.includes(':')) {
900
- const [prefix, ...rest] = k.split(':');
901
- normalizedKey = `${prefix.toLowerCase()}:${rest.join(':')}`;
902
- }
903
- // Store with normalized key
904
- mids[normalizedKey] = v;
905
- // Also store with original key for backward compatibility
906
- if (k !== normalizedKey) {
907
- mids[k] = v;
908
- }
909
- // Also store with display symbol for backward compatibility
910
- const displayKey = toDisplaySymbol(k);
911
- // Only set display key if it doesn't already exist (avoid overwriting market-specific prices)
912
- if (!(displayKey in mids)) {
913
- mids[displayKey] = v;
914
- }
915
- });
916
- setAllMids({ mids });
985
+ setAllMids(data);
917
986
  }
918
987
  break;
919
988
  case 'activeAssetData':
920
989
  {
921
990
  const assetData = response.data;
922
- const symbol = toDisplaySymbol(assetData.coin);
923
- const normalized = {
924
- ...assetData,
925
- coin: symbol,
926
- };
927
- upsertActiveAssetData(symbol, normalized);
991
+ upsertActiveAssetData(assetData.coin, assetData);
928
992
  }
929
993
  break;
930
994
  case 'candle':
931
995
  {
932
996
  const candleDataItem = response.data;
933
- const symbol = toDisplaySymbol(candleDataItem.s || '');
934
- const normalized = { ...candleDataItem, s: symbol };
935
- addCandleData(symbol, normalized);
997
+ const symbol = candleDataItem.s || '';
998
+ addCandleData(symbol, candleDataItem);
936
999
  }
937
1000
  break;
938
1001
  case 'spotState':
@@ -1155,9 +1218,8 @@ const useHyperliquidNativeWebSocket = ({ address, enabled = true, onUserFills, }
1155
1218
  setRawClearinghouseStates,
1156
1219
  setSpotState,
1157
1220
  ]);
1158
- // Subscribe to userFills only after allDexsClearinghouseState data is received
1159
1221
  useEffect(() => {
1160
- if (!isConnected || !subscribedAddress || !clearinghouseStateReceived)
1222
+ if (!isConnected || !subscribedAddress || !clearinghouseStateReceived || !userSummary)
1161
1223
  return;
1162
1224
  const subscribeUserFills = {
1163
1225
  method: 'subscribe',
@@ -1167,7 +1229,7 @@ const useHyperliquidNativeWebSocket = ({ address, enabled = true, onUserFills, }
1167
1229
  },
1168
1230
  };
1169
1231
  sendJsonMessage(subscribeUserFills);
1170
- }, [isConnected, subscribedAddress, clearinghouseStateReceived, sendJsonMessage]);
1232
+ }, [isConnected, subscribedAddress, clearinghouseStateReceived, userSummary, sendJsonMessage]);
1171
1233
  // Handle token subscriptions for activeAssetData
1172
1234
  useEffect(() => {
1173
1235
  if (!isConnected || !address)
@@ -1338,381 +1400,116 @@ class AccountSummaryCalculator {
1338
1400
  getClearinghouseState() {
1339
1401
  return this.clearinghouseState || null;
1340
1402
  }
1341
- /**
1342
- * Check if real-time data is available
1343
- */
1344
- hasRealTimeData() {
1345
- return !!this.clearinghouseState;
1346
- }
1347
- }
1348
-
1349
- const useAccountSummary = () => {
1350
- const context = useContext(PearHyperliquidContext);
1351
- if (!context) {
1352
- throw new Error('useAccountSummary must be used within a PearHyperliquidProvider');
1353
- }
1354
- const platformAccountSummary = useUserData((state) => state.accountSummary);
1355
- const aggregatedClearingHouseState = useHyperliquidData((state) => state.aggregatedClearingHouseState);
1356
- const registeredAgentWallets = useUserData((state) => state.userExtraAgents);
1357
- const isLoading = useMemo(() => {
1358
- return !platformAccountSummary || !registeredAgentWallets || !aggregatedClearingHouseState;
1359
- }, [platformAccountSummary, registeredAgentWallets, aggregatedClearingHouseState]);
1360
- // Create calculator and compute account summary
1361
- const calculator = new AccountSummaryCalculator(aggregatedClearingHouseState);
1362
- const calculated = calculator.calculateAccountSummary(platformAccountSummary, registeredAgentWallets || []);
1363
- return { data: calculated, isLoading };
1364
- };
1365
-
1366
- function findAssetMeta$4(coinName, perpMetaAssets, knownPrefix, desiredCollateral) {
1367
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
1368
- if (!perpMetaAssets) {
1369
- return { collateralToken: 'USDC', marketPrefix: null };
1370
- }
1371
- if (desiredCollateral) {
1372
- const collateralMatch = perpMetaAssets.find((a) => a.name === coinName && a.collateralToken === desiredCollateral);
1373
- if (collateralMatch) {
1374
- return {
1375
- collateralToken: (_a = collateralMatch.collateralToken) !== null && _a !== void 0 ? _a : 'USDC',
1376
- marketPrefix: (_b = collateralMatch.marketPrefix) !== null && _b !== void 0 ? _b : null,
1377
- };
1378
- }
1379
- }
1380
- if (coinName.includes(':')) {
1381
- const [prefix, symbol] = coinName.split(':');
1382
- const exactMatch = perpMetaAssets.find((a) => {
1383
- var _a;
1384
- return a.name === symbol &&
1385
- ((_a = a.marketPrefix) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === prefix.toLowerCase();
1386
- });
1387
- if (exactMatch) {
1388
- return {
1389
- collateralToken: (_c = exactMatch.collateralToken) !== null && _c !== void 0 ? _c : 'USDC',
1390
- marketPrefix: (_d = exactMatch.marketPrefix) !== null && _d !== void 0 ? _d : null,
1391
- };
1392
- }
1393
- }
1394
- if (knownPrefix) {
1395
- const exactMatch = perpMetaAssets.find((a) => {
1396
- var _a;
1397
- return a.name === coinName &&
1398
- ((_a = a.marketPrefix) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === knownPrefix.toLowerCase();
1399
- });
1400
- if (exactMatch) {
1401
- return {
1402
- collateralToken: (_e = exactMatch.collateralToken) !== null && _e !== void 0 ? _e : 'USDC',
1403
- marketPrefix: (_f = exactMatch.marketPrefix) !== null && _f !== void 0 ? _f : null,
1404
- };
1405
- }
1406
- }
1407
- const exactMatch = perpMetaAssets.find((a) => a.name === coinName && !a.marketPrefix);
1408
- if (exactMatch) {
1409
- return {
1410
- collateralToken: (_g = exactMatch.collateralToken) !== null && _g !== void 0 ? _g : 'USDC',
1411
- marketPrefix: (_h = exactMatch.marketPrefix) !== null && _h !== void 0 ? _h : null,
1412
- };
1413
- }
1414
- const hip3Matches = perpMetaAssets.filter((a) => a.name === coinName && a.marketPrefix);
1415
- if (hip3Matches.length > 0) {
1416
- if (desiredCollateral) {
1417
- const collateralMatch = hip3Matches.find((a) => a.collateralToken === desiredCollateral);
1418
- if (collateralMatch) {
1419
- return {
1420
- collateralToken: (_j = collateralMatch.collateralToken) !== null && _j !== void 0 ? _j : 'USDC',
1421
- marketPrefix: (_k = collateralMatch.marketPrefix) !== null && _k !== void 0 ? _k : null,
1422
- };
1423
- }
1424
- }
1425
- const usdHMatch = hip3Matches.find((a) => a.collateralToken === 'USDH');
1426
- const chosen = usdHMatch !== null && usdHMatch !== void 0 ? usdHMatch : hip3Matches[0];
1427
- return {
1428
- collateralToken: (_l = chosen.collateralToken) !== null && _l !== void 0 ? _l : 'USDC',
1429
- marketPrefix: (_m = chosen.marketPrefix) !== null && _m !== void 0 ? _m : null,
1430
- };
1431
- }
1432
- return { collateralToken: 'USDC', marketPrefix: null };
1433
- }
1434
- function enrichTradeHistoryAssets(assets, perpMetaAssets) {
1435
- return assets.map((asset) => {
1436
- var _a;
1437
- if (asset.marketPrefix && asset.collateralToken) {
1438
- return asset;
1439
- }
1440
- const meta = findAssetMeta$4(asset.coin, perpMetaAssets, asset.marketPrefix, asset.collateralToken);
1441
- return {
1442
- ...asset,
1443
- marketPrefix: asset.marketPrefix || meta.marketPrefix,
1444
- collateralToken: (_a = asset.collateralToken) !== null && _a !== void 0 ? _a : meta.collateralToken,
1445
- };
1446
- });
1447
- }
1448
- function enrichTradeHistories(histories, perpMetaAssets) {
1449
- return histories.map((history) => ({
1450
- ...history,
1451
- closedLongAssets: enrichTradeHistoryAssets(history.closedLongAssets, perpMetaAssets),
1452
- closedShortAssets: enrichTradeHistoryAssets(history.closedShortAssets, perpMetaAssets),
1453
- }));
1454
- }
1455
- const useTradeHistories = () => {
1456
- const context = useContext(PearHyperliquidContext);
1457
- if (!context) {
1458
- throw new Error('useTradeHistories must be used within a PearHyperliquidProvider');
1459
- }
1460
- const tradeHistories = useUserData((state) => state.tradeHistories);
1461
- const allPerpMetaAssets = useHyperliquidData((state) => state.allPerpMetaAssets);
1462
- const isLoading = useMemo(() => {
1463
- return tradeHistories === null && context.isConnected;
1464
- }, [tradeHistories, context.isConnected]);
1465
- const enrichedTradeHistories = useMemo(() => {
1466
- if (!tradeHistories)
1467
- return null;
1468
- return enrichTradeHistories(tradeHistories, allPerpMetaAssets);
1469
- }, [tradeHistories, allPerpMetaAssets]);
1470
- return { data: enrichedTradeHistories, isLoading };
1471
- };
1472
- const useOpenOrders = () => {
1473
- const context = useContext(PearHyperliquidContext);
1474
- if (!context) {
1475
- throw new Error('useOpenOrders must be used within a PearHyperliquidProvider');
1476
- }
1477
- const openOrders = useUserData((state) => state.openOrders);
1478
- const isLoading = useMemo(() => {
1479
- return openOrders === null && context.isConnected;
1480
- }, [openOrders, context.isConnected]);
1481
- return { data: openOrders, isLoading };
1482
- };
1483
-
1484
- const useUserSelection = () => {
1485
- return useUserSelection$1();
1486
- };
1487
-
1488
- /**
1489
- * Hook to access webData and native WebSocket state
1490
- */
1491
- const useWebData = () => {
1492
- const context = useContext(PearHyperliquidContext);
1493
- if (!context) {
1494
- throw new Error('useWebData must be used within a PearHyperliquidProvider');
1495
- }
1496
- const finalAssetContexts = useHyperliquidData((state) => state.finalAssetContexts);
1497
- const perpMetaAssets = useHyperliquidData((state) => state.perpMetaAssets);
1498
- const aggregatedClearinghouseState = useHyperliquidData((state) => state.aggregatedClearingHouseState);
1499
- const finalAtOICaps = useHyperliquidData((state) => state.finalAtOICaps);
1500
- const hip3Assets = useHyperliquidData((state) => state.hip3Assets);
1501
- const hip3MarketPrefixes = useHyperliquidData((state) => state.hip3MarketPrefixes);
1502
- let marketDataBySymbol = {};
1503
- if (finalAssetContexts && perpMetaAssets) {
1504
- const result = {};
1505
- // Build a map of display name -> asset context index (for unique display names)
1506
- const displayNameToContextIndex = new Map();
1507
- const seenNames = new Set();
1508
- let contextIndex = 0;
1509
- // First pass: map unique display names to their context index
1510
- for (let index = 0; index < perpMetaAssets.length; index++) {
1511
- const name = perpMetaAssets[index].name;
1512
- if (!seenNames.has(name)) {
1513
- seenNames.add(name);
1514
- if (contextIndex < finalAssetContexts.length) {
1515
- displayNameToContextIndex.set(name, contextIndex);
1516
- contextIndex++;
1517
- }
1518
- }
1519
- }
1520
- // Second pass: create nested entries for all market variants
1521
- for (let index = 0; index < perpMetaAssets.length; index++) {
1522
- const universeAsset = perpMetaAssets[index];
1523
- const displayName = universeAsset.name;
1524
- const marketPrefix = universeAsset.marketPrefix;
1525
- const ctxIndex = displayNameToContextIndex.get(displayName);
1526
- if (ctxIndex !== undefined) {
1527
- const assetContext = finalAssetContexts[ctxIndex];
1528
- // Initialize the symbol entry if it doesn't exist
1529
- if (!result[displayName]) {
1530
- result[displayName] = {};
1531
- }
1532
- // Use marketPrefix as key for HIP-3 assets, "default" for regular assets
1533
- const variantKey = marketPrefix || 'default';
1534
- result[displayName][variantKey] = {
1535
- asset: assetContext,
1536
- universe: universeAsset,
1537
- };
1538
- }
1539
- }
1540
- marketDataBySymbol = result;
1541
- }
1542
- return {
1543
- hip3Assets,
1544
- hip3MarketPrefixes,
1545
- clearinghouseState: aggregatedClearinghouseState,
1546
- perpsAtOpenInterestCap: finalAtOICaps,
1547
- marketDataBySymbol,
1548
- isConnected: context.nativeIsConnected,
1549
- error: context.nativeLastError,
1550
- };
1551
- };
1552
-
1553
- /**
1554
- * Check if two symbols match, handling kPEPE/KPEPE variations
1555
- * Returns true if symbols match (case-insensitive for k-prefix tokens)
1556
- */
1557
- function symbolsMatch(assetName, searchSymbol) {
1558
- // Exact match
1559
- if (assetName === searchSymbol)
1560
- return true;
1561
- // Try case-insensitive match for k-prefix tokens (kPEPE vs KPEPE)
1562
- if (assetName.toUpperCase() === searchSymbol.toUpperCase()) {
1563
- return true;
1564
- }
1565
- return false;
1566
- }
1567
- /**
1568
- * Extracts token metadata from aggregated WebData3 contexts and AllMids data
1569
- */
1570
- class TokenMetadataExtractor {
1571
- /**
1572
- * Extracts comprehensive token metadata
1573
- * @param symbol - Token symbol (base symbol without prefix, e.g., "TSLA")
1574
- * @param perpMetaAssets - Aggregated universe assets (flattened across dexes)
1575
- * @param finalAssetContexts - Aggregated asset contexts (flattened across dexes)
1576
- * @param allMids - AllMids data containing current prices
1577
- * @param activeAssetData - Optional active asset data containing leverage information
1578
- * @param marketPrefix - Optional market prefix (e.g., "xyz", "flx") for HIP3 multi-market assets
1579
- * @returns TokenMetadata or null if token not found
1580
- */
1581
- static extractTokenMetadata(symbol, perpMetaAssets, finalAssetContexts, allMids, activeAssetData, marketPrefix) {
1582
- if (!perpMetaAssets || !finalAssetContexts || !allMids) {
1583
- return null;
1584
- }
1585
- // Find token index in aggregated universe
1586
- // For HIP3 assets, match both name AND marketPrefix
1587
- // Uses symbolsMatch to handle kPEPE/KPEPE case variations
1588
- const universeIndex = perpMetaAssets.findIndex((asset) => {
1589
- if (!symbolsMatch(asset.name, symbol))
1590
- return false;
1591
- // If marketPrefix is specified, match it; otherwise match assets without prefix
1592
- if (marketPrefix) {
1593
- return asset.marketPrefix === marketPrefix;
1594
- }
1595
- // No prefix specified - match non-HIP3 asset (no marketPrefix) or first matching asset
1596
- return !asset.marketPrefix;
1597
- });
1598
- if (universeIndex === -1) {
1599
- return null;
1600
- }
1601
- const universeAsset = perpMetaAssets[universeIndex];
1602
- const assetCtx = finalAssetContexts[universeIndex];
1603
- if (!assetCtx) {
1604
- return null;
1605
- }
1606
- // Get current price - prefer assetCtx.midPx as it's already index-matched,
1607
- // fall back to allMids lookup if midPx is null
1608
- const actualSymbol = universeAsset.name; // Use actual symbol from universe (handles kPEPE vs KPEPE)
1609
- const prefixedKeyColon = marketPrefix
1610
- ? `${marketPrefix}:${actualSymbol}`
1611
- : null;
1612
- let currentPrice = 0;
1613
- // Primary source: assetCtx.midPx (already properly indexed)
1614
- if (assetCtx.midPx) {
1615
- currentPrice = parseFloat(assetCtx.midPx);
1616
- }
1617
- // Fallback: allMids lookup with multiple key formats for HIP3 markets
1618
- // Try actual symbol from universe first, then input symbol
1619
- if (!currentPrice || isNaN(currentPrice)) {
1620
- const currentPriceStr = (prefixedKeyColon && allMids.mids[prefixedKeyColon]) ||
1621
- allMids.mids[actualSymbol] ||
1622
- allMids.mids[symbol];
1623
- currentPrice = currentPriceStr ? parseFloat(currentPriceStr) : 0;
1624
- }
1625
- // Get previous day price
1626
- const prevDayPrice = parseFloat(assetCtx.prevDayPx);
1627
- // Calculate 24h price change
1628
- const priceChange24h = currentPrice - prevDayPrice;
1629
- const priceChange24hPercent = prevDayPrice !== 0 ? (priceChange24h / prevDayPrice) * 100 : 0;
1630
- // Parse other metadata
1631
- const netFunding = parseFloat(assetCtx.funding) * 100;
1632
- const markPrice = parseFloat(assetCtx.markPx);
1633
- const oraclePrice = parseFloat(assetCtx.oraclePx);
1634
- // Extract leverage info from activeAssetData if available
1635
- // Try prefixed key first (e.g., "xyz:TSLA"), then actual symbol, then input symbol
1636
- const activeDataKey = prefixedKeyColon && (activeAssetData === null || activeAssetData === void 0 ? void 0 : activeAssetData[prefixedKeyColon])
1637
- ? prefixedKeyColon
1638
- : (activeAssetData === null || activeAssetData === void 0 ? void 0 : activeAssetData[actualSymbol])
1639
- ? actualSymbol
1640
- : symbol;
1641
- const tokenActiveData = activeAssetData === null || activeAssetData === void 0 ? void 0 : activeAssetData[activeDataKey];
1642
- const leverage = tokenActiveData === null || tokenActiveData === void 0 ? void 0 : tokenActiveData.leverage;
1643
- const maxTradeSzs = tokenActiveData === null || tokenActiveData === void 0 ? void 0 : tokenActiveData.maxTradeSzs;
1644
- const availableToTrade = tokenActiveData === null || tokenActiveData === void 0 ? void 0 : tokenActiveData.availableToTrade;
1645
- return {
1646
- currentPrice,
1647
- prevDayPrice,
1648
- priceChange24h,
1649
- priceChange24hPercent,
1650
- netFunding,
1651
- maxLeverage: universeAsset.maxLeverage,
1652
- markPrice,
1653
- oraclePrice,
1654
- openInterest: assetCtx.openInterest,
1655
- dayVolume: assetCtx.dayNtlVlm,
1656
- leverage,
1657
- maxTradeSzs,
1658
- availableToTrade,
1659
- collateralToken: universeAsset.collateralToken,
1660
- };
1661
- }
1662
- /**
1663
- * Extracts metadata for multiple tokens
1664
- * @param tokens - Array of token objects with symbol and optional marketPrefix
1665
- * @param perpMetaAssets - Aggregated universe assets
1666
- * @param finalAssetContexts - Aggregated asset contexts
1667
- * @param allMids - AllMids data
1668
- * @param activeAssetData - Optional active asset data containing leverage information
1669
- * @returns Record of unique key to TokenMetadata. Key is "{prefix}:{symbol}" for HIP3 assets, or just "{symbol}" otherwise
1670
- */
1671
- static extractMultipleTokensMetadata(tokens, perpMetaAssets, finalAssetContexts, allMids, activeAssetData) {
1672
- const result = {};
1673
- for (const token of tokens) {
1674
- // Use a unique key that includes the prefix for HIP3 assets
1675
- // This ensures xyz:TSLA and flx:TSLA get separate entries
1676
- const resultKey = token.marketPrefix
1677
- ? `${token.marketPrefix}:${token.symbol}`
1678
- : token.symbol;
1679
- result[resultKey] = this.extractTokenMetadata(token.symbol, perpMetaAssets, finalAssetContexts, allMids, activeAssetData, token.marketPrefix);
1680
- }
1681
- return result;
1682
- }
1683
- /**
1684
- * Checks if token data is available in aggregated universe assets
1685
- * @param symbol - Token symbol
1686
- * @param perpMetaAssets - Aggregated universe assets
1687
- * @returns boolean indicating if token exists in universe
1403
+ /**
1404
+ * Check if real-time data is available
1688
1405
  */
1689
- static isTokenAvailable(symbol, perpMetaAssets) {
1690
- if (!perpMetaAssets)
1691
- return false;
1692
- return perpMetaAssets.some((asset) => symbolsMatch(asset.name, symbol));
1406
+ hasRealTimeData() {
1407
+ return !!this.clearinghouseState;
1693
1408
  }
1694
1409
  }
1695
1410
 
1411
+ const useAccountSummary = () => {
1412
+ const context = useContext(PearHyperliquidContext);
1413
+ if (!context) {
1414
+ throw new Error('useAccountSummary must be used within a PearHyperliquidProvider');
1415
+ }
1416
+ const platformAccountSummary = useUserData((state) => state.accountSummary);
1417
+ const aggregatedClearingHouseState = useHyperliquidData((state) => state.aggregatedClearingHouseState);
1418
+ const registeredAgentWallets = useUserData((state) => state.userExtraAgents);
1419
+ const isLoading = useMemo(() => {
1420
+ return !platformAccountSummary || !registeredAgentWallets || !aggregatedClearingHouseState;
1421
+ }, [platformAccountSummary, registeredAgentWallets, aggregatedClearingHouseState]);
1422
+ // Create calculator and compute account summary
1423
+ const calculator = new AccountSummaryCalculator(aggregatedClearingHouseState);
1424
+ const calculated = calculator.calculateAccountSummary(platformAccountSummary, registeredAgentWallets || []);
1425
+ return { data: calculated, isLoading };
1426
+ };
1427
+
1428
+ const selectTokenMetadataBySymbols = (tokenMetadata, symbols) => {
1429
+ const result = {};
1430
+ symbols.forEach((symbol) => {
1431
+ var _a;
1432
+ result[symbol] = (_a = tokenMetadata[symbol]) !== null && _a !== void 0 ? _a : null;
1433
+ });
1434
+ return result;
1435
+ };
1436
+ const getAssetByName = (tokenMetadata, symbol) => {
1437
+ var _a, _b;
1438
+ if (symbol in tokenMetadata) {
1439
+ return (_a = tokenMetadata[symbol]) !== null && _a !== void 0 ? _a : null;
1440
+ }
1441
+ const normalizedSymbol = symbol.toUpperCase();
1442
+ const matchKey = Object.keys(tokenMetadata).find((key) => key.toUpperCase() === normalizedSymbol);
1443
+ return matchKey ? (_b = tokenMetadata[matchKey]) !== null && _b !== void 0 ? _b : null : null;
1444
+ };
1445
+
1696
1446
  /**
1697
- * Parse a token string that may have a market prefix (e.g., "xyz:GOOGL" -> { prefix: "xyz", symbol: "GOOGL" })
1698
- * This allows us to keep the full name (xyz:GOOGL) for URLs/tags while extracting just the symbol for SDK lookups.
1447
+ * Hook to access webData
1699
1448
  */
1700
- function parseTokenWithPrefix(token) {
1701
- if (token.includes(":")) {
1702
- const [prefix, ...rest] = token.split(":");
1703
- const symbol = rest.join(":").toUpperCase();
1704
- return {
1705
- prefix: prefix.toLowerCase(),
1706
- symbol,
1707
- fullName: `${prefix.toLowerCase()}:${symbol}`,
1708
- };
1449
+ const useMarket = () => {
1450
+ const tokenMetadata = useHyperliquidData((state) => state.tokenMetadata);
1451
+ const allTokenMetadata = useMemo(() => Object.values(tokenMetadata).filter((metadata) => Boolean(metadata)), [tokenMetadata]);
1452
+ const getAssetByName$1 = useCallback((symbol) => getAssetByName(tokenMetadata, symbol), [tokenMetadata]);
1453
+ return { allTokenMetadata, getAssetByName: getAssetByName$1 };
1454
+ };
1455
+
1456
+ const useTradeHistories = () => {
1457
+ const context = useContext(PearHyperliquidContext);
1458
+ if (!context) {
1459
+ throw new Error('useTradeHistories must be used within a PearHyperliquidProvider');
1709
1460
  }
1710
- return {
1711
- prefix: null,
1712
- symbol: token.toUpperCase(),
1713
- fullName: token.toUpperCase(),
1714
- };
1715
- }
1461
+ const tradeHistories = useUserData((state) => state.tradeHistories);
1462
+ const { getAssetByName } = useMarket();
1463
+ const enrichedTradeHistories = useMemo(() => {
1464
+ if (!tradeHistories)
1465
+ return null;
1466
+ return tradeHistories.map((history) => ({
1467
+ ...history,
1468
+ closedLongAssets: history.closedLongAssets.map((asset) => ({
1469
+ ...asset,
1470
+ metadata: getAssetByName(asset.coin),
1471
+ })),
1472
+ closedShortAssets: history.closedShortAssets.map((asset) => ({
1473
+ ...asset,
1474
+ metadata: getAssetByName(asset.coin),
1475
+ })),
1476
+ }));
1477
+ }, [tradeHistories, getAssetByName]);
1478
+ const isLoading = useMemo(() => {
1479
+ return tradeHistories === null && context.isConnected;
1480
+ }, [tradeHistories, context.isConnected]);
1481
+ return { data: enrichedTradeHistories, isLoading };
1482
+ };
1483
+ const useOpenOrders = () => {
1484
+ const context = useContext(PearHyperliquidContext);
1485
+ if (!context) {
1486
+ throw new Error('useOpenOrders must be used within a PearHyperliquidProvider');
1487
+ }
1488
+ const openOrders = useUserData((state) => state.openOrders);
1489
+ const { getAssetByName } = useMarket();
1490
+ const enrichedOpenOrders = useMemo(() => {
1491
+ if (!openOrders)
1492
+ return null;
1493
+ const mapAssets = (assets) => (assets !== null && assets !== void 0 ? assets : []).map((asset) => ({
1494
+ ...asset,
1495
+ metadata: getAssetByName(asset.asset),
1496
+ }));
1497
+ return openOrders.map((order) => ({
1498
+ ...order,
1499
+ longAssets: mapAssets(order.longAssets),
1500
+ shortAssets: mapAssets(order.shortAssets),
1501
+ }));
1502
+ }, [openOrders, getAssetByName]);
1503
+ const isLoading = useMemo(() => {
1504
+ return openOrders === null && context.isConnected;
1505
+ }, [openOrders, context.isConnected]);
1506
+ return { data: enrichedOpenOrders, isLoading };
1507
+ };
1508
+
1509
+ const useUserSelection = () => {
1510
+ return useUserSelection$1();
1511
+ };
1512
+
1716
1513
  const useTokenSelectionMetadataStore = create((set) => ({
1717
1514
  isPriceDataReady: false,
1718
1515
  isLoading: true,
@@ -1728,59 +1525,18 @@ const useTokenSelectionMetadataStore = create((set) => ({
1728
1525
  maxLeverage: 0,
1729
1526
  minMargin: 0,
1730
1527
  leverageMatched: true,
1731
- recompute: ({ perpMetaAssets, finalAssetContexts, allMids, activeAssetData, marketData, longTokens, shortTokens, }) => {
1732
- const isPriceDataReady = !!(perpMetaAssets &&
1733
- finalAssetContexts &&
1734
- allMids);
1735
- // Parse tokens - handle prefixed tokens like "xyz:GOOGL" by extracting the symbol and market prefix
1736
- // The full name (xyz:GOOGL) is kept as the metadata key for UI consistency
1737
- const parsedLongTokens = longTokens.map((t) => ({
1738
- ...t,
1739
- parsed: parseTokenWithPrefix(t.symbol),
1740
- }));
1741
- const parsedShortTokens = shortTokens.map((t) => ({
1742
- ...t,
1743
- parsed: parseTokenWithPrefix(t.symbol),
1744
- }));
1745
- // Extract base symbols with their market prefixes for SDK lookups
1746
- // This ensures xyz:TSLA and flx:TSLA get different market data
1747
- const longTokensForLookup = parsedLongTokens.map((t) => ({
1748
- symbol: t.parsed.symbol,
1749
- marketPrefix: t.parsed.prefix,
1750
- }));
1751
- const shortTokensForLookup = parsedShortTokens.map((t) => ({
1752
- symbol: t.parsed.symbol,
1753
- marketPrefix: t.parsed.prefix,
1754
- }));
1755
- // Also extract just the base symbols (without prefix) for lookups that don't support prefixes
1756
- const longBaseSymbols = longTokensForLookup.map((t) => t.symbol);
1757
- const shortBaseSymbols = shortTokensForLookup.map((t) => t.symbol);
1758
- // Get metadata using base symbols with market prefix for proper market differentiation
1759
- const longBaseMetadata = isPriceDataReady
1760
- ? TokenMetadataExtractor.extractMultipleTokensMetadata(longTokensForLookup, perpMetaAssets, finalAssetContexts, allMids, activeAssetData)
1528
+ recompute: ({ perpMetaAssets, tokenMetadata, marketData, longTokens, shortTokens, }) => {
1529
+ const isPriceDataReady = Object.keys(tokenMetadata).length > 0;
1530
+ // Get token symbols for lookups
1531
+ const longSymbols = longTokens.map((t) => t.symbol);
1532
+ const shortSymbols = shortTokens.map((t) => t.symbol);
1533
+ // Get metadata
1534
+ const longTokensMetadata = isPriceDataReady
1535
+ ? selectTokenMetadataBySymbols(tokenMetadata, longSymbols)
1761
1536
  : {};
1762
- const shortBaseMetadata = isPriceDataReady
1763
- ? TokenMetadataExtractor.extractMultipleTokensMetadata(shortTokensForLookup, perpMetaAssets, finalAssetContexts, allMids, activeAssetData)
1537
+ const shortTokensMetadata = isPriceDataReady
1538
+ ? selectTokenMetadataBySymbols(tokenMetadata, shortSymbols)
1764
1539
  : {};
1765
- // Re-map metadata using original full names (with prefix) as keys for UI consistency
1766
- // The extractor now keys by "{prefix}:{symbol}" for prefixed tokens, which matches our parsed.fullName
1767
- const longTokensMetadata = {};
1768
- parsedLongTokens.forEach((t) => {
1769
- var _a;
1770
- // Use the full name (e.g., "xyz:TSLA") as the lookup key since extractor uses the same format
1771
- const lookupKey = t.parsed.prefix
1772
- ? `${t.parsed.prefix}:${t.parsed.symbol}`
1773
- : t.parsed.symbol;
1774
- longTokensMetadata[t.symbol] = (_a = longBaseMetadata[lookupKey]) !== null && _a !== void 0 ? _a : null;
1775
- });
1776
- const shortTokensMetadata = {};
1777
- parsedShortTokens.forEach((t) => {
1778
- var _a;
1779
- const lookupKey = t.parsed.prefix
1780
- ? `${t.parsed.prefix}:${t.parsed.symbol}`
1781
- : t.parsed.symbol;
1782
- shortTokensMetadata[t.symbol] = (_a = shortBaseMetadata[lookupKey]) !== null && _a !== void 0 ? _a : null;
1783
- });
1784
1540
  // Determine loading state
1785
1541
  const allTokens = [...longTokens, ...shortTokens];
1786
1542
  const isLoading = (() => {
@@ -1795,13 +1551,12 @@ const useTokenSelectionMetadataStore = create((set) => ({
1795
1551
  return allTokens.some((token) => !allMetadata[token.symbol]);
1796
1552
  })();
1797
1553
  // Open interest and volume (from market data for matching asset basket)
1798
- // Use base symbols (without prefix) for matching against market data
1799
1554
  const { openInterest, volume } = (() => {
1800
1555
  const empty = { openInterest: "0", volume: "0" };
1801
1556
  if (!(marketData === null || marketData === void 0 ? void 0 : marketData.active) || (!longTokens.length && !shortTokens.length))
1802
1557
  return empty;
1803
- const selectedLong = longBaseSymbols.slice().sort();
1804
- const selectedShort = shortBaseSymbols.slice().sort();
1558
+ const selectedLong = longSymbols.slice().sort();
1559
+ const selectedShort = shortSymbols.slice().sort();
1805
1560
  const match = marketData.active.find((item) => {
1806
1561
  const longs = [...item.longAssets].sort();
1807
1562
  const shorts = [...item.shortAssets].sort();
@@ -1894,27 +1649,18 @@ const useTokenSelectionMetadataStore = create((set) => ({
1894
1649
  return totalFunding;
1895
1650
  })();
1896
1651
  // Max leverage (maximum across all tokens)
1897
- // Use tokens with their market prefixes for proper lookup in perpMetaAssets
1898
1652
  const maxLeverage = (() => {
1899
1653
  if (!perpMetaAssets)
1900
1654
  return 0;
1901
- const allTokensForLookup = [
1902
- ...longTokensForLookup,
1903
- ...shortTokensForLookup,
1904
- ];
1905
- if (allTokensForLookup.length === 0)
1655
+ const allSymbols = [...longSymbols, ...shortSymbols];
1656
+ if (allSymbols.length === 0)
1906
1657
  return 0;
1907
1658
  let maxLev = 0;
1908
- allTokensForLookup.forEach(({ symbol, marketPrefix }) => {
1909
- // Match by both name AND marketPrefix for HIP3 assets
1910
- const tokenUniverse = perpMetaAssets.find((u) => u.name === symbol &&
1911
- (marketPrefix
1912
- ? u.marketPrefix === marketPrefix
1913
- : !u.marketPrefix));
1914
- // Fallback to just matching by name if no exact match
1915
- const fallbackUniverse = tokenUniverse || perpMetaAssets.find((u) => u.name === symbol);
1916
- if (fallbackUniverse === null || fallbackUniverse === void 0 ? void 0 : fallbackUniverse.maxLeverage)
1917
- maxLev = Math.max(maxLev, fallbackUniverse.maxLeverage);
1659
+ allSymbols.forEach((symbol) => {
1660
+ const tokenUniverse = perpMetaAssets.find((u) => u.name === symbol);
1661
+ if (tokenUniverse === null || tokenUniverse === void 0 ? void 0 : tokenUniverse.maxLeverage) {
1662
+ maxLev = Math.max(maxLev, tokenUniverse.maxLeverage);
1663
+ }
1918
1664
  });
1919
1665
  return maxLev;
1920
1666
  })();
@@ -1968,9 +1714,7 @@ const useTokenSelectionMetadata = () => {
1968
1714
  throw new Error('useTokenSelection must be used within PearHyperliquidProvider');
1969
1715
  }
1970
1716
  const perpMetaAssets = useHyperliquidData((state) => state.perpMetaAssets);
1971
- const finalAssetContexts = useHyperliquidData((state) => state.finalAssetContexts);
1972
- const allMids = useHyperliquidData((state) => state.allMids);
1973
- const activeAssetData = useHyperliquidData((state) => state.activeAssetData);
1717
+ const tokenMetadata = useHyperliquidData((state) => state.tokenMetadata);
1974
1718
  const marketData = useMarketData((state) => state.marketData);
1975
1719
  const { longTokens, shortTokens } = useUserSelection$1();
1976
1720
  const { isLoading, isPriceDataReady, longTokensMetadata, shortTokensMetadata, weightedRatio, weightedRatio24h, priceRatio, priceRatio24h, openInterest, volume, sumNetFunding, maxLeverage, minMargin, leverageMatched, recompute, } = useTokenSelectionMetadataStore();
@@ -1978,16 +1722,14 @@ const useTokenSelectionMetadata = () => {
1978
1722
  useEffect(() => {
1979
1723
  recompute({
1980
1724
  perpMetaAssets,
1981
- finalAssetContexts,
1982
- allMids,
1983
- activeAssetData: activeAssetData || null,
1725
+ tokenMetadata,
1984
1726
  marketData: marketData || null,
1985
1727
  longTokens,
1986
1728
  shortTokens,
1987
1729
  });
1988
1730
  // We want to recompute when token lists or upstream data change
1989
1731
  // eslint-disable-next-line react-hooks/exhaustive-deps
1990
- }, [perpMetaAssets, finalAssetContexts, allMids, activeAssetData, JSON.stringify(longTokens), JSON.stringify(shortTokens)]);
1732
+ }, [perpMetaAssets, tokenMetadata, JSON.stringify(longTokens), JSON.stringify(shortTokens)]);
1991
1733
  return {
1992
1734
  // Loading states
1993
1735
  isLoading,
@@ -6114,10 +5856,9 @@ function addAuthInterceptors(params) {
6114
5856
  /**
6115
5857
  * Fetch historical candle data from HyperLiquid API
6116
5858
  */
6117
- const fetchHistoricalCandles = async (coin, startTime, endTime, interval, hip3Assets) => {
6118
- const backendCoin = toBackendSymbol(coin, hip3Assets);
5859
+ const fetchHistoricalCandles = async (coin, startTime, endTime, interval) => {
6119
5860
  const request = {
6120
- req: { coin: backendCoin, startTime, endTime, interval },
5861
+ req: { coin, startTime, endTime, interval },
6121
5862
  type: 'candleSnapshot',
6122
5863
  };
6123
5864
  try {
@@ -6274,10 +6015,9 @@ const useHistoricalPriceData = () => {
6274
6015
  setTokenLoading(token.symbol, true);
6275
6016
  });
6276
6017
  try {
6277
- const hip3Assets = useHyperliquidData.getState().hip3Assets;
6278
6018
  const fetchPromises = tokensToFetch.map(async (token) => {
6279
6019
  try {
6280
- const response = await fetchHistoricalCandles(token.symbol, startTime, endTime, interval, hip3Assets);
6020
+ const response = await fetchHistoricalCandles(token.symbol, startTime, endTime, interval);
6281
6021
  addHistoricalPriceData(token.symbol, interval, response.data, { start: startTime, end: endTime });
6282
6022
  return { symbol: token.symbol, candles: response.data, success: true };
6283
6023
  }
@@ -6825,24 +6565,14 @@ function useAgentWallet() {
6825
6565
  * @throws MinimumPositionSizeError if any asset has less than $11 USD value
6826
6566
  * @throws MaxAssetsPerLegError if any leg exceeds the maximum allowed assets (15)
6827
6567
  */
6828
- async function createPosition(baseUrl, payload, hip3Assets) {
6568
+ async function createPosition(baseUrl, payload) {
6829
6569
  // Validate maximum assets per leg before creating position
6830
6570
  validateMaxAssetsPerLeg(payload.longAssets, payload.shortAssets);
6831
6571
  // Validate minimum asset size before creating position
6832
6572
  validateMinimumAssetSize(payload.usdValue, payload.longAssets, payload.shortAssets);
6833
6573
  const url = joinUrl(baseUrl, "/positions");
6834
- // Translate display symbols to backend format
6835
- const mapAssets = (arr) => arr === null || arr === void 0 ? void 0 : arr.map((a) => ({ ...a, asset: toBackendSymbol(a.asset, hip3Assets) }));
6836
- const translatedPayload = {
6837
- ...payload,
6838
- longAssets: mapAssets(payload.longAssets),
6839
- shortAssets: mapAssets(payload.shortAssets),
6840
- assetName: payload.assetName
6841
- ? toBackendSymbol(payload.assetName, hip3Assets)
6842
- : undefined,
6843
- };
6844
6574
  try {
6845
- const resp = await apiClient.post(url, translatedPayload, {
6575
+ const resp = await apiClient.post(url, payload, {
6846
6576
  headers: {
6847
6577
  "Content-Type": "application/json",
6848
6578
  },
@@ -6934,15 +6664,10 @@ async function adjustPosition(baseUrl, positionId, payload) {
6934
6664
  throw toApiError(error);
6935
6665
  }
6936
6666
  }
6937
- async function adjustAdvancePosition(baseUrl, positionId, payload, hip3Assets) {
6667
+ async function adjustAdvancePosition(baseUrl, positionId, payload) {
6938
6668
  const url = joinUrl(baseUrl, `/positions/${positionId}/adjust-advance`);
6939
- const mapAssets = (arr) => arr === null || arr === void 0 ? void 0 : arr.map((a) => ({ ...a, asset: toBackendSymbol(a.asset, hip3Assets) }));
6940
- const translatedPayload = (payload || []).map((item) => ({
6941
- longAssets: mapAssets(item.longAssets),
6942
- shortAssets: mapAssets(item.shortAssets),
6943
- }));
6944
6669
  try {
6945
- const resp = await apiClient.post(url, translatedPayload, {
6670
+ const resp = await apiClient.post(url, payload, {
6946
6671
  headers: {
6947
6672
  "Content-Type": "application/json",
6948
6673
  },
@@ -7002,7 +6727,7 @@ async function updateLeverage(baseUrl, positionId, payload) {
7002
6727
  }
7003
6728
  }
7004
6729
 
7005
- const calculatePositionAsset = (asset, currentPrice, totalInitialPositionSize, leverage, isLong = true) => {
6730
+ const calculatePositionAsset = (asset, currentPrice, totalInitialPositionSize, leverage, metadata, isLong = true) => {
7006
6731
  var _a;
7007
6732
  const entryNotional = asset.entryPrice * asset.size;
7008
6733
  const currentNotional = currentPrice * asset.size;
@@ -7021,13 +6746,12 @@ const calculatePositionAsset = (asset, currentPrice, totalInitialPositionSize, l
7021
6746
  entryPositionValue: entryNotional,
7022
6747
  initialWeight: totalInitialPositionSize > 0 ? entryNotional / totalInitialPositionSize : 0,
7023
6748
  fundingPaid: (_a = asset.fundingPaid) !== null && _a !== void 0 ? _a : 0,
7024
- // Preserve market metadata from raw asset (if provided by backend)
7025
- marketPrefix: asset.marketPrefix,
7026
- collateralToken: asset.collateralToken,
6749
+ metadata,
7027
6750
  };
7028
6751
  };
7029
- const buildPositionValue = (rawPositions, clearinghouseState, allMids) => {
6752
+ const buildPositionValue = (rawPositions, clearinghouseState, getAssetByName) => {
7030
6753
  return rawPositions.map((position) => {
6754
+ var _a, _b, _c, _d, _e, _f, _g, _h;
7031
6755
  let mappedPosition = {
7032
6756
  positionId: position.positionId,
7033
6757
  address: position.address,
@@ -7045,11 +6769,12 @@ const buildPositionValue = (rawPositions, clearinghouseState, allMids) => {
7045
6769
  const totalInitialPositionSize = position.longAssets.reduce((acc, asset) => acc + asset.entryPrice * asset.size, 0) +
7046
6770
  position.shortAssets.reduce((acc, asset) => acc + asset.entryPrice * asset.size, 0);
7047
6771
  mappedPosition.longAssets = position.longAssets.map((longAsset) => {
7048
- var _a, _b, _c;
7049
- const currentPrice = parseFloat(allMids.mids[longAsset.coin]);
7050
- const assetState = (_a = clearinghouseState.assetPositions.find((ap) => toDisplaySymbol(ap.position.coin) === longAsset.coin)) === null || _a === void 0 ? void 0 : _a.position;
7051
- const leverage = (_c = (_b = assetState === null || assetState === void 0 ? void 0 : assetState.leverage) === null || _b === void 0 ? void 0 : _b.value) !== null && _c !== void 0 ? _c : longAsset.leverage;
7052
- const mappedPositionAssets = calculatePositionAsset(longAsset, currentPrice, totalInitialPositionSize, leverage, true);
6772
+ var _a, _b, _c, _d;
6773
+ const metadata = getAssetByName(longAsset.coin);
6774
+ const currentPrice = (_a = metadata === null || metadata === void 0 ? void 0 : metadata.currentPrice) !== null && _a !== void 0 ? _a : 0;
6775
+ const assetState = (_b = clearinghouseState.assetPositions.find((ap) => ap.position.coin === longAsset.coin)) === null || _b === void 0 ? void 0 : _b.position;
6776
+ const leverage = (_d = (_c = assetState === null || assetState === void 0 ? void 0 : assetState.leverage) === null || _c === void 0 ? void 0 : _c.value) !== null && _d !== void 0 ? _d : longAsset.leverage;
6777
+ const mappedPositionAssets = calculatePositionAsset(longAsset, currentPrice, totalInitialPositionSize, leverage, metadata, true);
7053
6778
  mappedPosition.entryPositionValue +=
7054
6779
  mappedPositionAssets.entryPositionValue;
7055
6780
  mappedPosition.unrealizedPnl += mappedPositionAssets.unrealizedPnl;
@@ -7060,11 +6785,12 @@ const buildPositionValue = (rawPositions, clearinghouseState, allMids) => {
7060
6785
  return mappedPositionAssets;
7061
6786
  });
7062
6787
  mappedPosition.shortAssets = position.shortAssets.map((shortAsset) => {
7063
- var _a, _b, _c;
7064
- const currentPrice = parseFloat(allMids.mids[shortAsset.coin]);
7065
- const assetState = (_a = clearinghouseState.assetPositions.find((ap) => toDisplaySymbol(ap.position.coin) === shortAsset.coin)) === null || _a === void 0 ? void 0 : _a.position;
7066
- const leverage = (_c = (_b = assetState === null || assetState === void 0 ? void 0 : assetState.leverage) === null || _b === void 0 ? void 0 : _b.value) !== null && _c !== void 0 ? _c : shortAsset.leverage;
7067
- const mappedPositionAssets = calculatePositionAsset(shortAsset, currentPrice, totalInitialPositionSize, leverage, false);
6788
+ var _a, _b, _c, _d;
6789
+ const metadata = getAssetByName(shortAsset.coin);
6790
+ const currentPrice = (_a = metadata === null || metadata === void 0 ? void 0 : metadata.currentPrice) !== null && _a !== void 0 ? _a : 0;
6791
+ const assetState = (_b = clearinghouseState.assetPositions.find((ap) => ap.position.coin === shortAsset.coin)) === null || _b === void 0 ? void 0 : _b.position;
6792
+ const leverage = (_d = (_c = assetState === null || assetState === void 0 ? void 0 : assetState.leverage) === null || _c === void 0 ? void 0 : _c.value) !== null && _d !== void 0 ? _d : shortAsset.leverage;
6793
+ const mappedPositionAssets = calculatePositionAsset(shortAsset, currentPrice, totalInitialPositionSize, leverage, metadata, false);
7068
6794
  mappedPosition.entryPositionValue +=
7069
6795
  mappedPositionAssets.entryPositionValue;
7070
6796
  mappedPosition.unrealizedPnl += mappedPositionAssets.unrealizedPnl;
@@ -7079,8 +6805,8 @@ const buildPositionValue = (rawPositions, clearinghouseState, allMids) => {
7079
6805
  if (position.longAssets.length === 1 && position.shortAssets.length === 1) {
7080
6806
  const long = position.longAssets[0];
7081
6807
  const short = position.shortAssets[0];
7082
- const longMark = parseFloat(allMids.mids[long.coin]);
7083
- const shortMark = parseFloat(allMids.mids[short.coin]);
6808
+ const longMark = (_b = (_a = getAssetByName(long.coin)) === null || _a === void 0 ? void 0 : _a.currentPrice) !== null && _b !== void 0 ? _b : 0;
6809
+ const shortMark = (_d = (_c = getAssetByName(short.coin)) === null || _c === void 0 ? void 0 : _c.currentPrice) !== null && _d !== void 0 ? _d : 0;
7084
6810
  if (long.size > 0 && short.size > 0) {
7085
6811
  mappedPosition.entryPriceRatio = long.entryPrice / short.entryPrice;
7086
6812
  mappedPosition.markPriceRatio = longMark / shortMark;
@@ -7096,13 +6822,13 @@ const buildPositionValue = (rawPositions, clearinghouseState, allMids) => {
7096
6822
  }
7097
6823
  if (position.longAssets.length === 1 && position.shortAssets.length === 0) {
7098
6824
  const long = position.longAssets[0];
7099
- const longMark = parseFloat(allMids.mids[long.coin]);
6825
+ const longMark = (_f = (_e = getAssetByName(long.coin)) === null || _e === void 0 ? void 0 : _e.currentPrice) !== null && _f !== void 0 ? _f : 0;
7100
6826
  mappedPosition.entryPriceRatio = long.entryPrice;
7101
6827
  mappedPosition.markPriceRatio = longMark;
7102
6828
  }
7103
6829
  if (position.longAssets.length === 0 && position.shortAssets.length === 1) {
7104
6830
  const short = position.shortAssets[0];
7105
- const shortMark = parseFloat(allMids.mids[short.coin]);
6831
+ const shortMark = (_h = (_g = getAssetByName(short.coin)) === null || _g === void 0 ? void 0 : _g.currentPrice) !== null && _h !== void 0 ? _h : 0;
7106
6832
  mappedPosition.entryPriceRatio = short.entryPrice;
7107
6833
  mappedPosition.markPriceRatio = shortMark;
7108
6834
  }
@@ -7112,93 +6838,14 @@ const buildPositionValue = (rawPositions, clearinghouseState, allMids) => {
7112
6838
  });
7113
6839
  };
7114
6840
 
7115
- function findAssetMeta$3(coinName, perpMetaAssets, knownPrefix, desiredCollateral) {
7116
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
7117
- if (!perpMetaAssets) {
7118
- return { collateralToken: 'USDC', marketPrefix: null };
7119
- }
7120
- if (desiredCollateral) {
7121
- const collateralMatch = perpMetaAssets.find((a) => a.name === coinName && a.collateralToken === desiredCollateral);
7122
- if (collateralMatch) {
7123
- return {
7124
- collateralToken: (_a = collateralMatch.collateralToken) !== null && _a !== void 0 ? _a : 'USDC',
7125
- marketPrefix: (_b = collateralMatch.marketPrefix) !== null && _b !== void 0 ? _b : null,
7126
- };
7127
- }
7128
- }
7129
- if (coinName.includes(':')) {
7130
- const [prefix, symbol] = coinName.split(':');
7131
- const exactMatch = perpMetaAssets.find((a) => {
7132
- var _a;
7133
- return a.name === symbol &&
7134
- ((_a = a.marketPrefix) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === prefix.toLowerCase();
7135
- });
7136
- if (exactMatch) {
7137
- return {
7138
- collateralToken: (_c = exactMatch.collateralToken) !== null && _c !== void 0 ? _c : 'USDC',
7139
- marketPrefix: (_d = exactMatch.marketPrefix) !== null && _d !== void 0 ? _d : null,
7140
- };
7141
- }
7142
- }
7143
- if (knownPrefix) {
7144
- const exactMatch = perpMetaAssets.find((a) => {
7145
- var _a;
7146
- return a.name === coinName &&
7147
- ((_a = a.marketPrefix) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === knownPrefix.toLowerCase();
7148
- });
7149
- if (exactMatch) {
7150
- return {
7151
- collateralToken: (_e = exactMatch.collateralToken) !== null && _e !== void 0 ? _e : 'USDC',
7152
- marketPrefix: (_f = exactMatch.marketPrefix) !== null && _f !== void 0 ? _f : null,
7153
- };
7154
- }
7155
- }
7156
- const regularAsset = perpMetaAssets.find((a) => a.name === coinName && !a.marketPrefix);
7157
- if (regularAsset) {
7158
- return {
7159
- collateralToken: (_g = regularAsset.collateralToken) !== null && _g !== void 0 ? _g : 'USDC',
7160
- marketPrefix: null,
7161
- };
7162
- }
7163
- const hip3Asset = perpMetaAssets.find((a) => a.name === coinName && a.marketPrefix);
7164
- if (hip3Asset) {
7165
- return {
7166
- collateralToken: (_h = hip3Asset.collateralToken) !== null && _h !== void 0 ? _h : 'USDC',
7167
- marketPrefix: (_j = hip3Asset.marketPrefix) !== null && _j !== void 0 ? _j : null,
7168
- };
7169
- }
7170
- return { collateralToken: 'USDC', marketPrefix: null };
7171
- }
7172
- function enrichPositionAssets(assets, perpMetaAssets) {
7173
- return assets.map((asset) => {
7174
- var _a;
7175
- if (asset.marketPrefix && asset.collateralToken) {
7176
- return asset;
7177
- }
7178
- const meta = findAssetMeta$3(asset.coin, perpMetaAssets, asset.marketPrefix, asset.collateralToken);
7179
- return {
7180
- ...asset,
7181
- marketPrefix: asset.marketPrefix || meta.marketPrefix,
7182
- collateralToken: (_a = asset.collateralToken) !== null && _a !== void 0 ? _a : meta.collateralToken,
7183
- };
7184
- });
7185
- }
7186
- function enrichPositions(positions, perpMetaAssets) {
7187
- return positions.map((position) => ({
7188
- ...position,
7189
- longAssets: enrichPositionAssets(position.longAssets, perpMetaAssets),
7190
- shortAssets: enrichPositionAssets(position.shortAssets, perpMetaAssets),
7191
- }));
7192
- }
7193
6841
  function usePosition() {
7194
6842
  const context = useContext(PearHyperliquidContext);
7195
6843
  if (!context) {
7196
6844
  throw new Error('usePosition must be used within a PearHyperliquidProvider');
7197
6845
  }
7198
6846
  const { apiBaseUrl, isConnected } = context;
7199
- const hip3Assets = useHyperliquidData((s) => s.hip3Assets);
7200
6847
  const createPosition$1 = async (payload) => {
7201
- return createPosition(apiBaseUrl, payload, hip3Assets);
6848
+ return createPosition(apiBaseUrl, payload);
7202
6849
  };
7203
6850
  const updateRiskParameters$1 = async (positionId, payload) => {
7204
6851
  return updateRiskParameters(apiBaseUrl, positionId, payload);
@@ -7213,7 +6860,7 @@ function usePosition() {
7213
6860
  return adjustPosition(apiBaseUrl, positionId, payload);
7214
6861
  };
7215
6862
  const adjustAdvancePosition$1 = async (positionId, payload) => {
7216
- return adjustAdvancePosition(apiBaseUrl, positionId, payload, hip3Assets);
6863
+ return adjustAdvancePosition(apiBaseUrl, positionId, payload);
7217
6864
  };
7218
6865
  const updateLeverage$1 = async (positionId, leverage) => {
7219
6866
  return updateLeverage(apiBaseUrl, positionId, { leverage });
@@ -7221,22 +6868,18 @@ function usePosition() {
7221
6868
  // Open positions using WS data, with derived values
7222
6869
  const userOpenPositions = useUserData((state) => state.rawOpenPositions);
7223
6870
  const aggregatedClearingHouseState = useHyperliquidData((state) => state.aggregatedClearingHouseState);
7224
- const allMids = useHyperliquidData((state) => state.allMids);
7225
- const allPerpMetaAssets = useHyperliquidData((state) => state.allPerpMetaAssets);
6871
+ const tokenMetadata = useHyperliquidData((state) => state.tokenMetadata);
6872
+ const { getAssetByName } = useMarket();
7226
6873
  const isLoading = useMemo(() => {
7227
6874
  return userOpenPositions === null && isConnected;
7228
6875
  }, [userOpenPositions, isConnected]);
7229
6876
  const openPositions = useMemo(() => {
7230
- if (!userOpenPositions || !aggregatedClearingHouseState || !allMids)
6877
+ if (!userOpenPositions ||
6878
+ !aggregatedClearingHouseState ||
6879
+ Object.keys(tokenMetadata).length === 0)
7231
6880
  return null;
7232
- const positions = buildPositionValue(userOpenPositions, aggregatedClearingHouseState, allMids);
7233
- return enrichPositions(positions, allPerpMetaAssets);
7234
- }, [
7235
- userOpenPositions,
7236
- aggregatedClearingHouseState,
7237
- allMids,
7238
- allPerpMetaAssets,
7239
- ]);
6881
+ return buildPositionValue(userOpenPositions, aggregatedClearingHouseState, getAssetByName);
6882
+ }, [userOpenPositions, aggregatedClearingHouseState, tokenMetadata, getAssetByName]);
7240
6883
  return {
7241
6884
  createPosition: createPosition$1,
7242
6885
  updateRiskParameters: updateRiskParameters$1,
@@ -7319,98 +6962,14 @@ async function executeSpotOrder(baseUrl, payload) {
7319
6962
  }
7320
6963
  }
7321
6964
 
7322
- function findAssetMeta$2(assetName, perpMetaAssets, knownPrefix, desiredCollateral) {
7323
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
7324
- if (!perpMetaAssets) {
7325
- return { collateralToken: 'USDC', marketPrefix: null };
7326
- }
7327
- if (desiredCollateral) {
7328
- const collateralMatch = perpMetaAssets.find((a) => a.name === assetName && a.collateralToken === desiredCollateral);
7329
- if (collateralMatch) {
7330
- return {
7331
- collateralToken: (_a = collateralMatch.collateralToken) !== null && _a !== void 0 ? _a : 'USDC',
7332
- marketPrefix: (_b = collateralMatch.marketPrefix) !== null && _b !== void 0 ? _b : null,
7333
- };
7334
- }
7335
- }
7336
- if (assetName.includes(':')) {
7337
- const [prefix, symbol] = assetName.split(':');
7338
- const exactMatch = perpMetaAssets.find((a) => {
7339
- var _a;
7340
- return a.name === symbol &&
7341
- ((_a = a.marketPrefix) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === prefix.toLowerCase();
7342
- });
7343
- if (exactMatch) {
7344
- return {
7345
- collateralToken: (_c = exactMatch.collateralToken) !== null && _c !== void 0 ? _c : 'USDC',
7346
- marketPrefix: (_d = exactMatch.marketPrefix) !== null && _d !== void 0 ? _d : null,
7347
- };
7348
- }
7349
- }
7350
- if (knownPrefix) {
7351
- const exactMatch = perpMetaAssets.find((a) => {
7352
- var _a;
7353
- return a.name === assetName &&
7354
- ((_a = a.marketPrefix) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === knownPrefix.toLowerCase();
7355
- });
7356
- if (exactMatch) {
7357
- return {
7358
- collateralToken: (_e = exactMatch.collateralToken) !== null && _e !== void 0 ? _e : 'USDC',
7359
- marketPrefix: (_f = exactMatch.marketPrefix) !== null && _f !== void 0 ? _f : null,
7360
- };
7361
- }
7362
- }
7363
- const regularAsset = perpMetaAssets.find((a) => a.name === assetName && !a.marketPrefix);
7364
- if (regularAsset) {
7365
- return {
7366
- collateralToken: (_g = regularAsset.collateralToken) !== null && _g !== void 0 ? _g : 'USDC',
7367
- marketPrefix: null,
7368
- };
7369
- }
7370
- const hip3Assets = perpMetaAssets.filter((a) => a.name === assetName && a.marketPrefix);
7371
- if (hip3Assets.length > 0) {
7372
- if (desiredCollateral) {
7373
- const collateralMatch = hip3Assets.find((a) => a.collateralToken === desiredCollateral);
7374
- if (collateralMatch) {
7375
- return {
7376
- collateralToken: (_h = collateralMatch.collateralToken) !== null && _h !== void 0 ? _h : 'USDC',
7377
- marketPrefix: (_j = collateralMatch.marketPrefix) !== null && _j !== void 0 ? _j : null,
7378
- };
7379
- }
7380
- }
7381
- const usdHMatch = hip3Assets.find((a) => a.collateralToken === 'USDH');
7382
- const chosen = usdHMatch !== null && usdHMatch !== void 0 ? usdHMatch : hip3Assets[0];
7383
- return {
7384
- collateralToken: (_k = chosen.collateralToken) !== null && _k !== void 0 ? _k : 'USDC',
7385
- marketPrefix: (_l = chosen.marketPrefix) !== null && _l !== void 0 ? _l : null,
7386
- };
7387
- }
7388
- return { collateralToken: 'USDC', marketPrefix: null };
7389
- }
7390
- function enrichOrderAssets$1(assets, perpMetaAssets) {
7391
- if (!assets)
7392
- return [];
7393
- return assets.map((asset) => {
7394
- var _a;
7395
- if (asset.marketPrefix && asset.collateralToken) {
7396
- return asset;
7397
- }
7398
- const meta = findAssetMeta$2(asset.asset, perpMetaAssets, asset.marketPrefix, asset.collateralToken);
7399
- return {
7400
- ...asset,
7401
- marketPrefix: asset.marketPrefix || meta.marketPrefix,
7402
- collateralToken: (_a = asset.collateralToken) !== null && _a !== void 0 ? _a : meta.collateralToken,
7403
- };
7404
- });
7405
- }
7406
6965
  function useOrders() {
7407
6966
  const context = useContext(PearHyperliquidContext);
7408
6967
  if (!context)
7409
6968
  throw new Error('useOrders must be used within a PearHyperliquidProvider');
7410
6969
  const { apiBaseUrl } = context;
7411
6970
  const openOrders = useUserData((state) => state.openOrders);
7412
- const allPerpMetaAssets = useHyperliquidData((state) => state.allPerpMetaAssets);
7413
6971
  const isLoading = useMemo(() => openOrders === null && context.isConnected, [openOrders, context.isConnected]);
6972
+ const { getAssetByName } = useMarket();
7414
6973
  const { openPositions } = usePosition();
7415
6974
  const positionsById = useMemo(() => {
7416
6975
  const map = new Map();
@@ -7423,22 +6982,26 @@ function useOrders() {
7423
6982
  const enrichedOpenOrders = useMemo(() => {
7424
6983
  if (!openOrders)
7425
6984
  return null;
6985
+ const mapOrderAssets = (assets) => assets.map((asset) => ({
6986
+ ...asset,
6987
+ metadata: getAssetByName(asset.asset),
6988
+ }));
7426
6989
  return openOrders.map((ord) => {
7427
- var _a, _b, _c, _d, _e;
6990
+ var _a, _b, _c, _d, _e, _f, _g;
7428
6991
  const isTpSl = ord.orderType === 'TP' || ord.orderType === 'SL';
7429
6992
  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;
7430
6993
  const pos = positionsById.get((_e = ord.positionId) !== null && _e !== void 0 ? _e : '');
7431
6994
  let enrichedOrd = {
7432
6995
  ...ord,
7433
- longAssets: enrichOrderAssets$1(ord.longAssets, allPerpMetaAssets),
7434
- shortAssets: enrichOrderAssets$1(ord.shortAssets, allPerpMetaAssets),
6996
+ longAssets: mapOrderAssets((_f = ord.longAssets) !== null && _f !== void 0 ? _f : []),
6997
+ shortAssets: mapOrderAssets((_g = ord.shortAssets) !== null && _g !== void 0 ? _g : []),
7435
6998
  };
6999
+ // For TP/SL orders without assets, derive them from the position
7436
7000
  if (isTpSl && !hasAssets && pos) {
7437
7001
  const mapAssets = (arr) => arr.map((a) => ({
7438
7002
  asset: a.coin,
7439
7003
  weight: a.initialWeight,
7440
- marketPrefix: a.marketPrefix,
7441
- collateralToken: a.collateralToken,
7004
+ metadata: getAssetByName(a.coin),
7442
7005
  }));
7443
7006
  enrichedOrd = {
7444
7007
  ...enrichedOrd,
@@ -7448,7 +7011,7 @@ function useOrders() {
7448
7011
  }
7449
7012
  return enrichedOrd;
7450
7013
  });
7451
- }, [openOrders, positionsById, allPerpMetaAssets]);
7014
+ }, [openOrders, positionsById, getAssetByName]);
7452
7015
  const adjustOrder$1 = async (orderId, payload) => {
7453
7016
  return adjustOrder(apiBaseUrl, orderId, payload);
7454
7017
  };
@@ -7506,108 +7069,27 @@ function useSpotOrder() {
7506
7069
  };
7507
7070
  }
7508
7071
 
7509
- function findAssetMeta$1(assetName, perpMetaAssets, knownPrefix, desiredCollateral) {
7510
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
7511
- if (!perpMetaAssets) {
7512
- return { collateralToken: 'USDC', marketPrefix: null };
7513
- }
7514
- if (desiredCollateral) {
7515
- const collateralMatch = perpMetaAssets.find((a) => a.name === assetName && a.collateralToken === desiredCollateral);
7516
- if (collateralMatch) {
7517
- return {
7518
- collateralToken: (_a = collateralMatch.collateralToken) !== null && _a !== void 0 ? _a : 'USDC',
7519
- marketPrefix: (_b = collateralMatch.marketPrefix) !== null && _b !== void 0 ? _b : null,
7520
- };
7521
- }
7522
- }
7523
- if (assetName.includes(':')) {
7524
- const [prefix, symbol] = assetName.split(':');
7525
- const exactMatch = perpMetaAssets.find((a) => {
7526
- var _a;
7527
- return a.name === symbol &&
7528
- ((_a = a.marketPrefix) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === prefix.toLowerCase();
7529
- });
7530
- if (exactMatch) {
7531
- return {
7532
- collateralToken: (_c = exactMatch.collateralToken) !== null && _c !== void 0 ? _c : 'USDC',
7533
- marketPrefix: (_d = exactMatch.marketPrefix) !== null && _d !== void 0 ? _d : null,
7534
- };
7535
- }
7536
- }
7537
- if (knownPrefix) {
7538
- const exactMatch = perpMetaAssets.find((a) => {
7539
- var _a;
7540
- return a.name === assetName &&
7541
- ((_a = a.marketPrefix) === null || _a === void 0 ? void 0 : _a.toLowerCase()) === knownPrefix.toLowerCase();
7542
- });
7543
- if (exactMatch) {
7544
- return {
7545
- collateralToken: (_e = exactMatch.collateralToken) !== null && _e !== void 0 ? _e : 'USDC',
7546
- marketPrefix: (_f = exactMatch.marketPrefix) !== null && _f !== void 0 ? _f : null,
7547
- };
7548
- }
7549
- }
7550
- const regularAsset = perpMetaAssets.find((a) => a.name === assetName && !a.marketPrefix);
7551
- if (regularAsset) {
7552
- return {
7553
- collateralToken: (_g = regularAsset.collateralToken) !== null && _g !== void 0 ? _g : 'USDC',
7554
- marketPrefix: null,
7555
- };
7556
- }
7557
- const hip3Assets = perpMetaAssets.filter((a) => a.name === assetName && a.marketPrefix);
7558
- if (hip3Assets.length > 0) {
7559
- if (desiredCollateral) {
7560
- const collateralMatch = hip3Assets.find((a) => a.collateralToken === desiredCollateral);
7561
- if (collateralMatch) {
7562
- return {
7563
- collateralToken: (_h = collateralMatch.collateralToken) !== null && _h !== void 0 ? _h : 'USDC',
7564
- marketPrefix: (_j = collateralMatch.marketPrefix) !== null && _j !== void 0 ? _j : null,
7565
- };
7566
- }
7567
- }
7568
- const usdHMatch = hip3Assets.find((a) => a.collateralToken === 'USDH');
7569
- const chosen = usdHMatch !== null && usdHMatch !== void 0 ? usdHMatch : hip3Assets[0];
7570
- return {
7571
- collateralToken: (_k = chosen.collateralToken) !== null && _k !== void 0 ? _k : 'USDC',
7572
- marketPrefix: (_l = chosen.marketPrefix) !== null && _l !== void 0 ? _l : null,
7573
- };
7574
- }
7575
- return { collateralToken: 'USDC', marketPrefix: null };
7576
- }
7577
- function enrichOrderAssets(assets, perpMetaAssets) {
7578
- if (!assets)
7579
- return [];
7580
- return assets.map((asset) => {
7581
- var _a;
7582
- if (asset.marketPrefix && asset.collateralToken) {
7583
- return asset;
7584
- }
7585
- const meta = findAssetMeta$1(asset.asset, perpMetaAssets, asset.marketPrefix, asset.collateralToken);
7586
- return {
7587
- ...asset,
7588
- marketPrefix: asset.marketPrefix || meta.marketPrefix,
7589
- collateralToken: (_a = asset.collateralToken) !== null && _a !== void 0 ? _a : meta.collateralToken,
7590
- };
7591
- });
7592
- }
7593
- function enrichTwapOrders(orders, perpMetaAssets) {
7594
- return orders.map((order) => ({
7595
- ...order,
7596
- longAssets: enrichOrderAssets(order.longAssets, perpMetaAssets),
7597
- shortAssets: enrichOrderAssets(order.shortAssets, perpMetaAssets),
7598
- }));
7599
- }
7600
7072
  function useTwap() {
7601
7073
  const twapDetails = useUserData((state) => state.twapDetails);
7602
- const allPerpMetaAssets = useHyperliquidData((state) => state.allPerpMetaAssets);
7603
7074
  const context = useContext(PearHyperliquidContext);
7604
7075
  if (!context)
7605
7076
  throw new Error('useTwap must be used within a PearHyperliquidProvider');
7606
7077
  const { apiBaseUrl } = context;
7078
+ const { getAssetByName } = useMarket();
7607
7079
  const orders = useMemo(() => {
7608
- const rawOrders = twapDetails !== null && twapDetails !== void 0 ? twapDetails : [];
7609
- return enrichTwapOrders(rawOrders, allPerpMetaAssets);
7610
- }, [twapDetails, allPerpMetaAssets]);
7080
+ const mapAssets = (assets) => assets.map((asset) => ({
7081
+ ...asset,
7082
+ metadata: getAssetByName(asset.asset),
7083
+ }));
7084
+ return (twapDetails !== null && twapDetails !== void 0 ? twapDetails : []).map((order) => {
7085
+ var _a, _b;
7086
+ return ({
7087
+ ...order,
7088
+ longAssets: mapAssets((_a = order.longAssets) !== null && _a !== void 0 ? _a : []),
7089
+ shortAssets: mapAssets((_b = order.shortAssets) !== null && _b !== void 0 ? _b : []),
7090
+ });
7091
+ });
7092
+ }, [twapDetails, getAssetByName]);
7611
7093
  const cancelTwap$1 = async (orderId) => {
7612
7094
  return cancelTwap(apiBaseUrl, orderId);
7613
7095
  };
@@ -7690,62 +7172,29 @@ function useNotifications() {
7690
7172
  };
7691
7173
  }
7692
7174
 
7693
- // Helper to find asset metadata from perpMetaAssets
7694
- function findAssetMeta(assetName, perpMetaAssets) {
7695
- var _a, _b, _c, _d;
7696
- if (!perpMetaAssets) {
7697
- return { collateralToken: 'USDC', marketPrefix: null };
7698
- }
7699
- // Try exact match first (for prefixed assets like "xyz:TSLA")
7700
- const exactMatch = perpMetaAssets.find((a) => a.name === assetName);
7701
- if (exactMatch) {
7702
- return {
7703
- collateralToken: (_a = exactMatch.collateralToken) !== null && _a !== void 0 ? _a : 'USDC',
7704
- marketPrefix: (_b = exactMatch.marketPrefix) !== null && _b !== void 0 ? _b : null,
7705
- };
7706
- }
7707
- // Try matching by base symbol (for non-prefixed names in data)
7708
- const baseMatch = perpMetaAssets.find((a) => {
7709
- const baseName = a.name.includes(':') ? a.name.split(':')[1] : a.name;
7710
- return baseName === assetName;
7711
- });
7712
- if (baseMatch) {
7713
- return {
7714
- collateralToken: (_c = baseMatch.collateralToken) !== null && _c !== void 0 ? _c : 'USDC',
7715
- marketPrefix: (_d = baseMatch.marketPrefix) !== null && _d !== void 0 ? _d : null,
7716
- };
7717
- }
7718
- return { collateralToken: 'USDC', marketPrefix: null };
7719
- }
7720
- // Enrich a single asset with metadata
7721
- function enrichAsset(asset, perpMetaAssets) {
7722
- const meta = findAssetMeta(asset.asset, perpMetaAssets);
7723
- return {
7724
- ...asset,
7725
- collateralToken: meta.collateralToken,
7726
- marketPrefix: meta.marketPrefix,
7727
- };
7728
- }
7729
- // Enrich a basket item with collateral info
7730
- function enrichBasketItem(item, perpMetaAssets) {
7731
- const enrichedLongs = item.longAssets.map((a) => enrichAsset(a, perpMetaAssets));
7732
- const enrichedShorts = item.shortAssets.map((a) => enrichAsset(a, perpMetaAssets));
7733
- // Determine collateral type
7734
- const allAssets = [...enrichedLongs, ...enrichedShorts];
7735
- const hasUsdc = allAssets.some((a) => a.collateralToken === 'USDC');
7736
- const hasUsdh = allAssets.some((a) => a.collateralToken === 'USDH');
7737
- let collateralType = 'USDC';
7738
- if (hasUsdc && hasUsdh) {
7739
- collateralType = 'MIXED';
7740
- }
7741
- else if (hasUsdh) {
7742
- collateralType = 'USDH';
7743
- }
7175
+ // Convert a basket item to the expected type
7176
+ function enrichBasketItem(item) {
7177
+ const enrichedLongs = item.longAssets.map((a) => ({
7178
+ ...a,
7179
+ }));
7180
+ const enrichedShorts = item.shortAssets.map((a) => ({
7181
+ ...a,
7182
+ }));
7183
+ // // Determine collateral type
7184
+ // const allAssets = [...enrichedLongs, ...enrichedShorts];
7185
+ // const hasUsdc = allAssets.some((a) => a.collateralToken === 'USDC');
7186
+ // const hasUsdh = allAssets.some((a) => a.collateralToken === 'USDH');
7187
+ // let collateralType: 'USDC' | 'USDH' | 'MIXED' = 'USDC';
7188
+ // if (hasUsdc && hasUsdh) {
7189
+ // collateralType = 'MIXED';
7190
+ // } else if (hasUsdh) {
7191
+ // collateralType = 'USDH';
7192
+ // }
7744
7193
  return {
7745
7194
  ...item,
7746
7195
  longAssets: enrichedLongs,
7747
7196
  shortAssets: enrichedShorts,
7748
- collateralType,
7197
+ collateralType: 'USDC', //TODO: change
7749
7198
  };
7750
7199
  }
7751
7200
  /**
@@ -7774,86 +7223,61 @@ function filterByCollateral(baskets, filter) {
7774
7223
  const useMarketDataPayload = () => {
7775
7224
  return useMarketData((s) => s.marketData);
7776
7225
  };
7777
- // Full payload for 'market-data-all' channel (raw from WS)
7778
- const useMarketDataAllPayload = () => {
7779
- return useMarketData((s) => s.marketDataAll);
7780
- };
7781
- // Access perpMetaAssets for enrichment
7782
- const usePerpMetaAssets = () => {
7783
- return useHyperliquidData((s) => s.perpMetaAssets);
7784
- };
7785
- // Active baskets (with collateral and market prefix info)
7226
+ // Active baskets
7786
7227
  const useActiveBaskets = (collateralFilter) => {
7787
7228
  const data = useMarketDataPayload();
7788
- const perpMetaAssets = usePerpMetaAssets();
7789
7229
  return useMemo(() => {
7790
7230
  if (!(data === null || data === void 0 ? void 0 : data.active))
7791
7231
  return [];
7792
- const enriched = data.active.map((item) => enrichBasketItem(item, perpMetaAssets));
7232
+ const enriched = data.active.map((item) => enrichBasketItem(item));
7793
7233
  return filterByCollateral(enriched, collateralFilter);
7794
- }, [data, perpMetaAssets, collateralFilter]);
7234
+ }, [data, collateralFilter]);
7795
7235
  };
7796
- // Top gainers (with collateral and market prefix info)
7236
+ // Top gainers
7797
7237
  const useTopGainers = (limit, collateralFilter) => {
7798
7238
  const data = useMarketDataPayload();
7799
- const perpMetaAssets = usePerpMetaAssets();
7800
7239
  return useMemo(() => {
7801
7240
  var _a;
7802
7241
  const list = (_a = data === null || data === void 0 ? void 0 : data.topGainers) !== null && _a !== void 0 ? _a : [];
7803
7242
  const limited = typeof limit === 'number' ? list.slice(0, Math.max(0, limit)) : list;
7804
- const enriched = limited.map((item) => enrichBasketItem(item, perpMetaAssets));
7243
+ const enriched = limited.map((item) => enrichBasketItem(item));
7805
7244
  return filterByCollateral(enriched, collateralFilter);
7806
- }, [data, perpMetaAssets, limit, collateralFilter]);
7245
+ }, [data, limit, collateralFilter]);
7807
7246
  };
7808
- // Top losers (with collateral and market prefix info)
7247
+ // Top losers
7809
7248
  const useTopLosers = (limit, collateralFilter) => {
7810
7249
  const data = useMarketDataPayload();
7811
- const perpMetaAssets = usePerpMetaAssets();
7812
7250
  return useMemo(() => {
7813
7251
  var _a;
7814
7252
  const list = (_a = data === null || data === void 0 ? void 0 : data.topLosers) !== null && _a !== void 0 ? _a : [];
7815
7253
  const limited = typeof limit === 'number' ? list.slice(0, Math.max(0, limit)) : list;
7816
- const enriched = limited.map((item) => enrichBasketItem(item, perpMetaAssets));
7254
+ const enriched = limited.map((item) => enrichBasketItem(item));
7817
7255
  return filterByCollateral(enriched, collateralFilter);
7818
- }, [data, perpMetaAssets, limit, collateralFilter]);
7256
+ }, [data, limit, collateralFilter]);
7819
7257
  };
7820
- // Highlighted baskets (with collateral and market prefix info)
7258
+ // Highlighted baskets
7821
7259
  const useHighlightedBaskets = (collateralFilter) => {
7822
7260
  const data = useMarketDataPayload();
7823
- const perpMetaAssets = usePerpMetaAssets();
7824
7261
  return useMemo(() => {
7825
7262
  if (!(data === null || data === void 0 ? void 0 : data.highlighted))
7826
7263
  return [];
7827
- const enriched = data.highlighted.map((item) => enrichBasketItem(item, perpMetaAssets));
7264
+ const enriched = data.highlighted.map((item) => enrichBasketItem(item));
7828
7265
  return filterByCollateral(enriched, collateralFilter);
7829
- }, [data, perpMetaAssets, collateralFilter]);
7266
+ }, [data, collateralFilter]);
7830
7267
  };
7831
- // Watchlist baskets (with collateral and market prefix info)
7268
+ // Watchlist baskets
7832
7269
  const useWatchlistBaskets = (collateralFilter) => {
7833
7270
  const data = useMarketDataPayload();
7834
- const perpMetaAssets = usePerpMetaAssets();
7835
7271
  return useMemo(() => {
7836
7272
  if (!(data === null || data === void 0 ? void 0 : data.watchlist))
7837
7273
  return [];
7838
- const enriched = data.watchlist.map((item) => enrichBasketItem(item, perpMetaAssets));
7839
- return filterByCollateral(enriched, collateralFilter);
7840
- }, [data, perpMetaAssets, collateralFilter]);
7841
- };
7842
- // All baskets (with collateral and market prefix info)
7843
- const useAllBaskets = (collateralFilter) => {
7844
- const dataAll = useMarketDataAllPayload();
7845
- const perpMetaAssets = usePerpMetaAssets();
7846
- return useMemo(() => {
7847
- if (!(dataAll === null || dataAll === void 0 ? void 0 : dataAll.all))
7848
- return [];
7849
- const enriched = dataAll.all.map((item) => enrichBasketItem(item, perpMetaAssets));
7274
+ const enriched = data.watchlist.map((item) => enrichBasketItem(item));
7850
7275
  return filterByCollateral(enriched, collateralFilter);
7851
- }, [dataAll, perpMetaAssets, collateralFilter]);
7276
+ }, [data, collateralFilter]);
7852
7277
  };
7853
7278
  // Find a basket by its exact asset composition (order-insensitive)
7854
7279
  const useFindBasket = (longs, shorts) => {
7855
7280
  const data = useMarketDataPayload();
7856
- const perpMetaAssets = usePerpMetaAssets();
7857
7281
  return useMemo(() => {
7858
7282
  if (!data)
7859
7283
  return undefined;
@@ -7871,18 +7295,17 @@ const useFindBasket = (longs, shorts) => {
7871
7295
  normalize(item.shortAssets) === sKey;
7872
7296
  const found = data.active.find(match) || data.highlighted.find(match);
7873
7297
  return found
7874
- ? enrichBasketItem(found, perpMetaAssets)
7298
+ ? enrichBasketItem(found)
7875
7299
  : undefined;
7876
- }, [data, longs, shorts, perpMetaAssets]);
7300
+ }, [data, longs, shorts]);
7877
7301
  };
7878
7302
 
7879
- async function toggleWatchlist(baseUrl, longAssets, shortAssets, hip3Assets) {
7303
+ async function toggleWatchlist(baseUrl, longAssets, shortAssets) {
7880
7304
  const url = joinUrl(baseUrl, '/watchlist');
7881
- const mapAssets = (arr) => arr.map((a) => ({ ...a, asset: toBackendSymbol(a.asset, hip3Assets) }));
7882
7305
  try {
7883
7306
  const response = await apiClient.post(url, {
7884
- longAssets: mapAssets(longAssets),
7885
- shortAssets: mapAssets(shortAssets),
7307
+ longAssets,
7308
+ shortAssets,
7886
7309
  }, { headers: { 'Content-Type': 'application/json' } });
7887
7310
  return {
7888
7311
  data: response.data,
@@ -7900,11 +7323,10 @@ function useWatchlist() {
7900
7323
  if (!context)
7901
7324
  throw new Error('useWatchlist must be used within a PearHyperliquidProvider');
7902
7325
  const { apiBaseUrl, isConnected } = context;
7903
- const hip3Assets = useHyperliquidData((s) => s.hip3Assets);
7904
7326
  const marketData = useMarketDataPayload();
7905
7327
  const isLoading = useMemo(() => !marketData && isConnected, [marketData, isConnected]);
7906
7328
  const toggle = async (longAssets, shortAssets) => {
7907
- const resp = await toggleWatchlist(apiBaseUrl, longAssets, shortAssets, hip3Assets);
7329
+ const resp = await toggleWatchlist(apiBaseUrl, longAssets, shortAssets);
7908
7330
  // Server will push updated market-data over WS; nothing to set here
7909
7331
  return resp;
7910
7332
  };
@@ -8162,7 +7584,6 @@ const useAllUserBalances = () => {
8162
7584
  const spotState = useUserData((state) => state.spotState);
8163
7585
  const aggregatedClearingHouseState = useHyperliquidData((state) => state.aggregatedClearingHouseState);
8164
7586
  const rawClearinghouseStates = useHyperliquidData((state) => state.rawClearinghouseStates);
8165
- const activeAssetData = useHyperliquidData((state) => state.activeAssetData);
8166
7587
  const { longTokensMetadata, shortTokensMetadata } = useTokenSelectionMetadata();
8167
7588
  return useMemo(() => {
8168
7589
  const isLoading = !spotState || !aggregatedClearingHouseState;
@@ -8185,39 +7606,50 @@ const useAllUserBalances = () => {
8185
7606
  }
8186
7607
  }
8187
7608
  }
7609
+ // Get available to trade from tokenMetadata for both USDC and USDH markets
7610
+ let availableToTradeUsdcFromAsset = 0;
8188
7611
  let availableToTradeUsdhFromAsset = 0;
8189
- // This activeAssetData only contains data for SELECTED tokens (user's long and short Tokens)
7612
+ // Token metadata only contains availableToTrade for SELECTED tokens (user's long and short Tokens)
8190
7613
  // It does NOT contain data for all tokens, so we cannot reliably use it for available to trade as used on hl trade page
8191
7614
  // so intead, we rely on rawClearinghouseStates which provides market-specific data
8192
- // if (activeAssetData) {
8193
- // Object.values(activeAssetData).forEach((assetData) => {
8194
- // if (!assetData.availableToTrade) return;
8195
- // const coinSymbol = assetData.coin;
8196
- // const availableValue = truncateToTwoDecimals(
8197
- // parseFloat(assetData.availableToTrade[0] || '0'),
8198
- // );
8199
- // // Determine collateral type based on market prefix
8200
- // // HIP3 markets have prefix: "xyz:SYMBOL", "flx:SYMBOL", "vntl:SYMBOL", etc.
8201
- // if (coinSymbol.includes(':')) {
8202
- // const prefix = coinSymbol.split(':')[0];
8203
- // if (prefix === 'xyz') {
8204
- // // xyz markets use USDC
8205
- // availableToTradeUsdcFromAsset = availableValue;
8206
- // } else {
8207
- // // flx, vntl, hyna and other markets use USDH
8208
- // availableToTradeUsdhFromAsset = availableValue;
8209
- // }
8210
- // } else {
8211
- // // Regular markets without prefix are automatically USDC
8212
- // availableToTradeUsdcFromAsset = availableValue;
8213
- // }
8214
- // });
8215
- // }
7615
+ const selectedMetadataEntries = [
7616
+ ...Object.entries(longTokensMetadata),
7617
+ ...Object.entries(shortTokensMetadata),
7618
+ ];
7619
+ selectedMetadataEntries.forEach(([symbol, metadata]) => {
7620
+ var _a;
7621
+ const availableStr = (_a = metadata === null || metadata === void 0 ? void 0 : metadata.availableToTrade) === null || _a === void 0 ? void 0 : _a[0];
7622
+ if (!availableStr)
7623
+ return;
7624
+ const availableValue = truncateToTwoDecimals(parseFloat(availableStr || '0'));
7625
+ if ((metadata === null || metadata === void 0 ? void 0 : metadata.collateralToken) === 'USDH') {
7626
+ availableToTradeUsdhFromAsset = Math.max(availableToTradeUsdhFromAsset, availableValue);
7627
+ return;
7628
+ }
7629
+ if ((metadata === null || metadata === void 0 ? void 0 : metadata.collateralToken) === 'USDC') {
7630
+ availableToTradeUsdcFromAsset = Math.max(availableToTradeUsdcFromAsset, availableValue);
7631
+ return;
7632
+ }
7633
+ if (symbol.includes(':')) {
7634
+ const prefix = symbol.split(':')[0];
7635
+ if (prefix === 'xyz') {
7636
+ availableToTradeUsdcFromAsset = Math.max(availableToTradeUsdcFromAsset, availableValue);
7637
+ }
7638
+ else {
7639
+ availableToTradeUsdhFromAsset = Math.max(availableToTradeUsdhFromAsset, availableValue);
7640
+ }
7641
+ return;
7642
+ }
7643
+ availableToTradeUsdcFromAsset = Math.max(availableToTradeUsdcFromAsset, availableValue);
7644
+ });
8216
7645
  // Calculate USDC available to trade
8217
7646
  // Priority 1: Use value from activeAssetData if available (> 0)
8218
7647
  // Priority 2: Calculate from USDC-specific clearinghouseState (empty prefix)
8219
7648
  let availableToTradeUsdcValue = undefined;
8220
- if (rawClearinghouseStates) {
7649
+ if (availableToTradeUsdcFromAsset > 0) {
7650
+ availableToTradeUsdcValue = availableToTradeUsdcFromAsset;
7651
+ }
7652
+ else if (rawClearinghouseStates) {
8221
7653
  // Find USDC market (empty prefix)
8222
7654
  const usdcMarket = rawClearinghouseStates.find(([prefix]) => prefix === '');
8223
7655
  const usdcState = usdcMarket === null || usdcMarket === void 0 ? void 0 : usdcMarket[1];
@@ -8245,7 +7677,6 @@ const useAllUserBalances = () => {
8245
7677
  spotState,
8246
7678
  aggregatedClearingHouseState,
8247
7679
  rawClearinghouseStates,
8248
- activeAssetData,
8249
7680
  longTokensMetadata,
8250
7681
  shortTokensMetadata,
8251
7682
  ]);
@@ -8347,7 +7778,7 @@ function useHyperliquidUserFills(options) {
8347
7778
  if (!userState.accountSummary)
8348
7779
  return;
8349
7780
  const clearinghouseState = useHyperliquidData.getState().aggregatedClearingHouseState;
8350
- if (!(clearinghouseState === null || clearinghouseState === void 0 ? void 0 : clearinghouseState.assetPositions))
7781
+ if (!clearinghouseState)
8351
7782
  return;
8352
7783
  setIsSyncing(true);
8353
7784
  setError(null);
@@ -8392,9 +7823,6 @@ const PearHyperliquidProvider = ({ children, apiBaseUrl = 'https://hl-ui.pearpro
8392
7823
  const setAddress = useUserData((s) => s.setAddress);
8393
7824
  const perpsMetaAssets = useHyperliquidData((state) => state.perpMetaAssets);
8394
7825
  const setPerpMetaAssets = useHyperliquidData((state) => state.setPerpMetaAssets);
8395
- const setAllPerpMetaAssets = useHyperliquidData((state) => state.setAllPerpMetaAssets);
8396
- const setHip3Assets = useHyperliquidData((state) => state.setHip3Assets);
8397
- const setHip3MarketPrefixes = useHyperliquidData((state) => state.setHip3MarketPrefixes);
8398
7826
  const websocketsEnabled = useMemo(() => Array.isArray(perpsMetaAssets) && perpsMetaAssets.length > 0, [perpsMetaAssets]);
8399
7827
  const { handleUserFillsEvent } = useHyperliquidUserFills({
8400
7828
  baseUrl: apiBaseUrl,
@@ -8415,106 +7843,34 @@ const PearHyperliquidProvider = ({ children, apiBaseUrl = 'https://hl-ui.pearpro
8415
7843
  if (perpsMetaAssets === null) {
8416
7844
  fetchAllPerpMetas()
8417
7845
  .then((res) => {
8418
- const assetToMarkets = new Map();
8419
- const marketPrefixes = new Map();
8420
- const FILTERED_PREFIXES = ['hyna'];
8421
- // Group assets by market prefix to match WebSocket flattening order
8422
- // WebSocket sends in order: "", "flx", "hyna", "vntl", "xyz" (we filter out hyna)
8423
- const assetsByPrefix = new Map();
8424
- const allAssetsByPrefix = new Map();
7846
+ const allPerpMetas = [];
8425
7847
  res.data.forEach((item) => {
8426
- const collateralToken = item.collateralToken === 360 ? 'USDH' : 'USDC';
7848
+ // Only include USDC and USDH collateral tokens
7849
+ if (item.collateralToken !== 360 && item.collateralToken !== 0) {
7850
+ return;
7851
+ }
7852
+ var collateralToken;
7853
+ if (item.collateralToken === 360) {
7854
+ collateralToken = 'USDH';
7855
+ }
7856
+ if (item.collateralToken === 0) {
7857
+ collateralToken = 'USDC';
7858
+ }
8427
7859
  item.universe.forEach((asset) => {
8428
- var _a;
8429
- const [maybePrefix, maybeMarket] = asset.name.split(':');
8430
- if (maybeMarket) {
8431
- // HIP3 asset with market prefix
8432
- const prefix = maybePrefix.toLowerCase();
8433
- const displayName = maybeMarket;
8434
- const fullName = `${prefix}:${displayName}`;
8435
- marketPrefixes.set(fullName, prefix);
8436
- if (!FILTERED_PREFIXES.includes(prefix)) {
8437
- const existingMarkets = (_a = assetToMarkets.get(displayName)) !== null && _a !== void 0 ? _a : [];
8438
- if (!existingMarkets.includes(fullName)) {
8439
- assetToMarkets.set(displayName, [
8440
- ...existingMarkets,
8441
- fullName,
8442
- ]);
8443
- }
8444
- }
8445
- const assetWithMeta = {
8446
- ...asset,
8447
- name: displayName,
8448
- marketPrefix: prefix,
8449
- collateralToken,
8450
- };
8451
- // Group by market prefix
8452
- const allList = allAssetsByPrefix.get(prefix) || [];
8453
- allList.push(assetWithMeta);
8454
- allAssetsByPrefix.set(prefix, allList);
8455
- if (!FILTERED_PREFIXES.includes(prefix)) {
8456
- const cleanedList = assetsByPrefix.get(prefix) || [];
8457
- cleanedList.push(assetWithMeta);
8458
- assetsByPrefix.set(prefix, cleanedList);
8459
- }
8460
- }
8461
- else {
8462
- // Default market asset (no prefix)
8463
- const assetWithMeta = {
8464
- ...asset,
8465
- collateralToken,
8466
- };
8467
- // Add to default market group ("")
8468
- const defaultList = assetsByPrefix.get('') || [];
8469
- defaultList.push(assetWithMeta);
8470
- assetsByPrefix.set('', defaultList);
8471
- const allDefaultList = allAssetsByPrefix.get('') || [];
8472
- allDefaultList.push(assetWithMeta);
8473
- allAssetsByPrefix.set('', allDefaultList);
8474
- }
7860
+ const assetWithMeta = {
7861
+ ...asset,
7862
+ collateralToken,
7863
+ };
7864
+ allPerpMetas.push(assetWithMeta);
8475
7865
  });
8476
7866
  });
8477
- // Flatten in consistent order: default market first, then HIP3 markets alphabetically
8478
- // This ensures both REST API and WebSocket data align properly
8479
- const cleanedPrefixes = Array.from(assetsByPrefix.keys()).sort((a, b) => {
8480
- // Empty prefix (default market) always comes first
8481
- if (a === '' && b !== '')
8482
- return -1;
8483
- if (a !== '' && b === '')
8484
- return 1;
8485
- // HIP3 markets sorted alphabetically
8486
- return a.localeCompare(b);
8487
- });
8488
- const allPrefixes = Array.from(allAssetsByPrefix.keys()).sort((a, b) => {
8489
- if (a === '' && b !== '')
8490
- return -1;
8491
- if (a !== '' && b === '')
8492
- return 1;
8493
- return a.localeCompare(b);
8494
- });
8495
- const cleanedPerpMetas = [];
8496
- const allPerpMetas = [];
8497
- cleanedPrefixes.forEach((prefix) => {
8498
- const assets = assetsByPrefix.get(prefix) || [];
8499
- cleanedPerpMetas.push(...assets);
8500
- });
8501
- allPrefixes.forEach((prefix) => {
8502
- const assets = allAssetsByPrefix.get(prefix) || [];
8503
- allPerpMetas.push(...assets);
8504
- });
8505
- setHip3Assets(assetToMarkets);
8506
- setHip3MarketPrefixes(marketPrefixes);
8507
- setPerpMetaAssets(cleanedPerpMetas);
8508
- setAllPerpMetaAssets(allPerpMetas);
7867
+ setPerpMetaAssets(allPerpMetas);
8509
7868
  })
8510
7869
  .catch(() => { });
8511
7870
  }
8512
7871
  }, [
8513
7872
  perpsMetaAssets,
8514
7873
  setPerpMetaAssets,
8515
- setAllPerpMetaAssets,
8516
- setHip3Assets,
8517
- setHip3MarketPrefixes,
8518
7874
  ]);
8519
7875
  const contextValue = useMemo(() => ({
8520
7876
  // Config
@@ -8799,4 +8155,4 @@ function getOrderTrailingInfo(order) {
8799
8155
  return undefined;
8800
8156
  }
8801
8157
 
8802
- 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, getKalshiMarkets, getMarketPrefix, getOrderDirection, getOrderLadderConfig, getOrderLeverage, getOrderReduceOnly, getOrderTpSlTriggerType, getOrderTrailingInfo, getOrderTriggerType, getOrderTriggerValue, getOrderTwapDuration, getOrderUsdValue, getPortfolio, isBtcDomOrder, isHip3Market, mapCandleIntervalToTradingViewInterval, mapTradingViewIntervalToCandleInterval, markNotificationReadById, markNotificationsRead, toBackendSymbol, toBackendSymbolWithMarket, toDisplaySymbol, toggleWatchlist, updateLeverage, updateRiskParameters, useAccountSummary, useActiveBaskets, useAgentWallet, useAllBaskets, useAllUserBalances, useAuth, useBasketCandles, useFindBasket, useHighlightedBaskets, useHistoricalPriceData, useHistoricalPriceDataStore, useHyperliquidNativeWebSocket, useHyperliquidUserFills, 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 };
8158
+ 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, getAssetByName, getCompleteTimestamps, getKalshiMarkets, getOrderDirection, getOrderLadderConfig, getOrderLeverage, getOrderReduceOnly, getOrderTpSlTriggerType, getOrderTrailingInfo, getOrderTriggerType, getOrderTriggerValue, getOrderTwapDuration, getOrderUsdValue, getPortfolio, isBtcDomOrder, mapCandleIntervalToTradingViewInterval, mapTradingViewIntervalToCandleInterval, markNotificationReadById, markNotificationsRead, selectTokenMetadataBySymbols, toggleWatchlist, updateLeverage, updateRiskParameters, useAccountSummary, useActiveBaskets, useAgentWallet, useAllUserBalances, useAuth, useBasketCandles, useFindBasket, useHighlightedBaskets, useHistoricalPriceData, useHistoricalPriceDataStore, useHyperliquidNativeWebSocket, useHyperliquidUserFills, useHyperliquidWebSocket, useMarket, useMarketData, useMarketDataPayload, useNotifications, useOpenOrders, useOrders, usePearHyperliquid, usePerformanceOverlays, usePortfolio, usePosition, useSpotOrder, useTokenSelectionMetadata, useTopGainers, useTopLosers, useTradeHistories, useTwap, useUserSelection, useWatchlist, useWatchlistBaskets, validateMaxAssetsPerLeg, validateMinimumAssetSize, validatePositionSize };