@tria-sdk/hyperliquid-core 6.50.0-beta → 6.52.0-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/dist/api.d.ts +59 -16
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +179 -105
- package/dist/api.js.map +1 -1
- package/dist/client.d.ts +20 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +41 -1
- package/dist/client.js.map +1 -1
- package/dist/exchange.d.ts +0 -2
- package/dist/exchange.d.ts.map +1 -1
- package/dist/exchange.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/utils/errorMapper.d.ts +14 -0
- package/dist/utils/errorMapper.d.ts.map +1 -0
- package/dist/utils/errorMapper.js +357 -0
- package/dist/utils/errorMapper.js.map +1 -0
- package/dist/utils/format.d.ts +1 -0
- package/dist/utils/format.d.ts.map +1 -1
- package/dist/utils/format.js +9 -4
- package/dist/utils/format.js.map +1 -1
- package/dist/utils/localization.d.ts +2 -1
- package/dist/utils/localization.d.ts.map +1 -1
- package/dist/utils/localization.js +2 -0
- package/dist/utils/localization.js.map +1 -1
- package/dist/utils/orderErrorParser.d.ts +29 -0
- package/dist/utils/orderErrorParser.d.ts.map +1 -0
- package/dist/utils/orderErrorParser.js +82 -0
- package/dist/utils/orderErrorParser.js.map +1 -0
- package/dist/websocket/WebSocketManager.d.ts +7 -0
- package/dist/websocket/WebSocketManager.d.ts.map +1 -1
- package/dist/websocket/WebSocketManager.js +84 -2
- package/dist/websocket/WebSocketManager.js.map +1 -1
- package/dist/websocket/types.d.ts +120 -3
- package/dist/websocket/types.d.ts.map +1 -1
- package/dist/websocket/types.js +7 -0
- package/dist/websocket/types.js.map +1 -1
- package/package.json +1 -1
package/dist/api.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* Platform-agnostic data fetching - no web or React Native specific code
|
|
4
4
|
*/
|
|
5
5
|
import { SymbolConverter } from "@nktkas/hyperliquid/utils";
|
|
6
|
-
import { getHyperliquidInfoClient, getHyperliquidTransport } from "./client";
|
|
6
|
+
import { getHyperliquidInfoClient, getHyperliquidTransport, getHyperliquidWsInfoClient, getHyperliquidWsTransport, } from "./client";
|
|
7
7
|
// ============================================================================
|
|
8
8
|
// Constants
|
|
9
9
|
// ============================================================================
|
|
@@ -40,6 +40,7 @@ const mapRawAssetPositionToPosition = (entry) => {
|
|
|
40
40
|
/**
|
|
41
41
|
* Maps a raw user fill entry to a typed HyperliquidUserFill.
|
|
42
42
|
* Shared between fetchUserFills and fetchUserFillsByTime to avoid duplication.
|
|
43
|
+
* Accepts both our internal RawUserFill type and SDK response types.
|
|
43
44
|
*/
|
|
44
45
|
const mapRawUserFill = (fill) => ({
|
|
45
46
|
coin: String(fill.coin ?? ""),
|
|
@@ -57,7 +58,7 @@ const mapRawUserFill = (fill) => ({
|
|
|
57
58
|
dir: fill.dir ? String(fill.dir) : undefined,
|
|
58
59
|
closedPnl: fill.closedPnl ? String(fill.closedPnl) : undefined,
|
|
59
60
|
crossed: typeof fill.crossed === "boolean" ? fill.crossed : undefined,
|
|
60
|
-
liquidation: fill.liquidation
|
|
61
|
+
liquidation: fill.liquidation,
|
|
61
62
|
twapId: typeof fill.twapId === "number" ? fill.twapId : undefined,
|
|
62
63
|
});
|
|
63
64
|
/**
|
|
@@ -187,16 +188,22 @@ const pickValidPrice = (...values) => {
|
|
|
187
188
|
// ============================================================================
|
|
188
189
|
/**
|
|
189
190
|
* Retrieves raw spot metadata from Hyperliquid public API
|
|
191
|
+
* Uses WebSocket POST by default to reduce HTTP rate limiting
|
|
190
192
|
*/
|
|
191
|
-
export async function fetchSpotMeta(network = "testnet") {
|
|
192
|
-
const client =
|
|
193
|
+
export async function fetchSpotMeta(network = "testnet", useWsPost = true) {
|
|
194
|
+
const client = useWsPost
|
|
195
|
+
? getHyperliquidWsInfoClient(network)
|
|
196
|
+
: getHyperliquidInfoClient(network);
|
|
193
197
|
return client.spotMeta();
|
|
194
198
|
}
|
|
195
199
|
/**
|
|
196
200
|
* Fetches token details for a specific token
|
|
201
|
+
* Uses WebSocket POST by default to reduce HTTP rate limiting
|
|
197
202
|
*/
|
|
198
|
-
export async function fetchTokenDetails(tokenId, network = "testnet") {
|
|
199
|
-
const client =
|
|
203
|
+
export async function fetchTokenDetails(tokenId, network = "testnet", useWsPost = true) {
|
|
204
|
+
const client = useWsPost
|
|
205
|
+
? getHyperliquidWsInfoClient(network)
|
|
206
|
+
: getHyperliquidInfoClient(network);
|
|
200
207
|
const details = await client.tokenDetails({ tokenId });
|
|
201
208
|
return {
|
|
202
209
|
name: details.name,
|
|
@@ -215,16 +222,22 @@ export async function fetchTokenDetails(tokenId, network = "testnet") {
|
|
|
215
222
|
}
|
|
216
223
|
/**
|
|
217
224
|
* Fetches all mid prices
|
|
225
|
+
* Uses WebSocket POST by default to reduce HTTP rate limiting
|
|
218
226
|
*/
|
|
219
|
-
export async function fetchAllMids(network = "testnet") {
|
|
220
|
-
const client =
|
|
227
|
+
export async function fetchAllMids(network = "testnet", useWsPost = true) {
|
|
228
|
+
const client = useWsPost
|
|
229
|
+
? getHyperliquidWsInfoClient(network)
|
|
230
|
+
: getHyperliquidInfoClient(network);
|
|
221
231
|
return client.allMids();
|
|
222
232
|
}
|
|
223
233
|
/**
|
|
224
234
|
* Fetches spot metadata and asset contexts
|
|
235
|
+
* Uses WebSocket POST by default to reduce HTTP rate limiting
|
|
225
236
|
*/
|
|
226
|
-
export async function fetchSpotMetaAndAssetCtxs(network = "testnet") {
|
|
227
|
-
const client =
|
|
237
|
+
export async function fetchSpotMetaAndAssetCtxs(network = "testnet", useWsPost = true) {
|
|
238
|
+
const client = useWsPost
|
|
239
|
+
? getHyperliquidWsInfoClient(network)
|
|
240
|
+
: getHyperliquidInfoClient(network);
|
|
228
241
|
return client.spotMetaAndAssetCtxs();
|
|
229
242
|
}
|
|
230
243
|
/**
|
|
@@ -396,18 +409,24 @@ export async function fetchSpotPairsWithMarketData(network = "testnet") {
|
|
|
396
409
|
}
|
|
397
410
|
/**
|
|
398
411
|
* Fetches spot order book for a token
|
|
412
|
+
* Uses WebSocket POST by default to reduce HTTP rate limiting
|
|
399
413
|
*/
|
|
400
|
-
export async function fetchSpotOrderBook(tokenName, network = "testnet") {
|
|
401
|
-
const client =
|
|
414
|
+
export async function fetchSpotOrderBook(tokenName, network = "testnet", useWsPost = true) {
|
|
415
|
+
const client = useWsPost
|
|
416
|
+
? getHyperliquidWsInfoClient(network)
|
|
417
|
+
: getHyperliquidInfoClient(network);
|
|
402
418
|
const coin = ensureSpotSymbol(tokenName);
|
|
403
419
|
return client.l2Book({ coin });
|
|
404
420
|
}
|
|
405
421
|
/**
|
|
406
422
|
* Fetches order book snapshot with normalized levels
|
|
423
|
+
* Uses WebSocket POST by default to reduce HTTP rate limiting
|
|
407
424
|
*/
|
|
408
|
-
export async function fetchOrderBook(symbol, depth = 25, network = "testnet") {
|
|
425
|
+
export async function fetchOrderBook(symbol, depth = 25, network = "testnet", useWsPost = true) {
|
|
409
426
|
const { coin, market } = parseSymbolForBook(symbol);
|
|
410
|
-
const client =
|
|
427
|
+
const client = useWsPost
|
|
428
|
+
? getHyperliquidWsInfoClient(network)
|
|
429
|
+
: getHyperliquidInfoClient(network);
|
|
411
430
|
const response = (await client.l2Book({ coin }));
|
|
412
431
|
const levels = Array.isArray(response?.levels)
|
|
413
432
|
? response.levels
|
|
@@ -438,18 +457,21 @@ export async function fetchOrderBook(symbol, depth = 25, network = "testnet") {
|
|
|
438
457
|
}
|
|
439
458
|
/**
|
|
440
459
|
* Fetches recent trades for a coin
|
|
460
|
+
* Uses WebSocket POST by default to reduce HTTP rate limiting
|
|
441
461
|
*/
|
|
442
|
-
export async function fetchRecentTrades(coin, limit = 20, network = "testnet"
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
462
|
+
export async function fetchRecentTrades(coin, limit = 20, network = "testnet",
|
|
463
|
+
/** Use WebSocket POST to reduce HTTP rate limiting (default: true) */
|
|
464
|
+
useWsPost = true) {
|
|
465
|
+
const client = useWsPost
|
|
466
|
+
? getHyperliquidWsInfoClient(network)
|
|
467
|
+
: getHyperliquidInfoClient(network);
|
|
468
|
+
const trades = await client.recentTrades({
|
|
446
469
|
coin,
|
|
447
|
-
limit,
|
|
448
470
|
});
|
|
449
471
|
if (!Array.isArray(trades)) {
|
|
450
472
|
throw new Error(`Unexpected API response for recentTrades: expected array, got ${typeof trades}`);
|
|
451
473
|
}
|
|
452
|
-
return trades.map((trade) => {
|
|
474
|
+
return trades.slice(0, limit).map((trade) => {
|
|
453
475
|
const price = trade.px ?? trade.p ?? "0";
|
|
454
476
|
const size = trade.sz ?? trade.s ?? "0";
|
|
455
477
|
const timestamp = trade.time ?? Date.now();
|
|
@@ -465,35 +487,45 @@ export async function fetchRecentTrades(coin, limit = 20, network = "testnet") {
|
|
|
465
487
|
}
|
|
466
488
|
/**
|
|
467
489
|
* Fetches perp metadata
|
|
490
|
+
* Uses WebSocket POST by default to reduce HTTP rate limiting
|
|
468
491
|
*/
|
|
469
|
-
export async function fetchPerpMeta(network = "testnet") {
|
|
470
|
-
const client =
|
|
492
|
+
export async function fetchPerpMeta(network = "testnet", useWsPost = true) {
|
|
493
|
+
const client = useWsPost
|
|
494
|
+
? getHyperliquidWsInfoClient(network)
|
|
495
|
+
: getHyperliquidInfoClient(network);
|
|
471
496
|
return client.meta();
|
|
472
497
|
}
|
|
473
498
|
/**
|
|
474
499
|
* Fetches perp metadata and asset contexts
|
|
500
|
+
* Uses WebSocket POST by default to reduce HTTP rate limiting
|
|
475
501
|
*/
|
|
476
|
-
export async function fetchPerpMetaAndAssetCtxs(network = "testnet") {
|
|
477
|
-
const client =
|
|
502
|
+
export async function fetchPerpMetaAndAssetCtxs(network = "testnet", useWsPost = true) {
|
|
503
|
+
const client = useWsPost
|
|
504
|
+
? getHyperliquidWsInfoClient(network)
|
|
505
|
+
: getHyperliquidInfoClient(network);
|
|
478
506
|
return client.metaAndAssetCtxs();
|
|
479
507
|
}
|
|
480
508
|
/**
|
|
481
509
|
* Fetches funding history for a coin
|
|
510
|
+
* Uses WebSocket POST by default to reduce HTTP rate limiting
|
|
482
511
|
*/
|
|
483
|
-
export async function fetchFundingHistory(coin, startTime, network = "testnet") {
|
|
484
|
-
const client =
|
|
512
|
+
export async function fetchFundingHistory(coin, startTime, network = "testnet", useWsPost = true) {
|
|
513
|
+
const client = useWsPost
|
|
514
|
+
? getHyperliquidWsInfoClient(network)
|
|
515
|
+
: getHyperliquidInfoClient(network);
|
|
485
516
|
return client.fundingHistory({ coin, startTime });
|
|
486
517
|
}
|
|
487
518
|
/**
|
|
488
519
|
* Fetches user fills (trade history)
|
|
489
520
|
*/
|
|
490
521
|
export async function fetchUserFills(params) {
|
|
491
|
-
const { user, aggregateByTime = false, limit = 100, network = "testnet", } = params;
|
|
492
|
-
const
|
|
522
|
+
const { user, aggregateByTime = false, limit = 100, network = "testnet", useWsPost = true, } = params;
|
|
523
|
+
const client = useWsPost
|
|
524
|
+
? getHyperliquidWsInfoClient(network)
|
|
525
|
+
: getHyperliquidInfoClient(network);
|
|
493
526
|
const now = Date.now();
|
|
494
|
-
const fills = await
|
|
495
|
-
|
|
496
|
-
user,
|
|
527
|
+
const fills = await client.userFillsByTime({
|
|
528
|
+
user: user,
|
|
497
529
|
aggregateByTime,
|
|
498
530
|
startTime: now - 30 * 24 * 60 * 60 * 1000,
|
|
499
531
|
endTime: now,
|
|
@@ -505,13 +537,15 @@ export async function fetchUserFills(params) {
|
|
|
505
537
|
}
|
|
506
538
|
/**
|
|
507
539
|
* Fetches user fills within a time window (order history)
|
|
540
|
+
* Uses WebSocket POST by default to reduce HTTP rate limiting
|
|
508
541
|
*/
|
|
509
542
|
export async function fetchUserFillsByTime(params) {
|
|
510
|
-
const { user, startTime, endTime = Date.now(), aggregateByTime = true, limit = 200, network = "testnet", } = params;
|
|
511
|
-
const
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
543
|
+
const { user, startTime, endTime = Date.now(), aggregateByTime = true, limit = 200, network = "testnet", useWsPost = true, } = params;
|
|
544
|
+
const client = useWsPost
|
|
545
|
+
? getHyperliquidWsInfoClient(network)
|
|
546
|
+
: getHyperliquidInfoClient(network);
|
|
547
|
+
const fills = await client.userFillsByTime({
|
|
548
|
+
user: user,
|
|
515
549
|
startTime,
|
|
516
550
|
endTime,
|
|
517
551
|
aggregateByTime,
|
|
@@ -529,15 +563,17 @@ export async function fetchUserFillsByTime(params) {
|
|
|
529
563
|
}
|
|
530
564
|
/**
|
|
531
565
|
* Fetches user funding ledger updates
|
|
566
|
+
* Uses WebSocket POST by default to reduce HTTP rate limiting
|
|
532
567
|
*/
|
|
533
568
|
export async function fetchUserFunding(params) {
|
|
534
|
-
const { user, startTime, endTime = null, limit = 200, network = "testnet", } = params;
|
|
535
|
-
const
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
569
|
+
const { user, startTime, endTime = null, limit = 200, network = "testnet", useWsPost = true, } = params;
|
|
570
|
+
const client = useWsPost
|
|
571
|
+
? getHyperliquidWsInfoClient(network)
|
|
572
|
+
: getHyperliquidInfoClient(network);
|
|
573
|
+
const updates = await client.userFunding({
|
|
574
|
+
user: user,
|
|
539
575
|
startTime,
|
|
540
|
-
endTime,
|
|
576
|
+
endTime: endTime ?? undefined,
|
|
541
577
|
});
|
|
542
578
|
if (!Array.isArray(updates)) {
|
|
543
579
|
throw new Error(`Unexpected API response for userFunding: expected array, got ${typeof updates}`);
|
|
@@ -551,21 +587,23 @@ export async function fetchUserFunding(params) {
|
|
|
551
587
|
usdc: update.delta?.usdc ?? "0",
|
|
552
588
|
szi: update.delta?.szi ?? "0",
|
|
553
589
|
fundingRate: update.delta?.fundingRate ?? "0",
|
|
554
|
-
nSamples: update.delta?.nSamples ?? 0,
|
|
590
|
+
nSamples: Number(update.delta?.nSamples ?? 0),
|
|
555
591
|
},
|
|
556
592
|
}));
|
|
557
593
|
}
|
|
558
594
|
/**
|
|
559
595
|
* Fetches user non-funding ledger updates (deposits, withdrawals, transfers)
|
|
596
|
+
* Uses WebSocket POST by default to reduce HTTP rate limiting
|
|
560
597
|
*/
|
|
561
598
|
export async function fetchUserNonFundingLedgerUpdates(params) {
|
|
562
|
-
const { user, startTime, endTime = null, limit = 200, network = "testnet", } = params;
|
|
563
|
-
const
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
599
|
+
const { user, startTime, endTime = null, limit = 200, network = "testnet", useWsPost = true, } = params;
|
|
600
|
+
const client = useWsPost
|
|
601
|
+
? getHyperliquidWsInfoClient(network)
|
|
602
|
+
: getHyperliquidInfoClient(network);
|
|
603
|
+
const updates = await client.userNonFundingLedgerUpdates({
|
|
604
|
+
user: user,
|
|
567
605
|
startTime,
|
|
568
|
-
endTime,
|
|
606
|
+
endTime: endTime ?? undefined,
|
|
569
607
|
});
|
|
570
608
|
if (!Array.isArray(updates)) {
|
|
571
609
|
throw new Error(`Unexpected API response for userNonFundingLedgerUpdates: expected array, got ${typeof updates}`);
|
|
@@ -635,10 +673,13 @@ export async function fetchPerpsWithMarketData(network = "testnet") {
|
|
|
635
673
|
}
|
|
636
674
|
/**
|
|
637
675
|
* Fetches candlestick data
|
|
676
|
+
* Uses WebSocket POST by default to reduce HTTP rate limiting
|
|
638
677
|
*/
|
|
639
678
|
export async function fetchCandlesticks(params) {
|
|
640
|
-
const { coin, interval, startTime, endTime, network = "testnet" } = params;
|
|
641
|
-
const client =
|
|
679
|
+
const { coin, interval, startTime, endTime, network = "testnet", useWsPost = true, } = params;
|
|
680
|
+
const client = useWsPost
|
|
681
|
+
? getHyperliquidWsInfoClient(network)
|
|
682
|
+
: getHyperliquidInfoClient(network);
|
|
642
683
|
const now = Date.now();
|
|
643
684
|
const fromTime = startTime ?? now - CANDLE_LOOKBACK * intervalToMs(interval);
|
|
644
685
|
const toTime = endTime ?? now;
|
|
@@ -743,12 +784,15 @@ export async function fetchLatestPrice(coin, network = "testnet") {
|
|
|
743
784
|
}
|
|
744
785
|
/**
|
|
745
786
|
* Fetches user leverage mode for a specific coin.
|
|
787
|
+
* Uses WebSocket POST by default to reduce HTTP rate limiting
|
|
746
788
|
* @throws Error if the API call fails - callers should implement retry logic.
|
|
747
789
|
* @returns The leverage mode, or null if the user has no position for this coin.
|
|
748
790
|
*/
|
|
749
|
-
export async function fetchUserLeverageMode(userAddress, coin, network = "testnet") {
|
|
791
|
+
export async function fetchUserLeverageMode(userAddress, coin, network = "testnet", useWsPost = true) {
|
|
750
792
|
try {
|
|
751
|
-
const client =
|
|
793
|
+
const client = useWsPost
|
|
794
|
+
? getHyperliquidWsInfoClient(network)
|
|
795
|
+
: getHyperliquidInfoClient(network);
|
|
752
796
|
const state = await client.clearinghouseState({
|
|
753
797
|
user: userAddress,
|
|
754
798
|
});
|
|
@@ -793,9 +837,15 @@ export async function fetchUserLeverageMode(userAddress, coin, network = "testne
|
|
|
793
837
|
/**
|
|
794
838
|
* Fetches top of book (best bid/ask) for a symbol
|
|
795
839
|
*/
|
|
796
|
-
|
|
840
|
+
/**
|
|
841
|
+
* Fetches top of book (best bid/ask) for a symbol
|
|
842
|
+
* Uses WebSocket POST by default to reduce HTTP rate limiting
|
|
843
|
+
*/
|
|
844
|
+
export async function fetchTopOfBook(symbol, network = "testnet", useWsPost = true) {
|
|
797
845
|
const { coin } = parseSymbolForBook(symbol);
|
|
798
|
-
const client =
|
|
846
|
+
const client = useWsPost
|
|
847
|
+
? getHyperliquidWsInfoClient(network)
|
|
848
|
+
: getHyperliquidInfoClient(network);
|
|
799
849
|
const book = (await client.l2Book({ coin }));
|
|
800
850
|
const levels = Array.isArray(book?.levels)
|
|
801
851
|
? book.levels
|
|
@@ -818,9 +868,12 @@ export async function fetchTopOfBook(symbol, network = "testnet") {
|
|
|
818
868
|
// ============================================================================
|
|
819
869
|
/**
|
|
820
870
|
* Fetches user positions from clearinghouse state
|
|
871
|
+
* Uses WebSocket POST by default to reduce HTTP rate limiting
|
|
821
872
|
*/
|
|
822
|
-
export async function fetchUserPositions(userAddress, network = "testnet") {
|
|
823
|
-
const client =
|
|
873
|
+
export async function fetchUserPositions(userAddress, network = "testnet", useWsPost = true) {
|
|
874
|
+
const client = useWsPost
|
|
875
|
+
? getHyperliquidWsInfoClient(network)
|
|
876
|
+
: getHyperliquidInfoClient(network);
|
|
824
877
|
const state = await client.clearinghouseState({
|
|
825
878
|
user: userAddress,
|
|
826
879
|
});
|
|
@@ -833,9 +886,13 @@ export async function fetchUserPositions(userAddress, network = "testnet") {
|
|
|
833
886
|
}
|
|
834
887
|
/**
|
|
835
888
|
* Fetches user's clearinghouse state (positions + margin summary)
|
|
889
|
+
* Uses WebSocket POST by default to reduce HTTP rate limiting
|
|
836
890
|
*/
|
|
837
|
-
export async function fetchUserState(userAddress, network = "testnet", dex) {
|
|
838
|
-
|
|
891
|
+
export async function fetchUserState(userAddress, network = "testnet", dex, useWsPost = true) {
|
|
892
|
+
// Use WebSocket client by default to avoid HTTP rate limiting
|
|
893
|
+
const client = useWsPost
|
|
894
|
+
? getHyperliquidWsInfoClient(network)
|
|
895
|
+
: getHyperliquidInfoClient(network);
|
|
839
896
|
const state = await client.clearinghouseState({
|
|
840
897
|
user: userAddress,
|
|
841
898
|
...(dex ? { dex } : {}),
|
|
@@ -872,9 +929,13 @@ export async function fetchUserState(userAddress, network = "testnet", dex) {
|
|
|
872
929
|
}
|
|
873
930
|
/**
|
|
874
931
|
* Fetches user's open orders with frontend info (includes trigger prices for TP/SL)
|
|
932
|
+
* Uses WebSocket POST by default to reduce HTTP rate limiting
|
|
875
933
|
*/
|
|
876
|
-
export async function fetchOpenOrders(userAddress, network = "testnet", dex) {
|
|
877
|
-
|
|
934
|
+
export async function fetchOpenOrders(userAddress, network = "testnet", dex, useWsPost = true) {
|
|
935
|
+
// Use WebSocket client by default to avoid HTTP rate limiting
|
|
936
|
+
const client = useWsPost
|
|
937
|
+
? getHyperliquidWsInfoClient(network)
|
|
938
|
+
: getHyperliquidInfoClient(network);
|
|
878
939
|
// Use frontendOpenOrders to get complete order info including triggerPx for TP/SL orders
|
|
879
940
|
const orders = await client.frontendOpenOrders({
|
|
880
941
|
user: userAddress,
|
|
@@ -905,6 +966,7 @@ export async function fetchOpenOrders(userAddress, network = "testnet", dex) {
|
|
|
905
966
|
// ============================================================================
|
|
906
967
|
/**
|
|
907
968
|
* Resolves asset index for a coin
|
|
969
|
+
* Uses WebSocket transport for consistency with other requests
|
|
908
970
|
*/
|
|
909
971
|
export async function resolveAssetIndex(coin, network = "testnet") {
|
|
910
972
|
const normalizedCoin = (coin || "")
|
|
@@ -915,7 +977,7 @@ export async function resolveAssetIndex(coin, network = "testnet") {
|
|
|
915
977
|
throw new Error("Coin is required to resolve asset index");
|
|
916
978
|
}
|
|
917
979
|
const converter = await SymbolConverter.create({
|
|
918
|
-
transport:
|
|
980
|
+
transport: getHyperliquidWsTransport(network),
|
|
919
981
|
});
|
|
920
982
|
const assetId = converter.getAssetId(normalizedCoin);
|
|
921
983
|
if (assetId === undefined) {
|
|
@@ -926,13 +988,16 @@ export async function resolveAssetIndex(coin, network = "testnet") {
|
|
|
926
988
|
/**
|
|
927
989
|
* Fetches user fee rates from Hyperliquid
|
|
928
990
|
* Returns taker/maker rates for perps and spot
|
|
991
|
+
* Uses WebSocket POST by default to reduce HTTP rate limiting
|
|
929
992
|
*/
|
|
930
993
|
export async function fetchUserFees(params) {
|
|
931
|
-
const { userAddress, network = "testnet" } = params;
|
|
994
|
+
const { userAddress, network = "testnet", useWsPost = true } = params;
|
|
932
995
|
if (!userAddress) {
|
|
933
996
|
throw new Error("User address is required to fetch fees");
|
|
934
997
|
}
|
|
935
|
-
const client =
|
|
998
|
+
const client = useWsPost
|
|
999
|
+
? getHyperliquidWsInfoClient(network)
|
|
1000
|
+
: getHyperliquidInfoClient(network);
|
|
936
1001
|
const response = await client.userFees({
|
|
937
1002
|
user: userAddress,
|
|
938
1003
|
});
|
|
@@ -947,46 +1012,54 @@ export async function fetchUserFees(params) {
|
|
|
947
1012
|
/**
|
|
948
1013
|
* Fetches user historical orders from Hyperliquid
|
|
949
1014
|
* Returns orders with their current status (open, filled, canceled, etc.)
|
|
1015
|
+
* Uses WebSocket POST by default to reduce HTTP rate limiting
|
|
950
1016
|
*/
|
|
951
1017
|
export async function fetchHistoricalOrders(params) {
|
|
952
|
-
const { user, limit = 200, network = "testnet" } = params;
|
|
1018
|
+
const { user, limit = 200, network = "testnet", useWsPost = true } = params;
|
|
953
1019
|
if (!user) {
|
|
954
1020
|
throw new Error("User address is required to fetch historical orders");
|
|
955
1021
|
}
|
|
956
|
-
const
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
1022
|
+
const client = useWsPost
|
|
1023
|
+
? getHyperliquidWsInfoClient(network)
|
|
1024
|
+
: getHyperliquidInfoClient(network);
|
|
1025
|
+
const response = await client.historicalOrders({
|
|
1026
|
+
user: user,
|
|
960
1027
|
});
|
|
961
1028
|
if (!Array.isArray(response)) {
|
|
962
1029
|
return [];
|
|
963
1030
|
}
|
|
964
1031
|
return response.slice(0, limit).map((item) => {
|
|
965
1032
|
const order = item.order ?? {};
|
|
1033
|
+
const orderObj = order;
|
|
966
1034
|
return {
|
|
967
1035
|
order: {
|
|
968
|
-
coin: String(
|
|
969
|
-
side:
|
|
970
|
-
limitPx: String(
|
|
971
|
-
sz: String(
|
|
972
|
-
oid: typeof
|
|
973
|
-
timestamp: typeof
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
1036
|
+
coin: String(orderObj.coin ?? ""),
|
|
1037
|
+
side: orderObj.side === "B" || orderObj.side === "A" ? orderObj.side : "B",
|
|
1038
|
+
limitPx: String(orderObj.limitPx ?? "0"),
|
|
1039
|
+
sz: String(orderObj.sz ?? "0"),
|
|
1040
|
+
oid: typeof orderObj.oid === "number" ? orderObj.oid : 0,
|
|
1041
|
+
timestamp: typeof orderObj.timestamp === "number"
|
|
1042
|
+
? orderObj.timestamp
|
|
1043
|
+
: Date.now(),
|
|
1044
|
+
origSz: String(orderObj.origSz ?? orderObj.sz ?? "0"),
|
|
1045
|
+
triggerCondition: orderObj.triggerCondition
|
|
1046
|
+
? String(orderObj.triggerCondition)
|
|
977
1047
|
: undefined,
|
|
978
|
-
isTrigger: typeof
|
|
979
|
-
triggerPx:
|
|
980
|
-
children: Array.isArray(
|
|
981
|
-
isPositionTpsl: typeof
|
|
982
|
-
?
|
|
1048
|
+
isTrigger: typeof orderObj.isTrigger === "boolean" ? orderObj.isTrigger : false,
|
|
1049
|
+
triggerPx: orderObj.triggerPx ? String(orderObj.triggerPx) : undefined,
|
|
1050
|
+
children: Array.isArray(orderObj.children) ? orderObj.children : [],
|
|
1051
|
+
isPositionTpsl: typeof orderObj.isPositionTpsl === "boolean"
|
|
1052
|
+
? orderObj.isPositionTpsl
|
|
983
1053
|
: false,
|
|
984
|
-
reduceOnly: typeof
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
1054
|
+
reduceOnly: typeof orderObj.reduceOnly === "boolean"
|
|
1055
|
+
? orderObj.reduceOnly
|
|
1056
|
+
: false,
|
|
1057
|
+
orderType: String(orderObj.orderType ?? "Limit"),
|
|
1058
|
+
tif: String(orderObj.tif ?? "Gtc"),
|
|
1059
|
+
cloid: orderObj.cloid ? String(orderObj.cloid) : undefined,
|
|
988
1060
|
},
|
|
989
|
-
status: (item.status ??
|
|
1061
|
+
status: (item.status ??
|
|
1062
|
+
"filled"),
|
|
990
1063
|
statusTimestamp: typeof item.statusTimestamp === "number"
|
|
991
1064
|
? item.statusTimestamp
|
|
992
1065
|
: Date.now(),
|
|
@@ -996,16 +1069,20 @@ export async function fetchHistoricalOrders(params) {
|
|
|
996
1069
|
/**
|
|
997
1070
|
* Fetches user frontend open orders from Hyperliquid
|
|
998
1071
|
* Returns open orders with additional display information (trigger conditions, TP/SL, etc.)
|
|
1072
|
+
* Uses WebSocket POST for dex-specific queries to reduce HTTP rate limiting
|
|
999
1073
|
*/
|
|
1000
1074
|
export async function fetchFrontendOpenOrders(params) {
|
|
1001
|
-
const { user, network = "testnet" } = params;
|
|
1075
|
+
const { user, dex, network = "testnet" } = params;
|
|
1002
1076
|
if (!user) {
|
|
1003
1077
|
throw new Error("User address is required to fetch open orders");
|
|
1004
1078
|
}
|
|
1005
|
-
|
|
1006
|
-
const
|
|
1007
|
-
|
|
1008
|
-
|
|
1079
|
+
// Use WebSocket client for dex-specific queries to avoid HTTP rate limiting
|
|
1080
|
+
const client = dex
|
|
1081
|
+
? getHyperliquidWsInfoClient(network)
|
|
1082
|
+
: getHyperliquidInfoClient(network);
|
|
1083
|
+
const response = await client.frontendOpenOrders({
|
|
1084
|
+
user: user,
|
|
1085
|
+
...(dex ? { dex } : {}),
|
|
1009
1086
|
});
|
|
1010
1087
|
if (!Array.isArray(response)) {
|
|
1011
1088
|
return [];
|
|
@@ -1043,6 +1120,7 @@ let inflightHip3DexsRequest = null;
|
|
|
1043
1120
|
const HIP3_DEXS_CACHE_TTL = 60000; // 60 seconds
|
|
1044
1121
|
/**
|
|
1045
1122
|
* Fetches all HIP-3 perp DEXs with caching and deduplication
|
|
1123
|
+
* Uses WebSocket POST to reduce HTTP rate limiting
|
|
1046
1124
|
*/
|
|
1047
1125
|
export async function fetchHip3Dexs(network = "mainnet") {
|
|
1048
1126
|
const now = Date.now();
|
|
@@ -1056,7 +1134,8 @@ export async function fetchHip3Dexs(network = "mainnet") {
|
|
|
1056
1134
|
}
|
|
1057
1135
|
inflightHip3DexsRequest = (async () => {
|
|
1058
1136
|
try {
|
|
1059
|
-
|
|
1137
|
+
// Use WebSocket transport for consistency with other requests
|
|
1138
|
+
const transport = getHyperliquidWsTransport(network);
|
|
1060
1139
|
const data = await transport.request("info", {
|
|
1061
1140
|
type: "perpDexs",
|
|
1062
1141
|
});
|
|
@@ -1115,17 +1194,12 @@ export async function fetchHip3Markets(dexName, network = "mainnet") {
|
|
|
1115
1194
|
if (dexIndex === -1) {
|
|
1116
1195
|
return [];
|
|
1117
1196
|
}
|
|
1118
|
-
|
|
1119
|
-
|
|
1197
|
+
// Use WebSocket InfoClient for dex-specific queries to reduce HTTP rate limiting
|
|
1198
|
+
const wsClient = getHyperliquidWsInfoClient(network);
|
|
1199
|
+
// Fetch metadata and mids in parallel using WebSocket POST requests
|
|
1120
1200
|
const [metaResult, midsResult] = await Promise.allSettled([
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
dex: dexName,
|
|
1124
|
-
}),
|
|
1125
|
-
transport.request("info", {
|
|
1126
|
-
type: "allMids",
|
|
1127
|
-
dex: dexName,
|
|
1128
|
-
}),
|
|
1201
|
+
wsClient.metaAndAssetCtxs({ dex: dexName }),
|
|
1202
|
+
wsClient.allMids({ dex: dexName }),
|
|
1129
1203
|
]);
|
|
1130
1204
|
if (metaResult.status === "rejected") {
|
|
1131
1205
|
console.error("[fetchHip3Markets] Meta fetch failed:", metaResult.reason);
|
|
@@ -1179,7 +1253,7 @@ export async function fetchHip3Markets(dexName, network = "mainnet") {
|
|
|
1179
1253
|
priceChangePercent24h,
|
|
1180
1254
|
volume24h: parseFloat(ctx.dayNtlVlm),
|
|
1181
1255
|
openInterest: parseFloat(ctx.openInterest),
|
|
1182
|
-
fundingRate: parseFloat(ctx.funding),
|
|
1256
|
+
fundingRate: parseFloat(ctx.funding) * 100, // Convert to percentage (same as perp markets)
|
|
1183
1257
|
markPrice,
|
|
1184
1258
|
sizeDecimals: asset.szDecimals,
|
|
1185
1259
|
maxLeverage: asset.maxLeverage,
|