@pear-protocol/hyperliquid-sdk 0.0.73-beta.5 → 0.0.73-beta.7

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.
@@ -1,4 +1,4 @@
1
- import type { ApiResponse, GetEIP712MessageResponse, AuthenticateRequest, AuthenticateResponse, RefreshTokenResponse, LogoutResponse } from '../types';
1
+ import type { ApiResponse, GetEIP712MessageResponse, AuthenticateRequest, AuthenticateResponse, RefreshTokenResponse, LogoutResponse } from "../types";
2
2
  export declare function getEIP712Message(baseUrl: string, address: string, clientId: string): Promise<ApiResponse<GetEIP712MessageResponse>>;
3
3
  export declare function authenticate(baseUrl: string, body: AuthenticateRequest): Promise<ApiResponse<AuthenticateResponse>>;
4
4
  /**
package/dist/index.js CHANGED
@@ -1509,6 +1509,20 @@ const useWebData = () => {
1509
1509
  };
1510
1510
  };
1511
1511
 
1512
+ /**
1513
+ * Check if two symbols match, handling kPEPE/KPEPE variations
1514
+ * Returns true if symbols match (case-insensitive for k-prefix tokens)
1515
+ */
1516
+ function symbolsMatch(assetName, searchSymbol) {
1517
+ // Exact match
1518
+ if (assetName === searchSymbol)
1519
+ return true;
1520
+ // Try case-insensitive match for k-prefix tokens (kPEPE vs KPEPE)
1521
+ if (assetName.toUpperCase() === searchSymbol.toUpperCase()) {
1522
+ return true;
1523
+ }
1524
+ return false;
1525
+ }
1512
1526
  /**
1513
1527
  * Extracts token metadata from aggregated WebData3 contexts and AllMids data
1514
1528
  */
@@ -1529,8 +1543,9 @@ class TokenMetadataExtractor {
1529
1543
  }
1530
1544
  // Find token index in aggregated universe
1531
1545
  // For HIP3 assets, match both name AND marketPrefix
