@pear-protocol/hyperliquid-sdk 0.0.73 → 0.0.75

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
@@ -775,7 +775,7 @@ const useUserSelection$1 = create((set, get) => ({
775
775
  resetToDefaults: () => set((prev) => ({ ...prev, ...DEFAULT_STATE })),
776
776
  }));
777
777
 
778
- const useHyperliquidNativeWebSocket = ({ address, enabled = true, }) => {
778
+ const useHyperliquidNativeWebSocket = ({ address, enabled = true, onUserFills, }) => {
779
779
  const { setAllMids, setActiveAssetData, upsertActiveAssetData, setCandleData, deleteCandleSymbol, deleteActiveAssetData, addCandleData, setFinalAssetContexts, setFinalAtOICaps, setAggregatedClearingHouseState, setRawClearinghouseStates, } = useHyperliquidData();
780
780
  const { setSpotState } = useUserData();
781
781
  const { candleInterval } = useUserSelection$1();
@@ -810,6 +810,14 @@ const useHyperliquidNativeWebSocket = ({ address, enabled = true, }) => {
810
810
  if ('channel' in message && 'data' in message) {
811
811
  const response = message;
812
812
  switch (response.channel) {
813
+ case 'userFills':
814
+ {
815
+ const maybePromise = onUserFills === null || onUserFills === void 0 ? void 0 : onUserFills();
816
+ if (maybePromise instanceof Promise) {
817
+ maybePromise.catch((err) => console.error('[HyperLiquid WS] userFills callback error', err));
818
+ }
819
+ }
820
+ break;
813
821
  case 'webData3':
814
822
  const webData3 = response.data;
815
823
  // finalAssetContexts now sourced from allDexsAssetCtxs channel
@@ -950,6 +958,7 @@ const useHyperliquidNativeWebSocket = ({ address, enabled = true, }) => {
950
958
  setAggregatedClearingHouseState,
951
959
  setRawClearinghouseStates,
952
960
  setSpotState,
961
+ onUserFills,
953
962
  ]);
954
963
  const connect = useCallback(() => {
955
964
  if (!enabled)
@@ -1067,6 +1076,14 @@ const useHyperliquidNativeWebSocket = ({ address, enabled = true, }) => {
1067
1076
  },
1068
1077
  };
1069
1078
  sendJsonMessage(unsubscribeAllDexsClearinghouseState);
1079
+ const unsubscribeUserFills = {
1080
+ method: 'unsubscribe',
1081
+ subscription: {
1082
+ type: 'userFills',
1083
+ user: subscribedAddress,
1084
+ },
1085
+ };
1086
+ sendJsonMessage(unsubscribeUserFills);
1070
1087
  }
1071
1088
  const subscribeWebData3 = {
1072
1089
  method: "subscribe",
@@ -1098,10 +1115,18 @@ const useHyperliquidNativeWebSocket = ({ address, enabled = true, }) => {
1098
1115
  type: "allDexsAssetCtxs",
1099
1116
  },
1100
1117
  };
1118
+ const subscribeUserFills = {
1119
+ method: 'subscribe',
1120
+ subscription: {
1121
+ type: 'userFills',
1122
+ user: userAddress,
1123
+ },
1124
+ };
1101
1125
  sendJsonMessage(subscribeWebData3);
1102
1126
  sendJsonMessage(subscribeAllDexsClearinghouseState);
1103
1127
  sendJsonMessage(subscribeAllMids);
1104
1128
  sendJsonMessage(subscribeAllDexsAssetCtxs);
1129
+ sendJsonMessage(subscribeUserFills);
1105
1130
  // Subscribe to spotState for real-time spot balances (USDH, USDC, etc.)
1106
1131
  // Only subscribe if we have a real user address (not the default)
1107
1132
  if (userAddress !== DEFAULT_ADDRESS) {
@@ -1514,6 +1539,20 @@ const useWebData = () => {
1514
1539
  };
1515
1540
  };
1516
1541
 
1542
+ /**
1543
+ * Check if two symbols match, handling kPEPE/KPEPE variations
1544
+ * Returns true if symbols match (case-insensitive for k-prefix tokens)
1545
+ */
1546
+ function symbolsMatch(assetName, searchSymbol) {
1547
+ // Exact match
1548
+ if (assetName === searchSymbol)
1549
+ return true;
1550
+ // Try case-insensitive match for k-prefix tokens (kPEPE vs KPEPE)
1551
+ if (assetName.toUpperCase() === searchSymbol.toUpperCase()) {
1552
+ return true;
1553
+ }
1554
+ return false;
1555
+ }
1517
1556
  /**
1518
1557
  * Extracts token metadata from aggregated WebData3 contexts and AllMids data
1519
1558
  */
@@ -1534,8 +1573,9 @@ class TokenMetadataExtractor {
1534
1573
  }
1535
1574
  // Find token index in aggregated universe
1536
1575
  // For HIP3 assets, match both name AND marketPrefix
1576
+ // Uses symbolsMatch to handle kPEPE/KPEPE case variations
1537
1577
  const universeIndex = perpMetaAssets.findIndex((asset) => {
1538
- if (asset.name !== symbol)
1578
+ if (!symbolsMatch(asset.name, symbol))
1539
1579
  return false;
1540
1580
  // If marketPrefix is specified, match it; otherwise match assets without prefix
1541
1581
  if (marketPrefix) {
@@ -1554,15 +1594,20 @@ class TokenMetadataExtractor {
1554
1594
  }
1555
1595
  // Get current price - prefer assetCtx.midPx as it's already index-matched,
1556
1596
  // fall back to allMids lookup if midPx is null
1557
- const prefixedKeyColon = marketPrefix ? `${marketPrefix}:${symbol}` : null;
1597
+ const actualSymbol = universeAsset.name; // Use actual symbol from universe (handles kPEPE vs KPEPE)
1598
+ const prefixedKeyColon = marketPrefix
1599
+ ? `${marketPrefix}:${actualSymbol}`
1600
+ : null;
1558
1601
  let currentPrice = 0;
1559
1602
  // Primary source: assetCtx.midPx (already properly indexed)
1560
1603
  if (assetCtx.midPx) {
1561
1604
  currentPrice = parseFloat(assetCtx.midPx);
1562
1605
  }
1563
1606
  // Fallback: allMids lookup with multiple key formats for HIP3 markets
1607
+ // Try actual symbol from universe first, then input symbol
1564
1608
  if (!currentPrice || isNaN(currentPrice)) {
1565
1609
  const currentPriceStr = (prefixedKeyColon && allMids.mids[prefixedKeyColon]) ||
1610
+ allMids.mids[actualSymbol] ||
1566
1611
  allMids.mids[symbol];
1567
1612
  currentPrice = currentPriceStr ? parseFloat(currentPriceStr) : 0;
1568
1613
  }
@@ -1576,10 +1621,12 @@ class TokenMetadataExtractor {
1576
1621
  const markPrice = parseFloat(assetCtx.markPx);
1577
1622
  const oraclePrice = parseFloat(assetCtx.oraclePx);
1578
1623
  // Extract leverage info from activeAssetData if available
1579
- // Try prefixed key first (e.g., "xyz:TSLA"), then fall back to plain symbol
1624
+ // Try prefixed key first (e.g., "xyz:TSLA"), then actual symbol, then input symbol
1580
1625
  const activeDataKey = prefixedKeyColon && (activeAssetData === null || activeAssetData === void 0 ? void 0 : activeAssetData[prefixedKeyColon])
1581
1626
  ? prefixedKeyColon
1582
- : symbol;
1627
+ : (activeAssetData === null || activeAssetData === void 0 ? void 0 : activeAssetData[actualSymbol])
1628
+ ? actualSymbol
1629
+ : symbol;
1583
1630
  const tokenActiveData = activeAssetData === null || activeAssetData === void 0 ? void 0 : activeAssetData[activeDataKey];
1584
1631
  const leverage = tokenActiveData === null || tokenActiveData === void 0 ? void 0 : tokenActiveData.leverage;
1585
1632
  const maxTradeSzs = tokenActiveData === null || tokenActiveData === void 0 ? void 0 : tokenActiveData.maxTradeSzs;
@@ -1631,7 +1678,7 @@ class TokenMetadataExtractor {
1631
1678
  static isTokenAvailable(symbol, perpMetaAssets) {
1632
1679
  if (!perpMetaAssets)
1633
1680
  return false;
1634
- return perpMetaAssets.some((asset) => asset.name === symbol);
1681
+ return perpMetaAssets.some((asset) => symbolsMatch(asset.name, symbol));
1635
1682
  }
1636
1683
  }
1637
1684
 
@@ -6761,147 +6808,6 @@ function useAgentWallet() {
6761
6808
  };
6762
6809
  }
6763
6810
 
6764
- /**
6765
- * Sync external fills into Pear Hyperliquid service (POST /sync/fills)
6766
- */
6767
- const syncFills = async (baseUrl, payload) => {
6768
- const url = joinUrl(baseUrl, '/sync/fills');
6769
- try {
6770
- const response = await apiClient.post(url, payload, {
6771
- headers: { 'Content-Type': 'application/json' },
6772
- timeout: 30000,
6773
- });
6774
- return { data: response.data, status: response.status, headers: response.headers };
6775
- }
6776
- catch (error) {
6777
- throw toApiError(error);
6778
- }
6779
- };
6780
- /**
6781
- * Convenience: fetch user fills from HyperLiquid, then sync them to Pear backend
6782
- */
6783
- const syncUserFillsFromHyperliquid = async (baseUrl, user, aggregateByTime = true, lastSyncAt = null, assetPositions) => {
6784
- const firstStartTime = lastSyncAt ? Number(lastSyncAt) + 1 : 0;
6785
- const allFills = [];
6786
- const seenTids = new Set();
6787
- let startTime = firstStartTime;
6788
- let batchSize = 0;
6789
- do {
6790
- const { data: batch } = await fetchUserFillsFromHyperliquid(user, startTime, aggregateByTime);
6791
- batchSize = batch.length;
6792
- for (const fill of batch) {
6793
- const tid = fill.tid;
6794
- if (tid === undefined)
6795
- continue;
6796
- if (!seenTids.has(tid)) {
6797
- seenTids.add(tid);
6798
- allFills.push(fill);
6799
- }
6800
- }
6801
- if (batchSize === 2000) {
6802
- const last = batch[batch.length - 1];
6803
- startTime = last.time;
6804
- }
6805
- } while (batchSize === 2000);
6806
- startTime = firstStartTime;
6807
- batchSize = 0;
6808
- do {
6809
- const { data: twapBatch } = await fetchUserTwapSliceFillsByTime(user, startTime, aggregateByTime);
6810
- batchSize = twapBatch.length;
6811
- for (const item of twapBatch) {
6812
- const fill = item.fill;
6813
- const tid = fill.tid;
6814
- if (tid === undefined)
6815
- continue;
6816
- if (!seenTids.has(tid)) {
6817
- seenTids.add(tid);
6818
- allFills.push(fill);
6819
- }
6820
- }
6821
- if (batchSize === 2000) {
6822
- const last = twapBatch[twapBatch.length - 1];
6823
- startTime = last.fill.time;
6824
- }
6825
- } while (batchSize === 2000);
6826
- const sortedFills = [...allFills].sort((a, b) => Number(a.time) - Number(b.time));
6827
- return syncFills(baseUrl, { user, fills: sortedFills, assetPositions });
6828
- };
6829
-
6830
- /**
6831
- * Listens to address changes and periodically syncs user fills
6832
- * Defaults: aggregate=true, interval=60s
6833
- */
6834
- function useAutoSyncFills(options) {
6835
- const { baseUrl, address, intervalMs = 60000, aggregateByTime = true, } = options;
6836
- const [lastRunAt, setLastRunAt] = useState(null);
6837
- const [lastResult, setLastResult] = useState(null);
6838
- const [error, setError] = useState(null);
6839
- const [isSyncing, setIsSyncing] = useState(false);
6840
- const mountedRef = useRef(true);
6841
- const runningRef = useRef(null);
6842
- const lastSyncedAt = useUserData((state) => { var _a; return (_a = state.accountSummary) === null || _a === void 0 ? void 0 : _a.lastSyncedAt; });
6843
- const enabled = useUserData((state) => state.isAuthenticated);
6844
- useEffect(() => {
6845
- mountedRef.current = true;
6846
- return () => { mountedRef.current = false; };
6847
- }, []);
6848
- const canRun = useMemo(() => {
6849
- return Boolean(enabled && address && baseUrl);
6850
- }, [enabled, address, baseUrl]);
6851
- const doSync = useCallback(async () => {
6852
- var _a;
6853
- if (!canRun)
6854
- return;
6855
- if (runningRef.current)
6856
- return;
6857
- if (!useUserData.getState().accountSummary)
6858
- return;
6859
- if (!((_a = useHyperliquidData.getState().aggregatedClearingHouseState) === null || _a === void 0 ? void 0 : _a.assetPositions))
6860
- return;
6861
- setIsSyncing(true);
6862
- setError(null);
6863
- const promise = (async () => {
6864
- var _a;
6865
- try {
6866
- const { data } = await syncUserFillsFromHyperliquid(baseUrl, address, aggregateByTime, lastSyncedAt, useHyperliquidData.getState().aggregatedClearingHouseState.assetPositions);
6867
- if (!mountedRef.current)
6868
- return;
6869
- setLastResult(data);
6870
- setLastRunAt(Date.now());
6871
- }
6872
- catch (e) {
6873
- if (!mountedRef.current)
6874
- return;
6875
- setError((_a = e === null || e === void 0 ? void 0 : e.message) !== null && _a !== void 0 ? _a : 'Failed to sync user fills');
6876
- }
6877
- finally {
6878
- if (mountedRef.current)
6879
- setIsSyncing(false);
6880
- runningRef.current = null;
6881
- }
6882
- })();
6883
- runningRef.current = promise;
6884
- await promise;
6885
- }, [canRun, baseUrl, address, aggregateByTime, lastSyncedAt]);
6886
- useEffect(() => {
6887
- if (!canRun)
6888
- return;
6889
- // Fire immediately on address change/enable
6890
- void doSync();
6891
- const id = setInterval(() => {
6892
- void doSync();
6893
- }, Math.max(1000, intervalMs));
6894
- return () => clearInterval(id);
6895
- }, [canRun, doSync, intervalMs]);
6896
- return {
6897
- lastRunAt,
6898
- lastResult,
6899
- error,
6900
- isSyncing,
6901
- triggerSync: doSync,
6902
- };
6903
- }
6904
-
6905
6811
  /**
6906
6812
  * Create a position (MARKET/LIMIT/TWAP) using Pear Hyperliquid service
6907
6813
  * Authorization is derived from headers (Axios defaults or browser localStorage fallback)
@@ -6920,6 +6826,9 @@ async function createPosition(baseUrl, payload, hip3Assets) {
6920
6826
  ...payload,
6921
6827
  longAssets: mapAssets(payload.longAssets),
6922
6828
  shortAssets: mapAssets(payload.shortAssets),
6829
+ assetName: payload.assetName
6830
+ ? toBackendSymbol(payload.assetName, hip3Assets)
6831
+ : undefined,
6923
6832
  };
6924
6833
  try {
6925
6834
  const resp = await apiClient.post(url, translatedPayload, {
@@ -8331,6 +8240,138 @@ const useAllUserBalances = () => {
8331
8240
  ]);
8332
8241
  };
8333
8242
 
8243
+ /**
8244
+ * Sync external fills into Pear Hyperliquid service (POST /sync/fills)
8245
+ */
8246
+ const syncFills = async (baseUrl, payload) => {
8247
+ const url = joinUrl(baseUrl, '/sync/fills');
8248
+ try {
8249
+ const response = await apiClient.post(url, payload, {
8250
+ headers: { 'Content-Type': 'application/json' },
8251
+ timeout: 30000,
8252
+ });
8253
+ return { data: response.data, status: response.status, headers: response.headers };
8254
+ }
8255
+ catch (error) {
8256
+ throw toApiError(error);
8257
+ }
8258
+ };
8259
+ /**
8260
+ * Convenience: fetch user fills from HyperLiquid, then sync them to Pear backend
8261
+ */
8262
+ const syncUserFillsFromHyperliquid = async (baseUrl, user, aggregateByTime = true, lastSyncAt = null, assetPositions) => {
8263
+ const firstStartTime = lastSyncAt ? Number(lastSyncAt) + 1 : 0;
8264
+ const allFills = [];
8265
+ const seenTids = new Set();
8266
+ let startTime = firstStartTime;
8267
+ let batchSize = 0;
8268
+ do {
8269
+ const { data: batch } = await fetchUserFillsFromHyperliquid(user, startTime, aggregateByTime);
8270
+ batchSize = batch.length;
8271
+ for (const fill of batch) {
8272
+ const tid = fill.tid;
8273
+ if (tid === undefined)
8274
+ continue;
8275
+ if (!seenTids.has(tid)) {
8276
+ seenTids.add(tid);
8277
+ allFills.push(fill);
8278
+ }
8279
+ }
8280
+ if (batchSize === 2000) {
8281
+ const last = batch[batch.length - 1];
8282
+ startTime = last.time;
8283
+ }
8284
+ } while (batchSize === 2000);
8285
+ startTime = firstStartTime;
8286
+ batchSize = 0;
8287
+ do {
8288
+ const { data: twapBatch } = await fetchUserTwapSliceFillsByTime(user, startTime, aggregateByTime);
8289
+ batchSize = twapBatch.length;
8290
+ for (const item of twapBatch) {
8291
+ const fill = item.fill;
8292
+ const tid = fill.tid;
8293
+ if (tid === undefined)
8294
+ continue;
8295
+ if (!seenTids.has(tid)) {
8296
+ seenTids.add(tid);
8297
+ allFills.push(fill);
8298
+ }
8299
+ }
8300
+ if (batchSize === 2000) {
8301
+ const last = twapBatch[twapBatch.length - 1];
8302
+ startTime = last.fill.time;
8303
+ }
8304
+ } while (batchSize === 2000);
8305
+ const sortedFills = [...allFills].sort((a, b) => Number(a.time) - Number(b.time));
8306
+ return syncFills(baseUrl, { user, fills: sortedFills, assetPositions });
8307
+ };
8308
+
8309
+ /**
8310
+ * Provides a callback to sync user fills whenever the native WebSocket emits a userFills event.
8311
+ */
8312
+ function useHyperliquidUserFills(options) {
8313
+ const { baseUrl, address: addressOverride, aggregateByTime = true } = options;
8314
+ const [lastRunAt, setLastRunAt] = useState(null);
8315
+ const [lastResult, setLastResult] = useState(null);
8316
+ const [error, setError] = useState(null);
8317
+ const [isSyncing, setIsSyncing] = useState(false);
8318
+ const mountedRef = useRef(true);
8319
+ const runningRef = useRef(null);
8320
+ const enabled = useUserData((state) => state.isAuthenticated);
8321
+ useEffect(() => {
8322
+ mountedRef.current = true;
8323
+ return () => {
8324
+ mountedRef.current = false;
8325
+ };
8326
+ }, []);
8327
+ const handleUserFillsEvent = useCallback(async () => {
8328
+ var _a;
8329
+ const userState = useUserData.getState();
8330
+ const currentAddress = userState.address || addressOverride;
8331
+ const lastSyncedAt = (_a = userState.accountSummary) === null || _a === void 0 ? void 0 : _a.lastSyncedAt;
8332
+ if (!(enabled && currentAddress && baseUrl))
8333
+ return;
8334
+ if (runningRef.current)
8335
+ return;
8336
+ if (!userState.accountSummary)
8337
+ return;
8338
+ const clearinghouseState = useHyperliquidData.getState().aggregatedClearingHouseState;
8339
+ if (!(clearinghouseState === null || clearinghouseState === void 0 ? void 0 : clearinghouseState.assetPositions))
8340
+ return;
8341
+ setIsSyncing(true);
8342
+ setError(null);
8343
+ const promise = (async () => {
8344
+ var _a;
8345
+ try {
8346
+ const { data } = await syncUserFillsFromHyperliquid(baseUrl, currentAddress, aggregateByTime, lastSyncedAt, clearinghouseState.assetPositions);
8347
+ if (!mountedRef.current)
8348
+ return;
8349
+ setLastResult(data);
8350
+ setLastRunAt(Date.now());
8351
+ }
8352
+ catch (e) {
8353
+ if (!mountedRef.current)
8354
+ return;
8355
+ setError((_a = e === null || e === void 0 ? void 0 : e.message) !== null && _a !== void 0 ? _a : 'Failed to sync user fills');
8356
+ }
8357
+ finally {
8358
+ if (mountedRef.current)
8359
+ setIsSyncing(false);
8360
+ runningRef.current = null;
8361
+ }
8362
+ })();
8363
+ runningRef.current = promise;
8364
+ await promise;
8365
+ }, [baseUrl, addressOverride, aggregateByTime, enabled]);
8366
+ return {
8367
+ lastRunAt,
8368
+ lastResult,
8369
+ error,
8370
+ isSyncing,
8371
+ handleUserFillsEvent,
8372
+ };
8373
+ }
8374
+
8334
8375
  const PearHyperliquidContext = createContext(undefined);
8335
8376
  /**
8336
8377
  * React Provider for PearHyperliquidClient
@@ -8344,6 +8385,11 @@ const PearHyperliquidProvider = ({ children, apiBaseUrl = 'https://hl-ui.pearpro
8344
8385
  const setHip3Assets = useHyperliquidData((state) => state.setHip3Assets);
8345
8386
  const setHip3MarketPrefixes = useHyperliquidData((state) => state.setHip3MarketPrefixes);
8346
8387
  const websocketsEnabled = useMemo(() => Array.isArray(perpsMetaAssets) && perpsMetaAssets.length > 0, [perpsMetaAssets]);
8388
+ const { handleUserFillsEvent } = useHyperliquidUserFills({
8389
+ baseUrl: apiBaseUrl,
8390
+ address,
8391
+ aggregateByTime: true,
8392
+ });
8347
8393
  const { isConnected, lastError } = useHyperliquidWebSocket({
8348
8394
  wsUrl,
8349
8395
  address,
@@ -8352,6 +8398,7 @@ const PearHyperliquidProvider = ({ children, apiBaseUrl = 'https://hl-ui.pearpro
8352
8398
  const { isConnected: nativeIsConnected, lastError: nativeLastError } = useHyperliquidNativeWebSocket({
8353
8399
  address,
8354
8400
  enabled: websocketsEnabled,
8401
+ onUserFills: handleUserFillsEvent,
8355
8402
  });
8356
8403
  useEffect(() => {
8357
8404
  if (perpsMetaAssets === null) {
@@ -8458,12 +8505,6 @@ const PearHyperliquidProvider = ({ children, apiBaseUrl = 'https://hl-ui.pearpro
8458
8505
  setHip3Assets,
8459
8506
  setHip3MarketPrefixes,
8460
8507
  ]);
8461
- useAutoSyncFills({
8462
- baseUrl: apiBaseUrl,
8463
- address,
8464
- intervalMs: 60000,
8465
- aggregateByTime: true,
8466
- });
8467
8508
  const contextValue = useMemo(() => ({
8468
8509
  // Config
8469
8510
  clientId,
@@ -8499,6 +8540,42 @@ function usePearHyperliquid() {
8499
8540
  return ctx;
8500
8541
  }
8501
8542
 
8543
+ const KALSHI_API_BASE_URL = 'https://api.elections.kalshi.com/trade-api/v2';
8544
+ async function getKalshiMarkets(params) {
8545
+ const url = new URL(`${KALSHI_API_BASE_URL}/markets`);
8546
+ if (params) {
8547
+ if (params.limit !== undefined) {
8548
+ url.searchParams.set('limit', String(params.limit));
8549
+ }
8550
+ if (params.cursor) {
8551
+ url.searchParams.set('cursor', params.cursor);
8552
+ }
8553
+ if (params.tickers && params.tickers.length > 0) {
8554
+ url.searchParams.set('tickers', params.tickers.join(','));
8555
+ }
8556
+ if (params.event_ticker) {
8557
+ url.searchParams.set('event_ticker', params.event_ticker);
8558
+ }
8559
+ if (params.series_ticker) {
8560
+ url.searchParams.set('series_ticker', params.series_ticker);
8561
+ }
8562
+ if (params.status) {
8563
+ url.searchParams.set('status', params.status);
8564
+ }
8565
+ }
8566
+ try {
8567
+ const response = await axios$1.get(url.toString());
8568
+ return {
8569
+ data: response.data,
8570
+ status: response.status,
8571
+ headers: response.headers,
8572
+ };
8573
+ }
8574
+ catch (error) {
8575
+ throw toApiError(error);
8576
+ }
8577
+ }
8578
+
8502
8579
  /**
8503
8580
  * Detects conflicts between selected tokens and existing positions
8504
8581
  */
@@ -8586,4 +8663,129 @@ function mapCandleIntervalToTradingViewInterval(interval) {
8586
8663
  }
8587
8664
  }
8588
8665
 
8589
- export { AccountSummaryCalculator, ConflictDetector, MAX_ASSETS_PER_LEG, MINIMUM_ASSET_USD_VALUE, MaxAssetsPerLegError, MinimumPositionSizeError, PearHyperliquidProvider, TokenMetadataExtractor, adjustAdvancePosition, adjustOrder, adjustPosition, calculateMinimumPositionValue, calculateWeightedRatio, cancelOrder, cancelTwap, cancelTwapOrder, closeAllPositions, closePosition, computeBasketCandles, createCandleLookups, createPosition, executeSpotOrder, getAvailableMarkets, getCompleteTimestamps, getMarketPrefix, getPortfolio, isHip3Market, mapCandleIntervalToTradingViewInterval, mapTradingViewIntervalToCandleInterval, markNotificationReadById, markNotificationsRead, toBackendSymbol, toBackendSymbolWithMarket, toDisplaySymbol, toggleWatchlist, updateLeverage, updateRiskParameters, useAccountSummary, useActiveBaskets, useAgentWallet, useAllBaskets, useAllUserBalances, useAuth, useAutoSyncFills, useBasketCandles, useFindBasket, useHighlightedBaskets, useHistoricalPriceData, useHistoricalPriceDataStore, useHyperliquidNativeWebSocket, useHyperliquidWebSocket, useMarketData, useMarketDataAllPayload, useMarketDataPayload, useNotifications, useOpenOrders, useOrders, usePearHyperliquid, usePerformanceOverlays, usePerpMetaAssets, usePortfolio, usePosition, useSpotOrder, useTokenSelectionMetadata, useTopGainers, useTopLosers, useTradeHistories, useTwap, useUserSelection, useWatchlist, useWatchlistBaskets, useWebData, validateMaxAssetsPerLeg, validateMinimumAssetSize, validatePositionSize };
8666
+ /**
8667
+ * Helper functions to safely extract values from order parameters
8668
+ * based on the order type and parameter structure.
8669
+ */
8670
+ /**
8671
+ * Get leverage from order parameters (available for Market, Trigger, Twap, Ladder orders)
8672
+ */
8673
+ function getOrderLeverage(order) {
8674
+ const p = order.parameters;
8675
+ if ('leverage' in p && p.leverage !== undefined) {
8676
+ return p.leverage;
8677
+ }
8678
+ return undefined;
8679
+ }
8680
+ /**
8681
+ * Get USD value from order parameters (available for Market, Trigger, Twap, Ladder orders)
8682
+ */
8683
+ function getOrderUsdValue(order) {
8684
+ const p = order.parameters;
8685
+ if ('usdValue' in p) {
8686
+ return p.usdValue;
8687
+ }
8688
+ return undefined;
8689
+ }
8690
+ /**
8691
+ * Get trigger value from order parameters (available for TP/SL and Trigger orders)
8692
+ */
8693
+ function getOrderTriggerValue(order) {
8694
+ const p = order.parameters;
8695
+ if ('triggerValue' in p) {
8696
+ return p.triggerValue;
8697
+ }
8698
+ return undefined;
8699
+ }
8700
+ /**
8701
+ * Get TP/SL trigger type from order parameters (only for TP/SL orders)
8702
+ */
8703
+ function getOrderTpSlTriggerType(order) {
8704
+ if (order.orderType === 'TP' || order.orderType === 'SL') {
8705
+ const p = order.parameters;
8706
+ return p.triggerType;
8707
+ }
8708
+ return undefined;
8709
+ }
8710
+ /**
8711
+ * Get trigger type from order parameters (for Trigger orders)
8712
+ */
8713
+ function getOrderTriggerType(order) {
8714
+ if (order.orderType === 'TRIGGER') {
8715
+ const p = order.parameters;
8716
+ return p.triggerType;
8717
+ }
8718
+ return undefined;
8719
+ }
8720
+ /**
8721
+ * Get order direction from order parameters (for Trigger orders)
8722
+ */
8723
+ function getOrderDirection(order) {
8724
+ if (order.orderType === 'TRIGGER') {
8725
+ const p = order.parameters;
8726
+ return p.direction;
8727
+ }
8728
+ return undefined;
8729
+ }
8730
+ /**
8731
+ * Get reduce only flag from order parameters (available for all order types)
8732
+ */
8733
+ function getOrderReduceOnly(order) {
8734
+ var _a;
8735
+ const p = order.parameters;
8736
+ if ('reduceOnly' in p) {
8737
+ return (_a = p.reduceOnly) !== null && _a !== void 0 ? _a : false;
8738
+ }
8739
+ return false;
8740
+ }
8741
+ /**
8742
+ * Get TWAP duration from order parameters (only for TWAP orders)
8743
+ */
8744
+ function getOrderTwapDuration(order) {
8745
+ if (order.orderType === 'TWAP') {
8746
+ const p = order.parameters;
8747
+ return p.duration;
8748
+ }
8749
+ return undefined;
8750
+ }
8751
+ /**
8752
+ * Get ladder config from order parameters (only for Ladder orders)
8753
+ */
8754
+ function getOrderLadderConfig(order) {
8755
+ if (order.orderType === 'LADDER') {
8756
+ const p = order.parameters;
8757
+ return {
8758
+ ratioStart: p.ratioStart,
8759
+ ratioEnd: p.ratioEnd,
8760
+ numberOfLevels: p.numberOfLevels,
8761
+ };
8762
+ }
8763
+ return undefined;
8764
+ }
8765
+ /**
8766
+ * Check if the order is a BTC Dominance trigger order
8767
+ */
8768
+ function isBtcDomOrder(order) {
8769
+ if (order.orderType === 'TRIGGER') {
8770
+ const p = order.parameters;
8771
+ return p.triggerType === 'BTC_DOM';
8772
+ }
8773
+ return false;
8774
+ }
8775
+ /**
8776
+ * Get trailing info from TP/SL order parameters
8777
+ */
8778
+ function getOrderTrailingInfo(order) {
8779
+ var _a;
8780
+ if (order.orderType === 'TP' || order.orderType === 'SL') {
8781
+ const p = order.parameters;
8782
+ return {
8783
+ isTrailing: (_a = p.isTrailing) !== null && _a !== void 0 ? _a : false,
8784
+ trailingDeltaValue: p.trailingDeltaValue,
8785
+ trailingActivationValue: p.trailingActivationValue,
8786
+ };
8787
+ }
8788
+ return undefined;
8789
+ }
8790
+
8791
+ 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 };