@pear-protocol/hyperliquid-sdk 0.1.20-pnl → 0.1.22-beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -557,8 +557,17 @@ const result = await createPosition(apiBaseUrl, {
557
557
  executionType: 'MARKET',
558
558
  });
559
559
 
560
- // Close position
561
- await closePosition(apiBaseUrl, positionId, { slippage: 0.5 });
560
+ // Close position immediately
561
+ await closePosition(apiBaseUrl, positionId, { executionType: 'MARKET' });
562
+
563
+ // Close position conditionally
564
+ // Example: close when the weighted price ratio rises above 1.08.
565
+ await closePosition(apiBaseUrl, positionId, {
566
+ executionType: 'TRIGGER',
567
+ triggerType: 'WEIGHTED_RATIO',
568
+ triggerValue: '1.08',
569
+ direction: 'MORE_THAN',
570
+ });
562
571
 
563
572
  // Update TP/SL
564
573
  await updateRiskParameters(apiBaseUrl, positionId, {
@@ -864,7 +873,7 @@ function TradingInterface() {
864
873
  {openPositions?.map(pos => (
865
874
  <div key={pos.positionId}>
866
875
  PnL: ${pos.unrealizedPnl.toFixed(2)}
867
- <button onClick={() => closePosition(pos.positionId, { slippage: 0.5 })}>
876
+ <button onClick={() => closePosition(pos.positionId, { executionType: 'MARKET' })}>
868
877
  Close
869
878
  </button>
870
879
  </div>
@@ -1,4 +1,4 @@
1
- import type { ApiResponse, CreatePositionRequestInput, CreatePositionResponseDto, TpSlThresholdInput } from "../types";
1
+ import type { ApiResponse, CloseExecutionType, CloseTriggerType, CreatePositionRequestInput, CreatePositionResponseDto, OrderDirection, TpSlThresholdInput } from "../types";
2
2
  import type { CancelTwapResponseDto } from "./orders";
3
3
  /**
4
4
  * Create a position (MARKET/LIMIT/TWAP) using Pear Hyperliquid service
@@ -18,17 +18,22 @@ export interface UpdateRiskParametersResponseDto {
18
18
  updatedAt: string;
19
19
  }
20
20
  export declare function updateRiskParameters(baseUrl: string, positionId: string, payload: UpdateRiskParametersRequestInput): Promise<ApiResponse<UpdateRiskParametersResponseDto>>;
21
- export type CloseExecutionType = "MARKET" | "TWAP";
21
+ export type ClosePositionExecutionType = CloseExecutionType;
22
+ export type CloseAllExecutionType = "MARKET" | "TWAP";
22
23
  export interface ClosePositionRequestInput {
23
24
  executionType: CloseExecutionType;
24
25
  twapDuration?: number;
25
26
  twapIntervalSeconds?: number;
26
27
  randomizeExecution?: boolean;
28
+ triggerType?: CloseTriggerType;
29
+ triggerValue?: string;
30
+ direction?: OrderDirection;
27
31
  referralCode?: string;
28
32
  }
29
33
  export interface ClosePositionResponseDto {
30
34
  orderId: string;
31
35
  executionTime?: string;
36
+ orderIds?: string[];
32
37
  chunksScheduled?: number;
33
38
  }
34
39
  export declare function closePosition(baseUrl: string, positionId: string, payload: ClosePositionRequestInput): Promise<ApiResponse<ClosePositionResponseDto>>;
@@ -41,7 +46,14 @@ export interface CloseAllPositionsResultDto {
41
46
  export interface CloseAllPositionsResponseDto {
42
47
  results: CloseAllPositionsResultDto[];
43
48
  }
44
- export declare function closeAllPositions(baseUrl: string, payload: ClosePositionRequestInput): Promise<ApiResponse<CloseAllPositionsResponseDto>>;
49
+ export interface CloseAllPositionsRequestInput {
50
+ executionType: CloseAllExecutionType;
51
+ twapDuration?: number;
52
+ twapIntervalSeconds?: number;
53
+ randomizeExecution?: boolean;
54
+ referralCode?: string;
55
+ }
56
+ export declare function closeAllPositions(baseUrl: string, payload: CloseAllPositionsRequestInput): Promise<ApiResponse<CloseAllPositionsResponseDto>>;
45
57
  export type AdjustExecutionType = "MARKET" | "LIMIT";
46
58
  export type PositionAdjustmentType = "REDUCE" | "INCREASE";
47
59
  export interface AdjustPositionRequestInput {
@@ -18,5 +18,3 @@ export * from './usePortfolio';
18
18
  export * from './useAuth';
19
19
  export * from './useAllUserBalances';
20
20
  export * from './useHyperliquidUserFills';
21
- export * from './usePnlCalendar';
22
- export * from './usePnlHeatmap';
@@ -1,4 +1,4 @@
1
- import { type UpdateRiskParametersRequestInput, type UpdateRiskParametersResponseDto, type ClosePositionRequestInput, type ClosePositionResponseDto, type CloseAllPositionsResponseDto, type AdjustPositionRequestInput, type AdjustPositionResponseDto, type AdjustAdvanceItemInput, type AdjustAdvanceResponseDto, type UpdateLeverageResponseDto } from '../clients/positions';
1
+ import { type UpdateRiskParametersRequestInput, type UpdateRiskParametersResponseDto, type ClosePositionRequestInput, type ClosePositionResponseDto, type CloseAllPositionsRequestInput, type CloseAllPositionsResponseDto, type AdjustPositionRequestInput, type AdjustPositionResponseDto, type AdjustAdvanceItemInput, type AdjustAdvanceResponseDto, type UpdateLeverageResponseDto } from '../clients/positions';
2
2
  import type { ApiResponse, CreatePositionRequestInput, CreatePositionResponseDto, OpenPositionDto } from '../types';
3
3
  export interface RebalanceAssetPlan {
4
4
  coin: string;
@@ -23,7 +23,7 @@ export declare function usePosition(): {
23
23
  readonly createPosition: (payload: CreatePositionRequestInput) => Promise<ApiResponse<CreatePositionResponseDto>>;
24
24
  readonly updateRiskParameters: (positionId: string, payload: UpdateRiskParametersRequestInput) => Promise<ApiResponse<UpdateRiskParametersResponseDto>>;
25
25
  readonly closePosition: (positionId: string, payload: ClosePositionRequestInput) => Promise<ApiResponse<ClosePositionResponseDto>>;
26
- readonly closeAllPositions: (payload: ClosePositionRequestInput) => Promise<ApiResponse<CloseAllPositionsResponseDto>>;
26
+ readonly closeAllPositions: (payload: CloseAllPositionsRequestInput) => Promise<ApiResponse<CloseAllPositionsResponseDto>>;
27
27
  readonly adjustPosition: (positionId: string, payload: AdjustPositionRequestInput) => Promise<ApiResponse<AdjustPositionResponseDto>>;
28
28
  readonly adjustAdvancePosition: (positionId: string, payload: AdjustAdvanceItemInput[]) => Promise<ApiResponse<AdjustAdvanceResponseDto>>;
29
29
  readonly updateLeverage: (positionId: string, leverage: number) => Promise<ApiResponse<UpdateLeverageResponseDto | null>>;
package/dist/index.d.ts CHANGED
@@ -342,6 +342,8 @@ type TpSlTriggerType = 'PERCENTAGE' | 'DOLLAR' | 'POSITION_VALUE' | 'PRICE' | 'P
342
342
  * Trigger type for trigger orders
343
343
  */
344
344
  type TriggerType = 'PRICE' | 'PRICE_RATIO' | 'WEIGHTED_RATIO' | 'BTC_DOM' | 'CROSS_ASSET_PRICE' | 'PREDICTION_MARKET_OUTCOME';
345
+ type CloseTriggerType = 'PRICE' | 'PRICE_RATIO' | 'WEIGHTED_RATIO' | 'PERCENTAGE' | 'DOLLAR' | 'POSITION_VALUE';
346
+ type CloseExecutionType = 'MARKET' | 'TWAP' | 'TRIGGER';
345
347
  type OrderDirection = 'MORE_THAN' | 'LESS_THAN';
346
348
  /**
347
349
  * Market order parameters
@@ -1232,17 +1234,22 @@ interface UpdateRiskParametersResponseDto {
1232
1234
  updatedAt: string;
1233
1235
  }
1234
1236
  declare function updateRiskParameters(baseUrl: string, positionId: string, payload: UpdateRiskParametersRequestInput): Promise<ApiResponse<UpdateRiskParametersResponseDto>>;
1235
- type CloseExecutionType = "MARKET" | "TWAP";
1237
+ type ClosePositionExecutionType = CloseExecutionType;
1238
+ type CloseAllExecutionType = "MARKET" | "TWAP";
1236
1239
  interface ClosePositionRequestInput {
1237
1240
  executionType: CloseExecutionType;
1238
1241
  twapDuration?: number;
1239
1242
  twapIntervalSeconds?: number;
1240
1243
  randomizeExecution?: boolean;
1244
+ triggerType?: CloseTriggerType;
1245
+ triggerValue?: string;
1246
+ direction?: OrderDirection;
1241
1247
  referralCode?: string;
1242
1248
  }
1243
1249
  interface ClosePositionResponseDto {
1244
1250
  orderId: string;
1245
1251
  executionTime?: string;
1252
+ orderIds?: string[];
1246
1253
  chunksScheduled?: number;
1247
1254
  }
1248
1255
  declare function closePosition(baseUrl: string, positionId: string, payload: ClosePositionRequestInput): Promise<ApiResponse<ClosePositionResponseDto>>;
@@ -1255,7 +1262,14 @@ interface CloseAllPositionsResultDto {
1255
1262
  interface CloseAllPositionsResponseDto {
1256
1263
  results: CloseAllPositionsResultDto[];
1257
1264
  }
1258
- declare function closeAllPositions(baseUrl: string, payload: ClosePositionRequestInput): Promise<ApiResponse<CloseAllPositionsResponseDto>>;
1265
+ interface CloseAllPositionsRequestInput {
1266
+ executionType: CloseAllExecutionType;
1267
+ twapDuration?: number;
1268
+ twapIntervalSeconds?: number;
1269
+ randomizeExecution?: boolean;
1270
+ referralCode?: string;
1271
+ }
1272
+ declare function closeAllPositions(baseUrl: string, payload: CloseAllPositionsRequestInput): Promise<ApiResponse<CloseAllPositionsResponseDto>>;
1259
1273
  type AdjustExecutionType = "MARKET" | "LIMIT";
1260
1274
  type PositionAdjustmentType = "REDUCE" | "INCREASE";
1261
1275
  interface AdjustPositionRequestInput {
@@ -1320,7 +1334,7 @@ declare function usePosition(): {
1320
1334
  readonly createPosition: (payload: CreatePositionRequestInput) => Promise<ApiResponse<CreatePositionResponseDto>>;
1321
1335
  readonly updateRiskParameters: (positionId: string, payload: UpdateRiskParametersRequestInput) => Promise<ApiResponse<UpdateRiskParametersResponseDto>>;
1322
1336
  readonly closePosition: (positionId: string, payload: ClosePositionRequestInput) => Promise<ApiResponse<ClosePositionResponseDto>>;
1323
- readonly closeAllPositions: (payload: ClosePositionRequestInput) => Promise<ApiResponse<CloseAllPositionsResponseDto>>;
1337
+ readonly closeAllPositions: (payload: CloseAllPositionsRequestInput) => Promise<ApiResponse<CloseAllPositionsResponseDto>>;
1324
1338
  readonly adjustPosition: (positionId: string, payload: AdjustPositionRequestInput) => Promise<ApiResponse<AdjustPositionResponseDto>>;
1325
1339
  readonly adjustAdvancePosition: (positionId: string, payload: AdjustAdvanceItemInput[]) => Promise<ApiResponse<AdjustAdvanceResponseDto>>;
1326
1340
  readonly updateLeverage: (positionId: string, leverage: number) => Promise<ApiResponse<UpdateLeverageResponseDto | null>>;
@@ -1498,81 +1512,6 @@ interface UseHyperliquidUserFillsState {
1498
1512
  */
1499
1513
  declare function useHyperliquidUserFills(options: UseHyperliquidUserFillsOptions): UseHyperliquidUserFillsState;
1500
1514
 
1501
- type PnlCalendarTimeframe = '2W' | '3W' | '2M' | '3M';
1502
- interface PnlCalendarOptions {
1503
- timeframe?: PnlCalendarTimeframe;
1504
- startDate?: Date | string;
1505
- endDate?: Date | string;
1506
- }
1507
- interface PnlCalendarAsset {
1508
- coin: string;
1509
- symbol: string;
1510
- assetName: string;
1511
- marketPrefix: string;
1512
- percentage: number;
1513
- collateralToken: string;
1514
- }
1515
- interface PnlCalendarTrade {
1516
- tradeHistoryId: string;
1517
- realizedPnl: number;
1518
- result: 'profit' | 'loss' | 'breakeven';
1519
- collateralTypes: string[];
1520
- closedLongAssets: PnlCalendarAsset[];
1521
- closedShortAssets: PnlCalendarAsset[];
1522
- }
1523
- interface PnlCalendarDay {
1524
- date: string;
1525
- totalPnl: number;
1526
- volume: number;
1527
- positionsClosed: number;
1528
- result: 'profit' | 'loss' | 'breakeven';
1529
- trades: PnlCalendarTrade[];
1530
- }
1531
- interface PeriodSummary {
1532
- pnl: number;
1533
- volume: number;
1534
- winRate: number;
1535
- wins: number;
1536
- losses: number;
1537
- totalProfit: number;
1538
- totalLoss: number;
1539
- }
1540
- interface PnlCalendarWeek {
1541
- weekStart: string;
1542
- weekEnd: string;
1543
- days: PnlCalendarDay[];
1544
- summary: PeriodSummary;
1545
- }
1546
- interface PnlCalendarMonth {
1547
- month: string;
1548
- label: string;
1549
- days: PnlCalendarDay[];
1550
- summary: PeriodSummary;
1551
- }
1552
- interface UsePnlCalendarResult {
1553
- timeframe: PnlCalendarTimeframe;
1554
- weeks: PnlCalendarWeek[];
1555
- months: PnlCalendarMonth[];
1556
- overall: PeriodSummary;
1557
- isLoading: boolean;
1558
- error: string | null;
1559
- refetch: () => void;
1560
- }
1561
- declare function usePnlCalendar(options?: PnlCalendarTimeframe | PnlCalendarOptions): UsePnlCalendarResult;
1562
-
1563
- type PnlHeatmapTimeframe = 'allTime' | '100D' | '30D' | '7D';
1564
- interface PnlHeatmapTrade extends PnlCalendarTrade {
1565
- percentage: number;
1566
- }
1567
- interface UsePnlHeatmapResult {
1568
- timeframe: PnlHeatmapTimeframe;
1569
- trades: PnlHeatmapTrade[];
1570
- isLoading: boolean;
1571
- error: string | null;
1572
- refetch: () => void;
1573
- }
1574
- declare function usePnlHeatmap(timeframe?: PnlHeatmapTimeframe): UsePnlHeatmapResult;
1575
-
1576
1515
  /**
1577
1516
  * Mark notifications as read up to a given timestamp (ms)
1578
1517
  */
@@ -1748,6 +1687,9 @@ declare class MaxAssetsPerLegError extends Error {
1748
1687
  maxAllowed: number;
1749
1688
  constructor(leg: "long" | "short", assetCount: number, maxAllowed: number);
1750
1689
  }
1690
+ declare class ClosePositionValidationError extends Error {
1691
+ constructor(message: string);
1692
+ }
1751
1693
  /**
1752
1694
  * Validates that each leg doesn't exceed the maximum number of assets
1753
1695
  * @param longAssets Array of long assets
@@ -1782,6 +1724,16 @@ declare function validatePositionSize(usdValue: number, longAssets?: PairAssetIn
1782
1724
  error?: string;
1783
1725
  minimumRequired?: number;
1784
1726
  };
1727
+ interface ClosePositionValidationInput {
1728
+ executionType: CloseExecutionType;
1729
+ twapDuration?: number;
1730
+ twapIntervalSeconds?: number;
1731
+ randomizeExecution?: boolean;
1732
+ triggerType?: CloseTriggerType;
1733
+ triggerValue?: string;
1734
+ direction?: OrderDirection;
1735
+ }
1736
+ declare function validateClosePositionRequest(payload: ClosePositionValidationInput): void;
1785
1737
 
1786
1738
  /**
1787
1739
  * Helper functions to safely extract values from order parameters
@@ -1847,5 +1799,5 @@ interface MarketDataState {
1847
1799
  }
1848
1800
  declare const useMarketData: zustand.UseBoundStore<zustand.StoreApi<MarketDataState>>;
1849
1801
 
1850
- export { ConflictDetector, MAX_ASSETS_PER_LEG, MINIMUM_ASSET_USD_VALUE, MaxAssetsPerLegError, MinimumPositionSizeError, PearHyperliquidProvider, ReadyState, adjustAdvancePosition, adjustOrder, adjustPosition, calculateMinimumPositionValue, calculateWeightedRatio, cancelOrder, cancelTwap, cancelTwapOrder, closeAllPositions, closePosition, computeBasketCandles, createCandleLookups, createPosition, executeSpotOrder, getCompleteTimestamps, getKalshiMarkets, getOrderDirection, getOrderLadderConfig, getOrderLeverage, getOrderReduceOnly, getOrderTpSlTriggerType, getOrderTrailingInfo, getOrderTriggerType, getOrderTriggerValue, getOrderTwapDuration, getOrderUsdValue, getPortfolio, isBtcDomOrder, mapCandleIntervalToTradingViewInterval, mapTradingViewIntervalToCandleInterval, markNotificationReadById, markNotificationsRead, toggleWatchlist, updateLeverage, updateRiskParameters, useAccountSummary, useAgentWallet, useAllUserBalances, useAuth, useBasketCandles, useHistoricalPriceData, useHistoricalPriceDataStore, useHyperliquidUserFills, useMarket, useMarketData, useMarketDataHook, useNotifications, useOpenOrders, useOrders, usePearHyperliquid, usePerformanceOverlays, usePnlCalendar, usePnlHeatmap, usePortfolio, usePosition, useSpotOrder, useTokenSelectionMetadata, useTradeHistories, useTwap, useUserSelection, useWatchlist, validateMaxAssetsPerLeg, validateMinimumAssetSize, validatePositionSize };
1851
- export type { AccountSummaryResponseDto, ActiveAssetData, ActiveAssetGroupItem, ActiveAssetsAllResponse, ActiveAssetsResponse, AddressState, AdjustAdvanceAssetInput, AdjustAdvanceItemInput, AdjustAdvanceResponseDto, AdjustExecutionType, AdjustOrderRequestInput, AdjustOrderResponseDto, AdjustPositionRequestInput, AdjustPositionResponseDto, AgentWalletDto, AgentWalletState, AgentWalletStatus, AllDexsAssetCtxsData, AllDexsClearinghouseStateData, AllPerpMetasItem, AllPerpMetasResponse, ApiErrorResponse, ApiResponse, AssetCtx, AssetInformationDetail, AssetMarketData, AssetPosition, AuthenticateRequest, AuthenticateResponse, AvailableToTrades, BalanceSummaryDto, BaseTriggerOrderNotificationParams, BtcDomTriggerParams, CancelOrderResponseDto, CancelTwapResponseDto, CandleChartData, CandleData, CandleInterval, CandleSnapshotRequest, ChunkFillDto, ClearinghouseState, CloseAllPositionsResponseDto, CloseAllPositionsResultDto, CloseExecutionType, ClosePositionRequestInput, ClosePositionResponseDto, CollateralToken, CreateAgentWalletResponseDto, CreatePositionRequestInput, CreatePositionResponseDto, CrossAssetPriceTriggerParams, CrossMarginSummaryDto, CumFundingDto, EIP712AuthDetails, ExecutionType, ExternalFillDto, ExternalLiquidationDto, ExtraAgent, GetAgentWalletResponseDto, GetEIP712MessageResponse, GetKalshiMarketsParams, HLChannel, HLChannelDataMap, HLWebSocketResponse, HistoricalRange, KalshiMarket, KalshiMarketsResponse, KalshiMveLeg, KalshiPriceRange, LadderConfigInput, LadderOrderParameters, LeverageInfo, LogoutRequest, LogoutResponse, MarginRequiredPerCollateral, MarginRequiredResult, MarginSummaryDto, MarginTableDef, MarginTablesEntry, MarginTier, MarketOrderParameters, NotificationCategory, NotificationDto, OpenLimitOrderDto, OpenPositionDto, OrderAssetDto, OrderDirection, OrderParameters, OrderStatus, OrderType, PairAssetDto, PairAssetInput, PerformanceOverlay, PeriodSummary, PerpDex, PerpDexsResponse, PerpMetaAsset, PlatformAccountSummaryResponseDto, PnlCalendarAsset, PnlCalendarDay, PnlCalendarMonth, PnlCalendarOptions, PnlCalendarTimeframe, PnlCalendarTrade, PnlCalendarWeek, PnlHeatmapTimeframe, PnlHeatmapTrade, PortfolioBucketDto, PortfolioInterval, PortfolioIntervalsDto, PortfolioOverallDto, PortfolioResponseDto, PositionAdjustmentType, PositionAssetDetailDto, PredictionMarketOutcomeTriggerParams, PriceRatioTriggerParams, PriceTriggerParams, PrivyAuthDetails, RawAssetDto, RawPositionDto, RealtimeBar, RealtimeBarsCallback, RebalanceAssetPlan, RebalancePlan, RefreshTokenRequest, RefreshTokenResponse, SpotBalance, SpotBalances, SpotOrderFilledStatus, SpotOrderHyperliquidData, SpotOrderHyperliquidResult, SpotOrderRequestInput, SpotOrderResponseDto, SpotState, SyncFillsRequestDto, SyncFillsResponseDto, ToggleWatchlistResponseDto, TokenConflict, TokenEntry, TokenHistoricalPriceData, TokenMetadata, TokenSelection, TokenSelectorConfig, TpSlOrderParameters, TpSlThreshold, TpSlThresholdInput, TpSlThresholdType, TpSlTriggerType, TradeHistoryAssetDataDto, TradeHistoryDataDto, TriggerOrderNotificationAsset, TriggerOrderNotificationParams, TriggerOrderNotificationType, TriggerOrderParameters, TriggerType, TwapChunkStatus, TwapChunkStatusDto, TwapMonitoringDto, TwapOrderOverallStatus, TwapOrderParameters, TwapSliceFillResponseItem, UniverseAsset, UpdateLeverageRequestInput, UpdateLeverageResponseDto, UpdateRiskParametersRequestInput, UpdateRiskParametersResponseDto, UseAuthOptions, UseBasketCandlesReturn, UseHistoricalPriceDataReturn, UseHyperliquidUserFillsOptions, UseHyperliquidUserFillsState, UseNotificationsResult, UsePerformanceOverlaysReturn, UsePnlCalendarResult, UsePnlHeatmapResult, UsePortfolioResult, UseSpotOrderResult, UseTokenSelectionMetadataReturn, UserAbstraction, UserProfile, UserSelectionState, WatchlistAssetDto, WatchlistItemDto, WebData3AssetCtx, WebData3PerpDexState, WebData3Response, WebData3UserState, WebSocketAckResponse, WebSocketChannel, WebSocketConnectionState, WebSocketDataMessage, WebSocketMessage, WebSocketSubscribeMessage, WsAllMidsData };
1802
+ export { ClosePositionValidationError, ConflictDetector, MAX_ASSETS_PER_LEG, MINIMUM_ASSET_USD_VALUE, MaxAssetsPerLegError, MinimumPositionSizeError, PearHyperliquidProvider, ReadyState, adjustAdvancePosition, adjustOrder, adjustPosition, calculateMinimumPositionValue, calculateWeightedRatio, cancelOrder, cancelTwap, cancelTwapOrder, closeAllPositions, closePosition, computeBasketCandles, createCandleLookups, createPosition, executeSpotOrder, getCompleteTimestamps, getKalshiMarkets, getOrderDirection, getOrderLadderConfig, getOrderLeverage, getOrderReduceOnly, getOrderTpSlTriggerType, getOrderTrailingInfo, getOrderTriggerType, getOrderTriggerValue, getOrderTwapDuration, getOrderUsdValue, getPortfolio, isBtcDomOrder, mapCandleIntervalToTradingViewInterval, mapTradingViewIntervalToCandleInterval, markNotificationReadById, markNotificationsRead, toggleWatchlist, updateLeverage, updateRiskParameters, useAccountSummary, useAgentWallet, useAllUserBalances, useAuth, useBasketCandles, useHistoricalPriceData, useHistoricalPriceDataStore, useHyperliquidUserFills, useMarket, useMarketData, useMarketDataHook, useNotifications, useOpenOrders, useOrders, usePearHyperliquid, usePerformanceOverlays, usePortfolio, usePosition, useSpotOrder, useTokenSelectionMetadata, useTradeHistories, useTwap, useUserSelection, useWatchlist, validateClosePositionRequest, validateMaxAssetsPerLeg, validateMinimumAssetSize, validatePositionSize };
1803
+ export type { AccountSummaryResponseDto, ActiveAssetData, ActiveAssetGroupItem, ActiveAssetsAllResponse, ActiveAssetsResponse, AddressState, AdjustAdvanceAssetInput, AdjustAdvanceItemInput, AdjustAdvanceResponseDto, AdjustExecutionType, AdjustOrderRequestInput, AdjustOrderResponseDto, AdjustPositionRequestInput, AdjustPositionResponseDto, AgentWalletDto, AgentWalletState, AgentWalletStatus, AllDexsAssetCtxsData, AllDexsClearinghouseStateData, AllPerpMetasItem, AllPerpMetasResponse, ApiErrorResponse, ApiResponse, AssetCtx, AssetInformationDetail, AssetMarketData, AssetPosition, AuthenticateRequest, AuthenticateResponse, AvailableToTrades, BalanceSummaryDto, BaseTriggerOrderNotificationParams, BtcDomTriggerParams, CancelOrderResponseDto, CancelTwapResponseDto, CandleChartData, CandleData, CandleInterval, CandleSnapshotRequest, ChunkFillDto, ClearinghouseState, CloseAllExecutionType, CloseAllPositionsRequestInput, CloseAllPositionsResponseDto, CloseAllPositionsResultDto, CloseExecutionType, ClosePositionExecutionType, ClosePositionRequestInput, ClosePositionResponseDto, CloseTriggerType, CollateralToken, CreateAgentWalletResponseDto, CreatePositionRequestInput, CreatePositionResponseDto, CrossAssetPriceTriggerParams, CrossMarginSummaryDto, CumFundingDto, EIP712AuthDetails, ExecutionType, ExternalFillDto, ExternalLiquidationDto, ExtraAgent, GetAgentWalletResponseDto, GetEIP712MessageResponse, GetKalshiMarketsParams, HLChannel, HLChannelDataMap, HLWebSocketResponse, HistoricalRange, KalshiMarket, KalshiMarketsResponse, KalshiMveLeg, KalshiPriceRange, LadderConfigInput, LadderOrderParameters, LeverageInfo, LogoutRequest, LogoutResponse, MarginRequiredPerCollateral, MarginRequiredResult, MarginSummaryDto, MarginTableDef, MarginTablesEntry, MarginTier, MarketOrderParameters, NotificationCategory, NotificationDto, OpenLimitOrderDto, OpenPositionDto, OrderAssetDto, OrderDirection, OrderParameters, OrderStatus, OrderType, PairAssetDto, PairAssetInput, PerformanceOverlay, PerpDex, PerpDexsResponse, PerpMetaAsset, PlatformAccountSummaryResponseDto, PortfolioBucketDto, PortfolioInterval, PortfolioIntervalsDto, PortfolioOverallDto, PortfolioResponseDto, PositionAdjustmentType, PositionAssetDetailDto, PredictionMarketOutcomeTriggerParams, PriceRatioTriggerParams, PriceTriggerParams, PrivyAuthDetails, RawAssetDto, RawPositionDto, RealtimeBar, RealtimeBarsCallback, RebalanceAssetPlan, RebalancePlan, RefreshTokenRequest, RefreshTokenResponse, SpotBalance, SpotBalances, SpotOrderFilledStatus, SpotOrderHyperliquidData, SpotOrderHyperliquidResult, SpotOrderRequestInput, SpotOrderResponseDto, SpotState, SyncFillsRequestDto, SyncFillsResponseDto, ToggleWatchlistResponseDto, TokenConflict, TokenEntry, TokenHistoricalPriceData, TokenMetadata, TokenSelection, TokenSelectorConfig, TpSlOrderParameters, TpSlThreshold, TpSlThresholdInput, TpSlThresholdType, TpSlTriggerType, TradeHistoryAssetDataDto, TradeHistoryDataDto, TriggerOrderNotificationAsset, TriggerOrderNotificationParams, TriggerOrderNotificationType, TriggerOrderParameters, TriggerType, TwapChunkStatus, TwapChunkStatusDto, TwapMonitoringDto, TwapOrderOverallStatus, TwapOrderParameters, TwapSliceFillResponseItem, UniverseAsset, UpdateLeverageRequestInput, UpdateLeverageResponseDto, UpdateRiskParametersRequestInput, UpdateRiskParametersResponseDto, UseAuthOptions, UseBasketCandlesReturn, UseHistoricalPriceDataReturn, UseHyperliquidUserFillsOptions, UseHyperliquidUserFillsState, UseNotificationsResult, UsePerformanceOverlaysReturn, UsePortfolioResult, UseSpotOrderResult, UseTokenSelectionMetadataReturn, UserAbstraction, UserProfile, UserSelectionState, WatchlistAssetDto, WatchlistItemDto, WebData3AssetCtx, WebData3PerpDexState, WebData3Response, WebData3UserState, WebSocketAckResponse, WebSocketChannel, WebSocketConnectionState, WebSocketDataMessage, WebSocketMessage, WebSocketSubscribeMessage, WsAllMidsData };
package/dist/index.js CHANGED
@@ -696,6 +696,12 @@ class MaxAssetsPerLegError extends Error {
696
696
  this.name = "MaxAssetsPerLegError";
697
697
  }
698
698
  }
699
+ class ClosePositionValidationError extends Error {
700
+ constructor(message) {
701
+ super(message);
702
+ this.name = "ClosePositionValidationError";
703
+ }
704
+ }
699
705
  /**
700
706
  * Validates that each leg doesn't exceed the maximum number of assets
701
707
  * @param longAssets Array of long assets
@@ -776,6 +782,44 @@ function validatePositionSize(usdValue, longAssets, shortAssets) {
776
782
  throw error;
777
783
  }
778
784
  }
785
+ function isNumberString(value) {
786
+ if (value.trim() === "") {
787
+ return false;
788
+ }
789
+ return Number.isFinite(Number(value));
790
+ }
791
+ function validateClosePositionRequest(payload) {
792
+ if (payload.executionType === "TWAP") {
793
+ if (payload.twapDuration === undefined || payload.twapDuration <= 0) {
794
+ throw new ClosePositionValidationError("twapDuration is required and must be greater than 0 when executionType is TWAP");
795
+ }
796
+ if (payload.twapIntervalSeconds !== undefined &&
797
+ payload.twapIntervalSeconds <= 0) {
798
+ throw new ClosePositionValidationError("twapIntervalSeconds must be greater than 0 when provided for TWAP closes");
799
+ }
800
+ }
801
+ else if (payload.twapDuration !== undefined ||
802
+ payload.twapIntervalSeconds !== undefined ||
803
+ payload.randomizeExecution !== undefined) {
804
+ throw new ClosePositionValidationError("twapDuration, twapIntervalSeconds, and randomizeExecution are only supported when executionType is TWAP");
805
+ }
806
+ if (payload.executionType === "TRIGGER") {
807
+ if (!payload.triggerType) {
808
+ throw new ClosePositionValidationError("triggerType is required when executionType is TRIGGER");
809
+ }
810
+ if (!payload.direction) {
811
+ throw new ClosePositionValidationError("direction is required when executionType is TRIGGER");
812
+ }
813
+ if (!payload.triggerValue || !isNumberString(payload.triggerValue)) {
814
+ throw new ClosePositionValidationError("triggerValue is required and must be a numeric string when executionType is TRIGGER");
815
+ }
816
+ }
817
+ else if (payload.triggerType !== undefined ||
818
+ payload.triggerValue !== undefined ||
819
+ payload.direction !== undefined) {
820
+ throw new ClosePositionValidationError("triggerType, triggerValue, and direction are only supported when executionType is TRIGGER");
821
+ }
822
+ }
779
823
 
780
824
  const DEFAULT_STATE = {
781
825
  longTokens: [
@@ -981,7 +1025,7 @@ const useHyperliquidNativeWebSocket = ({ address, enabled = true, onUserFills, }
981
1025
  // finalAssetContexts now sourced from allDexsAssetCtxs channel
982
1026
  const finalAtOICaps = webData3.perpDexStates.flatMap((dex) => dex.perpsAtOpenInterestCap);
983
1027
  setFinalAtOICaps(finalAtOICaps);
984
- setUserAbstractionMode(webData3.userState.abstraction || null);
1028
+ setUserAbstractionMode(webData3.userState.abstraction || 'disabled');
985
1029
  break;
986
1030
  case "allDexsAssetCtxs":
987
1031
  {
@@ -6950,10 +6994,20 @@ async function updateRiskParameters(baseUrl, positionId, payload) {
6950
6994
  throw toApiError(error);
6951
6995
  }
6952
6996
  }
6997
+ function normalizeClosePositionPayload(payload) {
6998
+ return {
6999
+ ...payload,
7000
+ triggerValue: payload.triggerValue === undefined
7001
+ ? undefined
7002
+ : String(payload.triggerValue),
7003
+ };
7004
+ }
6953
7005
  async function closePosition(baseUrl, positionId, payload) {
6954
7006
  const url = joinUrl(baseUrl, `/positions/${positionId}/close`);
7007
+ const normalizedPayload = normalizeClosePositionPayload(payload);
7008
+ validateClosePositionRequest(normalizedPayload);
6955
7009
  try {
6956
- const resp = await apiClient.post(url, payload, {
7010
+ const resp = await apiClient.post(url, normalizedPayload, {
6957
7011
  headers: {
6958
7012
  "Content-Type": "application/json",
6959
7013
  },
@@ -8422,456 +8476,6 @@ function useHyperliquidUserFills(options) {
8422
8476
  };
8423
8477
  }
8424
8478
 
8425
- async function getTradeHistory(baseUrl, params) {
8426
- const url = joinUrl(baseUrl, '/trade-history');
8427
- try {
8428
- const resp = await apiClient.get(url, {
8429
- params,
8430
- timeout: 60000,
8431
- });
8432
- return { data: resp.data, status: resp.status, headers: resp.headers };
8433
- }
8434
- catch (error) {
8435
- throw toApiError(error);
8436
- }
8437
- }
8438
-
8439
- // ─── helpers ────────────────────────────────────────────────────
8440
- const EMPTY_SUMMARY = {
8441
- pnl: 0,
8442
- volume: 0,
8443
- winRate: 0,
8444
- wins: 0,
8445
- losses: 0,
8446
- totalProfit: 0,
8447
- totalLoss: 0,
8448
- };
8449
- const getTimeframeDays$1 = (tf) => {
8450
- switch (tf) {
8451
- case '2W':
8452
- return 14;
8453
- case '3W':
8454
- return 21;
8455
- case '2M':
8456
- return 60;
8457
- case '3M':
8458
- return 90;
8459
- }
8460
- };
8461
- const isWeekTimeframe = (tf) => tf === '2W' || tf === '3W';
8462
- const toDateKey = (date) => {
8463
- const y = date.getFullYear();
8464
- const m = String(date.getMonth() + 1).padStart(2, '0');
8465
- const d = String(date.getDate()).padStart(2, '0');
8466
- return `${y}-${m}-${d}`;
8467
- };
8468
- const toMonthKey = (date) => {
8469
- const y = date.getFullYear();
8470
- const m = String(date.getMonth() + 1).padStart(2, '0');
8471
- return `${y}-${m}`;
8472
- };
8473
- const formatMonthLabel = (date) => date.toLocaleDateString('en-US', { month: 'short', year: 'numeric' });
8474
- const getMonday = (date) => {
8475
- const d = new Date(date);
8476
- const day = d.getDay(); // 0=Sun … 6=Sat
8477
- const diff = day === 0 ? -6 : 1 - day;
8478
- d.setDate(d.getDate() + diff);
8479
- d.setHours(0, 0, 0, 0);
8480
- return d;
8481
- };
8482
- const toLocalMidnight = (input) => {
8483
- const d = typeof input === 'string' ? new Date(input + 'T00:00:00') : new Date(input);
8484
- d.setHours(0, 0, 0, 0);
8485
- return d;
8486
- };
8487
- const diffDays = (start, end) => {
8488
- return Math.round((end.getTime() - start.getTime()) / (1000 * 60 * 60 * 24)) + 1;
8489
- };
8490
- const toISODateString$1 = (input) => {
8491
- const d = typeof input === 'string' ? new Date(input + 'T00:00:00') : new Date(input);
8492
- return d.toISOString();
8493
- };
8494
- const round2 = (n) => Math.round(n * 100) / 100;
8495
- const mapAsset$1 = (asset, getAssetByName) => {
8496
- var _a, _b, _c, _d;
8497
- const metadata = getAssetByName(asset.coin);
8498
- const marketInfo = getMarketInfoFromSymbol(asset.coin);
8499
- return {
8500
- coin: asset.coin,
8501
- symbol: (_a = metadata === null || metadata === void 0 ? void 0 : metadata.symbolName) !== null && _a !== void 0 ? _a : marketInfo.symbolName,
8502
- assetName: (_b = metadata === null || metadata === void 0 ? void 0 : metadata.assetName) !== null && _b !== void 0 ? _b : asset.coin,
8503
- marketPrefix: (_c = metadata === null || metadata === void 0 ? void 0 : metadata.marketName) !== null && _c !== void 0 ? _c : marketInfo.marketName,
8504
- percentage: asset.closeWeight * 100,
8505
- collateralToken: (_d = metadata === null || metadata === void 0 ? void 0 : metadata.collateralToken) !== null && _d !== void 0 ? _d : 'USDC',
8506
- };
8507
- };
8508
- const getCollateralTypes$1 = (assets) => {
8509
- const set = new Set();
8510
- for (const a of assets)
8511
- set.add(a.collateralToken);
8512
- return set.size > 0 ? Array.from(set) : ['USDC'];
8513
- };
8514
- const buildSummary = (days) => {
8515
- let pnl = 0;
8516
- let volume = 0;
8517
- let wins = 0;
8518
- let losses = 0;
8519
- let totalProfit = 0;
8520
- let totalLoss = 0;
8521
- for (const day of days) {
8522
- pnl += day.totalPnl;
8523
- volume += day.volume;
8524
- if (day.positionsClosed === 0)
8525
- continue;
8526
- if (day.totalPnl > 0) {
8527
- wins++;
8528
- totalProfit += day.totalPnl;
8529
- }
8530
- else if (day.totalPnl < 0) {
8531
- losses++;
8532
- totalLoss += Math.abs(day.totalPnl);
8533
- }
8534
- }
8535
- const total = wins + losses;
8536
- const winRate = total > 0 ? Math.round((wins / total) * 100) : 0;
8537
- return {
8538
- pnl: round2(pnl),
8539
- volume: round2(volume),
8540
- winRate,
8541
- wins,
8542
- losses,
8543
- totalProfit: round2(totalProfit),
8544
- totalLoss: round2(totalLoss),
8545
- };
8546
- };
8547
- const buildCalendarData = (tradeHistories, timeframe, rangeStart, rangeEnd, totalDays, useCustomDates, getAssetByName) => {
8548
- const startKey = toDateKey(rangeStart);
8549
- const endKey = toDateKey(rangeEnd);
8550
- // Build day buckets for the full range
8551
- const buckets = new Map();
8552
- for (let i = 0; i < totalDays; i++) {
8553
- const d = new Date(rangeStart);
8554
- d.setDate(rangeStart.getDate() + i);
8555
- buckets.set(toDateKey(d), {
8556
- pnl: 0,
8557
- volume: 0,
8558
- positionsClosed: 0,
8559
- trades: [],
8560
- });
8561
- }
8562
- // Populate buckets from trade histories
8563
- for (const trade of tradeHistories) {
8564
- if (!trade.createdAt)
8565
- continue;
8566
- const date = new Date(trade.createdAt);
8567
- if (isNaN(date.getTime()))
8568
- continue;
8569
- const dateKey = toDateKey(date);
8570
- if (dateKey < startKey || dateKey > endKey)
8571
- continue;
8572
- const bucket = buckets.get(dateKey);
8573
- if (!bucket)
8574
- continue;
8575
- const pnl = trade.realizedPnl;
8576
- bucket.pnl += isFinite(pnl) ? pnl : 0;
8577
- const vol = trade.totalValue;
8578
- bucket.volume += isFinite(vol) ? vol : 0;
8579
- bucket.positionsClosed += 1;
8580
- const tradePnl = trade.realizedPnl;
8581
- const longAssets = trade.closedLongAssets.map((a) => mapAsset$1(a, getAssetByName));
8582
- const shortAssets = trade.closedShortAssets.map((a) => mapAsset$1(a, getAssetByName));
8583
- bucket.trades.push({
8584
- tradeHistoryId: trade.tradeHistoryId,
8585
- realizedPnl: tradePnl,
8586
- result: tradePnl > 0 ? 'profit' : tradePnl < 0 ? 'loss' : 'breakeven',
8587
- collateralTypes: getCollateralTypes$1([...longAssets, ...shortAssets]),
8588
- closedLongAssets: longAssets,
8589
- closedShortAssets: shortAssets,
8590
- });
8591
- }
8592
- // Build day objects
8593
- const allDays = [];
8594
- const sortedKeys = Array.from(buckets.keys()).sort();
8595
- for (const key of sortedKeys) {
8596
- const bucket = buckets.get(key);
8597
- const roundedPnl = round2(bucket.pnl);
8598
- const result = roundedPnl > 0 ? 'profit' : roundedPnl < 0 ? 'loss' : 'breakeven';
8599
- allDays.push({
8600
- date: key,
8601
- totalPnl: roundedPnl,
8602
- volume: round2(bucket.volume),
8603
- positionsClosed: bucket.positionsClosed,
8604
- result,
8605
- trades: bucket.trades,
8606
- });
8607
- }
8608
- // Group into periods
8609
- let weeks = [];
8610
- let months = [];
8611
- const useWeekGrouping = useCustomDates
8612
- ? totalDays <= 28
8613
- : isWeekTimeframe(timeframe);
8614
- if (useWeekGrouping) {
8615
- const weekMap = new Map();
8616
- for (const day of allDays) {
8617
- const date = new Date(day.date + 'T00:00:00');
8618
- const monday = getMonday(date);
8619
- const mondayKey = toDateKey(monday);
8620
- if (!weekMap.has(mondayKey)) {
8621
- weekMap.set(mondayKey, []);
8622
- }
8623
- weekMap.get(mondayKey).push(day);
8624
- }
8625
- const sortedWeekKeys = Array.from(weekMap.keys()).sort();
8626
- weeks = sortedWeekKeys.map((mondayKey) => {
8627
- const days = weekMap.get(mondayKey);
8628
- const monday = new Date(mondayKey + 'T00:00:00');
8629
- const sunday = new Date(monday);
8630
- sunday.setDate(monday.getDate() + 6);
8631
- return {
8632
- weekStart: mondayKey,
8633
- weekEnd: toDateKey(sunday),
8634
- days,
8635
- summary: buildSummary(days),
8636
- };
8637
- });
8638
- }
8639
- else {
8640
- const monthMap = new Map();
8641
- for (const day of allDays) {
8642
- const date = new Date(day.date + 'T00:00:00');
8643
- const mk = toMonthKey(date);
8644
- if (!monthMap.has(mk)) {
8645
- monthMap.set(mk, { days: [], label: formatMonthLabel(date) });
8646
- }
8647
- monthMap.get(mk).days.push(day);
8648
- }
8649
- const sortedMonthKeys = Array.from(monthMap.keys()).sort();
8650
- months = sortedMonthKeys.map((mk) => {
8651
- const { days, label } = monthMap.get(mk);
8652
- return {
8653
- month: mk,
8654
- label,
8655
- days,
8656
- summary: buildSummary(days),
8657
- };
8658
- });
8659
- }
8660
- return {
8661
- timeframe,
8662
- weeks,
8663
- months,
8664
- overall: buildSummary(allDays),
8665
- isLoading: false,
8666
- };
8667
- };
8668
- // ─── hook ───────────────────────────────────────────────────────
8669
- function usePnlCalendar(options) {
8670
- var _a;
8671
- const opts = typeof options === 'string'
8672
- ? { timeframe: options }
8673
- : options !== null && options !== void 0 ? options : {};
8674
- const timeframe = (_a = opts.timeframe) !== null && _a !== void 0 ? _a : '2W';
8675
- const customStart = opts.startDate;
8676
- const customEnd = opts.endDate;
8677
- const context = useContext(PearHyperliquidContext);
8678
- if (!context) {
8679
- throw new Error('usePnlCalendar must be used within a PearHyperliquidProvider');
8680
- }
8681
- const { apiBaseUrl } = context;
8682
- const isAuthenticated = useUserData((state) => state.isAuthenticated);
8683
- const { getAssetByName } = useMarket();
8684
- const [trades, setTrades] = useState(null);
8685
- const [isLoading, setIsLoading] = useState(false);
8686
- const [error, setError] = useState(null);
8687
- const mountedRef = useRef(true);
8688
- useEffect(() => {
8689
- mountedRef.current = true;
8690
- return () => { mountedRef.current = false; };
8691
- }, []);
8692
- // Compute the date range
8693
- const useCustomDates = !!(customStart && customEnd);
8694
- let rangeStart;
8695
- let rangeEnd;
8696
- let totalDays;
8697
- if (useCustomDates) {
8698
- rangeStart = toLocalMidnight(customStart);
8699
- rangeEnd = toLocalMidnight(customEnd);
8700
- totalDays = diffDays(rangeStart, rangeEnd);
8701
- }
8702
- else {
8703
- totalDays = getTimeframeDays$1(timeframe);
8704
- rangeEnd = new Date();
8705
- rangeEnd.setHours(0, 0, 0, 0);
8706
- rangeStart = new Date(rangeEnd);
8707
- rangeStart.setDate(rangeEnd.getDate() - totalDays + 1);
8708
- }
8709
- const startIso = toISODateString$1(rangeStart);
8710
- const endIso = toISODateString$1(rangeEnd);
8711
- const fetchData = useCallback(async () => {
8712
- if (!isAuthenticated)
8713
- return;
8714
- setIsLoading(true);
8715
- setError(null);
8716
- try {
8717
- const response = await getTradeHistory(apiBaseUrl, {
8718
- startDate: startIso,
8719
- endDate: endIso,
8720
- limit: totalDays * 50,
8721
- });
8722
- if (!mountedRef.current)
8723
- return;
8724
- setTrades(response.data);
8725
- }
8726
- catch (err) {
8727
- if (!mountedRef.current)
8728
- return;
8729
- setError(err instanceof Error ? err.message : 'Failed to fetch trade history');
8730
- setTrades(null);
8731
- }
8732
- finally {
8733
- if (mountedRef.current)
8734
- setIsLoading(false);
8735
- }
8736
- }, [apiBaseUrl, isAuthenticated, startIso, endIso, totalDays]);
8737
- useEffect(() => {
8738
- fetchData();
8739
- }, [fetchData]);
8740
- const result = useMemo(() => {
8741
- const empty = {
8742
- timeframe,
8743
- weeks: [],
8744
- months: [],
8745
- overall: EMPTY_SUMMARY,
8746
- isLoading: true,
8747
- };
8748
- if (!trades)
8749
- return empty;
8750
- if (totalDays <= 0)
8751
- return empty;
8752
- return buildCalendarData(trades, timeframe, rangeStart, rangeEnd, totalDays, useCustomDates, getAssetByName);
8753
- }, [trades, timeframe, startIso, endIso, getAssetByName]);
8754
- return { ...result, isLoading, error, refetch: fetchData };
8755
- }
8756
-
8757
- const HEATMAP_LIMIT = 50;
8758
- // ─── helpers ────────────────────────────────────────────────────
8759
- const getTimeframeDays = (tf) => {
8760
- switch (tf) {
8761
- case '7D':
8762
- return 7;
8763
- case '30D':
8764
- return 30;
8765
- case '100D':
8766
- return 100;
8767
- case 'allTime':
8768
- return null;
8769
- }
8770
- };
8771
- const toISODateString = (date) => date.toISOString();
8772
- const mapAsset = (asset, getAssetByName) => {
8773
- var _a, _b, _c, _d;
8774
- const metadata = getAssetByName(asset.coin);
8775
- const marketInfo = getMarketInfoFromSymbol(asset.coin);
8776
- return {
8777
- coin: asset.coin,
8778
- symbol: (_a = metadata === null || metadata === void 0 ? void 0 : metadata.symbolName) !== null && _a !== void 0 ? _a : marketInfo.symbolName,
8779
- assetName: (_b = metadata === null || metadata === void 0 ? void 0 : metadata.assetName) !== null && _b !== void 0 ? _b : asset.coin,
8780
- marketPrefix: (_c = metadata === null || metadata === void 0 ? void 0 : metadata.marketName) !== null && _c !== void 0 ? _c : marketInfo.marketName,
8781
- percentage: asset.closeWeight * 100,
8782
- collateralToken: (_d = metadata === null || metadata === void 0 ? void 0 : metadata.collateralToken) !== null && _d !== void 0 ? _d : 'USDC',
8783
- };
8784
- };
8785
- const getCollateralTypes = (assets) => {
8786
- const set = new Set();
8787
- for (const a of assets)
8788
- set.add(a.collateralToken);
8789
- return set.size > 0 ? Array.from(set) : ['USDC'];
8790
- };
8791
- const toCalendarTrade = (trade, getAssetByName) => {
8792
- const pnl = trade.realizedPnl;
8793
- const longAssets = trade.closedLongAssets.map((a) => mapAsset(a, getAssetByName));
8794
- const shortAssets = trade.closedShortAssets.map((a) => mapAsset(a, getAssetByName));
8795
- return {
8796
- tradeHistoryId: trade.tradeHistoryId,
8797
- realizedPnl: pnl,
8798
- result: pnl > 0 ? 'profit' : pnl < 0 ? 'loss' : 'breakeven',
8799
- collateralTypes: getCollateralTypes([...longAssets, ...shortAssets]),
8800
- closedLongAssets: longAssets,
8801
- closedShortAssets: shortAssets,
8802
- };
8803
- };
8804
- // ─── hook ───────────────────────────────────────────────────────
8805
- function usePnlHeatmap(timeframe = 'allTime') {
8806
- const context = useContext(PearHyperliquidContext);
8807
- if (!context) {
8808
- throw new Error('usePnlHeatmap must be used within a PearHyperliquidProvider');
8809
- }
8810
- const { apiBaseUrl } = context;
8811
- const isAuthenticated = useUserData((state) => state.isAuthenticated);
8812
- const { getAssetByName } = useMarket();
8813
- const [trades, setTrades] = useState(null);
8814
- const [isLoading, setIsLoading] = useState(false);
8815
- const [error, setError] = useState(null);
8816
- const mountedRef = useRef(true);
8817
- useEffect(() => {
8818
- mountedRef.current = true;
8819
- return () => { mountedRef.current = false; };
8820
- }, []);
8821
- const days = getTimeframeDays(timeframe);
8822
- let startIso;
8823
- if (days !== null) {
8824
- const start = new Date();
8825
- start.setHours(0, 0, 0, 0);
8826
- start.setDate(start.getDate() - days);
8827
- startIso = toISODateString(start);
8828
- }
8829
- const fetchData = useCallback(async () => {
8830
- if (!isAuthenticated)
8831
- return;
8832
- setIsLoading(true);
8833
- setError(null);
8834
- try {
8835
- const response = await getTradeHistory(apiBaseUrl, {
8836
- ...(startIso ? { startDate: startIso } : {}),
8837
- limit: 5000,
8838
- });
8839
- if (!mountedRef.current)
8840
- return;
8841
- setTrades(response.data);
8842
- }
8843
- catch (err) {
8844
- if (!mountedRef.current)
8845
- return;
8846
- setError(err instanceof Error ? err.message : 'Failed to fetch trade history');
8847
- setTrades(null);
8848
- }
8849
- finally {
8850
- if (mountedRef.current)
8851
- setIsLoading(false);
8852
- }
8853
- }, [apiBaseUrl, isAuthenticated, startIso]);
8854
- useEffect(() => {
8855
- fetchData();
8856
- }, [fetchData]);
8857
- const result = useMemo(() => {
8858
- if (!trades)
8859
- return [];
8860
- const top = trades
8861
- .slice()
8862
- .sort((a, b) => Math.abs(b.realizedPnl) - Math.abs(a.realizedPnl))
8863
- .slice(0, HEATMAP_LIMIT);
8864
- const totalAbsPnl = top.reduce((sum, t) => sum + Math.abs(t.realizedPnl), 0);
8865
- return top.map((t) => ({
8866
- ...toCalendarTrade(t, getAssetByName),
8867
- percentage: totalAbsPnl > 0
8868
- ? Math.round((Math.abs(t.realizedPnl) / totalAbsPnl) * 10000) / 100
8869
- : 0,
8870
- }));
8871
- }, [trades, getAssetByName]);
8872
- return { timeframe, trades: result, isLoading, error, refetch: fetchData };
8873
- }
8874
-
8875
8479
  const PearHyperliquidContext = createContext(undefined);
8876
8480
  /**
8877
8481
  * React Provider for PearHyperliquidClient
@@ -9223,4 +8827,4 @@ function getOrderTrailingInfo(order) {
9223
8827
  return undefined;
9224
8828
  }
9225
8829
 
9226
- export { ConflictDetector, MAX_ASSETS_PER_LEG, MINIMUM_ASSET_USD_VALUE, MaxAssetsPerLegError, MinimumPositionSizeError, PearHyperliquidProvider, adjustAdvancePosition, adjustOrder, adjustPosition, calculateMinimumPositionValue, calculateWeightedRatio, cancelOrder, cancelTwap, cancelTwapOrder, closeAllPositions, closePosition, computeBasketCandles, createCandleLookups, createPosition, executeSpotOrder, getCompleteTimestamps, getKalshiMarkets, getOrderDirection, getOrderLadderConfig, getOrderLeverage, getOrderReduceOnly, getOrderTpSlTriggerType, getOrderTrailingInfo, getOrderTriggerType, getOrderTriggerValue, getOrderTwapDuration, getOrderUsdValue, getPortfolio, isBtcDomOrder, mapCandleIntervalToTradingViewInterval, mapTradingViewIntervalToCandleInterval, markNotificationReadById, markNotificationsRead, toggleWatchlist, updateLeverage, updateRiskParameters, useAccountSummary, useAgentWallet, useAllUserBalances, useAuth, useBasketCandles, useHistoricalPriceData, useHistoricalPriceDataStore, useHyperliquidUserFills, useMarket, useMarketData, useMarketDataHook, useNotifications, useOpenOrders, useOrders, usePearHyperliquid, usePerformanceOverlays, usePnlCalendar, usePnlHeatmap, usePortfolio, usePosition, useSpotOrder, useTokenSelectionMetadata, useTradeHistories, useTwap, useUserSelection, useWatchlist, validateMaxAssetsPerLeg, validateMinimumAssetSize, validatePositionSize };
8830
+ export { ClosePositionValidationError, ConflictDetector, MAX_ASSETS_PER_LEG, MINIMUM_ASSET_USD_VALUE, MaxAssetsPerLegError, MinimumPositionSizeError, PearHyperliquidProvider, adjustAdvancePosition, adjustOrder, adjustPosition, calculateMinimumPositionValue, calculateWeightedRatio, cancelOrder, cancelTwap, cancelTwapOrder, closeAllPositions, closePosition, computeBasketCandles, createCandleLookups, createPosition, executeSpotOrder, getCompleteTimestamps, getKalshiMarkets, getOrderDirection, getOrderLadderConfig, getOrderLeverage, getOrderReduceOnly, getOrderTpSlTriggerType, getOrderTrailingInfo, getOrderTriggerType, getOrderTriggerValue, getOrderTwapDuration, getOrderUsdValue, getPortfolio, isBtcDomOrder, mapCandleIntervalToTradingViewInterval, mapTradingViewIntervalToCandleInterval, markNotificationReadById, markNotificationsRead, toggleWatchlist, updateLeverage, updateRiskParameters, useAccountSummary, useAgentWallet, useAllUserBalances, useAuth, useBasketCandles, useHistoricalPriceData, useHistoricalPriceDataStore, useHyperliquidUserFills, useMarket, useMarketData, useMarketDataHook, useNotifications, useOpenOrders, useOrders, usePearHyperliquid, usePerformanceOverlays, usePortfolio, usePosition, useSpotOrder, useTokenSelectionMetadata, useTradeHistories, useTwap, useUserSelection, useWatchlist, validateClosePositionRequest, validateMaxAssetsPerLeg, validateMinimumAssetSize, validatePositionSize };
package/dist/types.d.ts CHANGED
@@ -314,6 +314,8 @@ export type TpSlTriggerType = 'PERCENTAGE' | 'DOLLAR' | 'POSITION_VALUE' | 'PRIC
314
314
  * Trigger type for trigger orders
315
315
  */
316
316
  export type TriggerType = 'PRICE' | 'PRICE_RATIO' | 'WEIGHTED_RATIO' | 'BTC_DOM' | 'CROSS_ASSET_PRICE' | 'PREDICTION_MARKET_OUTCOME';
317
+ export type CloseTriggerType = 'PRICE' | 'PRICE_RATIO' | 'WEIGHTED_RATIO' | 'PERCENTAGE' | 'DOLLAR' | 'POSITION_VALUE';
318
+ export type CloseExecutionType = 'MARKET' | 'TWAP' | 'TRIGGER';
317
319
  export type OrderDirection = 'MORE_THAN' | 'LESS_THAN';
318
320
  /**
319
321
  * Market order parameters
@@ -1,4 +1,4 @@
1
- import { PairAssetInput } from "../types";
1
+ import type { CloseExecutionType, CloseTriggerType, OrderDirection, PairAssetInput } from "../types";
2
2
  /**
3
3
  * Minimum USD value required per asset when creating a position
4
4
  */
@@ -25,6 +25,9 @@ export declare class MaxAssetsPerLegError extends Error {
25
25
  maxAllowed: number;
26
26
  constructor(leg: "long" | "short", assetCount: number, maxAllowed: number);
27
27
  }
28
+ export declare class ClosePositionValidationError extends Error {
29
+ constructor(message: string);
30
+ }
28
31
  /**
29
32
  * Validates that each leg doesn't exceed the maximum number of assets
30
33
  * @param longAssets Array of long assets
@@ -59,3 +62,13 @@ export declare function validatePositionSize(usdValue: number, longAssets?: Pair
59
62
  error?: string;
60
63
  minimumRequired?: number;
61
64
  };
65
+ export interface ClosePositionValidationInput {
66
+ executionType: CloseExecutionType;
67
+ twapDuration?: number;
68
+ twapIntervalSeconds?: number;
69
+ randomizeExecution?: boolean;
70
+ triggerType?: CloseTriggerType;
71
+ triggerValue?: string;
72
+ direction?: OrderDirection;
73
+ }
74
+ export declare function validateClosePositionRequest(payload: ClosePositionValidationInput): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pear-protocol/hyperliquid-sdk",
3
- "version": "0.1.20-pnl",
3
+ "version": "0.1.22-beta",
4
4
  "description": "React SDK for Pear Protocol Hyperliquid API integration",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,7 +0,0 @@
1
- import type { ApiResponse, TradeHistoryDataDto } from '../types';
2
- export interface GetTradeHistoryParams {
3
- startDate?: string;
4
- endDate?: string;
5
- limit?: number;
6
- }
7
- export declare function getTradeHistory(baseUrl: string, params?: GetTradeHistoryParams): Promise<ApiResponse<TradeHistoryDataDto[]>>;
@@ -1,61 +0,0 @@
1
- export type PnlCalendarTimeframe = '2W' | '3W' | '2M' | '3M';
2
- export interface PnlCalendarOptions {
3
- timeframe?: PnlCalendarTimeframe;
4
- startDate?: Date | string;
5
- endDate?: Date | string;
6
- }
7
- export interface PnlCalendarAsset {
8
- coin: string;
9
- symbol: string;
10
- assetName: string;
11
- marketPrefix: string;
12
- percentage: number;
13
- collateralToken: string;
14
- }
15
- export interface PnlCalendarTrade {
16
- tradeHistoryId: string;
17
- realizedPnl: number;
18
- result: 'profit' | 'loss' | 'breakeven';
19
- collateralTypes: string[];
20
- closedLongAssets: PnlCalendarAsset[];
21
- closedShortAssets: PnlCalendarAsset[];
22
- }
23
- export interface PnlCalendarDay {
24
- date: string;
25
- totalPnl: number;
26
- volume: number;
27
- positionsClosed: number;
28
- result: 'profit' | 'loss' | 'breakeven';
29
- trades: PnlCalendarTrade[];
30
- }
31
- export interface PeriodSummary {
32
- pnl: number;
33
- volume: number;
34
- winRate: number;
35
- wins: number;
36
- losses: number;
37
- totalProfit: number;
38
- totalLoss: number;
39
- }
40
- export interface PnlCalendarWeek {
41
- weekStart: string;
42
- weekEnd: string;
43
- days: PnlCalendarDay[];
44
- summary: PeriodSummary;
45
- }
46
- export interface PnlCalendarMonth {
47
- month: string;
48
- label: string;
49
- days: PnlCalendarDay[];
50
- summary: PeriodSummary;
51
- }
52
- export interface UsePnlCalendarResult {
53
- timeframe: PnlCalendarTimeframe;
54
- weeks: PnlCalendarWeek[];
55
- months: PnlCalendarMonth[];
56
- overall: PeriodSummary;
57
- isLoading: boolean;
58
- error: string | null;
59
- refetch: () => void;
60
- }
61
- export declare function usePnlCalendar(options?: PnlCalendarTimeframe | PnlCalendarOptions): UsePnlCalendarResult;
@@ -1,13 +0,0 @@
1
- import type { PnlCalendarTrade } from './usePnlCalendar';
2
- export type PnlHeatmapTimeframe = 'allTime' | '100D' | '30D' | '7D';
3
- export interface PnlHeatmapTrade extends PnlCalendarTrade {
4
- percentage: number;
5
- }
6
- export interface UsePnlHeatmapResult {
7
- timeframe: PnlHeatmapTimeframe;
8
- trades: PnlHeatmapTrade[];
9
- isLoading: boolean;
10
- error: string | null;
11
- refetch: () => void;
12
- }
13
- export declare function usePnlHeatmap(timeframe?: PnlHeatmapTimeframe): UsePnlHeatmapResult;