@pear-protocol/hyperliquid-sdk 0.0.44 → 0.0.46

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.d.ts CHANGED
@@ -804,19 +804,6 @@ interface UsePerformanceOverlaysReturn {
804
804
  }
805
805
  declare const usePerformanceOverlays: () => UsePerformanceOverlaysReturn;
806
806
 
807
- declare function useAuth(): {
808
- readonly status: AuthStatus;
809
- readonly isAuthenticated: boolean;
810
- readonly accessToken: string | null;
811
- readonly user: UserProfile | null;
812
- readonly error: string | null;
813
- readonly getEip712: (address: string) => Promise<any>;
814
- readonly loginWithSignedMessage: (address: string, signature: string, timestamp: number) => Promise<void>;
815
- readonly loginWithPrivyToken: (address: string, appId: string, accessToken: string) => Promise<void>;
816
- readonly refreshTokens: () => Promise<any>;
817
- readonly logout: () => Promise<void>;
818
- };
819
-
820
807
  declare function useAgentWallet({ baseUrl }: UseAgentWalletOptions): {
821
808
  readonly agentWallet: AgentWalletState;
822
809
  readonly isReady: boolean;
@@ -872,8 +859,8 @@ interface CancelTwapResponseDto {
872
859
  }
873
860
  declare function cancelTwapOrder(baseUrl: string, accessToken: string, orderId: string): Promise<ApiResponse<CancelTwapResponseDto>>;
874
861
 
875
- type ExecutionType = 'MARKET' | 'LIMIT' | 'TWAP' | 'LADDER' | 'LIMIT_BTCDOM';
876
- type TpSlThresholdType = 'PERCENTAGE' | 'DOLLAR' | 'POSITION_VALUE';
862
+ type ExecutionType = "MARKET" | "LIMIT" | "TWAP" | "LADDER" | "LIMIT_BTCDOM";
863
+ type TpSlThresholdType = "PERCENTAGE" | "DOLLAR" | "POSITION_VALUE";
877
864
  interface PairAssetInput {
878
865
  asset: string;
879
866
  weight?: number;
@@ -895,7 +882,7 @@ interface CreatePositionRequestInput {
895
882
  longAssets?: PairAssetInput[];
896
883
  shortAssets?: PairAssetInput[];
897
884
  triggerValue?: number;
898
- direction?: 'MORE_THAN' | 'LESS_THAN';
885
+ direction?: "MORE_THAN" | "LESS_THAN";
899
886
  twapDuration?: number;
900
887
  twapIntervalSeconds?: number;
901
888
  randomizeExecution?: boolean;
@@ -903,10 +890,10 @@ interface CreatePositionRequestInput {
903
890
  takeProfit?: TpSlThresholdInput | null;
904
891
  stopLoss?: TpSlThresholdInput | null;
905
892
  }
906
- type PositionResponseStatus = 'SUCCESS' | 'FAILED' | 'PENDING' | 'PARTIALLY_FILLED' | 'OPEN';
893
+ type PositionResponseStatus = "SUCCESS" | "FAILED" | "PENDING" | "PARTIALLY_FILLED" | "OPEN";
907
894
  interface PositionAssetSummaryDto {
908
895
  asset: string;
909
- side: 'LONG' | 'SHORT';
896
+ side: "LONG" | "SHORT";
910
897
  size: number;
911
898
  entryRatio: number;
912
899
  usdValue: number;
@@ -925,6 +912,7 @@ interface CreatePositionResponseDto {
925
912
  /**
926
913
  * Create a position (MARKET/LIMIT/TWAP) using Pear Hyperliquid service
927
914
  * Caller should supply an accessToken from localStorage.getItem('accessToken')
915
+ * @throws MinimumPositionSizeError if any asset has less than $11 USD value
928
916
  */
929
917
  declare function createPosition(baseUrl: string, accessToken: string, payload: CreatePositionRequestInput): Promise<ApiResponse<CreatePositionResponseDto>>;
930
918
  interface UpdateRiskParametersRequestInput {
@@ -938,7 +926,7 @@ interface UpdateRiskParametersResponseDto {
938
926
  updatedAt: string;
939
927
  }
940
928
  declare function updateRiskParameters(baseUrl: string, accessToken: string, positionId: string, payload: UpdateRiskParametersRequestInput): Promise<ApiResponse<UpdateRiskParametersResponseDto>>;
941
- type CloseExecutionType = 'MARKET' | 'TWAP';
929
+ type CloseExecutionType = "MARKET" | "TWAP";
942
930
  interface ClosePositionRequestInput {
943
931
  executionType: CloseExecutionType;
944
932
  twapDuration?: number;
@@ -961,8 +949,8 @@ interface CloseAllPositionsResponseDto {
961
949
  results: CloseAllPositionsResultDto[];
962
950
  }
963
951
  declare function closeAllPositions(baseUrl: string, accessToken: string, payload: ClosePositionRequestInput): Promise<ApiResponse<CloseAllPositionsResponseDto>>;
964
- type AdjustExecutionType = 'MARKET' | 'LIMIT';
965
- type PositionAdjustmentType = 'REDUCE' | 'INCREASE';
952
+ type AdjustExecutionType = "MARKET" | "LIMIT";
953
+ type PositionAdjustmentType = "REDUCE" | "INCREASE";
966
954
  interface AdjustPositionRequestInput {
967
955
  adjustmentType: PositionAdjustmentType;
968
956
  adjustmentSize: number;
@@ -1033,6 +1021,58 @@ declare function useWatchlist(): {
1033
1021
  readonly toggle: (longAssets: WatchlistAssetDto[], shortAssets: WatchlistAssetDto[]) => Promise<ApiResponse<ToggleWatchlistResponseDto>>;
1034
1022
  };
1035
1023
 
1024
+ type PortfolioInterval = '1d' | '1w' | '1m' | '1y' | 'all';
1025
+ interface PortfolioBucketDto {
1026
+ periodStart: string;
1027
+ periodEnd: string;
1028
+ volume: number;
1029
+ openInterest: number;
1030
+ winningTradesCount: number;
1031
+ winningTradesUsd: number;
1032
+ losingTradesCount: number;
1033
+ losingTradesUsd: number;
1034
+ }
1035
+ interface PortfolioOverallDto {
1036
+ totalWinningTradesCount: number;
1037
+ totalLosingTradesCount: number;
1038
+ totalWinningUsd: number;
1039
+ totalLosingUsd: number;
1040
+ currentOpenInterest: number;
1041
+ currentTotalVolume: number;
1042
+ unrealizedPnl: number;
1043
+ totalTrades: number;
1044
+ }
1045
+ interface PortfolioIntervalsDto {
1046
+ oneDay: PortfolioBucketDto[];
1047
+ oneWeek: PortfolioBucketDto[];
1048
+ oneMonth: PortfolioBucketDto[];
1049
+ oneYear: PortfolioBucketDto[];
1050
+ all: PortfolioBucketDto[];
1051
+ }
1052
+ interface PortfolioResponseDto {
1053
+ intervals: PortfolioIntervalsDto;
1054
+ overall: PortfolioOverallDto;
1055
+ }
1056
+ /**
1057
+ * Get portfolio summary buckets and overall metrics
1058
+ * Returns bucketed volume, open interest snapshot, win/loss trade counts, and overall metrics filtered to PEAR fills (cloid LIKE 0x50454152%)
1059
+ * Caller should supply an accessToken from localStorage.getItem('accessToken')
1060
+ */
1061
+ declare function getPortfolio(baseUrl: string, accessToken: string): Promise<ApiResponse<PortfolioResponseDto>>;
1062
+
1063
+ interface UsePortfolioResult {
1064
+ data: PortfolioResponseDto | null;
1065
+ isLoading: boolean;
1066
+ error: Error | null;
1067
+ refetch: () => Promise<void>;
1068
+ }
1069
+ /**
1070
+ * Hook to fetch and manage portfolio data
1071
+ * Returns bucketed volume, open interest snapshot, win/loss trade counts,
1072
+ * and overall metrics filtered to PEAR fills (cloid LIKE 0x50454152%)
1073
+ */
1074
+ declare function usePortfolio(): UsePortfolioResult;
1075
+
1036
1076
  interface UseHyperliquidWebSocketProps {
1037
1077
  wsUrl: string;
1038
1078
  address: string | null;
@@ -1171,7 +1211,48 @@ declare function mapTradingViewIntervalToCandleInterval(interval: string): Candl
1171
1211
  */
1172
1212
  declare function mapCandleIntervalToTradingViewInterval(interval: CandleInterval): string;
1173
1213
 
1214
+ /**
1215
+ * Minimum USD value required per asset when creating a position
1216
+ */
1217
+ declare const MINIMUM_ASSET_USD_VALUE = 11;
1218
+ /**
1219
+ * Validation error for minimum position size
1220
+ */
1221
+ declare class MinimumPositionSizeError extends Error {
1222
+ assetName: string;
1223
+ assetValue: number;
1224
+ minimumRequired: number;
1225
+ constructor(assetName: string, assetValue: number, minimumRequired: number);
1226
+ }
1227
+ /**
1228
+ * Validates that each asset in a position has at least the minimum USD value
1229
+ * @param usdValue Total USD value for the position
1230
+ * @param longAssets Array of long assets with weights
1231
+ * @param shortAssets Array of short assets with weights
1232
+ * @throws MinimumPositionSizeError if any asset has less than the minimum USD value
1233
+ */
1234
+ declare function validateMinimumAssetSize(usdValue: number, longAssets?: PairAssetInput[], shortAssets?: PairAssetInput[]): void;
1235
+ /**
1236
+ * Calculates the minimum USD value required for a position based on the number of assets
1237
+ * @param longAssets Array of long assets
1238
+ * @param shortAssets Array of short assets
1239
+ * @returns The minimum total USD value required
1240
+ */
1241
+ declare function calculateMinimumPositionValue(longAssets?: PairAssetInput[], shortAssets?: PairAssetInput[]): number;
1242
+ /**
1243
+ * Validates and provides a user-friendly error message with suggestions
1244
+ * @param usdValue Total USD value for the position
1245
+ * @param longAssets Array of long assets with weights
1246
+ * @param shortAssets Array of short assets with weights
1247
+ * @returns Validation result with success flag and optional error message
1248
+ */
1249
+ declare function validatePositionSize(usdValue: number, longAssets?: PairAssetInput[], shortAssets?: PairAssetInput[]): {
1250
+ valid: boolean;
1251
+ error?: string;
1252
+ minimumRequired?: number;
1253
+ };
1254
+
1174
1255
  declare const useMarketData: any;
1175
1256
 
1176
- export { AccountSummaryCalculator, AuthStatus, ConflictDetector, PearHyperliquidProvider, TokenMetadataExtractor, adjustOrder, adjustPosition, calculateWeightedRatio, cancelOrder, cancelTwap, cancelTwapOrder, closeAllPositions, closePosition, computeBasketCandles, createCandleLookups, createPosition, getCompleteTimestamps, mapCandleIntervalToTradingViewInterval, mapTradingViewIntervalToCandleInterval, markNotificationReadById, markNotificationsRead, toggleWatchlist, updateRiskParameters, useAccountSummary, useActiveBaskets, useAddress, useAgentWallet, useAuth, useAutoSyncFills, useBasketCandles, useFindBasket, useHighlightedBaskets, useHistoricalPriceData, useHistoricalPriceDataStore, useHyperliquidNativeWebSocket, useHyperliquidWebSocket, useMarketData, useMarketDataPayload, useNotifications, useOpenOrders, useOrders, usePearAgentWallet, usePearAuth, usePearHyperliquid, usePerformanceOverlays, usePosition, useTokenSelectionMetadata, useTopGainers, useTopLosers, useTradeHistories, useTwap, useUserSelection, useWatchlist, useWatchlistBaskets, useWebData };
1177
- export type { AccountSummaryResponseDto, ActiveAssetGroupItem, ActiveAssetsResponse, AdjustExecutionType, AdjustOrderRequestInput, AdjustOrderResponseDto, AdjustPositionRequestInput, AdjustPositionResponseDto, AgentWalletDto, AgentWalletState, ApiErrorResponse, ApiResponse, AssetCtx, AssetInformationDetail, AssetMarketData, AssetPosition, AutoSyncFillsOptions, AutoSyncFillsState, BalanceSummaryDto, CancelOrderResponseDto, CancelTwapResponseDto, CandleChartData, CandleData, CandleInterval, CandleSnapshotRequest, ClearinghouseState, CloseAllPositionsResponseDto, CloseAllPositionsResultDto, CloseExecutionType, ClosePositionRequestInput, ClosePositionResponseDto, CreatePositionRequestInput, CreatePositionResponseDto, CrossMarginSummaryDto, CumFundingDto, ExecutionType, HLWebSocketResponse, HistoricalRange, LadderConfigInput, MarginSummaryDto, NotificationCategory, NotificationDto, OpenLimitOrderDto, OpenPositionDto, OrderAssetDto, OrderStatus, PairAssetDto, PairAssetInput, PerformanceOverlay, PositionAdjustmentType, PositionAssetDetailDto, PositionAssetSummaryDto, PositionResponseStatus, RealtimeBar, RealtimeBarsCallback, ToggleWatchlistResponseDto, TokenConflict, TokenHistoricalPriceData, TokenMetadata, TokenSelection, TpSlThresholdInput, TpSlThresholdType, TradeHistoryAssetDataDto, TradeHistoryDataDto, TwapChunkStatusDto, TwapMonitoringDto, UniverseAsset, UpdateRiskParametersRequestInput, UpdateRiskParametersResponseDto, UseAgentWalletOptions, UseAuthOptions, UseBasketCandlesReturn, UseHistoricalPriceDataReturn, UseNotificationsResult, UsePerformanceOverlaysReturn, UseTokenSelectionMetadataReturn, UserProfile, UserSelectionState, WatchlistItemDto, WebData2Response, WebSocketAckResponse, WebSocketChannel, WebSocketConnectionState, WebSocketDataMessage, WebSocketMessage, WebSocketSubscribeMessage, WsAllMidsData };
1257
+ export { AccountSummaryCalculator, AuthStatus, ConflictDetector, MINIMUM_ASSET_USD_VALUE, MinimumPositionSizeError, PearHyperliquidProvider, TokenMetadataExtractor, adjustOrder, adjustPosition, calculateMinimumPositionValue, calculateWeightedRatio, cancelOrder, cancelTwap, cancelTwapOrder, closeAllPositions, closePosition, computeBasketCandles, createCandleLookups, createPosition, getCompleteTimestamps, getPortfolio, mapCandleIntervalToTradingViewInterval, mapTradingViewIntervalToCandleInterval, markNotificationReadById, markNotificationsRead, toggleWatchlist, updateRiskParameters, useAccountSummary, useActiveBaskets, useAddress, useAgentWallet, useAutoSyncFills, useBasketCandles, useFindBasket, useHighlightedBaskets, useHistoricalPriceData, useHistoricalPriceDataStore, useHyperliquidNativeWebSocket, useHyperliquidWebSocket, useMarketData, useMarketDataPayload, useNotifications, useOpenOrders, useOrders, usePearAgentWallet, usePearAuth, usePearHyperliquid, usePerformanceOverlays, usePortfolio, usePosition, useTokenSelectionMetadata, useTopGainers, useTopLosers, useTradeHistories, useTwap, useUserSelection, useWatchlist, useWatchlistBaskets, useWebData, validateMinimumAssetSize, validatePositionSize };
1258
+ export type { AccountSummaryResponseDto, ActiveAssetGroupItem, ActiveAssetsResponse, AdjustExecutionType, AdjustOrderRequestInput, AdjustOrderResponseDto, AdjustPositionRequestInput, AdjustPositionResponseDto, AgentWalletDto, AgentWalletState, ApiErrorResponse, ApiResponse, AssetCtx, AssetInformationDetail, AssetMarketData, AssetPosition, AutoSyncFillsOptions, AutoSyncFillsState, BalanceSummaryDto, CancelOrderResponseDto, CancelTwapResponseDto, CandleChartData, CandleData, CandleInterval, CandleSnapshotRequest, ClearinghouseState, CloseAllPositionsResponseDto, CloseAllPositionsResultDto, CloseExecutionType, ClosePositionRequestInput, ClosePositionResponseDto, CreatePositionRequestInput, CreatePositionResponseDto, CrossMarginSummaryDto, CumFundingDto, ExecutionType, HLWebSocketResponse, HistoricalRange, LadderConfigInput, MarginSummaryDto, NotificationCategory, NotificationDto, OpenLimitOrderDto, OpenPositionDto, OrderAssetDto, OrderStatus, PairAssetDto, PairAssetInput, PerformanceOverlay, PortfolioBucketDto, PortfolioInterval, PortfolioIntervalsDto, PortfolioOverallDto, PortfolioResponseDto, PositionAdjustmentType, PositionAssetDetailDto, PositionAssetSummaryDto, PositionResponseStatus, RealtimeBar, RealtimeBarsCallback, ToggleWatchlistResponseDto, TokenConflict, TokenHistoricalPriceData, TokenMetadata, TokenSelection, TpSlThresholdInput, TpSlThresholdType, TradeHistoryAssetDataDto, TradeHistoryDataDto, TwapChunkStatusDto, TwapMonitoringDto, UniverseAsset, UpdateRiskParametersRequestInput, UpdateRiskParametersResponseDto, UseAgentWalletOptions, UseAuthOptions, UseBasketCandlesReturn, UseHistoricalPriceDataReturn, UseNotificationsResult, UsePerformanceOverlaysReturn, UsePortfolioResult, UseTokenSelectionMetadataReturn, UserProfile, UserSelectionState, WatchlistItemDto, WebData2Response, WebSocketAckResponse, WebSocketChannel, WebSocketConnectionState, WebSocketDataMessage, WebSocketMessage, WebSocketSubscribeMessage, WsAllMidsData };
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import React, { useState, useEffect, useMemo, useRef, useCallback, useContext, createContext } from 'react';
1
+ import require$$0, { useState, useEffect, useMemo, useRef, useCallback, useContext, createContext } from 'react';
2
2
  import require$$1 from 'react-dom';
3
3
  import { create } from 'zustand';
4
4
 
@@ -27,7 +27,7 @@ var hasRequiredReactJsxRuntime_production_min;
27
27
  function requireReactJsxRuntime_production_min () {
28
28
  if (hasRequiredReactJsxRuntime_production_min) return reactJsxRuntime_production_min;
29
29
  hasRequiredReactJsxRuntime_production_min = 1;
30
- var f=React,k=Symbol.for("react.element"),l=Symbol.for("react.fragment"),m=Object.prototype.hasOwnProperty,n=f.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,p={key:!0,ref:!0,__self:!0,__source:!0};
30
+ var f=require$$0,k=Symbol.for("react.element"),l=Symbol.for("react.fragment"),m=Object.prototype.hasOwnProperty,n=f.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,p={key:!0,ref:!0,__self:!0,__source:!0};
31
31
  function q(c,a,g){var b,d={},e=null,h=null;void 0!==g&&(e=""+g);void 0!==a.key&&(e=""+a.key);void 0!==a.ref&&(h=a.ref);for(b in a)m.call(a,b)&&!p.hasOwnProperty(b)&&(d[b]=a[b]);if(c&&c.defaultProps)for(b in a=c.defaultProps,a)void 0===d[b]&&(d[b]=a[b]);return {$$typeof:k,type:c,key:e,ref:h,props:d,_owner:n.current}}reactJsxRuntime_production_min.Fragment=l;reactJsxRuntime_production_min.jsx=q;reactJsxRuntime_production_min.jsxs=q;
32
32
  return reactJsxRuntime_production_min;
33
33
  }
@@ -53,7 +53,7 @@ function requireReactJsxRuntime_development () {
53
53
  if (process.env.NODE_ENV !== "production") {
54
54
  (function() {
55
55
 
56
- var React$1 = React;
56
+ var React = require$$0;
57
57
 
58
58
  // ATTENTION
59
59
  // When adding new symbols to this file,
@@ -88,7 +88,7 @@ function requireReactJsxRuntime_development () {
88
88
  return null;
89
89
  }
90
90
 
91
- var ReactSharedInternals = React$1.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
91
+ var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
92
92
 
93
93
  function error(format) {
94
94
  {
@@ -2142,7 +2142,7 @@ var __importDefault = (commonjsGlobal && commonjsGlobal.__importDefault) || func
2142
2142
  };
2143
2143
  Object.defineProperty(useWebsocket, "__esModule", { value: true });
2144
2144
  useWebsocket.useWebSocket = void 0;
2145
- var react_1$2 = React;
2145
+ var react_1$2 = require$$0;
2146
2146
  var react_dom_1 = require$$1;
2147
2147
  var constants_1$2 = constants;
2148
2148
  var create_or_join_1 = createOrJoin;
@@ -2308,7 +2308,7 @@ var __assign$1 = (commonjsGlobal && commonjsGlobal.__assign) || function () {
2308
2308
  };
2309
2309
  Object.defineProperty(useSocketIo, "__esModule", { value: true });
2310
2310
  useSocketIo.useSocketIO = void 0;
2311
- var react_1$1 = React;
2311
+ var react_1$1 = require$$0;
2312
2312
  var use_websocket_1$1 = useWebsocket;
2313
2313
  var constants_1$1 = constants;
2314
2314
  var emptyEvent = {
@@ -2377,7 +2377,7 @@ var __rest = (commonjsGlobal && commonjsGlobal.__rest) || function (s, e) {
2377
2377
  };
2378
2378
  Object.defineProperty(useEventSource$1, "__esModule", { value: true });
2379
2379
  useEventSource$1.useEventSource = void 0;
2380
- var react_1 = React;
2380
+ var react_1 = require$$0;
2381
2381
  var use_websocket_1 = useWebsocket;
2382
2382
  var constants_1 = constants;
2383
2383
  var useEventSource = function (url, _a, connect) {
@@ -8234,23 +8234,6 @@ const usePerformanceOverlays = () => {
8234
8234
  };
8235
8235
  };
8236
8236
 
8237
- // Refactored to read auth state/actions from Provider context
8238
- function useAuth() {
8239
- const ctx = usePearHyperliquid();
8240
- return {
8241
- status: ctx.authStatus,
8242
- isAuthenticated: ctx.isAuthenticated,
8243
- accessToken: ctx.accessToken,
8244
- user: ctx.user,
8245
- error: ctx.authError,
8246
- getEip712: ctx.getEip712,
8247
- loginWithSignedMessage: ctx.loginWithSignedMessage,
8248
- loginWithPrivyToken: ctx.loginWithPrivyToken,
8249
- refreshTokens: ctx.refreshTokens,
8250
- logout: ctx.logout,
8251
- };
8252
- }
8253
-
8254
8237
  /**
8255
8238
  * Sync external fills into Pear Hyperliquid service (POST /sync/fills)
8256
8239
  */
@@ -8364,15 +8347,109 @@ function useAutoSyncFills(options) {
8364
8347
  };
8365
8348
  }
8366
8349
 
8350
+ /**
8351
+ * Minimum USD value required per asset when creating a position
8352
+ */
8353
+ const MINIMUM_ASSET_USD_VALUE = 11;
8354
+ /**
8355
+ * Validation error for minimum position size
8356
+ */
8357
+ class MinimumPositionSizeError extends Error {
8358
+ constructor(assetName, assetValue, minimumRequired) {
8359
+ super(`Asset "${assetName}" has a USD value of $${assetValue.toFixed(2)}, which is below the minimum required value of $${minimumRequired.toFixed(2)}`);
8360
+ this.assetName = assetName;
8361
+ this.assetValue = assetValue;
8362
+ this.minimumRequired = minimumRequired;
8363
+ this.name = "MinimumPositionSizeError";
8364
+ }
8365
+ }
8366
+ /**
8367
+ * Validates that each asset in a position has at least the minimum USD value
8368
+ * @param usdValue Total USD value for the position
8369
+ * @param longAssets Array of long assets with weights
8370
+ * @param shortAssets Array of short assets with weights
8371
+ * @throws MinimumPositionSizeError if any asset has less than the minimum USD value
8372
+ */
8373
+ function validateMinimumAssetSize(usdValue, longAssets, shortAssets) {
8374
+ var _a;
8375
+ const allAssets = [...(longAssets || []), ...(shortAssets || [])];
8376
+ if (allAssets.length === 0) {
8377
+ return; // No assets to validate
8378
+ }
8379
+ // Calculate total weight
8380
+ const totalWeight = allAssets.reduce((sum, asset) => { var _a; return sum + ((_a = asset.weight) !== null && _a !== void 0 ? _a : 0); }, 0);
8381
+ // If weights are not provided or sum to 0, assume equal distribution
8382
+ const hasWeights = totalWeight > 0;
8383
+ const equalWeight = hasWeights ? 0 : 1 / allAssets.length;
8384
+ // Validate each asset
8385
+ for (const asset of allAssets) {
8386
+ const weight = hasWeights ? (_a = asset.weight) !== null && _a !== void 0 ? _a : 0 : equalWeight;
8387
+ const assetUsdValue = usdValue * weight;
8388
+ if (assetUsdValue < MINIMUM_ASSET_USD_VALUE) {
8389
+ throw new MinimumPositionSizeError(asset.asset, assetUsdValue, MINIMUM_ASSET_USD_VALUE);
8390
+ }
8391
+ }
8392
+ }
8393
+ /**
8394
+ * Calculates the minimum USD value required for a position based on the number of assets
8395
+ * @param longAssets Array of long assets
8396
+ * @param shortAssets Array of short assets
8397
+ * @returns The minimum total USD value required
8398
+ */
8399
+ function calculateMinimumPositionValue(longAssets, shortAssets) {
8400
+ const totalAssets = ((longAssets === null || longAssets === void 0 ? void 0 : longAssets.length) || 0) + ((shortAssets === null || shortAssets === void 0 ? void 0 : shortAssets.length) || 0);
8401
+ if (totalAssets === 0) {
8402
+ return 0;
8403
+ }
8404
+ return MINIMUM_ASSET_USD_VALUE * totalAssets;
8405
+ }
8406
+ /**
8407
+ * Validates and provides a user-friendly error message with suggestions
8408
+ * @param usdValue Total USD value for the position
8409
+ * @param longAssets Array of long assets with weights
8410
+ * @param shortAssets Array of short assets with weights
8411
+ * @returns Validation result with success flag and optional error message
8412
+ */
8413
+ function validatePositionSize(usdValue, longAssets, shortAssets) {
8414
+ try {
8415
+ validateMinimumAssetSize(usdValue, longAssets, shortAssets);
8416
+ return { valid: true };
8417
+ }
8418
+ catch (error) {
8419
+ if (error instanceof MinimumPositionSizeError) {
8420
+ const minimumRequired = calculateMinimumPositionValue(longAssets, shortAssets);
8421
+ return {
8422
+ valid: false,
8423
+ error: error.message,
8424
+ minimumRequired,
8425
+ };
8426
+ }
8427
+ throw error;
8428
+ }
8429
+ }
8430
+
8367
8431
  /**
8368
8432
  * Create a position (MARKET/LIMIT/TWAP) using Pear Hyperliquid service
8369
8433
  * Caller should supply an accessToken from localStorage.getItem('accessToken')
8434
+ * @throws MinimumPositionSizeError if any asset has less than $11 USD value
8370
8435
  */
8371
8436
  async function createPosition(baseUrl, accessToken, payload) {
8372
- const url = joinUrl(baseUrl, '/positions');
8437
+ // Validate minimum asset size before creating position
8438
+ validateMinimumAssetSize(payload.usdValue, payload.longAssets, payload.shortAssets);
8439
+ const url = joinUrl(baseUrl, "/positions");
8373
8440
  try {
8374
- const resp = await axios$1.post(url, payload, { headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${accessToken}` }, timeout: 60000 });
8375
- return { data: resp.data, status: resp.status, headers: resp.headers };
8441
+ const resp = await axios$1.post(url, payload, {
8442
+ headers: {
8443
+ "Content-Type": "application/json",
8444
+ Authorization: `Bearer ${accessToken}`,
8445
+ },
8446
+ timeout: 60000,
8447
+ });
8448
+ return {
8449
+ data: resp.data,
8450
+ status: resp.status,
8451
+ headers: resp.headers,
8452
+ };
8376
8453
  }
8377
8454
  catch (error) {
8378
8455
  throw toApiError(error);
@@ -8381,8 +8458,18 @@ async function createPosition(baseUrl, accessToken, payload) {
8381
8458
  async function updateRiskParameters(baseUrl, accessToken, positionId, payload) {
8382
8459
  const url = joinUrl(baseUrl, `/positions/${positionId}/riskParameters`);
8383
8460
  try {
8384
- const resp = await axios$1.put(url, payload, { headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${accessToken}` }, timeout: 60000 });
8385
- return { data: resp.data, status: resp.status, headers: resp.headers };
8461
+ const resp = await axios$1.put(url, payload, {
8462
+ headers: {
8463
+ "Content-Type": "application/json",
8464
+ Authorization: `Bearer ${accessToken}`,
8465
+ },
8466
+ timeout: 60000,
8467
+ });
8468
+ return {
8469
+ data: resp.data,
8470
+ status: resp.status,
8471
+ headers: resp.headers,
8472
+ };
8386
8473
  }
8387
8474
  catch (error) {
8388
8475
  throw toApiError(error);
@@ -8391,8 +8478,18 @@ async function updateRiskParameters(baseUrl, accessToken, positionId, payload) {
8391
8478
  async function closePosition(baseUrl, accessToken, positionId, payload) {
8392
8479
  const url = joinUrl(baseUrl, `/positions/${positionId}/close`);
8393
8480
  try {
8394
- const resp = await axios$1.post(url, payload, { headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${accessToken}` }, timeout: 60000 });
8395
- return { data: resp.data, status: resp.status, headers: resp.headers };
8481
+ const resp = await axios$1.post(url, payload, {
8482
+ headers: {
8483
+ "Content-Type": "application/json",
8484
+ Authorization: `Bearer ${accessToken}`,
8485
+ },
8486
+ timeout: 60000,
8487
+ });
8488
+ return {
8489
+ data: resp.data,
8490
+ status: resp.status,
8491
+ headers: resp.headers,
8492
+ };
8396
8493
  }
8397
8494
  catch (error) {
8398
8495
  throw toApiError(error);
@@ -8401,8 +8498,18 @@ async function closePosition(baseUrl, accessToken, positionId, payload) {
8401
8498
  async function closeAllPositions(baseUrl, accessToken, payload) {
8402
8499
  const url = joinUrl(baseUrl, `/positions/close-all`);
8403
8500
  try {
8404
- const resp = await axios$1.post(url, payload, { headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${accessToken}` }, timeout: 60000 });
8405
- return { data: resp.data, status: resp.status, headers: resp.headers };
8501
+ const resp = await axios$1.post(url, payload, {
8502
+ headers: {
8503
+ "Content-Type": "application/json",
8504
+ Authorization: `Bearer ${accessToken}`,
8505
+ },
8506
+ timeout: 60000,
8507
+ });
8508
+ return {
8509
+ data: resp.data,
8510
+ status: resp.status,
8511
+ headers: resp.headers,
8512
+ };
8406
8513
  }
8407
8514
  catch (error) {
8408
8515
  throw toApiError(error);
@@ -8411,8 +8518,18 @@ async function closeAllPositions(baseUrl, accessToken, payload) {
8411
8518
  async function adjustPosition(baseUrl, accessToken, positionId, payload) {
8412
8519
  const url = joinUrl(baseUrl, `/positions/${positionId}/adjust`);
8413
8520
  try {
8414
- const resp = await axios$1.post(url, payload, { headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${accessToken}` }, timeout: 60000 });
8415
- return { data: resp.data, status: resp.status, headers: resp.headers };
8521
+ const resp = await axios$1.post(url, payload, {
8522
+ headers: {
8523
+ "Content-Type": "application/json",
8524
+ Authorization: `Bearer ${accessToken}`,
8525
+ },
8526
+ timeout: 60000,
8527
+ });
8528
+ return {
8529
+ data: resp.data,
8530
+ status: resp.status,
8531
+ headers: resp.headers,
8532
+ };
8416
8533
  }
8417
8534
  catch (error) {
8418
8535
  throw toApiError(error);
@@ -8423,8 +8540,18 @@ async function adjustPosition(baseUrl, accessToken, positionId, payload) {
8423
8540
  async function cancelTwap(baseUrl, accessToken, orderId) {
8424
8541
  const url = joinUrl(baseUrl, `/orders/${orderId}/twap/cancel`);
8425
8542
  try {
8426
- const resp = await axios$1.post(url, {}, { headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${accessToken}` }, timeout: 60000 });
8427
- return { data: resp.data, status: resp.status, headers: resp.headers };
8543
+ const resp = await axios$1.post(url, {}, {
8544
+ headers: {
8545
+ "Content-Type": "application/json",
8546
+ Authorization: `Bearer ${accessToken}`,
8547
+ },
8548
+ timeout: 60000,
8549
+ });
8550
+ return {
8551
+ data: resp.data,
8552
+ status: resp.status,
8553
+ headers: resp.headers,
8554
+ };
8428
8555
  }
8429
8556
  catch (error) {
8430
8557
  throw toApiError(error);
@@ -8827,6 +8954,63 @@ function useWatchlist() {
8827
8954
  return { watchlists: watchlists !== null && watchlists !== void 0 ? watchlists : null, isLoading, toggle };
8828
8955
  }
8829
8956
 
8957
+ /**
8958
+ * Get portfolio summary buckets and overall metrics
8959
+ * Returns bucketed volume, open interest snapshot, win/loss trade counts, and overall metrics filtered to PEAR fills (cloid LIKE 0x50454152%)
8960
+ * Caller should supply an accessToken from localStorage.getItem('accessToken')
8961
+ */
8962
+ async function getPortfolio(baseUrl, accessToken) {
8963
+ const url = joinUrl(baseUrl, '/portfolio');
8964
+ try {
8965
+ const resp = await axios$1.get(url, { headers: { Authorization: `Bearer ${accessToken}` }, timeout: 60000 });
8966
+ return { data: resp.data, status: resp.status, headers: resp.headers };
8967
+ }
8968
+ catch (error) {
8969
+ throw toApiError(error);
8970
+ }
8971
+ }
8972
+
8973
+ /**
8974
+ * Hook to fetch and manage portfolio data
8975
+ * Returns bucketed volume, open interest snapshot, win/loss trade counts,
8976
+ * and overall metrics filtered to PEAR fills (cloid LIKE 0x50454152%)
8977
+ */
8978
+ function usePortfolio() {
8979
+ const context = useContext(PearHyperliquidContext);
8980
+ if (!context) {
8981
+ throw new Error('usePortfolio must be used within a PearHyperliquidProvider');
8982
+ }
8983
+ const { apiBaseUrl, accessToken, isAuthenticated } = context;
8984
+ const [data, setData] = useState(null);
8985
+ const [isLoading, setIsLoading] = useState(false);
8986
+ const [error, setError] = useState(null);
8987
+ const fetchPortfolio = useCallback(async () => {
8988
+ if (!isAuthenticated || !accessToken) {
8989
+ setError(new Error('Not authenticated'));
8990
+ return;
8991
+ }
8992
+ setIsLoading(true);
8993
+ setError(null);
8994
+ try {
8995
+ const response = await getPortfolio(apiBaseUrl, accessToken);
8996
+ setData(response.data);
8997
+ }
8998
+ catch (err) {
8999
+ setError(err instanceof Error ? err : new Error('Failed to fetch portfolio'));
9000
+ setData(null);
9001
+ }
9002
+ finally {
9003
+ setIsLoading(false);
9004
+ }
9005
+ }, [apiBaseUrl, accessToken, isAuthenticated]);
9006
+ return {
9007
+ data,
9008
+ isLoading,
9009
+ error,
9010
+ refetch: fetchPortfolio,
9011
+ };
9012
+ }
9013
+
8830
9014
  const PearHyperliquidContext = createContext(undefined);
8831
9015
  /**
8832
9016
  * React Provider for PearHyperliquidClient
@@ -8850,7 +9034,7 @@ const PearHyperliquidProvider = ({ children, apiBaseUrl = 'https://hl-v2.pearpro
8850
9034
  const [accessToken, setAccessToken] = useState(null);
8851
9035
  const isAuthenticated = useMemo(() => !!accessToken, [accessToken]);
8852
9036
  // Hydrate from existing token
8853
- React.useEffect(() => {
9037
+ useEffect(() => {
8854
9038
  const access = localStorage.getItem('accessToken');
8855
9039
  if (access) {
8856
9040
  try {
@@ -8867,11 +9051,11 @@ const PearHyperliquidProvider = ({ children, apiBaseUrl = 'https://hl-v2.pearpro
8867
9051
  }
8868
9052
  }
8869
9053
  }, [clientId]);
8870
- const getEip712 = React.useCallback(async (address) => {
9054
+ const getEip712 = useCallback(async (address) => {
8871
9055
  const { data } = await getEIP712Message(apiBaseUrl, address, clientId);
8872
9056
  return data;
8873
9057
  }, [apiBaseUrl, clientId]);
8874
- const loginWithSignedMessage = React.useCallback(async (address, signature, timestamp) => {
9058
+ const loginWithSignedMessage = useCallback(async (address, signature, timestamp) => {
8875
9059
  setAuthError(null);
8876
9060
  setAuthStatus(AuthStatus.Authenticating);
8877
9061
  try {
@@ -8887,6 +9071,7 @@ const PearHyperliquidProvider = ({ children, apiBaseUrl = 'https://hl-v2.pearpro
8887
9071
  const lower = data.address.toLowerCase();
8888
9072
  setUser({ userId: lower, address: lower, appId: clientId });
8889
9073
  setAuthStatus(AuthStatus.Authenticated);
9074
+ setAddress(lower);
8890
9075
  }
8891
9076
  catch (e) {
8892
9077
  setAuthError((e === null || e === void 0 ? void 0 : e.message) || 'Authentication failed');
@@ -8894,7 +9079,7 @@ const PearHyperliquidProvider = ({ children, apiBaseUrl = 'https://hl-v2.pearpro
8894
9079
  throw e;
8895
9080
  }
8896
9081
  }, [apiBaseUrl, clientId]);
8897
- const refreshTokens = React.useCallback(async () => {
9082
+ const refreshTokens = useCallback(async () => {
8898
9083
  const refresh = localStorage.getItem('refreshToken');
8899
9084
  if (!refresh)
8900
9085
  throw new Error('No refresh token');
@@ -8904,7 +9089,7 @@ const PearHyperliquidProvider = ({ children, apiBaseUrl = 'https://hl-v2.pearpro
8904
9089
  setAccessToken(data.accessToken);
8905
9090
  return data;
8906
9091
  }, [apiBaseUrl]);
8907
- const loginWithPrivyToken = React.useCallback(async (address, appId, privyAccessToken) => {
9092
+ const loginWithPrivyToken = useCallback(async (address, appId, privyAccessToken) => {
8908
9093
  setAuthError(null);
8909
9094
  setAuthStatus(AuthStatus.Authenticating);
8910
9095
  try {
@@ -8915,6 +9100,7 @@ const PearHyperliquidProvider = ({ children, apiBaseUrl = 'https://hl-v2.pearpro
8915
9100
  const lower = data.address.toLowerCase();
8916
9101
  setUser({ userId: lower, address: lower, appId: clientId });
8917
9102
  setAuthStatus(AuthStatus.Authenticated);
9103
+ setAddress(lower);
8918
9104
  }
8919
9105
  catch (e) {
8920
9106
  setAuthError((e === null || e === void 0 ? void 0 : e.message) || 'Authentication failed');
@@ -8922,7 +9108,7 @@ const PearHyperliquidProvider = ({ children, apiBaseUrl = 'https://hl-v2.pearpro
8922
9108
  throw e;
8923
9109
  }
8924
9110
  }, [apiBaseUrl, clientId]);
8925
- const logout$1 = React.useCallback(async () => {
9111
+ const logout$1 = useCallback(async () => {
8926
9112
  const refresh = localStorage.getItem('refreshToken');
8927
9113
  if (refresh) {
8928
9114
  try {
@@ -8936,6 +9122,7 @@ const PearHyperliquidProvider = ({ children, apiBaseUrl = 'https://hl-v2.pearpro
8936
9122
  setUser(null);
8937
9123
  setAuthStatus(AuthStatus.Idle);
8938
9124
  setAuthError(null);
9125
+ setAddress(null);
8939
9126
  }, [apiBaseUrl]);
8940
9127
  // Agent wallet hook
8941
9128
  const { agentWallet, isReady: isAgentWalletReady, loading: agentWalletLoading, error: agentWalletError, refreshAgentWalletStatus, createAgentWallet, notifyAgentWalletApproved, } = useAgentWallet({ baseUrl: apiBaseUrl });
@@ -9125,4 +9312,4 @@ function mapCandleIntervalToTradingViewInterval(interval) {
9125
9312
  }
9126
9313
  }
9127
9314
 
9128
- export { AccountSummaryCalculator, AuthStatus, ConflictDetector, PearHyperliquidProvider, TokenMetadataExtractor, adjustOrder, adjustPosition, calculateWeightedRatio, cancelOrder, cancelTwap, cancelTwapOrder, closeAllPositions, closePosition, computeBasketCandles, createCandleLookups, createPosition, getCompleteTimestamps, mapCandleIntervalToTradingViewInterval, mapTradingViewIntervalToCandleInterval, markNotificationReadById, markNotificationsRead, toggleWatchlist, updateRiskParameters, useAccountSummary, useActiveBaskets, useAddress, useAgentWallet, useAuth, useAutoSyncFills, useBasketCandles, useFindBasket, useHighlightedBaskets, useHistoricalPriceData, useHistoricalPriceDataStore, useHyperliquidNativeWebSocket, useHyperliquidWebSocket, useMarketData, useMarketDataPayload, useNotifications, useOpenOrders, useOrders, usePearAgentWallet, usePearAuth, usePearHyperliquid, usePerformanceOverlays, usePosition, useTokenSelectionMetadata, useTopGainers, useTopLosers, useTradeHistories, useTwap, useUserSelection, useWatchlist, useWatchlistBaskets, useWebData };
9315
+ export { AccountSummaryCalculator, AuthStatus, ConflictDetector, MINIMUM_ASSET_USD_VALUE, MinimumPositionSizeError, PearHyperliquidProvider, TokenMetadataExtractor, adjustOrder, adjustPosition, calculateMinimumPositionValue, calculateWeightedRatio, cancelOrder, cancelTwap, cancelTwapOrder, closeAllPositions, closePosition, computeBasketCandles, createCandleLookups, createPosition, getCompleteTimestamps, getPortfolio, mapCandleIntervalToTradingViewInterval, mapTradingViewIntervalToCandleInterval, markNotificationReadById, markNotificationsRead, toggleWatchlist, updateRiskParameters, useAccountSummary, useActiveBaskets, useAddress, useAgentWallet, useAutoSyncFills, useBasketCandles, useFindBasket, useHighlightedBaskets, useHistoricalPriceData, useHistoricalPriceDataStore, useHyperliquidNativeWebSocket, useHyperliquidWebSocket, useMarketData, useMarketDataPayload, useNotifications, useOpenOrders, useOrders, usePearAgentWallet, usePearAuth, usePearHyperliquid, usePerformanceOverlays, usePortfolio, usePosition, useTokenSelectionMetadata, useTopGainers, useTopLosers, useTradeHistories, useTwap, useUserSelection, useWatchlist, useWatchlistBaskets, useWebData, validateMinimumAssetSize, validatePositionSize };