@pear-protocol/hyperliquid-sdk 0.0.74 → 0.0.76
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/clients/kalshi.d.ts +87 -0
- package/dist/clients/positions.d.ts +13 -21
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/useHyperliquidUserFills.d.ts +17 -0
- package/dist/hyperliquid-websocket.d.ts +2 -1
- package/dist/index.d.ts +300 -59
- package/dist/index.js +329 -149
- package/dist/types.d.ts +123 -17
- package/dist/utils/order-helpers.d.ts +57 -0
- package/package.json +1 -1
- package/dist/hooks/useAutoSyncFills.d.ts +0 -19
package/dist/index.js
CHANGED
|
@@ -775,7 +775,7 @@ const useUserSelection$1 = create((set, get) => ({
|
|
|
775
775
|
resetToDefaults: () => set((prev) => ({ ...prev, ...DEFAULT_STATE })),
|
|
776
776
|
}));
|
|
777
777
|
|
|
778
|
-
const useHyperliquidNativeWebSocket = ({ address, enabled = true, }) => {
|
|
778
|
+
const useHyperliquidNativeWebSocket = ({ address, enabled = true, onUserFills, }) => {
|
|
779
779
|
const { setAllMids, setActiveAssetData, upsertActiveAssetData, setCandleData, deleteCandleSymbol, deleteActiveAssetData, addCandleData, setFinalAssetContexts, setFinalAtOICaps, setAggregatedClearingHouseState, setRawClearinghouseStates, } = useHyperliquidData();
|
|
780
780
|
const { setSpotState } = useUserData();
|
|
781
781
|
const { candleInterval } = useUserSelection$1();
|
|
@@ -810,6 +810,14 @@ const useHyperliquidNativeWebSocket = ({ address, enabled = true, }) => {
|
|
|
810
810
|
if ('channel' in message && 'data' in message) {
|
|
811
811
|
const response = message;
|
|
812
812
|
switch (response.channel) {
|
|
813
|
+
case 'userFills':
|
|
814
|
+
{
|
|
815
|
+
const maybePromise = onUserFills === null || onUserFills === void 0 ? void 0 : onUserFills();
|
|
816
|
+
if (maybePromise instanceof Promise) {
|
|
817
|
+
maybePromise.catch((err) => console.error('[HyperLiquid WS] userFills callback error', err));
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
break;
|
|
813
821
|
case 'webData3':
|
|
814
822
|
const webData3 = response.data;
|
|
815
823
|
// finalAssetContexts now sourced from allDexsAssetCtxs channel
|
|
@@ -950,6 +958,7 @@ const useHyperliquidNativeWebSocket = ({ address, enabled = true, }) => {
|
|
|
950
958
|
setAggregatedClearingHouseState,
|
|
951
959
|
setRawClearinghouseStates,
|
|
952
960
|
setSpotState,
|
|
961
|
+
onUserFills,
|
|
953
962
|
]);
|
|
954
963
|
const connect = useCallback(() => {
|
|
955
964
|
if (!enabled)
|
|
@@ -1067,6 +1076,14 @@ const useHyperliquidNativeWebSocket = ({ address, enabled = true, }) => {
|
|
|
1067
1076
|
},
|
|
1068
1077
|
};
|
|
1069
1078
|
sendJsonMessage(unsubscribeAllDexsClearinghouseState);
|
|
1079
|
+
const unsubscribeUserFills = {
|
|
1080
|
+
method: 'unsubscribe',
|
|
1081
|
+
subscription: {
|
|
1082
|
+
type: 'userFills',
|
|
1083
|
+
user: subscribedAddress,
|
|
1084
|
+
},
|
|
1085
|
+
};
|
|
1086
|
+
sendJsonMessage(unsubscribeUserFills);
|
|
1070
1087
|
}
|
|
1071
1088
|
const subscribeWebData3 = {
|
|
1072
1089
|
method: "subscribe",
|
|
@@ -1098,10 +1115,18 @@ const useHyperliquidNativeWebSocket = ({ address, enabled = true, }) => {
|
|
|
1098
1115
|
type: "allDexsAssetCtxs",
|
|
1099
1116
|
},
|
|
1100
1117
|
};
|
|
1118
|
+
const subscribeUserFills = {
|
|
1119
|
+
method: 'subscribe',
|
|
1120
|
+
subscription: {
|
|
1121
|
+
type: 'userFills',
|
|
1122
|
+
user: userAddress,
|
|
1123
|
+
},
|
|
1124
|
+
};
|
|
1101
1125
|
sendJsonMessage(subscribeWebData3);
|
|
1102
1126
|
sendJsonMessage(subscribeAllDexsClearinghouseState);
|
|
1103
1127
|
sendJsonMessage(subscribeAllMids);
|
|
1104
1128
|
sendJsonMessage(subscribeAllDexsAssetCtxs);
|
|
1129
|
+
sendJsonMessage(subscribeUserFills);
|
|
1105
1130
|
// Subscribe to spotState for real-time spot balances (USDH, USDC, etc.)
|
|
1106
1131
|
// Only subscribe if we have a real user address (not the default)
|
|
1107
1132
|
if (userAddress !== DEFAULT_ADDRESS) {
|
|
@@ -6783,147 +6808,6 @@ function useAgentWallet() {
|
|
|
6783
6808
|
};
|
|
6784
6809
|
}
|
|
6785
6810
|
|
|
6786
|
-
/**
|
|
6787
|
-
* Sync external fills into Pear Hyperliquid service (POST /sync/fills)
|
|
6788
|
-
*/
|
|
6789
|
-
const syncFills = async (baseUrl, payload) => {
|
|
6790
|
-
const url = joinUrl(baseUrl, '/sync/fills');
|
|
6791
|
-
try {
|
|
6792
|
-
const response = await apiClient.post(url, payload, {
|
|
6793
|
-
headers: { 'Content-Type': 'application/json' },
|
|
6794
|
-
timeout: 30000,
|
|
6795
|
-
});
|
|
6796
|
-
return { data: response.data, status: response.status, headers: response.headers };
|
|
6797
|
-
}
|
|
6798
|
-
catch (error) {
|
|
6799
|
-
throw toApiError(error);
|
|
6800
|
-
}
|
|
6801
|
-
};
|
|
6802
|
-
/**
|
|
6803
|
-
* Convenience: fetch user fills from HyperLiquid, then sync them to Pear backend
|
|
6804
|
-
*/
|
|
6805
|
-
const syncUserFillsFromHyperliquid = async (baseUrl, user, aggregateByTime = true, lastSyncAt = null, assetPositions) => {
|
|
6806
|
-
const firstStartTime = lastSyncAt ? Number(lastSyncAt) + 1 : 0;
|
|
6807
|
-
const allFills = [];
|
|
6808
|
-
const seenTids = new Set();
|
|
6809
|
-
let startTime = firstStartTime;
|
|
6810
|
-
let batchSize = 0;
|
|
6811
|
-
do {
|
|
6812
|
-
const { data: batch } = await fetchUserFillsFromHyperliquid(user, startTime, aggregateByTime);
|
|
6813
|
-
batchSize = batch.length;
|
|
6814
|
-
for (const fill of batch) {
|
|
6815
|
-
const tid = fill.tid;
|
|
6816
|
-
if (tid === undefined)
|
|
6817
|
-
continue;
|
|
6818
|
-
if (!seenTids.has(tid)) {
|
|
6819
|
-
seenTids.add(tid);
|
|
6820
|
-
allFills.push(fill);
|
|
6821
|
-
}
|
|
6822
|
-
}
|
|
6823
|
-
if (batchSize === 2000) {
|
|
6824
|
-
const last = batch[batch.length - 1];
|
|
6825
|
-
startTime = last.time;
|
|
6826
|
-
}
|
|
6827
|
-
} while (batchSize === 2000);
|
|
6828
|
-
startTime = firstStartTime;
|
|
6829
|
-
batchSize = 0;
|
|
6830
|
-
do {
|
|
6831
|
-
const { data: twapBatch } = await fetchUserTwapSliceFillsByTime(user, startTime, aggregateByTime);
|
|
6832
|
-
batchSize = twapBatch.length;
|
|
6833
|
-
for (const item of twapBatch) {
|
|
6834
|
-
const fill = item.fill;
|
|
6835
|
-
const tid = fill.tid;
|
|
6836
|
-
if (tid === undefined)
|
|
6837
|
-
continue;
|
|
6838
|
-
if (!seenTids.has(tid)) {
|
|
6839
|
-
seenTids.add(tid);
|
|
6840
|
-
allFills.push(fill);
|
|
6841
|
-
}
|
|
6842
|
-
}
|
|
6843
|
-
if (batchSize === 2000) {
|
|
6844
|
-
const last = twapBatch[twapBatch.length - 1];
|
|
6845
|
-
startTime = last.fill.time;
|
|
6846
|
-
}
|
|
6847
|
-
} while (batchSize === 2000);
|
|
6848
|
-
const sortedFills = [...allFills].sort((a, b) => Number(a.time) - Number(b.time));
|
|
6849
|
-
return syncFills(baseUrl, { user, fills: sortedFills, assetPositions });
|
|
6850
|
-
};
|
|
6851
|
-
|
|
6852
|
-
/**
|
|
6853
|
-
* Listens to address changes and periodically syncs user fills
|
|
6854
|
-
* Defaults: aggregate=true, interval=60s
|
|
6855
|
-
*/
|
|
6856
|
-
function useAutoSyncFills(options) {
|
|
6857
|
-
const { baseUrl, address, intervalMs = 60000, aggregateByTime = true, } = options;
|
|
6858
|
-
const [lastRunAt, setLastRunAt] = useState(null);
|
|
6859
|
-
const [lastResult, setLastResult] = useState(null);
|
|
6860
|
-
const [error, setError] = useState(null);
|
|
6861
|
-
const [isSyncing, setIsSyncing] = useState(false);
|
|
6862
|
-
const mountedRef = useRef(true);
|
|
6863
|
-
const runningRef = useRef(null);
|
|
6864
|
-
const lastSyncedAt = useUserData((state) => { var _a; return (_a = state.accountSummary) === null || _a === void 0 ? void 0 : _a.lastSyncedAt; });
|
|
6865
|
-
const enabled = useUserData((state) => state.isAuthenticated);
|
|
6866
|
-
useEffect(() => {
|
|
6867
|
-
mountedRef.current = true;
|
|
6868
|
-
return () => { mountedRef.current = false; };
|
|
6869
|
-
}, []);
|
|
6870
|
-
const canRun = useMemo(() => {
|
|
6871
|
-
return Boolean(enabled && address && baseUrl);
|
|
6872
|
-
}, [enabled, address, baseUrl]);
|
|
6873
|
-
const doSync = useCallback(async () => {
|
|
6874
|
-
var _a;
|
|
6875
|
-
if (!canRun)
|
|
6876
|
-
return;
|
|
6877
|
-
if (runningRef.current)
|
|
6878
|
-
return;
|
|
6879
|
-
if (!useUserData.getState().accountSummary)
|
|
6880
|
-
return;
|
|
6881
|
-
if (!((_a = useHyperliquidData.getState().aggregatedClearingHouseState) === null || _a === void 0 ? void 0 : _a.assetPositions))
|
|
6882
|
-
return;
|
|
6883
|
-
setIsSyncing(true);
|
|
6884
|
-
setError(null);
|
|
6885
|
-
const promise = (async () => {
|
|
6886
|
-
var _a;
|
|
6887
|
-
try {
|
|
6888
|
-
const { data } = await syncUserFillsFromHyperliquid(baseUrl, address, aggregateByTime, lastSyncedAt, useHyperliquidData.getState().aggregatedClearingHouseState.assetPositions);
|
|
6889
|
-
if (!mountedRef.current)
|
|
6890
|
-
return;
|
|
6891
|
-
setLastResult(data);
|
|
6892
|
-
setLastRunAt(Date.now());
|
|
6893
|
-
}
|
|
6894
|
-
catch (e) {
|
|
6895
|
-
if (!mountedRef.current)
|
|
6896
|
-
return;
|
|
6897
|
-
setError((_a = e === null || e === void 0 ? void 0 : e.message) !== null && _a !== void 0 ? _a : 'Failed to sync user fills');
|
|
6898
|
-
}
|
|
6899
|
-
finally {
|
|
6900
|
-
if (mountedRef.current)
|
|
6901
|
-
setIsSyncing(false);
|
|
6902
|
-
runningRef.current = null;
|
|
6903
|
-
}
|
|
6904
|
-
})();
|
|
6905
|
-
runningRef.current = promise;
|
|
6906
|
-
await promise;
|
|
6907
|
-
}, [canRun, baseUrl, address, aggregateByTime, lastSyncedAt]);
|
|
6908
|
-
useEffect(() => {
|
|
6909
|
-
if (!canRun)
|
|
6910
|
-
return;
|
|
6911
|
-
// Fire immediately on address change/enable
|
|
6912
|
-
void doSync();
|
|
6913
|
-
const id = setInterval(() => {
|
|
6914
|
-
void doSync();
|
|
6915
|
-
}, Math.max(1000, intervalMs));
|
|
6916
|
-
return () => clearInterval(id);
|
|
6917
|
-
}, [canRun, doSync, intervalMs]);
|
|
6918
|
-
return {
|
|
6919
|
-
lastRunAt,
|
|
6920
|
-
lastResult,
|
|
6921
|
-
error,
|
|
6922
|
-
isSyncing,
|
|
6923
|
-
triggerSync: doSync,
|
|
6924
|
-
};
|
|
6925
|
-
}
|
|
6926
|
-
|
|
6927
6811
|
/**
|
|
6928
6812
|
* Create a position (MARKET/LIMIT/TWAP) using Pear Hyperliquid service
|
|
6929
6813
|
* Authorization is derived from headers (Axios defaults or browser localStorage fallback)
|
|
@@ -6942,6 +6826,9 @@ async function createPosition(baseUrl, payload, hip3Assets) {
|
|
|
6942
6826
|
...payload,
|
|
6943
6827
|
longAssets: mapAssets(payload.longAssets),
|
|
6944
6828
|
shortAssets: mapAssets(payload.shortAssets),
|
|
6829
|
+
assetName: payload.assetName
|
|
6830
|
+
? toBackendSymbol(payload.assetName, hip3Assets)
|
|
6831
|
+
: undefined,
|
|
6945
6832
|
};
|
|
6946
6833
|
try {
|
|
6947
6834
|
const resp = await apiClient.post(url, translatedPayload, {
|
|
@@ -8353,6 +8240,138 @@ const useAllUserBalances = () => {
|
|
|
8353
8240
|
]);
|
|
8354
8241
|
};
|
|
8355
8242
|
|
|
8243
|
+
/**
|
|
8244
|
+
* Sync external fills into Pear Hyperliquid service (POST /sync/fills)
|
|
8245
|
+
*/
|
|
8246
|
+
const syncFills = async (baseUrl, payload) => {
|
|
8247
|
+
const url = joinUrl(baseUrl, '/sync/fills');
|
|
8248
|
+
try {
|
|
8249
|
+
const response = await apiClient.post(url, payload, {
|
|
8250
|
+
headers: { 'Content-Type': 'application/json' },
|
|
8251
|
+
timeout: 30000,
|
|
8252
|
+
});
|
|
8253
|
+
return { data: response.data, status: response.status, headers: response.headers };
|
|
8254
|
+
}
|
|
8255
|
+
catch (error) {
|
|
8256
|
+
throw toApiError(error);
|
|
8257
|
+
}
|
|
8258
|
+
};
|
|
8259
|
+
/**
|
|
8260
|
+
* Convenience: fetch user fills from HyperLiquid, then sync them to Pear backend
|
|
8261
|
+
*/
|
|
8262
|
+
const syncUserFillsFromHyperliquid = async (baseUrl, user, aggregateByTime = true, lastSyncAt = null, assetPositions) => {
|
|
8263
|
+
const firstStartTime = lastSyncAt ? Number(lastSyncAt) + 1 : 0;
|
|
8264
|
+
const allFills = [];
|
|
8265
|
+
const seenTids = new Set();
|
|
8266
|
+
let startTime = firstStartTime;
|
|
8267
|
+
let batchSize = 0;
|
|
8268
|
+
do {
|
|
8269
|
+
const { data: batch } = await fetchUserFillsFromHyperliquid(user, startTime, aggregateByTime);
|
|
8270
|
+
batchSize = batch.length;
|
|
8271
|
+
for (const fill of batch) {
|
|
8272
|
+
const tid = fill.tid;
|
|
8273
|
+
if (tid === undefined)
|
|
8274
|
+
continue;
|
|
8275
|
+
if (!seenTids.has(tid)) {
|
|
8276
|
+
seenTids.add(tid);
|
|
8277
|
+
allFills.push(fill);
|
|
8278
|
+
}
|
|
8279
|
+
}
|
|
8280
|
+
if (batchSize === 2000) {
|
|
8281
|
+
const last = batch[batch.length - 1];
|
|
8282
|
+
startTime = last.time;
|
|
8283
|
+
}
|
|
8284
|
+
} while (batchSize === 2000);
|
|
8285
|
+
startTime = firstStartTime;
|
|
8286
|
+
batchSize = 0;
|
|
8287
|
+
do {
|
|
8288
|
+
const { data: twapBatch } = await fetchUserTwapSliceFillsByTime(user, startTime, aggregateByTime);
|
|
8289
|
+
batchSize = twapBatch.length;
|
|
8290
|
+
for (const item of twapBatch) {
|
|
8291
|
+
const fill = item.fill;
|
|
8292
|
+
const tid = fill.tid;
|
|
8293
|
+
if (tid === undefined)
|
|
8294
|
+
continue;
|
|
8295
|
+
if (!seenTids.has(tid)) {
|
|
8296
|
+
seenTids.add(tid);
|
|
8297
|
+
allFills.push(fill);
|
|
8298
|
+
}
|
|
8299
|
+
}
|
|
8300
|
+
if (batchSize === 2000) {
|
|
8301
|
+
const last = twapBatch[twapBatch.length - 1];
|
|
8302
|
+
startTime = last.fill.time;
|
|
8303
|
+
}
|
|
8304
|
+
} while (batchSize === 2000);
|
|
8305
|
+
const sortedFills = [...allFills].sort((a, b) => Number(a.time) - Number(b.time));
|
|
8306
|
+
return syncFills(baseUrl, { user, fills: sortedFills, assetPositions });
|
|
8307
|
+
};
|
|
8308
|
+
|
|
8309
|
+
/**
|
|
8310
|
+
* Provides a callback to sync user fills whenever the native WebSocket emits a userFills event.
|
|
8311
|
+
*/
|
|
8312
|
+
function useHyperliquidUserFills(options) {
|
|
8313
|
+
const { baseUrl, address: addressOverride, aggregateByTime = true } = options;
|
|
8314
|
+
const [lastRunAt, setLastRunAt] = useState(null);
|
|
8315
|
+
const [lastResult, setLastResult] = useState(null);
|
|
8316
|
+
const [error, setError] = useState(null);
|
|
8317
|
+
const [isSyncing, setIsSyncing] = useState(false);
|
|
8318
|
+
const mountedRef = useRef(true);
|
|
8319
|
+
const runningRef = useRef(null);
|
|
8320
|
+
const enabled = useUserData((state) => state.isAuthenticated);
|
|
8321
|
+
useEffect(() => {
|
|
8322
|
+
mountedRef.current = true;
|
|
8323
|
+
return () => {
|
|
8324
|
+
mountedRef.current = false;
|
|
8325
|
+
};
|
|
8326
|
+
}, []);
|
|
8327
|
+
const handleUserFillsEvent = useCallback(async () => {
|
|
8328
|
+
var _a;
|
|
8329
|
+
const userState = useUserData.getState();
|
|
8330
|
+
const currentAddress = userState.address || addressOverride;
|
|
8331
|
+
const lastSyncedAt = (_a = userState.accountSummary) === null || _a === void 0 ? void 0 : _a.lastSyncedAt;
|
|
8332
|
+
if (!(enabled && currentAddress && baseUrl))
|
|
8333
|
+
return;
|
|
8334
|
+
if (runningRef.current)
|
|
8335
|
+
return;
|
|
8336
|
+
if (!userState.accountSummary)
|
|
8337
|
+
return;
|
|
8338
|
+
const clearinghouseState = useHyperliquidData.getState().aggregatedClearingHouseState;
|
|
8339
|
+
if (!(clearinghouseState === null || clearinghouseState === void 0 ? void 0 : clearinghouseState.assetPositions))
|
|
8340
|
+
return;
|
|
8341
|
+
setIsSyncing(true);
|
|
8342
|
+
setError(null);
|
|
8343
|
+
const promise = (async () => {
|
|
8344
|
+
var _a;
|
|
8345
|
+
try {
|
|
8346
|
+
const { data } = await syncUserFillsFromHyperliquid(baseUrl, currentAddress, aggregateByTime, lastSyncedAt, clearinghouseState.assetPositions);
|
|
8347
|
+
if (!mountedRef.current)
|
|
8348
|
+
return;
|
|
8349
|
+
setLastResult(data);
|
|
8350
|
+
setLastRunAt(Date.now());
|
|
8351
|
+
}
|
|
8352
|
+
catch (e) {
|
|
8353
|
+
if (!mountedRef.current)
|
|
8354
|
+
return;
|
|
8355
|
+
setError((_a = e === null || e === void 0 ? void 0 : e.message) !== null && _a !== void 0 ? _a : 'Failed to sync user fills');
|
|
8356
|
+
}
|
|
8357
|
+
finally {
|
|
8358
|
+
if (mountedRef.current)
|
|
8359
|
+
setIsSyncing(false);
|
|
8360
|
+
runningRef.current = null;
|
|
8361
|
+
}
|
|
8362
|
+
})();
|
|
8363
|
+
runningRef.current = promise;
|
|
8364
|
+
await promise;
|
|
8365
|
+
}, [baseUrl, addressOverride, aggregateByTime, enabled]);
|
|
8366
|
+
return {
|
|
8367
|
+
lastRunAt,
|
|
8368
|
+
lastResult,
|
|
8369
|
+
error,
|
|
8370
|
+
isSyncing,
|
|
8371
|
+
handleUserFillsEvent,
|
|
8372
|
+
};
|
|
8373
|
+
}
|
|
8374
|
+
|
|
8356
8375
|
const PearHyperliquidContext = createContext(undefined);
|
|
8357
8376
|
/**
|
|
8358
8377
|
* React Provider for PearHyperliquidClient
|
|
@@ -8366,6 +8385,11 @@ const PearHyperliquidProvider = ({ children, apiBaseUrl = 'https://hl-ui.pearpro
|
|
|
8366
8385
|
const setHip3Assets = useHyperliquidData((state) => state.setHip3Assets);
|
|
8367
8386
|
const setHip3MarketPrefixes = useHyperliquidData((state) => state.setHip3MarketPrefixes);
|
|
8368
8387
|
const websocketsEnabled = useMemo(() => Array.isArray(perpsMetaAssets) && perpsMetaAssets.length > 0, [perpsMetaAssets]);
|
|
8388
|
+
const { handleUserFillsEvent } = useHyperliquidUserFills({
|
|
8389
|
+
baseUrl: apiBaseUrl,
|
|
8390
|
+
address,
|
|
8391
|
+
aggregateByTime: true,
|
|
8392
|
+
});
|
|
8369
8393
|
const { isConnected, lastError } = useHyperliquidWebSocket({
|
|
8370
8394
|
wsUrl,
|
|
8371
8395
|
address,
|
|
@@ -8374,6 +8398,7 @@ const PearHyperliquidProvider = ({ children, apiBaseUrl = 'https://hl-ui.pearpro
|
|
|
8374
8398
|
const { isConnected: nativeIsConnected, lastError: nativeLastError } = useHyperliquidNativeWebSocket({
|
|
8375
8399
|
address,
|
|
8376
8400
|
enabled: websocketsEnabled,
|
|
8401
|
+
onUserFills: handleUserFillsEvent,
|
|
8377
8402
|
});
|
|
8378
8403
|
useEffect(() => {
|
|
8379
8404
|
if (perpsMetaAssets === null) {
|
|
@@ -8480,12 +8505,6 @@ const PearHyperliquidProvider = ({ children, apiBaseUrl = 'https://hl-ui.pearpro
|
|
|
8480
8505
|
setHip3Assets,
|
|
8481
8506
|
setHip3MarketPrefixes,
|
|
8482
8507
|
]);
|
|
8483
|
-
useAutoSyncFills({
|
|
8484
|
-
baseUrl: apiBaseUrl,
|
|
8485
|
-
address,
|
|
8486
|
-
intervalMs: 60000,
|
|
8487
|
-
aggregateByTime: true,
|
|
8488
|
-
});
|
|
8489
8508
|
const contextValue = useMemo(() => ({
|
|
8490
8509
|
// Config
|
|
8491
8510
|
clientId,
|
|
@@ -8521,6 +8540,42 @@ function usePearHyperliquid() {
|
|
|
8521
8540
|
return ctx;
|
|
8522
8541
|
}
|
|
8523
8542
|
|
|
8543
|
+
const KALSHI_API_BASE_URL = 'https://api.elections.kalshi.com/trade-api/v2';
|
|
8544
|
+
async function getKalshiMarkets(params) {
|
|
8545
|
+
const url = new URL(`${KALSHI_API_BASE_URL}/markets`);
|
|
8546
|
+
if (params) {
|
|
8547
|
+
if (params.limit !== undefined) {
|
|
8548
|
+
url.searchParams.set('limit', String(params.limit));
|
|
8549
|
+
}
|
|
8550
|
+
if (params.cursor) {
|
|
8551
|
+
url.searchParams.set('cursor', params.cursor);
|
|
8552
|
+
}
|
|
8553
|
+
if (params.tickers && params.tickers.length > 0) {
|
|
8554
|
+
url.searchParams.set('tickers', params.tickers.join(','));
|
|
8555
|
+
}
|
|
8556
|
+
if (params.event_ticker) {
|
|
8557
|
+
url.searchParams.set('event_ticker', params.event_ticker);
|
|
8558
|
+
}
|
|
8559
|
+
if (params.series_ticker) {
|
|
8560
|
+
url.searchParams.set('series_ticker', params.series_ticker);
|
|
8561
|
+
}
|
|
8562
|
+
if (params.status) {
|
|
8563
|
+
url.searchParams.set('status', params.status);
|
|
8564
|
+
}
|
|
8565
|
+
}
|
|
8566
|
+
try {
|
|
8567
|
+
const response = await axios$1.get(url.toString());
|
|
8568
|
+
return {
|
|
8569
|
+
data: response.data,
|
|
8570
|
+
status: response.status,
|
|
8571
|
+
headers: response.headers,
|
|
8572
|
+
};
|
|
8573
|
+
}
|
|
8574
|
+
catch (error) {
|
|
8575
|
+
throw toApiError(error);
|
|
8576
|
+
}
|
|
8577
|
+
}
|
|
8578
|
+
|
|
8524
8579
|
/**
|
|
8525
8580
|
* Detects conflicts between selected tokens and existing positions
|
|
8526
8581
|
*/
|
|
@@ -8608,4 +8663,129 @@ function mapCandleIntervalToTradingViewInterval(interval) {
|
|
|
8608
8663
|
}
|
|
8609
8664
|
}
|
|
8610
8665
|
|
|
8611
|
-
|
|
8666
|
+
/**
|
|
8667
|
+
* Helper functions to safely extract values from order parameters
|
|
8668
|
+
* based on the order type and parameter structure.
|
|
8669
|
+
*/
|
|
8670
|
+
/**
|
|
8671
|
+
* Get leverage from order parameters (available for Market, Trigger, Twap, Ladder orders)
|
|
8672
|
+
*/
|
|
8673
|
+
function getOrderLeverage(order) {
|
|
8674
|
+
const p = order.parameters;
|
|
8675
|
+
if ('leverage' in p && p.leverage !== undefined) {
|
|
8676
|
+
return p.leverage;
|
|
8677
|
+
}
|
|
8678
|
+
return undefined;
|
|
8679
|
+
}
|
|
8680
|
+
/**
|
|
8681
|
+
* Get USD value from order parameters (available for Market, Trigger, Twap, Ladder orders)
|
|
8682
|
+
*/
|
|
8683
|
+
function getOrderUsdValue(order) {
|
|
8684
|
+
const p = order.parameters;
|
|
8685
|
+
if ('usdValue' in p) {
|
|
8686
|
+
return p.usdValue;
|
|
8687
|
+
}
|
|
8688
|
+
return undefined;
|
|
8689
|
+
}
|
|
8690
|
+
/**
|
|
8691
|
+
* Get trigger value from order parameters (available for TP/SL and Trigger orders)
|
|
8692
|
+
*/
|
|
8693
|
+
function getOrderTriggerValue(order) {
|
|
8694
|
+
const p = order.parameters;
|
|
8695
|
+
if ('triggerValue' in p) {
|
|
8696
|
+
return p.triggerValue;
|
|
8697
|
+
}
|
|
8698
|
+
return undefined;
|
|
8699
|
+
}
|
|
8700
|
+
/**
|
|
8701
|
+
* Get TP/SL trigger type from order parameters (only for TP/SL orders)
|
|
8702
|
+
*/
|
|
8703
|
+
function getOrderTpSlTriggerType(order) {
|
|
8704
|
+
if (order.orderType === 'TP' || order.orderType === 'SL') {
|
|
8705
|
+
const p = order.parameters;
|
|
8706
|
+
return p.triggerType;
|
|
8707
|
+
}
|
|
8708
|
+
return undefined;
|
|
8709
|
+
}
|
|
8710
|
+
/**
|
|
8711
|
+
* Get trigger type from order parameters (for Trigger orders)
|
|
8712
|
+
*/
|
|
8713
|
+
function getOrderTriggerType(order) {
|
|
8714
|
+
if (order.orderType === 'TRIGGER') {
|
|
8715
|
+
const p = order.parameters;
|
|
8716
|
+
return p.triggerType;
|
|
8717
|
+
}
|
|
8718
|
+
return undefined;
|
|
8719
|
+
}
|
|
8720
|
+
/**
|
|
8721
|
+
* Get order direction from order parameters (for Trigger orders)
|
|
8722
|
+
*/
|
|
8723
|
+
function getOrderDirection(order) {
|
|
8724
|
+
if (order.orderType === 'TRIGGER') {
|
|
8725
|
+
const p = order.parameters;
|
|
8726
|
+
return p.direction;
|
|
8727
|
+
}
|
|
8728
|
+
return undefined;
|
|
8729
|
+
}
|
|
8730
|
+
/**
|
|
8731
|
+
* Get reduce only flag from order parameters (available for all order types)
|
|
8732
|
+
*/
|
|
8733
|
+
function getOrderReduceOnly(order) {
|
|
8734
|
+
var _a;
|
|
8735
|
+
const p = order.parameters;
|
|
8736
|
+
if ('reduceOnly' in p) {
|
|
8737
|
+
return (_a = p.reduceOnly) !== null && _a !== void 0 ? _a : false;
|
|
8738
|
+
}
|
|
8739
|
+
return false;
|
|
8740
|
+
}
|
|
8741
|
+
/**
|
|
8742
|
+
* Get TWAP duration from order parameters (only for TWAP orders)
|
|
8743
|
+
*/
|
|
8744
|
+
function getOrderTwapDuration(order) {
|
|
8745
|
+
if (order.orderType === 'TWAP') {
|
|
8746
|
+
const p = order.parameters;
|
|
8747
|
+
return p.duration;
|
|
8748
|
+
}
|
|
8749
|
+
return undefined;
|
|
8750
|
+
}
|
|
8751
|
+
/**
|
|
8752
|
+
* Get ladder config from order parameters (only for Ladder orders)
|
|
8753
|
+
*/
|
|
8754
|
+
function getOrderLadderConfig(order) {
|
|
8755
|
+
if (order.orderType === 'LADDER') {
|
|
8756
|
+
const p = order.parameters;
|
|
8757
|
+
return {
|
|
8758
|
+
ratioStart: p.ratioStart,
|
|
8759
|
+
ratioEnd: p.ratioEnd,
|
|
8760
|
+
numberOfLevels: p.numberOfLevels,
|
|
8761
|
+
};
|
|
8762
|
+
}
|
|
8763
|
+
return undefined;
|
|
8764
|
+
}
|
|
8765
|
+
/**
|
|
8766
|
+
* Check if the order is a BTC Dominance trigger order
|
|
8767
|
+
*/
|
|
8768
|
+
function isBtcDomOrder(order) {
|
|
8769
|
+
if (order.orderType === 'TRIGGER') {
|
|
8770
|
+
const p = order.parameters;
|
|
8771
|
+
return p.triggerType === 'BTC_DOM';
|
|
8772
|
+
}
|
|
8773
|
+
return false;
|
|
8774
|
+
}
|
|
8775
|
+
/**
|
|
8776
|
+
* Get trailing info from TP/SL order parameters
|
|
8777
|
+
*/
|
|
8778
|
+
function getOrderTrailingInfo(order) {
|
|
8779
|
+
var _a;
|
|
8780
|
+
if (order.orderType === 'TP' || order.orderType === 'SL') {
|
|
8781
|
+
const p = order.parameters;
|
|
8782
|
+
return {
|
|
8783
|
+
isTrailing: (_a = p.isTrailing) !== null && _a !== void 0 ? _a : false,
|
|
8784
|
+
trailingDeltaValue: p.trailingDeltaValue,
|
|
8785
|
+
trailingActivationValue: p.trailingActivationValue,
|
|
8786
|
+
};
|
|
8787
|
+
}
|
|
8788
|
+
return undefined;
|
|
8789
|
+
}
|
|
8790
|
+
|
|
8791
|
+
export { AccountSummaryCalculator, ConflictDetector, MAX_ASSETS_PER_LEG, MINIMUM_ASSET_USD_VALUE, MaxAssetsPerLegError, MinimumPositionSizeError, PearHyperliquidProvider, TokenMetadataExtractor, adjustAdvancePosition, adjustOrder, adjustPosition, calculateMinimumPositionValue, calculateWeightedRatio, cancelOrder, cancelTwap, cancelTwapOrder, closeAllPositions, closePosition, computeBasketCandles, createCandleLookups, createPosition, executeSpotOrder, getAvailableMarkets, getCompleteTimestamps, getKalshiMarkets, getMarketPrefix, getOrderDirection, getOrderLadderConfig, getOrderLeverage, getOrderReduceOnly, getOrderTpSlTriggerType, getOrderTrailingInfo, getOrderTriggerType, getOrderTriggerValue, getOrderTwapDuration, getOrderUsdValue, getPortfolio, isBtcDomOrder, isHip3Market, mapCandleIntervalToTradingViewInterval, mapTradingViewIntervalToCandleInterval, markNotificationReadById, markNotificationsRead, toBackendSymbol, toBackendSymbolWithMarket, toDisplaySymbol, toggleWatchlist, updateLeverage, updateRiskParameters, useAccountSummary, useActiveBaskets, useAgentWallet, useAllBaskets, useAllUserBalances, useAuth, useBasketCandles, useFindBasket, useHighlightedBaskets, useHistoricalPriceData, useHistoricalPriceDataStore, useHyperliquidNativeWebSocket, useHyperliquidUserFills, useHyperliquidWebSocket, useMarketData, useMarketDataAllPayload, useMarketDataPayload, useNotifications, useOpenOrders, useOrders, usePearHyperliquid, usePerformanceOverlays, usePerpMetaAssets, usePortfolio, usePosition, useSpotOrder, useTokenSelectionMetadata, useTopGainers, useTopLosers, useTradeHistories, useTwap, useUserSelection, useWatchlist, useWatchlistBaskets, useWebData, validateMaxAssetsPerLeg, validateMinimumAssetSize, validatePositionSize };
|