@pear-protocol/hyperliquid-sdk 0.0.7 → 0.0.9

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.esm.js CHANGED
@@ -2743,8 +2743,8 @@ const useHyperliquidNativeWebSocket = ({ address }) => {
2743
2743
  shouldReconnect: () => true,
2744
2744
  reconnectAttempts: 5,
2745
2745
  reconnectInterval: 3000,
2746
- onOpen: () => console.log('[HyperLiquid WS] Connected to wss://api.hyperliquid.xyz/ws'),
2747
- onClose: () => console.log('[HyperLiquid WS] Connection closed'),
2746
+ onOpen: () => { },
2747
+ onClose: () => { },
2748
2748
  onError: (event) => console.error('[HyperLiquid WS] Connection error:', event),
2749
2749
  onReconnectStop: () => console.error('[HyperLiquid WS] Reconnection stopped after 5 attempts'),
2750
2750
  });
@@ -2752,16 +2752,13 @@ const useHyperliquidNativeWebSocket = ({ address }) => {
2752
2752
  // Setup ping mechanism
2753
2753
  useEffect(() => {
2754
2754
  if (isConnected) {
2755
- console.log('[HyperLiquid WS] Setting up ping mechanism (30s interval)');
2756
2755
  // Send ping every 30 seconds
2757
2756
  pingIntervalRef.current = setInterval(() => {
2758
- console.log('[HyperLiquid WS] Sending ping');
2759
2757
  sendJsonMessage({ method: 'ping' });
2760
2758
  }, 30000);
2761
2759
  }
2762
2760
  else {
2763
2761
  if (pingIntervalRef.current) {
2764
- console.log('[HyperLiquid WS] Clearing ping interval');
2765
2762
  clearInterval(pingIntervalRef.current);
2766
2763
  pingIntervalRef.current = null;
2767
2764
  }
@@ -2783,7 +2780,6 @@ const useHyperliquidNativeWebSocket = ({ address }) => {
2783
2780
  return;
2784
2781
  // Unsubscribe from previous address if exists
2785
2782
  if (subscribedAddress) {
2786
- console.log(`[HyperLiquid WS] Unsubscribing from webData2 for previous address: ${subscribedAddress}`);
2787
2783
  const unsubscribeMessage = {
2788
2784
  method: 'unsubscribe',
2789
2785
  subscription: {
@@ -2794,7 +2790,6 @@ const useHyperliquidNativeWebSocket = ({ address }) => {
2794
2790
  sendJsonMessage(unsubscribeMessage);
2795
2791
  }
2796
2792
  // Subscribe to webData2 with new address
2797
- console.log(`[HyperLiquid WS] Subscribing to webData2 for address: ${userAddress}`);
2798
2793
  const subscribeWebData2 = {
2799
2794
  method: 'subscribe',
2800
2795
  subscription: {
@@ -2803,7 +2798,6 @@ const useHyperliquidNativeWebSocket = ({ address }) => {
2803
2798
  },
2804
2799
  };
2805
2800
  // Subscribe to allMids
2806
- console.log('[HyperLiquid WS] Subscribing to allMids');
2807
2801
  const subscribeAllMids = {
2808
2802
  method: 'subscribe',
2809
2803
  subscription: {
@@ -2815,7 +2809,6 @@ const useHyperliquidNativeWebSocket = ({ address }) => {
2815
2809
  setSubscribedAddress(userAddress);
2816
2810
  // Clear previous data when address changes
2817
2811
  if (subscribedAddress && subscribedAddress !== userAddress) {
2818
- console.log('[HyperLiquid WS] Address changed, clearing previous webData2');
2819
2812
  setWebData2(null);
2820
2813
  }
2821
2814
  }, [isConnected, address, subscribedAddress, sendJsonMessage]);
@@ -2825,7 +2818,6 @@ const useHyperliquidNativeWebSocket = ({ address }) => {
2825
2818
  return;
2826
2819
  try {
2827
2820
  const message = JSON.parse(lastMessage.data);
2828
- console.log('[HyperLiquid WS] Received message:', message);
2829
2821
  // Handle subscription responses
2830
2822
  if ('success' in message || 'error' in message) {
2831
2823
  if (message.error) {
@@ -2833,7 +2825,6 @@ const useHyperliquidNativeWebSocket = ({ address }) => {
2833
2825
  setLastError(message.error);
2834
2826
  }
2835
2827
  else {
2836
- console.log('[HyperLiquid WS] Subscription success:', message);
2837
2828
  setLastError(null);
2838
2829
  }
2839
2830
  return;
@@ -2841,14 +2832,11 @@ const useHyperliquidNativeWebSocket = ({ address }) => {
2841
2832
  // Handle channel data messages
2842
2833
  if ('channel' in message && 'data' in message) {
2843
2834
  const response = message;
2844
- console.log(`[HyperLiquid WS] Received ${response.channel} data`);
2845
2835
  switch (response.channel) {
2846
2836
  case 'webData2':
2847
- console.log('[HyperLiquid WS] Setting webData2:', response.data);
2848
2837
  setWebData2(response.data);
2849
2838
  break;
2850
2839
  case 'allMids':
2851
- console.log('[HyperLiquid WS] Setting allMids:', response.data);
2852
2840
  setAllMids(response.data);
2853
2841
  break;
2854
2842
  default:
@@ -2949,193 +2937,213 @@ const useAddress = () => {
2949
2937
  };
2950
2938
  };
2951
2939
 
2952
- /**
2953
- * Position side enum for calculations
2954
- */
2955
2940
  var PositionSide;
2956
2941
  (function (PositionSide) {
2957
2942
  PositionSide["LONG"] = "LONG";
2958
2943
  PositionSide["SHORT"] = "SHORT";
2959
2944
  })(PositionSide || (PositionSide = {}));
2960
- /**
2961
- * Position calculation utility class
2962
- */
2963
- class PositionCalculator {
2945
+ class PositionProcessor {
2964
2946
  constructor(webData2, allMids) {
2965
2947
  this.webData2 = webData2;
2966
2948
  this.allMids = allMids;
2967
2949
  }
2968
- /**
2969
- * Get market price for a coin from allMids data
2970
- */
2950
+ execute(rawPositions) {
2951
+ if (!rawPositions || rawPositions.length === 0) {
2952
+ return [];
2953
+ }
2954
+ const userHyperliquidPositions = this.getUserPositions();
2955
+ const platformTotalsByAsset = this.calculatePlatformTotalsByAsset(rawPositions);
2956
+ const hlPositionsMap = new Map();
2957
+ (userHyperliquidPositions || []).forEach(assetPos => {
2958
+ var _a;
2959
+ if ((_a = assetPos.position) === null || _a === void 0 ? void 0 : _a.coin) {
2960
+ hlPositionsMap.set(assetPos.position.coin, assetPos);
2961
+ }
2962
+ });
2963
+ const openPositionDtos = [];
2964
+ for (const position of rawPositions) {
2965
+ const syncedPositionDto = this.syncPositionWithAggregateData(position, hlPositionsMap, platformTotalsByAsset);
2966
+ openPositionDtos.push(syncedPositionDto);
2967
+ }
2968
+ return openPositionDtos;
2969
+ }
2970
+ getUserPositions() {
2971
+ var _a, _b;
2972
+ return ((_b = (_a = this.webData2) === null || _a === void 0 ? void 0 : _a.clearinghouseState) === null || _b === void 0 ? void 0 : _b.assetPositions) || [];
2973
+ }
2971
2974
  getMarketPrice(coin) {
2972
2975
  var _a;
2973
2976
  if (!((_a = this.allMids) === null || _a === void 0 ? void 0 : _a.mids))
2974
2977
  return 0;
2975
- // Try exact match first
2976
2978
  const exactPrice = this.allMids.mids[coin];
2977
2979
  if (exactPrice) {
2978
2980
  return Number(exactPrice);
2979
2981
  }
2980
- // If coin has a slash (like "BTC/USD"), try just the base currency
2981
- const baseCurrency = coin.split('/')[0];
2982
+ const baseCurrency = this.extractBaseCurrency(coin);
2982
2983
  const basePrice = this.allMids.mids[baseCurrency];
2983
2984
  if (basePrice) {
2984
2985
  return Number(basePrice);
2985
2986
  }
2986
- console.warn(`[PositionCalculator] No market price found for coin: ${coin}`);
2987
2987
  return 0;
2988
2988
  }
2989
- /**
2990
- * Get user positions from webData2
2991
- */
2992
- getUserPositions() {
2993
- var _a, _b;
2994
- return ((_b = (_a = this.webData2) === null || _a === void 0 ? void 0 : _a.clearinghouseState) === null || _b === void 0 ? void 0 : _b.assetPositions) || [];
2995
- }
2996
- /**
2997
- * Calculate updated open positions by syncing platform positions with HyperLiquid data
2998
- */
2999
- calculateOpenPositions(platformPositions) {
3000
- if (!(platformPositions === null || platformPositions === void 0 ? void 0 : platformPositions.length)) {
3001
- return [];
2989
+ calculatePlatformTotalsByAsset(positions) {
2990
+ const totalsMap = new Map();
2991
+ for (const position of positions) {
2992
+ for (const asset of position.longAssets || []) {
2993
+ const baseCurrency = this.extractBaseCurrency(asset.coin);
2994
+ if (!totalsMap.has(baseCurrency)) {
2995
+ totalsMap.set(baseCurrency, {
2996
+ totalSize: 0,
2997
+ positions: []
2998
+ });
2999
+ }
3000
+ const totals = totalsMap.get(baseCurrency);
3001
+ const assetSize = Number(asset.size || 0);
3002
+ totals.totalSize += assetSize;
3003
+ totals.positions.push({
3004
+ positionId: position.positionId,
3005
+ asset: asset,
3006
+ size: assetSize
3007
+ });
3008
+ }
3009
+ for (const asset of position.shortAssets || []) {
3010
+ const baseCurrency = this.extractBaseCurrency(asset.coin);
3011
+ if (!totalsMap.has(baseCurrency)) {
3012
+ totalsMap.set(baseCurrency, {
3013
+ totalSize: 0,
3014
+ positions: []
3015
+ });
3016
+ }
3017
+ const totals = totalsMap.get(baseCurrency);
3018
+ const assetSize = Number(asset.size || 0);
3019
+ totals.totalSize += assetSize;
3020
+ totals.positions.push({
3021
+ positionId: position.positionId,
3022
+ asset: asset,
3023
+ size: assetSize
3024
+ });
3025
+ }
3002
3026
  }
3003
- const hyperliquidPositions = this.getUserPositions();
3004
- return platformPositions.map(position => this.syncPositionWithHyperliquid(position, hyperliquidPositions));
3027
+ return totalsMap;
3005
3028
  }
3006
- /**
3007
- * Sync a single position with HyperLiquid data
3008
- */
3009
- syncPositionWithHyperliquid(position, hyperliquidPositions) {
3010
- // Create a map of HyperLiquid positions by coin for quick lookup
3011
- const hlPositionsMap = new Map();
3012
- hyperliquidPositions.forEach(assetPos => {
3013
- var _a;
3014
- if ((_a = assetPos.position) === null || _a === void 0 ? void 0 : _a.coin) {
3015
- hlPositionsMap.set(assetPos.position.coin, assetPos);
3016
- }
3017
- });
3018
- // Combine all assets for processing
3019
- const allAssets = [
3020
- ...position.longAssets.map(asset => ({ ...asset, side: PositionSide.LONG })),
3021
- ...position.shortAssets.map(asset => ({ ...asset, side: PositionSide.SHORT }))
3022
- ];
3023
- // Group assets by base currency for multi-pair position handling
3024
- const assetsByBaseCurrency = this.groupAssetsByBaseCurrency(allAssets);
3025
- // Sync each asset group with HyperLiquid data
3029
+ extractBaseCurrency(assetName) {
3030
+ return assetName.split('/')[0] || assetName;
3031
+ }
3032
+ syncPositionWithAggregateData(position, hlPositionsMap, platformTotalsByAsset) {
3026
3033
  const syncResults = [];
3027
- for (const [baseCurrency, assets] of assetsByBaseCurrency.entries()) {
3034
+ let hasExternalModification = false;
3035
+ let allAssetsClosed = true;
3036
+ let longAssetStatuses = { total: 0, closed: 0 };
3037
+ let shortAssetStatuses = { total: 0, closed: 0 };
3038
+ // Process long assets
3039
+ for (const asset of position.longAssets || []) {
3040
+ const baseCurrency = this.extractBaseCurrency(asset.coin);
3028
3041
  const hlPosition = hlPositionsMap.get(baseCurrency);
3029
- const groupSyncResults = this.syncAssetGroupWithHyperliquid(assets, hlPosition);
3030
- syncResults.push(...groupSyncResults);
3031
- }
3032
- // Update position sync status based on asset sync results
3033
- const syncStatus = this.determineSyncStatus(syncResults);
3034
- // Rebuild position with synced data
3035
- return this.buildUpdatedPosition(position, syncResults, syncStatus);
3036
- }
3037
- /**
3038
- * Group assets by their base currency
3039
- */
3040
- groupAssetsByBaseCurrency(assets) {
3041
- const grouped = new Map();
3042
- for (const asset of assets) {
3043
- const baseCurrency = asset.coin.split('/')[0] || asset.coin;
3044
- if (!grouped.has(baseCurrency)) {
3045
- grouped.set(baseCurrency, []);
3042
+ const platformTotals = platformTotalsByAsset.get(baseCurrency);
3043
+ const syncResult = this.syncAssetWithAggregateData({ ...asset, side: PositionSide.LONG }, hlPosition, (platformTotals === null || platformTotals === void 0 ? void 0 : platformTotals.totalSize) || 0);
3044
+ syncResults.push(syncResult);
3045
+ longAssetStatuses.total++;
3046
+ if (syncResult.actualSize === 0) {
3047
+ longAssetStatuses.closed++;
3048
+ }
3049
+ if (syncResult.isExternallyModified) {
3050
+ hasExternalModification = true;
3051
+ }
3052
+ if (syncResult.actualSize !== 0) {
3053
+ allAssetsClosed = false;
3046
3054
  }
3047
- grouped.get(baseCurrency).push(asset);
3048
3055
  }
3049
- return grouped;
3050
- }
3051
- /**
3052
- * Sync a group of assets (same base currency) with HyperLiquid position data
3053
- */
3054
- syncAssetGroupWithHyperliquid(assets, hlPosition) {
3055
- const results = [];
3056
- // Calculate total platform size for this base currency
3057
- const totalPlatformSize = assets.reduce((sum, asset) => sum + asset.platformSize, 0);
3058
- const actualTotalSize = hlPosition ? Math.abs(Number(hlPosition.position.szi || 0)) : 0;
3059
- // Check if the total size matches (within tolerance)
3060
- const sizeDifference = Math.abs(actualTotalSize - totalPlatformSize);
3061
- const sizeDifferencePercentage = totalPlatformSize > 0
3062
- ? (sizeDifference / totalPlatformSize) * 100
3063
- : (actualTotalSize > 0 ? 100 : 0);
3064
- const isGroupExternallyModified = sizeDifferencePercentage > 0.1; // 0.1% tolerance
3065
- for (const asset of assets) {
3066
- const platformSize = asset.platformSize;
3067
- let actualSize = platformSize;
3068
- let isExternallyModified = isGroupExternallyModified;
3069
- let cumFunding = {
3070
- allTime: 0,
3071
- sinceChange: 0,
3072
- sinceOpen: 0
3073
- };
3074
- let unrealizedPnl = 0;
3075
- let liquidationPrice = 0;
3076
- if (hlPosition) {
3077
- // Proportionally distribute the actual size based on asset's contribution
3078
- const sizeRatio = totalPlatformSize > 0 ? platformSize / totalPlatformSize : 0;
3079
- actualSize = actualTotalSize * sizeRatio;
3080
- // Proportionally distribute funding and PnL based on asset's contribution
3081
- if (hlPosition.cumFunding) {
3082
- cumFunding = {
3083
- allTime: Number(hlPosition.cumFunding.allTime || 0),
3084
- sinceChange: Number(hlPosition.cumFunding.sinceChange || 0) * sizeRatio,
3085
- sinceOpen: Number(hlPosition.cumFunding.sinceOpen || 0) * sizeRatio
3086
- };
3087
- }
3088
- unrealizedPnl = Number(hlPosition.position.unrealizedPnl || 0) * sizeRatio;
3089
- liquidationPrice = Number(hlPosition.position.liquidationPx || 0);
3056
+ // Process short assets
3057
+ for (const asset of position.shortAssets || []) {
3058
+ const baseCurrency = this.extractBaseCurrency(asset.coin);
3059
+ const hlPosition = hlPositionsMap.get(baseCurrency);
3060
+ const platformTotals = platformTotalsByAsset.get(baseCurrency);
3061
+ const syncResult = this.syncAssetWithAggregateData({ ...asset, side: PositionSide.SHORT }, hlPosition, (platformTotals === null || platformTotals === void 0 ? void 0 : platformTotals.totalSize) || 0);
3062
+ syncResults.push(syncResult);
3063
+ shortAssetStatuses.total++;
3064
+ if (syncResult.actualSize === 0) {
3065
+ shortAssetStatuses.closed++;
3090
3066
  }
3091
- else {
3092
- // Position doesn't exist on HyperLiquid - it was closed externally
3093
- actualSize = 0;
3094
- isExternallyModified = true;
3067
+ if (syncResult.isExternallyModified) {
3068
+ hasExternalModification = true;
3069
+ }
3070
+ if (syncResult.actualSize !== 0) {
3071
+ allAssetsClosed = false;
3095
3072
  }
3096
- results.push({
3097
- asset,
3098
- actualSize,
3099
- isExternallyModified,
3100
- cumFunding,
3101
- unrealizedPnl,
3102
- liquidationPrice,
3103
- side: asset.side
3104
- });
3105
3073
  }
3106
- return results;
3074
+ const syncStatus = this.determineSyncStatus(hasExternalModification, allAssetsClosed, longAssetStatuses, shortAssetStatuses);
3075
+ return this.mapPositionToDtoWithSyncData(position, syncResults, syncStatus);
3107
3076
  }
3108
- /**
3109
- * Determine sync status based on asset sync results
3110
- */
3111
- determineSyncStatus(syncResults) {
3112
- const hasExternalModifications = syncResults.some(result => result.isExternallyModified);
3113
- const allAssetsClosed = syncResults.every(result => result.actualSize === 0);
3114
- const someAssetsClosed = syncResults.some(result => result.actualSize === 0) && !allAssetsClosed;
3077
+ determineSyncStatus(hasExternalModification, allAssetsClosed, longAssetStatuses, shortAssetStatuses) {
3115
3078
  if (allAssetsClosed) {
3116
3079
  return 'EXTERNALLY_CLOSED';
3117
3080
  }
3118
- else if (someAssetsClosed) {
3081
+ const allLongsClosed = longAssetStatuses.total > 0 &&
3082
+ longAssetStatuses.closed === longAssetStatuses.total;
3083
+ const allShortsClosed = shortAssetStatuses.total > 0 &&
3084
+ shortAssetStatuses.closed === shortAssetStatuses.total;
3085
+ if ((allLongsClosed && !allShortsClosed) || (!allLongsClosed && allShortsClosed)) {
3119
3086
  return 'PAIR_BROKEN';
3120
3087
  }
3121
- else if (hasExternalModifications) {
3088
+ if (hasExternalModification) {
3122
3089
  return 'EXTERNALLY_MODIFIED';
3123
3090
  }
3124
3091
  return 'SYNCED';
3125
3092
  }
3126
- /**
3127
- * Build updated position with synced data
3128
- */
3129
- buildUpdatedPosition(originalPosition, syncResults, syncStatus) {
3130
- const longSyncResults = syncResults.filter(result => result.side === PositionSide.LONG);
3131
- const shortSyncResults = syncResults.filter(result => result.side === PositionSide.SHORT);
3132
- // Calculate position metrics
3093
+ syncAssetWithAggregateData(asset, hlPosition, platformTotal) {
3094
+ const platformSize = Number(asset.size || 0);
3095
+ if (!hlPosition || !hlPosition.position || !hlPosition.position.szi) {
3096
+ return {
3097
+ asset,
3098
+ actualSize: 0,
3099
+ isExternallyModified: true,
3100
+ cumFunding: { allTime: 0, sinceChange: 0, sinceOpen: 0 },
3101
+ unrealizedPnl: 0,
3102
+ liquidationPrice: 0
3103
+ };
3104
+ }
3105
+ const hlTotalSize = Math.abs(Number(hlPosition.position.szi || 0));
3106
+ const totalDifference = Math.abs(hlTotalSize - platformTotal);
3107
+ const tolerance = platformTotal * 0.001;
3108
+ const isExternallyModified = totalDifference > tolerance;
3109
+ const proportion = platformTotal > 0 ? platformSize / platformTotal : 0;
3110
+ const actualSize = hlTotalSize * proportion;
3111
+ // Get cumFunding from hlPosition.position.cumFunding
3112
+ const rawCumFunding = hlPosition.position.cumFunding;
3113
+ const cumFunding = {
3114
+ allTime: Number((rawCumFunding === null || rawCumFunding === void 0 ? void 0 : rawCumFunding.allTime) || 0),
3115
+ sinceChange: Number((rawCumFunding === null || rawCumFunding === void 0 ? void 0 : rawCumFunding.sinceChange) || 0) * proportion,
3116
+ sinceOpen: Number((rawCumFunding === null || rawCumFunding === void 0 ? void 0 : rawCumFunding.sinceOpen) || 0) * proportion
3117
+ };
3118
+ const unrealizedPnl = Number(hlPosition.position.unrealizedPnl || 0) * proportion;
3119
+ const liquidationPrice = Number(hlPosition.position.liquidationPx || 0);
3120
+ return {
3121
+ asset,
3122
+ actualSize,
3123
+ isExternallyModified,
3124
+ cumFunding,
3125
+ unrealizedPnl,
3126
+ liquidationPrice
3127
+ };
3128
+ }
3129
+ mapPositionToDtoWithSyncData(position, syncResults, syncStatus) {
3130
+ var _a, _b;
3131
+ const longAssets = ((_a = position.longAssets) === null || _a === void 0 ? void 0 : _a.filter(asset => asset)) || [];
3132
+ const shortAssets = ((_b = position.shortAssets) === null || _b === void 0 ? void 0 : _b.filter(asset => asset)) || [];
3133
+ const syncResultsMap = new Map();
3134
+ syncResults.forEach(result => {
3135
+ syncResultsMap.set(`${result.asset.coin}-${result.asset.side}`, result);
3136
+ });
3133
3137
  const currentTotalPositionValue = this.calculateCurrentTotalPositionValue(syncResults);
3134
3138
  const entryTotalPositionValue = this.calculateEntryTotalPositionValue(syncResults);
3135
- const totalMarginUsed = entryTotalPositionValue / originalPosition.leverage;
3139
+ const totalMarginUsed = entryTotalPositionValue / position.leverage;
3136
3140
  return {
3137
- ...originalPosition,
3138
- syncStatus,
3141
+ syncStatus: syncStatus,
3142
+ positionId: position.positionId,
3143
+ address: position.address,
3144
+ leverage: position.leverage,
3145
+ stopLoss: position.stopLoss,
3146
+ takeProfit: position.takeProfit,
3139
3147
  entryRatio: this.calculateEntryRatio(syncResults),
3140
3148
  markRatio: this.calculateMarkRatio(syncResults),
3141
3149
  netFunding: this.calculateNetFundingFromSyncResults(syncResults),
@@ -3143,117 +3151,81 @@ class PositionCalculator {
3143
3151
  marginUsed: totalMarginUsed,
3144
3152
  unrealizedPnl: this.calculateTotalUnrealizedPnlFromSyncResults(syncResults),
3145
3153
  lastSyncAt: new Date().toISOString(),
3146
- longAssets: longSyncResults.map(result => this.mapSyncResultToAssetDto(result)),
3147
- shortAssets: shortSyncResults.map(result => this.mapSyncResultToAssetDto(result)),
3148
- updatedAt: new Date().toISOString()
3154
+ longAssets: longAssets.map(asset => this.mapAssetToDetailDto(asset, syncResultsMap.get(`${asset.coin}-LONG`))),
3155
+ shortAssets: shortAssets.map(asset => this.mapAssetToDetailDto(asset, syncResultsMap.get(`${asset.coin}-SHORT`))),
3156
+ createdAt: position.createdAt,
3157
+ updatedAt: position.updatedAt
3149
3158
  };
3150
3159
  }
3151
- /**
3152
- * Map sync result to PositionAssetDetailDto
3153
- */
3154
- mapSyncResultToAssetDto(syncResult) {
3155
- const currentPrice = this.getMarketPrice(syncResult.asset.coin);
3156
- const positionValue = syncResult.actualSize * currentPrice;
3157
- const entryValue = syncResult.actualSize * syncResult.asset.entryPrice;
3160
+ mapAssetToDetailDto(asset, syncData) {
3161
+ const currentPrice = this.getMarketPrice(asset.coin);
3162
+ const actualSize = (syncData === null || syncData === void 0 ? void 0 : syncData.actualSize) || Number(asset.size || 0);
3163
+ const positionValue = actualSize * currentPrice;
3164
+ const entryValue = Number(asset.size || 0) * Number(asset.entryPrice || 0);
3158
3165
  return {
3159
- ...syncResult.asset,
3160
- actualSize: syncResult.actualSize,
3161
- isExternallyModified: syncResult.isExternallyModified,
3162
- cumFunding: syncResult.cumFunding,
3166
+ coin: asset.coin,
3167
+ entryPrice: Number(asset.entryPrice || 0),
3168
+ platformSize: Number(asset.size || 0),
3169
+ actualSize: actualSize,
3170
+ isExternallyModified: (syncData === null || syncData === void 0 ? void 0 : syncData.isExternallyModified) || false,
3171
+ cumFunding: (syncData === null || syncData === void 0 ? void 0 : syncData.cumFunding) || {
3172
+ allTime: 0,
3173
+ sinceChange: 0,
3174
+ sinceOpen: 0
3175
+ },
3163
3176
  marginUsed: entryValue,
3164
3177
  positionValue: positionValue,
3165
- unrealizedPnl: syncResult.unrealizedPnl,
3166
- liquidationPrice: syncResult.liquidationPrice
3178
+ unrealizedPnl: (syncData === null || syncData === void 0 ? void 0 : syncData.unrealizedPnl) || 0,
3179
+ liquidationPrice: (syncData === null || syncData === void 0 ? void 0 : syncData.liquidationPrice) || 0
3167
3180
  };
3168
3181
  }
3169
- /**
3170
- * Calculate entry ratio (weighted long entry value / weighted short entry value)
3171
- */
3172
3182
  calculateEntryRatio(syncResults) {
3173
- const longResults = syncResults.filter(result => result.side === PositionSide.LONG);
3174
- const shortResults = syncResults.filter(result => result.side === PositionSide.SHORT);
3183
+ const longResults = syncResults.filter(result => result.asset.side === PositionSide.LONG);
3184
+ const shortResults = syncResults.filter(result => result.asset.side === PositionSide.SHORT);
3175
3185
  if (longResults.length === 0 || shortResults.length === 0)
3176
3186
  return 0;
3177
- // Calculate total position value at entry prices
3178
- const totalPositionValue = syncResults.reduce((sum, result) => {
3179
- return sum + (result.actualSize * result.asset.entryPrice);
3187
+ const longValue = longResults.reduce((sum, result) => {
3188
+ return sum + (Number(result.asset.size || 0) * Number(result.asset.entryPrice || 0));
3180
3189
  }, 0);
3181
- if (totalPositionValue === 0)
3182
- return 0;
3183
- // Calculate weighted long portfolio entry value
3184
- const weightedLongValue = longResults.reduce((sum, result) => {
3185
- const entryPrice = result.asset.entryPrice;
3186
- const assetValue = result.actualSize * entryPrice;
3187
- const weight = assetValue / totalPositionValue;
3188
- return sum + (entryPrice * weight);
3189
- }, 0);
3190
- // Calculate weighted short portfolio entry value
3191
- const weightedShortValue = shortResults.reduce((sum, result) => {
3192
- const entryPrice = result.asset.entryPrice;
3193
- const assetValue = result.actualSize * entryPrice;
3194
- const weight = assetValue / totalPositionValue;
3195
- return sum + (entryPrice * weight);
3190
+ const shortValue = shortResults.reduce((sum, result) => {
3191
+ return sum + (Number(result.asset.size || 0) * Number(result.asset.entryPrice || 0));
3196
3192
  }, 0);
3197
- return weightedShortValue > 0 ? weightedLongValue / weightedShortValue : 0;
3193
+ return shortValue > 0 ? longValue / shortValue : 0;
3198
3194
  }
3199
- /**
3200
- * Calculate mark ratio (weighted long mark value / weighted short mark value)
3201
- */
3202
3195
  calculateMarkRatio(syncResults) {
3203
- const longResults = syncResults.filter(result => result.side === PositionSide.LONG);
3204
- const shortResults = syncResults.filter(result => result.side === PositionSide.SHORT);
3196
+ const longResults = syncResults.filter(result => result.asset.side === PositionSide.LONG);
3197
+ const shortResults = syncResults.filter(result => result.asset.side === PositionSide.SHORT);
3205
3198
  if (longResults.length === 0 || shortResults.length === 0)
3206
3199
  return 0;
3207
- // Calculate total position value at current market prices
3208
- const totalPositionValue = syncResults.reduce((sum, result) => {
3200
+ const longValue = longResults.reduce((sum, result) => {
3209
3201
  const currentPrice = this.getMarketPrice(result.asset.coin);
3210
3202
  return sum + (result.actualSize * currentPrice);
3211
3203
  }, 0);
3212
- if (totalPositionValue === 0)
3213
- return 0;
3214
- // Calculate weighted long portfolio value
3215
- const weightedLongValue = longResults.reduce((sum, result) => {
3216
- const currentPrice = this.getMarketPrice(result.asset.coin);
3217
- const assetValue = result.actualSize * currentPrice;
3218
- const weight = assetValue / totalPositionValue;
3219
- return sum + (currentPrice * weight);
3220
- }, 0);
3221
- // Calculate weighted short portfolio value
3222
- const weightedShortValue = shortResults.reduce((sum, result) => {
3204
+ const shortValue = shortResults.reduce((sum, result) => {
3223
3205
  const currentPrice = this.getMarketPrice(result.asset.coin);
3224
- const assetValue = result.actualSize * currentPrice;
3225
- const weight = assetValue / totalPositionValue;
3226
- return sum + (currentPrice * weight);
3206
+ return sum + (result.actualSize * currentPrice);
3227
3207
  }, 0);
3228
- return weightedShortValue > 0 ? weightedLongValue / weightedShortValue : 0;
3208
+ return shortValue > 0 ? longValue / shortValue : 0;
3229
3209
  }
3230
- /**
3231
- * Calculate net funding from sync results
3232
- */
3233
3210
  calculateNetFundingFromSyncResults(syncResults) {
3234
- return syncResults.reduce((sum, result) => sum + result.cumFunding.sinceOpen, 0);
3211
+ const netFunding = syncResults.reduce((sum, result) => {
3212
+ const funding = result.cumFunding.sinceOpen;
3213
+ return sum + funding;
3214
+ }, 0);
3215
+ return netFunding;
3235
3216
  }
3236
- /**
3237
- * Calculate total unrealized PnL from sync results
3238
- */
3239
3217
  calculateTotalUnrealizedPnlFromSyncResults(syncResults) {
3240
3218
  return syncResults.reduce((sum, result) => sum + result.unrealizedPnl, 0);
3241
3219
  }
3242
- /**
3243
- * Calculate current total position value using market prices
3244
- */
3245
3220
  calculateCurrentTotalPositionValue(syncResults) {
3246
3221
  return syncResults.reduce((sum, result) => {
3247
3222
  const currentPrice = this.getMarketPrice(result.asset.coin);
3248
3223
  return sum + (result.actualSize * currentPrice);
3249
3224
  }, 0);
3250
3225
  }
3251
- /**
3252
- * Calculate entry total position value using entry prices
3253
- */
3254
3226
  calculateEntryTotalPositionValue(syncResults) {
3255
3227
  return syncResults.reduce((sum, result) => {
3256
- return sum + (result.actualSize * result.asset.entryPrice);
3228
+ return sum + (Number(result.asset.size || 0) * Number(result.asset.entryPrice || 0));
3257
3229
  }, 0);
3258
3230
  }
3259
3231
  }
@@ -3263,32 +3235,18 @@ class PositionCalculator {
3263
3235
  */
3264
3236
  const useCalculatedOpenPositions = (platformPositions, webData2, allMids) => {
3265
3237
  const calculatedPositions = useMemo(() => {
3266
- var _a, _b;
3267
3238
  // Return null if we don't have platform positions yet
3268
3239
  if (!platformPositions) {
3269
- console.log('[useCalculatedOpenPositions] No platform positions available');
3270
3240
  return null;
3271
3241
  }
3272
- // If we don't have real-time data yet, return platform positions as-is
3242
+ // If we don't have real-time data yet, we can't calculate properly, return null
3273
3243
  if (!webData2 || !allMids) {
3274
- console.log('[useCalculatedOpenPositions] Missing real-time data, returning platform positions');
3275
- return platformPositions;
3276
- }
3277
- console.log('[useCalculatedOpenPositions] Calculating positions with real-time data', {
3278
- platformPositionsCount: platformPositions.length,
3279
- hasWebData2: !!webData2,
3280
- hasAllMids: !!allMids,
3281
- hyperliquidPositionsCount: ((_b = (_a = webData2.clearinghouseState) === null || _a === void 0 ? void 0 : _a.assetPositions) === null || _b === void 0 ? void 0 : _b.length) || 0,
3282
- availableMids: Object.keys(allMids.mids || {}).length
3283
- });
3284
- // Create calculator and compute positions
3285
- const calculator = new PositionCalculator(webData2, allMids);
3286
- const calculated = calculator.calculateOpenPositions(platformPositions);
3287
- console.log('[useCalculatedOpenPositions] Calculation completed', {
3288
- inputCount: platformPositions.length,
3289
- outputCount: calculated.length
3290
- });
3291
- return calculated;
3244
+ return null;
3245
+ }
3246
+ // Create processor and compute positions
3247
+ const processor = new PositionProcessor(webData2, allMids);
3248
+ const processed = processor.execute(platformPositions);
3249
+ return processed;
3292
3250
  }, [platformPositions, webData2, allMids]);
3293
3251
  return calculatedPositions;
3294
3252
  };
@@ -3307,19 +3265,11 @@ class AccountSummaryCalculator {
3307
3265
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
3308
3266
  // If we don't have webData2, return platform data as-is
3309
3267
  if (!((_a = this.webData2) === null || _a === void 0 ? void 0 : _a.clearinghouseState)) {
3310
- console.log('[AccountSummaryCalculator] No webData2 clearinghouseState available, returning platform data');
3311
3268
  return platformAccountSummary;
3312
3269
  }
3313
- console.log('[AccountSummaryCalculator] Calculating account summary with real-time data', {
3314
- hasPlatformSummary: !!platformAccountSummary,
3315
- hasOpenOrders: !!platformOpenOrders,
3316
- openOrdersCount: (platformOpenOrders === null || platformOpenOrders === void 0 ? void 0 : platformOpenOrders.length) || 0,
3317
- hasAgentWallet: !!agentWalletAddress
3318
- });
3319
3270
  const clearinghouseState = this.webData2.clearinghouseState;
3320
3271
  // Calculate total limit order value from platform orders
3321
3272
  const totalLimitOrderValue = this.calculateTotalLimitOrderValue(platformOpenOrders || []);
3322
- console.log('[AccountSummaryCalculator] Total limit order value:', totalLimitOrderValue);
3323
3273
  // Use real-time data from webData2 clearinghouseState
3324
3274
  const withdrawableAmount = parseFloat(clearinghouseState.withdrawable || '0');
3325
3275
  const adjustedWithdrawable = Math.max(0, withdrawableAmount - totalLimitOrderValue);
@@ -3346,12 +3296,6 @@ class AccountSummaryCalculator {
3346
3296
  status: agentWalletStatus || ((_l = platformAccountSummary === null || platformAccountSummary === void 0 ? void 0 : platformAccountSummary.agentWallet) === null || _l === void 0 ? void 0 : _l.status) || 'UNKNOWN'
3347
3297
  }
3348
3298
  };
3349
- console.log('[AccountSummaryCalculator] Calculated account summary:', {
3350
- accountValue: accountSummary.balanceSummary.crossMarginSummary.accountValue,
3351
- withdrawable: accountSummary.balanceSummary.withdrawable,
3352
- totalMarginUsed: accountSummary.balanceSummary.crossMarginSummary.totalMarginUsed,
3353
- agentWalletAddress: accountSummary.agentWallet.address
3354
- });
3355
3299
  return accountSummary;
3356
3300
  }
3357
3301
  /**
@@ -3364,11 +3308,6 @@ class AccountSummaryCalculator {
3364
3308
  const totalValue = openOrders
3365
3309
  .filter(order => order.status === 'OPEN' || order.status === 'PROCESSING')
3366
3310
  .reduce((sum, order) => sum + order.usdValue, 0);
3367
- console.log('[AccountSummaryCalculator] Calculated limit order value:', {
3368
- totalOrders: openOrders.length,
3369
- openOrders: openOrders.filter(order => order.status === 'OPEN' || order.status === 'PROCESSING').length,
3370
- totalValue
3371
- });
3372
3311
  return totalValue;
3373
3312
  }
3374
3313
  /**
@@ -3392,35 +3331,17 @@ class AccountSummaryCalculator {
3392
3331
  */
3393
3332
  const useCalculatedAccountSummary = (platformAccountSummary, platformOpenOrders, webData2, agentWalletAddress, agentWalletStatus) => {
3394
3333
  const calculatedAccountSummary = useMemo(() => {
3395
- var _a, _b, _c;
3396
3334
  // Return null if we don't have platform account summary yet
3397
3335
  if (!platformAccountSummary) {
3398
- console.log('[useCalculatedAccountSummary] No platform account summary available');
3399
3336
  return null;
3400
3337
  }
3401
3338
  // If we don't have real-time data yet, return platform summary as-is
3402
3339
  if (!(webData2 === null || webData2 === void 0 ? void 0 : webData2.clearinghouseState)) {
3403
- console.log('[useCalculatedAccountSummary] Missing webData2 clearinghouseState, returning platform summary');
3404
3340
  return platformAccountSummary;
3405
3341
  }
3406
- console.log('[useCalculatedAccountSummary] Calculating account summary with real-time data', {
3407
- hasPlatformSummary: !!platformAccountSummary,
3408
- hasWebData2: !!webData2,
3409
- hasClearinghouseState: !!webData2.clearinghouseState,
3410
- hasOpenOrders: !!platformOpenOrders,
3411
- openOrdersCount: (platformOpenOrders === null || platformOpenOrders === void 0 ? void 0 : platformOpenOrders.length) || 0,
3412
- agentWalletAddress,
3413
- agentWalletStatus
3414
- });
3415
3342
  // Create calculator and compute account summary
3416
3343
  const calculator = new AccountSummaryCalculator(webData2);
3417
3344
  const calculated = calculator.calculateAccountSummary(platformAccountSummary, platformOpenOrders, agentWalletAddress, agentWalletStatus);
3418
- console.log('[useCalculatedAccountSummary] Calculation completed', {
3419
- hadPlatformSummary: !!platformAccountSummary,
3420
- calculatedSummary: !!calculated,
3421
- withdrawable: (_a = calculated === null || calculated === void 0 ? void 0 : calculated.balanceSummary) === null || _a === void 0 ? void 0 : _a.withdrawable,
3422
- accountValue: (_c = (_b = calculated === null || calculated === void 0 ? void 0 : calculated.balanceSummary) === null || _b === void 0 ? void 0 : _b.crossMarginSummary) === null || _c === void 0 ? void 0 : _c.accountValue
3423
- });
3424
3345
  return calculated;
3425
3346
  }, [platformAccountSummary, platformOpenOrders, webData2, agentWalletAddress, agentWalletStatus]);
3426
3347
  return calculatedAccountSummary;
@@ -3472,5 +3393,5 @@ const useAccountSummary = () => {
3472
3393
  return calculatedAccountSummary;
3473
3394
  };
3474
3395
 
3475
- export { AccountSummaryCalculator, PearHyperliquidClient, PearHyperliquidProvider, PearMigrationSDK, PositionCalculator, PositionSide, PearHyperliquidClient as default, useAccountSummary, useAddress, useCalculatedAccountSummary, useCalculatedOpenPositions, useHyperliquidNativeWebSocket, useHyperliquidWebSocket, useMigrationSDK, useOpenOrders, useOpenPositions, usePearHyperliquidClient, useTradeHistories };
3396
+ export { AccountSummaryCalculator, PearHyperliquidClient, PearHyperliquidProvider, PearMigrationSDK, PearHyperliquidClient as default, useAccountSummary, useAddress, useCalculatedAccountSummary, useCalculatedOpenPositions, useHyperliquidNativeWebSocket, useHyperliquidWebSocket, useMigrationSDK, useOpenOrders, useOpenPositions, usePearHyperliquidClient, useTradeHistories };
3476
3397
  //# sourceMappingURL=index.esm.js.map