1546
+ // Uses symbolsMatch to handle kPEPE/KPEPE case variations
1532
1547
  const universeIndex = perpMetaAssets.findIndex((asset) => {
1533
- if (asset.name !== symbol)
1548
+ if (!symbolsMatch(asset.name, symbol))
1534
1549
  return false;
1535
1550
  // If marketPrefix is specified, match it; otherwise match assets without prefix
1536
1551
  if (marketPrefix) {
@@ -1549,15 +1564,20 @@ class TokenMetadataExtractor {
1549
1564
  }
1550
1565
  // Get current price - prefer assetCtx.midPx as it's already index-matched,
1551
1566
  // fall back to allMids lookup if midPx is null
1552
- const prefixedKeyColon = marketPrefix ? `${marketPrefix}:${symbol}` : null;
1567
+ const actualSymbol = universeAsset.name; // Use actual symbol from universe (handles kPEPE vs KPEPE)
1568
+ const prefixedKeyColon = marketPrefix
1569
+ ? `${marketPrefix}:${actualSymbol}`
1570
+ : null;
1553
1571
  let currentPrice = 0;
1554
1572
  // Primary source: assetCtx.midPx (already properly indexed)
1555
1573
  if (assetCtx.midPx) {
1556
1574
  currentPrice = parseFloat(assetCtx.midPx);
1557
1575
  }
1558
1576
  // Fallback: allMids lookup with multiple key formats for HIP3 markets
1577
+ // Try actual symbol from universe first, then input symbol
1559
1578
  if (!currentPrice || isNaN(currentPrice)) {
1560
1579
  const currentPriceStr = (prefixedKeyColon && allMids.mids[prefixedKeyColon]) ||
1580
+ allMids.mids[actualSymbol] ||
1561
1581
  allMids.mids[symbol];
1562
1582
  currentPrice = currentPriceStr ? parseFloat(currentPriceStr) : 0;
1563
1583
  }
@@ -1571,10 +1591,12 @@ class TokenMetadataExtractor {
1571
1591
  const markPrice = parseFloat(assetCtx.markPx);
1572
1592
  const oraclePrice = parseFloat(assetCtx.oraclePx);
1573
1593
  // Extract leverage info from activeAssetData if available
1574
- // Try prefixed key first (e.g., "xyz:TSLA"), then fall back to plain symbol
1594
+ // Try prefixed key first (e.g., "xyz:TSLA"), then actual symbol, then input symbol
1575
1595
  const activeDataKey = prefixedKeyColon && (activeAssetData === null || activeAssetData === void 0 ? void 0 : activeAssetData[prefixedKeyColon])
1576
1596
  ? prefixedKeyColon
1577
- : symbol;
1597
+ : (activeAssetData === null || activeAssetData === void 0 ? void 0 : activeAssetData[actualSymbol])
1598
+ ? actualSymbol
1599
+ : symbol;
1578
1600
  const tokenActiveData = activeAssetData === null || activeAssetData === void 0 ? void 0 : activeAssetData[activeDataKey];
1579
1601
  const leverage = tokenActiveData === null || tokenActiveData === void 0 ? void 0 : tokenActiveData.leverage;
1580
1602
  const maxTradeSzs = tokenActiveData === null || tokenActiveData === void 0 ? void 0 : tokenActiveData.maxTradeSzs;
@@ -1626,7 +1648,7 @@ class TokenMetadataExtractor {
1626
1648
  static isTokenAvailable(symbol, perpMetaAssets) {
1627
1649
  if (!perpMetaAssets)
1628
1650
  return false;
1629
- return perpMetaAssets.some((asset) => asset.name === symbol);
1651
+ return perpMetaAssets.some((asset) => symbolsMatch(asset.name, symbol));
1630
1652
  }
1631
1653
  }
1632
1654
 
@@ -5910,10 +5932,10 @@ function toApiError(error) {
5910
5932
  var _a;
5911
5933
  const axiosError = error;
5912
5934
  const payload = (axiosError && axiosError.response ? axiosError.response.data : undefined);
5913
- const message = typeof payload === 'object' && payload && 'message' in payload
5935
+ const message = typeof payload === "object" && payload && "message" in payload
5914
5936
  ? String(payload.message)
5915
- : (axiosError === null || axiosError === void 0 ? void 0 : axiosError.message) || 'Request failed';
5916
- const errField = typeof payload === 'object' && payload && 'error' in payload
5937
+ : (axiosError === null || axiosError === void 0 ? void 0 : axiosError.message) || "Request failed";
5938
+ const errField = typeof payload === "object" && payload && "error" in payload
5917
5939
  ? String(payload.error)
5918
5940
  : undefined;
5919
5941
  return {
@@ -5923,8 +5945,8 @@ function toApiError(error) {
5923
5945
  };
5924
5946
  }
5925
5947
  function joinUrl(baseUrl, path) {
5926
- const cleanBase = baseUrl.replace(/\/$/, '');
5927
- const cleanPath = path.startsWith('/') ? path : `/${path}`;
5948
+ const cleanBase = baseUrl.replace(/\/$/, "");
5949
+ const cleanPath = path.startsWith("/") ? path : `/${path}`;
5928
5950
  return `${cleanBase}${cleanPath}`;
5929
5951
  }
5930
5952
  /**
@@ -5953,7 +5975,7 @@ function addAuthInterceptors(params) {
5953
5975
  pendingRequests = [];
5954
5976
  }
5955
5977
  const isOurApiUrl = (url) => Boolean(url && url.startsWith(apiBaseUrl));
5956
- const isRefreshUrl = (url) => Boolean(url && url.startsWith(joinUrl(apiBaseUrl, '/auth/refresh')));
5978
+ const isRefreshUrl = (url) => Boolean(url && url.startsWith(joinUrl(apiBaseUrl, "/auth/refresh")));
5957
5979
  const reqId = apiClient.interceptors.request.use((config) => {
5958
5980
  var _a;
5959
5981
  try {
@@ -5961,11 +5983,12 @@ function addAuthInterceptors(params) {
5961
5983
  const token = getAccessToken();
5962
5984
  if (token) {
5963
5985
  config.headers = (_a = config.headers) !== null && _a !== void 0 ? _a : {};
5964
- (config.headers)['Authorization'] = `Bearer ${token}`;
5986
+ config.headers["Authorization"] = `Bearer ${token}`;
5965
5987
  }
5966
5988
  }
5967
5989
  }
5968
- catch (_b) {
5990
+ catch (err) {
5991
+ console.error("[Auth Interceptor] Request interceptor error:", err);
5969
5992
  }
5970
5993
  return config;
5971
5994
  });
@@ -5976,22 +5999,36 @@ function addAuthInterceptors(params) {
5976
5999
  const url = originalRequest === null || originalRequest === void 0 ? void 0 : originalRequest.url;
5977
6000
  // If not our API or not 401, just reject
5978
6001
  if (!status || status !== 401 || !isOurApiUrl(url)) {
6002
+ if (status === 401) {
6003
+ console.warn("[Auth Interceptor] 401 received but URL check failed:", {
6004
+ url,
6005
+ apiBaseUrl,
6006
+ isOurApiUrl: isOurApiUrl(url),
6007
+ });
6008
+ }
5979
6009
  return Promise.reject(error);
5980
6010
  }
6011
+ console.log("[Auth Interceptor] 401 detected, attempting token refresh for URL:", url);
5981
6012
  // If the 401 is from refresh endpoint itself -> force logout
5982
6013
  if (isRefreshUrl(url)) {
6014
+ console.warn("[Auth Interceptor] Refresh endpoint returned 401, logging out");
5983
6015
  try {
5984
6016
  await logout();
5985
6017
  }
5986
- catch (_d) { }
6018
+ catch (err) {
6019
+ console.error("[Auth Interceptor] Logout failed:", err);
6020
+ }
5987
6021
  return Promise.reject(error);
5988
6022
  }
5989
6023
  // Prevent infinite loop
5990
6024
  if (originalRequest && originalRequest._retry) {
6025
+ console.warn("[Auth Interceptor] Request already retried, logging out");
5991
6026
  try {
5992
6027
  await logout();
5993
6028
  }
5994
- catch (_e) { }
6029
+ catch (err) {
6030
+ console.error("[Auth Interceptor] Logout failed:", err);
6031
+ }
5995
6032
  return Promise.reject(error);
5996
6033
  }
5997
6034
  // Mark so we don't retry twice
@@ -6005,31 +6042,45 @@ function addAuthInterceptors(params) {
6005
6042
  if (!newToken || !originalRequest)
6006
6043
  return reject(error);
6007
6044
  originalRequest.headers = (_a = originalRequest.headers) !== null && _a !== void 0 ? _a : {};
6008
- originalRequest.headers['Authorization'] = `Bearer ${newToken}`;
6045
+ originalRequest.headers["Authorization"] =
6046
+ `Bearer ${newToken}`;
6009
6047
  resolve(apiClient.request(originalRequest));
6010
6048
  });
6011
6049
  });
6012
6050
  }
6013
6051
  isRefreshing = true;
6014
6052
  try {
6053
+ console.log("[Auth Interceptor] Refreshing tokens...");
6015
6054
  const refreshed = await refreshTokens();
6016
- const newAccessToken = (_b = (refreshed && (refreshed.accessToken || ((_a = refreshed.data) === null || _a === void 0 ? void 0 : _a.accessToken)))) !== null && _b !== void 0 ? _b : null;
6055
+ const newAccessToken = (_b = (refreshed &&
6056
+ (refreshed.accessToken || ((_a = refreshed.data) === null || _a === void 0 ? void 0 : _a.accessToken)))) !== null && _b !== void 0 ? _b : null;
6057
+ if (!newAccessToken) {
6058
+ console.error("[Auth Interceptor] Token refresh succeeded but no access token in response:", refreshed);
6059
+ }
6060
+ else {
6061
+ console.log("[Auth Interceptor] Token refresh successful");
6062
+ }
6017
6063
  resolvePendingRequests(newAccessToken);
6018
6064
  if (originalRequest) {
6019
6065
  originalRequest.headers = (_c = originalRequest.headers) !== null && _c !== void 0 ? _c : {};
6020
6066
  if (newAccessToken)
6021
- (originalRequest.headers)['Authorization'] = `Bearer ${newAccessToken}`;
6067
+ originalRequest.headers["Authorization"] =
6068
+ `Bearer ${newAccessToken}`;
6069
+ console.log("[Auth Interceptor] Retrying original request with new token");
6022
6070
  const resp = await apiClient.request(originalRequest);
6023
6071
  return resp;
6024
6072
  }
6025
6073
  return Promise.reject(error);
6026
6074
  }
6027
6075
  catch (refreshErr) {
6076
+ console.error("[Auth Interceptor] Token refresh failed:", refreshErr);
6028
6077
  resolvePendingRequests(null);
6029
6078
  try {
6030
6079
  await logout();
6031
6080
  }
6032
- catch (_f) { }
6081
+ catch (err) {
6082
+ console.error("[Auth Interceptor] Logout failed:", err);
6083
+ }
6033
6084
  return Promise.reject(refreshErr);
6034
6085
  }
6035
6086
  finally {
@@ -6040,11 +6091,15 @@ function addAuthInterceptors(params) {
6040
6091
  try {
6041
6092
  apiClient.interceptors.request.eject(reqId);
6042
6093
  }
6043
- catch (_a) { }
6094
+ catch (err) {
6095
+ console.error("[Auth Interceptor] Failed to eject request interceptor:", err);
6096
+ }
6044
6097
  try {
6045
6098
  apiClient.interceptors.response.eject(resId);
6046
6099
  }
6047
- catch (_b) { }
6100
+ catch (err) {
6101
+ console.error("[Auth Interceptor] Failed to eject response interceptor:", err);
6102
+ }
6048
6103
  };
6049
6104
  }
6050
6105
 
@@ -8046,20 +8101,34 @@ function usePortfolio() {
8046
8101
  }
8047
8102
 
8048
8103
  async function getEIP712Message(baseUrl, address, clientId) {
8049
- const url = joinUrl(baseUrl, '/auth/eip712-message');
8104
+ const url = joinUrl(baseUrl, "/auth/eip712-message");
8050
8105
  try {
8051
- const resp = await axios$1.get(url, { params: { address, clientId }, timeout: 30000 });
8052
- return { data: resp.data, status: resp.status, headers: resp.headers };
8106
+ const resp = await apiClient.get(url, {
8107
+ params: { address, clientId },
8108
+ timeout: 30000,
8109
+ });
8110
+ return {
8111
+ data: resp.data,
8112
+ status: resp.status,
8113
+ headers: resp.headers,
8114
+ };
8053
8115
  }
8054
8116
  catch (error) {
8055
8117
  throw toApiError(error);
8056
8118
  }
8057
8119
  }
8058
8120
  async function authenticate(baseUrl, body) {
8059
- const url = joinUrl(baseUrl, '/auth/login');
8121
+ const url = joinUrl(baseUrl, "/auth/login");
8060
8122
  try {
8061
- const resp = await axios$1.post(url, body, { headers: { 'Content-Type': 'application/json' }, timeout: 30000 });
8062
- return { data: resp.data, status: resp.status, headers: resp.headers };
8123
+ const resp = await apiClient.post(url, body, {
8124
+ headers: { "Content-Type": "application/json" },
8125
+ timeout: 30000,
8126
+ });
8127
+ return {
8128
+ data: resp.data,
8129
+ status: resp.status,
8130
+ headers: resp.headers,
8131
+ };
8063
8132
  }
8064
8133
  catch (error) {
8065
8134
  throw toApiError(error);
@@ -8070,7 +8139,7 @@ async function authenticate(baseUrl, body) {
8070
8139
  */
8071
8140
  async function authenticateWithPrivy(baseUrl, params) {
8072
8141
  const body = {
8073
- method: 'privy_access_token',
8142
+ method: "privy_access_token",
8074
8143
  address: params.address,
8075
8144
  clientId: params.clientId,
8076
8145
  details: { appId: params.appId, accessToken: params.accessToken },
@@ -8078,20 +8147,28 @@ async function authenticateWithPrivy(baseUrl, params) {
8078
8147
  return authenticate(baseUrl, body);
8079
8148
  }
8080
8149
  async function refreshToken(baseUrl, refreshTokenVal) {
8081
- const url = joinUrl(baseUrl, '/auth/refresh');
8150
+ const url = joinUrl(baseUrl, "/auth/refresh");
8082
8151
  try {
8083
- const resp = await axios$1.post(url, { refreshToken: refreshTokenVal }, { headers: { 'Content-Type': 'application/json' }, timeout: 30000 });
8084
- return { data: resp.data, status: resp.status, headers: resp.headers };
8152
+ const resp = await apiClient.post(url, { refreshToken: refreshTokenVal }, { headers: { "Content-Type": "application/json" }, timeout: 30000 });
8153
+ return {
8154
+ data: resp.data,
8155
+ status: resp.status,
8156
+ headers: resp.headers,
8157
+ };
8085
8158
  }
8086
8159
  catch (error) {
8087
8160
  throw toApiError(error);
8088
8161
  }
8089
8162
  }
8090
8163
  async function logout(baseUrl, refreshTokenVal) {
8091
- const url = joinUrl(baseUrl, '/auth/logout');
8164
+ const url = joinUrl(baseUrl, "/auth/logout");
8092
8165
  try {
8093
- const resp = await axios$1.post(url, { refreshToken: refreshTokenVal }, { headers: { 'Content-Type': 'application/json' }, timeout: 30000 });
8094
- return { data: resp.data, status: resp.status, headers: resp.headers };
8166
+ const resp = await apiClient.post(url, { refreshToken: refreshTokenVal }, { headers: { "Content-Type": "application/json" }, timeout: 30000 });
8167
+ return {
8168
+ data: resp.data,
8169
+ status: resp.status,
8170
+ headers: resp.headers,
8171
+ };
8095
8172
  }
8096
8173
  catch (error) {
8097
8174
  throw toApiError(error);
@@ -8119,6 +8196,7 @@ function useAuth() {
8119
8196
  return;
8120
8197
  }
8121
8198
  if (address) {
8199
+ refreshTokens();
8122
8200
  // If we already have an address in state, use it to load the session
8123
8201
  const accessTokenKey = `${address}_accessToken`;
8124
8202
  const refreshTokenKey = `${address}_refreshToken`;
@@ -1,5 +1,5 @@
1
- import type { AxiosInstance } from 'axios';
2
- import { ApiErrorResponse } from '../types';
1
+ import type { AxiosInstance } from "axios";
2
+ import { ApiErrorResponse } from "../types";
3
3
  export declare function toApiError(error: unknown): ApiErrorResponse;
4
4
  export declare function joinUrl(baseUrl: string, path: string): string;
5
5
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pear-protocol/hyperliquid-sdk",
3
- "version": "0.0.73-beta.5",
3
+ "version": "0.0.73-beta.7",
4
4
  "description": "React SDK for Pear Protocol Hyperliquid API integration",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",