@rabby-wallet/hyperliquid-sdk 1.0.0-beta.1 → 1.0.0-beta.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -32,8 +32,10 @@ const sdk = new HyperliquidSDK({
32
32
  // 获取所有中间价
33
33
  const prices = await sdk.info.getAllMids();
34
34
 
35
- // 获取市场元数据与资产上下文
36
- const [meta, assetCtxs] = await sdk.info.metaAndAssetCtxs();
35
+ // 获取市场元数据与资产上下文
36
+ const canUseCache = true; //默认使用缓存,多次请求并发去重 ,需要刷新传false
37
+ const [meta, assetCtxs] = await sdk.info.metaAndAssetCtxs(canUseCache);
38
+
37
39
 
38
40
  // 获取账户综合状态
39
41
  const account = await sdk.info.getClearingHouseState();
@@ -5,9 +5,9 @@ import type { OrderResponse, CancelResponse, ExchangeClientConfig, PlaceOrderPar
5
5
  */
6
6
  export declare class ExchangeClient {
7
7
  private readonly httpClient;
8
- private agentPrivateKey;
9
- private agentPublicKey;
10
- private agentName;
8
+ private agentPrivateKey?;
9
+ private agentPublicKey?;
10
+ private agentName?;
11
11
  private readonly isTestnet;
12
12
  private readonly masterAddress;
13
13
  private builder?;
@@ -17,6 +17,8 @@ export declare class ExchangeClient {
17
17
  * Get the wallet address
18
18
  */
19
19
  get address(): string;
20
+ updateExchangeAgent(agentPrivateKey: string, agentPublicKey: string, agentName?: string): void;
21
+ private getAgentPrivateKey;
20
22
  updateBuilder(address: string, fee: number): Promise<any>;
21
23
  updateLeverage(params: UpdateLeverageParams): Promise<any>;
22
24
  /**
@@ -30,7 +32,7 @@ export declare class ExchangeClient {
30
32
  * need to update leverage before place order
31
33
  */
32
34
  marketOrderOpen(params: MarketOrderParams): Promise<OrderResponse>;
33
- marketOrderClose(params: MarketOrderParams): Promise<OrderResponse>;
35
+ marketOrderClose(params: Omit<MarketOrderParams, 'tpTriggerPx' | 'slTriggerPx'>): Promise<OrderResponse>;
34
36
  /**
35
37
  * Place multiple orders at once
36
38
  */
@@ -86,4 +88,5 @@ export declare class ExchangeClient {
86
88
  * Withdraw funds to L1 need use master wallet
87
89
  */
88
90
  prepareWithdraw(params: WithdrawParams): PrepareApproveBuilderFeeResult;
91
+ sendWithdraw(params: SendApproveParams): Promise<any>;
89
92
  }
@@ -47,6 +47,7 @@ const ethUtil = __importStar(require("@ethereumjs/util"));
47
47
  const http_client_1 = require("./http-client");
48
48
  const constants_1 = require("../types/constants");
49
49
  const signer_1 = require("../utils/signer");
50
+ const symbolConversion_1 = require("./symbolConversion");
50
51
  /**
51
52
  * Client for executing trades on Hyperliquid (perpetuals only)
52
53
  * Only includes essential trading APIs as specified
@@ -58,11 +59,25 @@ class ExchangeClient {
58
59
  isTestnet: config.isTestnet,
59
60
  timeout: config.timeout,
60
61
  });
61
- this.agentPrivateKey = config.agentPrivateKey.startsWith('0x') ? config.agentPrivateKey : ethUtil.addHexPrefix(config.agentPrivateKey);
62
- this.agentPublicKey = config.agentPublicKey.startsWith('0x') ? config.agentPublicKey : ethUtil.addHexPrefix(config.agentPublicKey);
63
- this.agentName = config.agentName || 'Rabby';
62
+ if (!config.symbolConversion) {
63
+ this.symbolConversion = new symbolConversion_1.SymbolConversion({
64
+ isTestnet: config.isTestnet,
65
+ timeout: config.timeout,
66
+ });
67
+ }
68
+ else {
69
+ this.symbolConversion = config.symbolConversion;
70
+ }
71
+ if (config.agentPrivateKey) {
72
+ this.agentPrivateKey = config.agentPrivateKey.startsWith('0x') ? config.agentPrivateKey : ethUtil.addHexPrefix(config.agentPrivateKey);
73
+ }
74
+ if (config.agentPublicKey) {
75
+ this.agentPublicKey = config.agentPublicKey.startsWith('0x') ? config.agentPublicKey : ethUtil.addHexPrefix(config.agentPublicKey);
76
+ }
77
+ if (config.agentName) {
78
+ this.agentName = config.agentName;
79
+ }
64
80
  this.isTestnet = config.isTestnet || false;
65
- this.symbolConversion = config.symbolConversion;
66
81
  }
67
82
  /**
68
83
  * Get the wallet address
@@ -70,6 +85,17 @@ class ExchangeClient {
70
85
  get address() {
71
86
  return this.masterAddress;
72
87
  }
88
+ updateExchangeAgent(agentPrivateKey, agentPublicKey, agentName) {
89
+ this.agentPrivateKey = agentPrivateKey.startsWith('0x') ? agentPrivateKey : ethUtil.addHexPrefix(agentPrivateKey);
90
+ this.agentPublicKey = agentPublicKey.startsWith('0x') ? agentPublicKey : ethUtil.addHexPrefix(agentPublicKey);
91
+ this.agentName = agentName || '';
92
+ }
93
+ getAgentPrivateKey() {
94
+ if (!this.agentPrivateKey) {
95
+ throw new Error('Agent private key is not set');
96
+ }
97
+ return this.agentPrivateKey;
98
+ }
73
99
  // 50 = '0.05%'
74
100
  updateBuilder(address, fee) {
75
101
  return __awaiter(this, void 0, void 0, function* () {
@@ -91,7 +117,7 @@ class ExchangeClient {
91
117
  isCross: params.isCross || false,
92
118
  leverage: params.leverage,
93
119
  };
94
- const signature = (0, signer_1.signL1AgentAction)(this.agentPrivateKey, action, this.isTestnet, nonce);
120
+ const signature = (0, signer_1.signL1AgentAction)(this.getAgentPrivateKey(), action, this.isTestnet, nonce);
95
121
  return this.httpClient.exchange({
96
122
  action,
97
123
  nonce,
@@ -124,7 +150,7 @@ class ExchangeClient {
124
150
  f: this.builder.fee,
125
151
  };
126
152
  }
127
- const signature = (0, signer_1.signL1AgentAction)(this.agentPrivateKey, action, this.isTestnet, nonce);
153
+ const signature = (0, signer_1.signL1AgentAction)(this.getAgentPrivateKey(), action, this.isTestnet, nonce);
128
154
  return this.httpClient.exchange({
129
155
  action,
130
156
  nonce,
@@ -257,7 +283,7 @@ class ExchangeClient {
257
283
  f: this.builder.fee,
258
284
  };
259
285
  }
260
- const signature = (0, signer_1.signL1AgentAction)(this.agentPrivateKey, action, this.isTestnet, nonce);
286
+ const signature = (0, signer_1.signL1AgentAction)(this.getAgentPrivateKey(), action, this.isTestnet, nonce);
261
287
  return this.httpClient.exchange({
262
288
  action,
263
289
  nonce,
@@ -326,7 +352,7 @@ class ExchangeClient {
326
352
  type: constants_1.ExchangeType.CANCEL,
327
353
  cancels: cancels,
328
354
  };
329
- const signature = (0, signer_1.signL1AgentAction)(this.agentPrivateKey, action, this.isTestnet, nonce);
355
+ const signature = (0, signer_1.signL1AgentAction)(this.getAgentPrivateKey(), action, this.isTestnet, nonce);
330
356
  return this.httpClient.exchange({
331
357
  action,
332
358
  nonce,
@@ -355,7 +381,7 @@ class ExchangeClient {
355
381
  type: constants_1.ExchangeType.MODIFY,
356
382
  modifies: [modify],
357
383
  };
358
- const signature = (0, signer_1.signL1AgentAction)(this.agentPrivateKey, action, this.isTestnet, nonce);
384
+ const signature = (0, signer_1.signL1AgentAction)(this.getAgentPrivateKey(), action, this.isTestnet, nonce);
359
385
  return this.httpClient.exchange({
360
386
  action,
361
387
  nonce,
@@ -374,7 +400,7 @@ class ExchangeClient {
374
400
  type: constants_1.ExchangeType.SET_REFERRER,
375
401
  code,
376
402
  };
377
- const signature = (0, signer_1.signL1AgentAction)(this.agentPrivateKey, action, this.isTestnet, nonce);
403
+ const signature = (0, signer_1.signL1AgentAction)(this.getAgentPrivateKey(), action, this.isTestnet, nonce);
378
404
  return this.httpClient.exchange({
379
405
  action,
380
406
  nonce,
@@ -443,7 +469,7 @@ class ExchangeClient {
443
469
  const action = {
444
470
  type: constants_1.ExchangeType.APPROVE_BUILDER_FEE,
445
471
  hyperliquidChain: this.isTestnet ? 'Testnet' : 'Mainnet',
446
- signatureChainId: this.isTestnet ? '0x66eee' : '0x42161',
472
+ signatureChainId: this.isTestnet ? '0x66eee' : '0xa4b1',
447
473
  builder: params.builder.toLowerCase(),
448
474
  maxFee: params.maxFee || '0.1%',
449
475
  nonce,
@@ -476,10 +502,11 @@ class ExchangeClient {
476
502
  */
477
503
  sendApproveBuilderFee(params) {
478
504
  return __awaiter(this, void 0, void 0, function* () {
505
+ const splitSignature = (0, signer_1.splitSig)(params.signature);
479
506
  return this.httpClient.exchange({
480
507
  action: params.action,
481
508
  nonce: params.nonce,
482
- signature: params.signature,
509
+ signature: splitSignature,
483
510
  });
484
511
  });
485
512
  }
@@ -491,10 +518,10 @@ class ExchangeClient {
491
518
  const action = {
492
519
  type: constants_1.ExchangeType.WITHDRAW,
493
520
  hyperliquidChain: this.isTestnet ? 'Testnet' : 'Mainnet',
494
- signatureChainId: this.isTestnet ? '0x66eee' : '0x42161',
521
+ signatureChainId: this.isTestnet ? '0x66eee' : '0xa4b1',
495
522
  destination: params.destination,
496
523
  amount: params.amount,
497
- time: Date.now(),
524
+ time: nonce,
498
525
  };
499
526
  const { domain, types, primaryType, message } = (0, signer_1.prepareMasterSignData)({
500
527
  action,
@@ -517,5 +544,13 @@ class ExchangeClient {
517
544
  nonce,
518
545
  };
519
546
  }
547
+ sendWithdraw(params) {
548
+ const splitSignature = (0, signer_1.splitSig)(params.signature);
549
+ return this.httpClient.exchange({
550
+ action: params.action,
551
+ nonce: params.nonce,
552
+ signature: splitSignature,
553
+ });
554
+ }
520
555
  }
521
556
  exports.ExchangeClient = ExchangeClient;
@@ -41,6 +41,9 @@ class HttpClient {
41
41
  throw new Error(`HTTP ${response.status}: ${response.statusText}`);
42
42
  }
43
43
  const result = yield response.json();
44
+ if (result.status === 'error' || result.status === 'fail' || result.status === 'err') {
45
+ throw new Error(JSON.stringify(result.response));
46
+ }
44
47
  return result;
45
48
  }
46
49
  catch (error) {
@@ -1,10 +1,8 @@
1
- import type { Meta, AssetCtx, ClearinghouseState, UserFills, CandleSnapshot, AllMids, ExtraAgent, OpenOrder, FeeResponse } from '../types';
2
- import { SymbolConversion } from './symbolConversion';
1
+ import type { Meta, AssetCtx, ClearinghouseState, UserFills, CandleSnapshot, AllMids, ExtraAgent, OpenOrder, FeeResponse, UserNonFundingLedgerUpdates } from '../types';
3
2
  export interface InfoClientConfig {
4
3
  isTestnet?: boolean;
5
4
  timeout?: number;
6
5
  masterAddress: string;
7
- symbolConversion: SymbolConversion;
8
6
  }
9
7
  /**
10
8
  * Client for querying Hyperliquid info endpoints (perpetuals only)
@@ -13,7 +11,8 @@ export interface InfoClientConfig {
13
11
  export declare class InfoClient {
14
12
  private readonly httpClient;
15
13
  private readonly masterAddress;
16
- private readonly symbolConversion;
14
+ private metaAndAssetCtxsCache;
15
+ private metaAndAssetCtxsInFlight;
17
16
  constructor(config: InfoClientConfig);
18
17
  /**
19
18
  * Get all mid prices for all assets
@@ -22,13 +21,14 @@ export declare class InfoClient {
22
21
  /**
23
22
  * Get metadata and asset contexts
24
23
  */
25
- metaAndAssetCtxs(): Promise<[Meta, AssetCtx[]]>;
26
- getClearingHouseState(): Promise<ClearinghouseState>;
27
- getFrontendOpenOrders(): Promise<OpenOrder[]>;
24
+ metaAndAssetCtxs(canUseCache?: boolean): Promise<[Meta, AssetCtx[]]>;
25
+ getClearingHouseState(address?: string): Promise<ClearinghouseState>;
26
+ getFrontendOpenOrders(address?: string): Promise<OpenOrder[]>;
27
+ getUserNonFundingLedgerUpdates(address?: string, startTime?: number, endTime?: number): Promise<UserNonFundingLedgerUpdates[]>;
28
28
  /**
29
29
  * Get user's fill history
30
30
  */
31
- getUserFills(): Promise<UserFills>;
31
+ getUserFills(address?: string): Promise<UserFills>;
32
32
  /**
33
33
  * Get candlestick data snapshot
34
34
  * Supported intervals: "1m", "3m", "5m", "15m", "30m", "1h", "2h", "4h", "8h", "12h", "1d", "3d", "1w", "1M"
@@ -37,13 +37,19 @@ export declare class InfoClient {
37
37
  /**
38
38
  * Check builder fee approval status
39
39
  */
40
- checkBuilderFeeApproval(builder: string): Promise<any>;
40
+ checkBuilderFeeApproval(builder: string, address?: string): Promise<any>;
41
+ /**
42
+ * Get user role
43
+ */
44
+ getUserRole(address?: string): Promise<{
45
+ role: 'user' | 'agent' | 'vault' | 'subAccount' | 'missing';
46
+ }>;
41
47
  /**
42
48
  * Get user fees information
43
49
  */
44
- getUsersFees(): Promise<FeeResponse>;
50
+ getUsersFees(address?: string): Promise<FeeResponse>;
45
51
  /**
46
52
  * Get user's approved persistent agents
47
53
  */
48
- extraAgents(): Promise<ExtraAgent[]>;
54
+ extraAgents(address?: string): Promise<ExtraAgent[]>;
49
55
  }
@@ -18,12 +18,13 @@ const constants_1 = require("../types/constants");
18
18
  */
19
19
  class InfoClient {
20
20
  constructor(config) {
21
+ this.metaAndAssetCtxsCache = null;
22
+ this.metaAndAssetCtxsInFlight = null;
21
23
  this.masterAddress = config.masterAddress;
22
24
  this.httpClient = new http_client_1.HttpClient({
23
25
  isTestnet: config.isTestnet,
24
26
  timeout: config.timeout,
25
27
  });
26
- this.symbolConversion = config.symbolConversion;
27
28
  }
28
29
  /**
29
30
  * Get all mid prices for all assets
@@ -39,26 +40,43 @@ class InfoClient {
39
40
  * Get metadata and asset contexts
40
41
  */
41
42
  metaAndAssetCtxs() {
42
- return __awaiter(this, void 0, void 0, function* () {
43
- return this.httpClient.info({
44
- type: constants_1.InfoType.META_AND_ASSET_CTXS,
45
- });
43
+ return __awaiter(this, arguments, void 0, function* (canUseCache = true) {
44
+ if (canUseCache && this.metaAndAssetCtxsCache) {
45
+ return this.metaAndAssetCtxsCache;
46
+ }
47
+ // De-duplicate concurrent requests
48
+ if (this.metaAndAssetCtxsInFlight) {
49
+ return this.metaAndAssetCtxsInFlight;
50
+ }
51
+ this.metaAndAssetCtxsInFlight = (() => __awaiter(this, void 0, void 0, function* () {
52
+ try {
53
+ const [meta, assetCtxs] = yield this.httpClient.info({
54
+ type: constants_1.InfoType.META_AND_ASSET_CTXS,
55
+ });
56
+ this.metaAndAssetCtxsCache = [meta, assetCtxs];
57
+ return [meta, assetCtxs];
58
+ }
59
+ finally {
60
+ this.metaAndAssetCtxsInFlight = null;
61
+ }
62
+ }))();
63
+ return this.metaAndAssetCtxsInFlight;
46
64
  });
47
65
  }
48
- getClearingHouseState() {
66
+ getClearingHouseState(address) {
49
67
  return __awaiter(this, void 0, void 0, function* () {
50
68
  return this.httpClient.info({
51
69
  type: constants_1.InfoType.CLEARINGHOUSE_STATE,
52
- user: this.masterAddress,
70
+ user: address || this.masterAddress,
53
71
  });
54
72
  });
55
73
  }
56
74
  // frontendOpenOrders
57
- getFrontendOpenOrders() {
75
+ getFrontendOpenOrders(address) {
58
76
  return __awaiter(this, void 0, void 0, function* () {
59
77
  return this.httpClient.info({
60
78
  type: constants_1.InfoType.FRONTEND_OPEN_ORDERS,
61
- user: this.masterAddress,
79
+ user: address || this.masterAddress,
62
80
  });
63
81
  });
64
82
  }
@@ -69,14 +87,24 @@ class InfoClient {
69
87
  // user: this.masterAddress,
70
88
  // });
71
89
  // }
90
+ getUserNonFundingLedgerUpdates(address, startTime, endTime) {
91
+ return __awaiter(this, void 0, void 0, function* () {
92
+ return this.httpClient.info({
93
+ type: constants_1.InfoType.USER_NON_FUNDING_LEDGER_UPDATES,
94
+ user: address || this.masterAddress,
95
+ startTime: startTime || 0,
96
+ endTime,
97
+ });
98
+ });
99
+ }
72
100
  /**
73
101
  * Get user's fill history
74
102
  */
75
- getUserFills() {
103
+ getUserFills(address) {
76
104
  return __awaiter(this, void 0, void 0, function* () {
77
105
  return this.httpClient.info({
78
106
  type: constants_1.InfoType.USER_FILLS,
79
- user: this.masterAddress,
107
+ user: address || this.masterAddress,
80
108
  });
81
109
  });
82
110
  }
@@ -103,23 +131,35 @@ class InfoClient {
103
131
  /**
104
132
  * Check builder fee approval status
105
133
  */
106
- checkBuilderFeeApproval(builder) {
134
+ checkBuilderFeeApproval(builder, address) {
107
135
  return __awaiter(this, void 0, void 0, function* () {
108
136
  return this.httpClient.info({
109
137
  type: constants_1.InfoType.CHECK_BUILDER_FEE_APPROVAL,
110
- user: this.masterAddress,
138
+ user: address || this.masterAddress,
111
139
  builder,
112
140
  });
113
141
  });
114
142
  }
143
+ /**
144
+ * Get user role
145
+ */
146
+ getUserRole(address) {
147
+ return __awaiter(this, void 0, void 0, function* () {
148
+ const res = yield this.httpClient.info({
149
+ type: constants_1.InfoType.USER_ROLE,
150
+ user: address || this.masterAddress,
151
+ });
152
+ return res;
153
+ });
154
+ }
115
155
  /**
116
156
  * Get user fees information
117
157
  */
118
- getUsersFees() {
158
+ getUsersFees(address) {
119
159
  return __awaiter(this, void 0, void 0, function* () {
120
160
  const res = yield this.httpClient.info({
121
161
  type: constants_1.InfoType.USER_FEES,
122
- user: this.masterAddress,
162
+ user: address || this.masterAddress,
123
163
  });
124
164
  // const perpFee = Number(res.userCrossRate) * (1 - Number(res.activeReferralDiscount));
125
165
  return res;
@@ -128,11 +168,11 @@ class InfoClient {
128
168
  /**
129
169
  * Get user's approved persistent agents
130
170
  */
131
- extraAgents() {
171
+ extraAgents(address) {
132
172
  return __awaiter(this, void 0, void 0, function* () {
133
173
  return this.httpClient.info({
134
174
  type: constants_1.InfoType.EXTRA_AGENTS,
135
- user: this.masterAddress,
175
+ user: address || this.masterAddress,
136
176
  });
137
177
  });
138
178
  }
@@ -1,9 +1,11 @@
1
1
  import { HttpClientConfig } from "./http-client";
2
+ import { InfoClient } from "./info-client";
2
3
  export declare class SymbolConversion {
3
4
  private assetToIndexMap;
4
5
  private httpClient;
5
6
  private initialized;
6
- constructor(config: HttpClientConfig);
7
+ private infoClient?;
8
+ constructor(config: HttpClientConfig, infoClient?: InfoClient);
7
9
  initialize(): Promise<void>;
8
10
  private ensureInitialized;
9
11
  private refreshAssetMaps;
@@ -13,9 +13,10 @@ exports.SymbolConversion = void 0;
13
13
  const constants_1 = require("../types/constants");
14
14
  const http_client_1 = require("./http-client");
15
15
  class SymbolConversion {
16
- constructor(config) {
16
+ constructor(config, infoClient) {
17
17
  this.assetToIndexMap = new Map();
18
18
  this.initialized = false;
19
+ this.infoClient = infoClient;
19
20
  this.httpClient = new http_client_1.HttpClient({
20
21
  isTestnet: config.isTestnet,
21
22
  timeout: config.timeout,
@@ -46,9 +47,15 @@ class SymbolConversion {
46
47
  refreshAssetMaps() {
47
48
  return __awaiter(this, void 0, void 0, function* () {
48
49
  try {
49
- const perpMeta = yield this.httpClient.info({
50
- type: constants_1.InfoType.META_AND_ASSET_CTXS,
51
- });
50
+ let perpMeta = null;
51
+ if (!this.infoClient) {
52
+ perpMeta = yield this.httpClient.info({
53
+ type: constants_1.InfoType.META_AND_ASSET_CTXS,
54
+ });
55
+ }
56
+ else {
57
+ perpMeta = yield this.infoClient.metaAndAssetCtxs(false);
58
+ }
52
59
  // Verify responses are valid before proceeding
53
60
  if (!perpMeta ||
54
61
  !perpMeta[0] ||
@@ -1,12 +1,10 @@
1
- import type { AllMids, L2Book, Candle, WsFill, WsOrder, WebData2 } from '../types';
2
- import { SymbolConversion } from './symbolConversion';
1
+ import type { AllMids, L2Book, Candle, WsFill, WsOrder, WebData2, WsActiveAssetCtx } from '../types';
3
2
  export interface WebSocketClientConfig {
4
3
  masterAddress: string;
5
4
  isTestnet?: boolean;
6
5
  autoReconnect?: boolean;
7
6
  reconnectDelay?: number;
8
7
  maxReconnectAttempts?: number;
9
- symbolConversion: SymbolConversion;
10
8
  }
11
9
  export type SubscriptionCallback<T = any> = (data: T) => void;
12
10
  export interface Subscription {
@@ -20,11 +18,9 @@ export declare class WebSocketClient {
20
18
  private readonly url;
21
19
  private readonly config;
22
20
  private subscriptions;
23
- private subscriptionId;
24
21
  private reconnectAttempts;
25
22
  private isConnecting;
26
23
  private pendingSubscriptions;
27
- private symbolConversion;
28
24
  constructor(config: WebSocketClientConfig);
29
25
  /**
30
26
  * Connect to the WebSocket
@@ -46,6 +42,10 @@ export declare class WebSocketClient {
46
42
  * Subscribe to L2 order book for a specific coin
47
43
  */
48
44
  subscribeToL2Book(coin: string, callback: SubscriptionCallback<L2Book>): Subscription;
45
+ /**
46
+ * Subscribe to active asset ctx
47
+ */
48
+ subscribeToActiveAssetCtx(coin: string, callback: SubscriptionCallback<WsActiveAssetCtx>): Subscription;
49
49
  /**
50
50
  * Subscribe to trades for a specific coin
51
51
  */
@@ -18,13 +18,11 @@ class WebSocketClient {
18
18
  constructor(config) {
19
19
  this.ws = null;
20
20
  this.subscriptions = new Map();
21
- this.subscriptionId = 0;
22
21
  this.reconnectAttempts = 0;
23
22
  this.isConnecting = false;
24
23
  this.pendingSubscriptions = [];
25
24
  this.config = Object.assign({ isTestnet: false, autoReconnect: true, reconnectDelay: 3000, maxReconnectAttempts: 5 }, config);
26
25
  this.url = this.config.isTestnet ? constants_1.WSS_URLS.TESTNET : constants_1.WSS_URLS.PRODUCTION;
27
- this.symbolConversion = config.symbolConversion;
28
26
  }
29
27
  /**
30
28
  * Connect to the WebSocket
@@ -58,13 +56,13 @@ class WebSocketClient {
58
56
  this.ws.onopen = () => {
59
57
  this.isConnecting = false;
60
58
  this.reconnectAttempts = 0;
61
- console.log('WebSocket connected');
59
+ console.log('hyperliquid sdk WebSocket connected');
62
60
  // Resubscribe to pending subscriptions
63
- this.pendingSubscriptions.forEach(({ id, message, callback }) => {
61
+ this.pendingSubscriptions.forEach(({ message, callback }) => {
64
62
  var _a;
65
- this.subscriptions.set(id, callback);
66
63
  if (((_a = this.ws) === null || _a === void 0 ? void 0 : _a.readyState) === WebSocket.OPEN) {
67
- this.ws.send(JSON.stringify(message));
64
+ this.subscriptions.set(message.subscription.type, callback);
65
+ this.ws.send(JSON.stringify(Object.assign(Object.assign({}, message), { method: 'subscribe' })));
68
66
  }
69
67
  });
70
68
  this.pendingSubscriptions = [];
@@ -73,12 +71,10 @@ class WebSocketClient {
73
71
  this.ws.onmessage = (event) => {
74
72
  try {
75
73
  const data = JSON.parse(event.data);
76
- if (data.method === 'subscription') {
77
- const subscriptionId = data.subscription;
78
- const callback = this.subscriptions.get(subscriptionId);
79
- if (callback) {
80
- callback(data.data);
81
- }
74
+ const type = data.channel;
75
+ const callback = this.subscriptions.get(type);
76
+ if (callback) {
77
+ callback(data.data);
82
78
  }
83
79
  }
84
80
  catch (error) {
@@ -118,15 +114,13 @@ class WebSocketClient {
118
114
  */
119
115
  subscribe(message, callback) {
120
116
  var _a;
121
- const id = ++this.subscriptionId;
122
- const subscriptionMessage = Object.assign(Object.assign({}, message), { id });
123
117
  if (((_a = this.ws) === null || _a === void 0 ? void 0 : _a.readyState) === WebSocket.OPEN) {
124
- this.subscriptions.set(id, callback);
125
- this.ws.send(JSON.stringify(Object.assign(Object.assign({}, subscriptionMessage), { method: 'subscribe' })));
118
+ this.subscriptions.set(message.subscription.type, callback);
119
+ this.ws.send(JSON.stringify(Object.assign(Object.assign({}, message), { method: 'subscribe' })));
126
120
  }
127
121
  else {
128
122
  // Store pending subscription for when connection is established
129
- this.pendingSubscriptions.push({ id, message: subscriptionMessage, callback });
123
+ this.pendingSubscriptions.push({ message, callback });
130
124
  // Auto-connect if not connected
131
125
  if (!this.isConnecting && (!this.ws || this.ws.readyState === WebSocket.CLOSED)) {
132
126
  this.connect().catch(console.error);
@@ -135,12 +129,12 @@ class WebSocketClient {
135
129
  return {
136
130
  unsubscribe: () => {
137
131
  var _a;
138
- this.subscriptions.delete(id);
132
+ this.subscriptions.delete(message.subscription.type);
139
133
  if (((_a = this.ws) === null || _a === void 0 ? void 0 : _a.readyState) === WebSocket.OPEN) {
140
- this.ws.send(JSON.stringify(Object.assign(Object.assign({}, subscriptionMessage), { method: 'unsubscribe' })));
134
+ this.ws.send(JSON.stringify(Object.assign(Object.assign({}, message), { method: 'unsubscribe' })));
141
135
  }
142
136
  // Remove from pending subscriptions
143
- this.pendingSubscriptions = this.pendingSubscriptions.filter(sub => sub.id !== id);
137
+ this.pendingSubscriptions = this.pendingSubscriptions.filter(sub => sub.message.subscription.type !== message.subscription.type);
144
138
  },
145
139
  };
146
140
  }
@@ -160,6 +154,14 @@ class WebSocketClient {
160
154
  subscription: { type: 'l2Book', coin },
161
155
  }, callback);
162
156
  }
157
+ /**
158
+ * Subscribe to active asset ctx
159
+ */
160
+ subscribeToActiveAssetCtx(coin, callback) {
161
+ return this.subscribe({
162
+ subscription: { type: 'activeAssetCtx', coin },
163
+ }, callback);
164
+ }
163
165
  /**
164
166
  * Subscribe to trades for a specific coin
165
167
  */
@@ -189,7 +191,7 @@ class WebSocketClient {
189
191
  */
190
192
  subscribeToUserOrders(callback) {
191
193
  return this.subscribe({
192
- subscription: { type: 'userEvents', user: this.config.masterAddress },
194
+ subscription: { type: 'orderUpdates', user: this.config.masterAddress },
193
195
  }, callback);
194
196
  }
195
197
  /**
@@ -29,7 +29,7 @@ export declare class HyperliquidSDK {
29
29
  * Get wallet address (only available if private key was provided)
30
30
  */
31
31
  get address(): string;
32
- updateExchangeAgent(agentPrivateKey: string, agentPublicKey: string, agentName: string): void;
32
+ updateExchangeAgent(agentPrivateKey: string, agentPublicKey: string, agentName?: string): void;
33
33
  /**
34
34
  * Connect to WebSocket for real-time data
35
35
  */
@@ -46,8 +46,4 @@ export declare class HyperliquidSDK {
46
46
  * Quick helper: Get account summary with essential info
47
47
  */
48
48
  getAccountSummary(): Promise<ClearinghouseState>;
49
- /**
50
- * Quick helper: Get market overview
51
- */
52
- getMarketOverview(): Promise<any>;
53
49
  }
@@ -21,17 +21,15 @@ const symbolConversion_1 = require("./client/symbolConversion");
21
21
  */
22
22
  class HyperliquidSDK {
23
23
  constructor(config) {
24
- // Initialize info client (always available)
25
- this.symbolConversion = new symbolConversion_1.SymbolConversion({
26
- isTestnet: config.isTestnet,
27
- timeout: config.timeout,
28
- });
29
24
  this.info = new info_client_1.InfoClient({
30
25
  masterAddress: config.masterAddress,
31
26
  isTestnet: config.isTestnet,
32
27
  timeout: config.timeout,
33
- symbolConversion: this.symbolConversion,
34
28
  });
29
+ this.symbolConversion = new symbolConversion_1.SymbolConversion({
30
+ isTestnet: config.isTestnet,
31
+ timeout: config.timeout,
32
+ }, this.info);
35
33
  this.masterAddress = config.masterAddress;
36
34
  this.configParams = config;
37
35
  // Initialize exchange client only if private key is provided
@@ -47,7 +45,7 @@ class HyperliquidSDK {
47
45
  });
48
46
  }
49
47
  // Initialize WebSocket client (full functionality preserved)
50
- this.ws = new websocket_client_1.WebSocketClient(Object.assign({ masterAddress: config.masterAddress, isTestnet: config.isTestnet, symbolConversion: this.symbolConversion }, config.wsConfig));
48
+ this.ws = new websocket_client_1.WebSocketClient(Object.assign({ masterAddress: config.masterAddress, isTestnet: config.isTestnet }, config.wsConfig));
51
49
  }
52
50
  /**
53
51
  * Get wallet address (only available if private key was provided)
@@ -88,18 +86,5 @@ class HyperliquidSDK {
88
86
  return this.info.getClearingHouseState();
89
87
  });
90
88
  }
91
- /**
92
- * Quick helper: Get market overview
93
- */
94
- getMarketOverview() {
95
- return __awaiter(this, void 0, void 0, function* () {
96
- const [meta, assetCtxs] = yield this.info.metaAndAssetCtxs();
97
- return {
98
- assets: meta.universe,
99
- assetContexts: assetCtxs,
100
- marginTables: meta.marginTables,
101
- };
102
- });
103
- }
104
89
  }
105
90
  exports.HyperliquidSDK = HyperliquidSDK;
@@ -27,6 +27,7 @@ export declare enum ExchangeType {
27
27
  }
28
28
  export declare enum InfoType {
29
29
  ALL_MIDS = "allMids",
30
+ USER_NON_FUNDING_LEDGER_UPDATES = "userNonFundingLedgerUpdates",
30
31
  USER_OPEN_ORDERS = "openOrders",
31
32
  USER_FILLS = "userFills",
32
33
  USER_FILLS_BY_TIME = "userFillsByTime",
@@ -35,7 +36,6 @@ export declare enum InfoType {
35
36
  CANDLES_SNAPSHOT = "candleSnapshot",
36
37
  META_AND_ASSET_CTXS = "metaAndAssetCtxs",
37
38
  USER_FUNDING = "userFunding",
38
- USER_NON_FUNDING_LEDGER_UPDATES = "userNonFundingLedgerUpdates",
39
39
  FUNDING_HISTORY = "fundingHistory",
40
40
  CLEARINGHOUSE_STATE = "clearinghouseState",
41
41
  META = "meta",
@@ -44,6 +44,7 @@ export declare enum InfoType {
44
44
  ACTIVE_ASSET_DATA = "activeAssetData",
45
45
  CHECK_BUILDER_FEE_APPROVAL = "checkBuilderFeeApproval",
46
46
  USER_FEES = "userFees",
47
+ USER_ROLE = "userRole",
47
48
  EXTRA_AGENTS = "extraAgents"
48
49
  }
49
50
  export declare enum OrderType {
@@ -35,6 +35,7 @@ var ExchangeType;
35
35
  var InfoType;
36
36
  (function (InfoType) {
37
37
  InfoType["ALL_MIDS"] = "allMids";
38
+ InfoType["USER_NON_FUNDING_LEDGER_UPDATES"] = "userNonFundingLedgerUpdates";
38
39
  InfoType["USER_OPEN_ORDERS"] = "openOrders";
39
40
  InfoType["USER_FILLS"] = "userFills";
40
41
  InfoType["USER_FILLS_BY_TIME"] = "userFillsByTime";
@@ -43,7 +44,6 @@ var InfoType;
43
44
  InfoType["CANDLES_SNAPSHOT"] = "candleSnapshot";
44
45
  InfoType["META_AND_ASSET_CTXS"] = "metaAndAssetCtxs";
45
46
  InfoType["USER_FUNDING"] = "userFunding";
46
- InfoType["USER_NON_FUNDING_LEDGER_UPDATES"] = "userNonFundingLedgerUpdates";
47
47
  InfoType["FUNDING_HISTORY"] = "fundingHistory";
48
48
  InfoType["CLEARINGHOUSE_STATE"] = "clearinghouseState";
49
49
  InfoType["META"] = "meta";
@@ -52,6 +52,7 @@ var InfoType;
52
52
  InfoType["ACTIVE_ASSET_DATA"] = "activeAssetData";
53
53
  InfoType["CHECK_BUILDER_FEE_APPROVAL"] = "checkBuilderFeeApproval";
54
54
  InfoType["USER_FEES"] = "userFees";
55
+ InfoType["USER_ROLE"] = "userRole";
55
56
  InfoType["EXTRA_AGENTS"] = "extraAgents";
56
57
  })(InfoType || (exports.InfoType = InfoType = {}));
57
58
  // Order types
@@ -4,6 +4,11 @@ export type TriggerType = 'tp' | 'sl';
4
4
  export type Side = 'A' | 'B';
5
5
  export type AssetId = number;
6
6
  export type OrderId = number;
7
+ export interface MarketOverview {
8
+ assets: AssetInfo[];
9
+ assetContexts: AssetCtx[];
10
+ marginTables: [number, MarginTable][];
11
+ }
7
12
  export interface OpenOrder {
8
13
  coin: string;
9
14
  side: Side;
@@ -52,6 +57,7 @@ export type OrderType = LimitOrderType | MarketOrderType | StopOrderType;
52
57
  export interface AssetInfo {
53
58
  name: string;
54
59
  szDecimals: number;
60
+ marginTableId: number;
55
61
  maxLeverage: number;
56
62
  onlyIsolated?: boolean;
57
63
  isDelisted?: boolean;
@@ -121,6 +127,24 @@ export interface UserFill {
121
127
  export type UserFills = {
122
128
  [asset: string]: UserFill[];
123
129
  };
130
+ export type UserNonFundingLedgerUpdates = {
131
+ time: number;
132
+ hash: string;
133
+ delta: {
134
+ type: string;
135
+ usdc?: string;
136
+ vault?: string;
137
+ user?: string;
138
+ token?: string;
139
+ amount?: string;
140
+ requestedUsd?: string;
141
+ commission?: string;
142
+ closingCost?: string;
143
+ basis?: string;
144
+ netWithdrawnUsd?: string;
145
+ toPerp?: boolean;
146
+ };
147
+ };
124
148
  export interface OrderResponse {
125
149
  status: 'ok';
126
150
  response: {
@@ -133,6 +157,7 @@ export interface OrderResponse {
133
157
  filled?: {
134
158
  totalSz: string;
135
159
  avgPx: string;
160
+ oid: number;
136
161
  };
137
162
  error?: string;
138
163
  }>;
@@ -201,6 +226,7 @@ export interface WsFill {
201
226
  tid: number;
202
227
  }
203
228
  export interface AssetCtx {
229
+ dayBaseVlm: string;
204
230
  dayNtlVlm: string;
205
231
  funding: string;
206
232
  impactPxs: [string, string];
@@ -219,6 +245,18 @@ export interface L2Book {
219
245
  levels: [WsLevel[], WsLevel[]];
220
246
  time: number;
221
247
  }
248
+ export interface WsActiveAssetCtx {
249
+ coin: string;
250
+ ctx: {
251
+ dayNtlVlm: string;
252
+ prevDayPx: string;
253
+ markPx: string;
254
+ midPx?: string;
255
+ funding: string;
256
+ openInterest: string;
257
+ oraclePx: string;
258
+ };
259
+ }
222
260
  export interface Candle {
223
261
  t: number;
224
262
  T: number;
@@ -274,12 +312,12 @@ export interface ExtraAgent {
274
312
  }
275
313
  export interface ExchangeClientConfig {
276
314
  masterAddress: string;
277
- agentPrivateKey: string;
278
- agentPublicKey: string;
315
+ agentPrivateKey?: string;
316
+ agentPublicKey?: string;
279
317
  agentName?: string;
280
318
  isTestnet?: boolean;
281
319
  timeout?: number;
282
- symbolConversion: SymbolConversion;
320
+ symbolConversion?: SymbolConversion;
283
321
  }
284
322
  export interface PlaceOrderParams {
285
323
  coin: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rabby-wallet/hyperliquid-sdk",
3
- "version": "1.0.0-beta.1",
3
+ "version": "1.0.0-beta.11",
4
4
  "description": "Simplified Hyperliquid Perpetuals Trading SDK for Frontend Applications",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",