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

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.
@@ -0,0 +1,140 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.InfoClient = void 0;
13
+ const http_client_1 = require("./http-client");
14
+ const constants_1 = require("../types/constants");
15
+ /**
16
+ * Client for querying Hyperliquid info endpoints (perpetuals only)
17
+ * Only includes essential APIs as specified
18
+ */
19
+ class InfoClient {
20
+ constructor(config) {
21
+ this.masterAddress = config.masterAddress;
22
+ this.httpClient = new http_client_1.HttpClient({
23
+ isTestnet: config.isTestnet,
24
+ timeout: config.timeout,
25
+ });
26
+ this.symbolConversion = config.symbolConversion;
27
+ }
28
+ /**
29
+ * Get all mid prices for all assets
30
+ */
31
+ getAllMids() {
32
+ return __awaiter(this, void 0, void 0, function* () {
33
+ return this.httpClient.info({
34
+ type: constants_1.InfoType.ALL_MIDS,
35
+ });
36
+ });
37
+ }
38
+ /**
39
+ * Get metadata and asset contexts
40
+ */
41
+ 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
+ });
46
+ });
47
+ }
48
+ getClearingHouseState() {
49
+ return __awaiter(this, void 0, void 0, function* () {
50
+ return this.httpClient.info({
51
+ type: constants_1.InfoType.CLEARINGHOUSE_STATE,
52
+ user: this.masterAddress,
53
+ });
54
+ });
55
+ }
56
+ // frontendOpenOrders
57
+ getFrontendOpenOrders() {
58
+ return __awaiter(this, void 0, void 0, function* () {
59
+ return this.httpClient.info({
60
+ type: constants_1.InfoType.FRONTEND_OPEN_ORDERS,
61
+ user: this.masterAddress,
62
+ });
63
+ });
64
+ }
65
+ // need use getFrontendOpenOrders
66
+ // async getOpenOrders(): Promise<any> {
67
+ // return this.httpClient.info({
68
+ // type: InfoType.USER_OPEN_ORDERS,
69
+ // user: this.masterAddress,
70
+ // });
71
+ // }
72
+ /**
73
+ * Get user's fill history
74
+ */
75
+ getUserFills() {
76
+ return __awaiter(this, void 0, void 0, function* () {
77
+ return this.httpClient.info({
78
+ type: constants_1.InfoType.USER_FILLS,
79
+ user: this.masterAddress,
80
+ });
81
+ });
82
+ }
83
+ /**
84
+ * Get candlestick data snapshot
85
+ * Supported intervals: "1m", "3m", "5m", "15m", "30m", "1h", "2h", "4h", "8h", "12h", "1d", "3d", "1w", "1M"
86
+ */
87
+ candleSnapshot(coin, interval, startTime, endTime) {
88
+ return __awaiter(this, void 0, void 0, function* () {
89
+ // if no time range is specified, default to 24 hours ago
90
+ const now = Date.now();
91
+ const defaultStartTime = now - 24 * 60 * 60 * 1000; // 24 hours ago
92
+ return this.httpClient.info({
93
+ type: constants_1.InfoType.CANDLES_SNAPSHOT,
94
+ req: {
95
+ coin,
96
+ interval,
97
+ startTime: startTime || defaultStartTime,
98
+ endTime: endTime || now,
99
+ },
100
+ });
101
+ });
102
+ }
103
+ /**
104
+ * Check builder fee approval status
105
+ */
106
+ checkBuilderFeeApproval(builder) {
107
+ return __awaiter(this, void 0, void 0, function* () {
108
+ return this.httpClient.info({
109
+ type: constants_1.InfoType.CHECK_BUILDER_FEE_APPROVAL,
110
+ user: this.masterAddress,
111
+ builder,
112
+ });
113
+ });
114
+ }
115
+ /**
116
+ * Get user fees information
117
+ */
118
+ getUsersFees() {
119
+ return __awaiter(this, void 0, void 0, function* () {
120
+ const res = yield this.httpClient.info({
121
+ type: constants_1.InfoType.USER_FEES,
122
+ user: this.masterAddress,
123
+ });
124
+ // const perpFee = Number(res.userCrossRate) * (1 - Number(res.activeReferralDiscount));
125
+ return res;
126
+ });
127
+ }
128
+ /**
129
+ * Get user's approved persistent agents
130
+ */
131
+ extraAgents() {
132
+ return __awaiter(this, void 0, void 0, function* () {
133
+ return this.httpClient.info({
134
+ type: constants_1.InfoType.EXTRA_AGENTS,
135
+ user: this.masterAddress,
136
+ });
137
+ });
138
+ }
139
+ }
140
+ exports.InfoClient = InfoClient;
@@ -0,0 +1,14 @@
1
+ import { HttpClientConfig } from "./http-client";
2
+ export declare class SymbolConversion {
3
+ private assetToIndexMap;
4
+ private httpClient;
5
+ private initialized;
6
+ constructor(config: HttpClientConfig);
7
+ initialize(): Promise<void>;
8
+ private ensureInitialized;
9
+ private refreshAssetMaps;
10
+ getAssetIndex(assetSymbol: string): Promise<number>;
11
+ getAllAssets(): Promise<{
12
+ perp: string[];
13
+ }>;
14
+ }
@@ -0,0 +1,91 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.SymbolConversion = void 0;
13
+ const constants_1 = require("../types/constants");
14
+ const http_client_1 = require("./http-client");
15
+ class SymbolConversion {
16
+ constructor(config) {
17
+ this.assetToIndexMap = new Map();
18
+ this.initialized = false;
19
+ this.httpClient = new http_client_1.HttpClient({
20
+ isTestnet: config.isTestnet,
21
+ timeout: config.timeout,
22
+ });
23
+ this.initialize();
24
+ }
25
+ initialize() {
26
+ return __awaiter(this, void 0, void 0, function* () {
27
+ if (this.initialized)
28
+ return;
29
+ try {
30
+ yield this.refreshAssetMaps();
31
+ this.initialized = true;
32
+ }
33
+ catch (error) {
34
+ console.error('Failed to initialize SymbolConversion:', error);
35
+ throw error;
36
+ }
37
+ });
38
+ }
39
+ ensureInitialized() {
40
+ return __awaiter(this, void 0, void 0, function* () {
41
+ if (!this.initialized) {
42
+ yield this.initialize();
43
+ }
44
+ });
45
+ }
46
+ refreshAssetMaps() {
47
+ return __awaiter(this, void 0, void 0, function* () {
48
+ try {
49
+ const perpMeta = yield this.httpClient.info({
50
+ type: constants_1.InfoType.META_AND_ASSET_CTXS,
51
+ });
52
+ // Verify responses are valid before proceeding
53
+ if (!perpMeta ||
54
+ !perpMeta[0] ||
55
+ !perpMeta[0].universe ||
56
+ !Array.isArray(perpMeta[0].universe)) {
57
+ throw new Error('Invalid perpetual metadata response');
58
+ }
59
+ this.assetToIndexMap.clear();
60
+ // Handle perpetual assets
61
+ perpMeta[0].universe.forEach((asset, index) => {
62
+ this.assetToIndexMap.set(asset.name, index);
63
+ });
64
+ }
65
+ catch (error) {
66
+ throw error;
67
+ }
68
+ });
69
+ }
70
+ getAssetIndex(assetSymbol) {
71
+ return __awaiter(this, void 0, void 0, function* () {
72
+ yield this.ensureInitialized();
73
+ const index = this.assetToIndexMap.get(assetSymbol);
74
+ if (index === undefined) {
75
+ throw new Error(`Unknown asset: ${assetSymbol}`);
76
+ }
77
+ return index;
78
+ });
79
+ }
80
+ getAllAssets() {
81
+ return __awaiter(this, void 0, void 0, function* () {
82
+ yield this.ensureInitialized();
83
+ const perp = [];
84
+ for (const [asset, index] of this.assetToIndexMap.entries()) {
85
+ perp.push(asset);
86
+ }
87
+ return { perp };
88
+ });
89
+ }
90
+ }
91
+ exports.SymbolConversion = SymbolConversion;
@@ -0,0 +1,82 @@
1
+ import type { AllMids, L2Book, Candle, WsFill, WsOrder, WebData2 } from '../types';
2
+ import { SymbolConversion } from './symbolConversion';
3
+ export interface WebSocketClientConfig {
4
+ masterAddress: string;
5
+ isTestnet?: boolean;
6
+ autoReconnect?: boolean;
7
+ reconnectDelay?: number;
8
+ maxReconnectAttempts?: number;
9
+ symbolConversion: SymbolConversion;
10
+ }
11
+ export type SubscriptionCallback<T = any> = (data: T) => void;
12
+ export interface Subscription {
13
+ unsubscribe(): void;
14
+ }
15
+ /**
16
+ * WebSocket client for real-time Hyperliquid data (perpetuals only)
17
+ */
18
+ export declare class WebSocketClient {
19
+ private ws;
20
+ private readonly url;
21
+ private readonly config;
22
+ private subscriptions;
23
+ private subscriptionId;
24
+ private reconnectAttempts;
25
+ private isConnecting;
26
+ private pendingSubscriptions;
27
+ private symbolConversion;
28
+ constructor(config: WebSocketClientConfig);
29
+ /**
30
+ * Connect to the WebSocket
31
+ */
32
+ connect(): Promise<void>;
33
+ /**
34
+ * Disconnect from the WebSocket
35
+ */
36
+ disconnect(): void;
37
+ /**
38
+ * Subscribe to a channel
39
+ */
40
+ private subscribe;
41
+ /**
42
+ * Subscribe to all mid prices
43
+ */
44
+ subscribeToAllMids(callback: SubscriptionCallback<AllMids>): Subscription;
45
+ /**
46
+ * Subscribe to L2 order book for a specific coin
47
+ */
48
+ subscribeToL2Book(coin: string, callback: SubscriptionCallback<L2Book>): Subscription;
49
+ /**
50
+ * Subscribe to trades for a specific coin
51
+ */
52
+ subscribeToTrades(coin: string, callback: SubscriptionCallback<any[]>): Subscription;
53
+ /**
54
+ * Subscribe to candlestick data
55
+ */
56
+ subscribeToCandles(coin: string, interval: string, callback: SubscriptionCallback<Candle>): Subscription;
57
+ /**
58
+ * Subscribe to user fills
59
+ */
60
+ subscribeToUserFills(callback: SubscriptionCallback<WsFill[]>): Subscription;
61
+ /**
62
+ * Subscribe to user order updates
63
+ */
64
+ subscribeToUserOrders(callback: SubscriptionCallback<WsOrder[]>): Subscription;
65
+ /**
66
+ * Subscribe to user funding updates
67
+ */
68
+ subscribeToUserFunding(callback: SubscriptionCallback<any>): Subscription;
69
+ /**
70
+ * Subscribe to webData2 - comprehensive user data updates
71
+ * Includes positions, margin summary, open orders, and other user data
72
+ */
73
+ subscribeToWebData2(callback: SubscriptionCallback<WebData2>): Subscription;
74
+ /**
75
+ * Check if WebSocket is connected
76
+ */
77
+ get isConnected(): boolean;
78
+ /**
79
+ * Get current connection state
80
+ */
81
+ get readyState(): number;
82
+ }
@@ -0,0 +1,227 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.WebSocketClient = void 0;
13
+ const constants_1 = require("../types/constants");
14
+ /**
15
+ * WebSocket client for real-time Hyperliquid data (perpetuals only)
16
+ */
17
+ class WebSocketClient {
18
+ constructor(config) {
19
+ this.ws = null;
20
+ this.subscriptions = new Map();
21
+ this.subscriptionId = 0;
22
+ this.reconnectAttempts = 0;
23
+ this.isConnecting = false;
24
+ this.pendingSubscriptions = [];
25
+ this.config = Object.assign({ isTestnet: false, autoReconnect: true, reconnectDelay: 3000, maxReconnectAttempts: 5 }, config);
26
+ this.url = this.config.isTestnet ? constants_1.WSS_URLS.TESTNET : constants_1.WSS_URLS.PRODUCTION;
27
+ this.symbolConversion = config.symbolConversion;
28
+ }
29
+ /**
30
+ * Connect to the WebSocket
31
+ */
32
+ connect() {
33
+ return __awaiter(this, void 0, void 0, function* () {
34
+ var _a;
35
+ if (((_a = this.ws) === null || _a === void 0 ? void 0 : _a.readyState) === WebSocket.OPEN) {
36
+ return;
37
+ }
38
+ if (this.isConnecting) {
39
+ return new Promise((resolve, reject) => {
40
+ const checkConnection = () => {
41
+ var _a;
42
+ if (((_a = this.ws) === null || _a === void 0 ? void 0 : _a.readyState) === WebSocket.OPEN) {
43
+ resolve();
44
+ }
45
+ else if (!this.isConnecting) {
46
+ reject(new Error('Failed to connect'));
47
+ }
48
+ else {
49
+ setTimeout(checkConnection, 100);
50
+ }
51
+ };
52
+ checkConnection();
53
+ });
54
+ }
55
+ return new Promise((resolve, reject) => {
56
+ this.isConnecting = true;
57
+ this.ws = new WebSocket(this.url);
58
+ this.ws.onopen = () => {
59
+ this.isConnecting = false;
60
+ this.reconnectAttempts = 0;
61
+ console.log('WebSocket connected');
62
+ // Resubscribe to pending subscriptions
63
+ this.pendingSubscriptions.forEach(({ id, message, callback }) => {
64
+ var _a;
65
+ this.subscriptions.set(id, callback);
66
+ if (((_a = this.ws) === null || _a === void 0 ? void 0 : _a.readyState) === WebSocket.OPEN) {
67
+ this.ws.send(JSON.stringify(message));
68
+ }
69
+ });
70
+ this.pendingSubscriptions = [];
71
+ resolve();
72
+ };
73
+ this.ws.onmessage = (event) => {
74
+ try {
75
+ 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
+ }
82
+ }
83
+ }
84
+ catch (error) {
85
+ console.error('Error parsing WebSocket message:', error);
86
+ }
87
+ };
88
+ this.ws.onclose = () => {
89
+ this.isConnecting = false;
90
+ console.log('WebSocket disconnected');
91
+ if (this.config.autoReconnect && this.reconnectAttempts < this.config.maxReconnectAttempts) {
92
+ this.reconnectAttempts++;
93
+ console.log(`Reconnecting... (${this.reconnectAttempts}/${this.config.maxReconnectAttempts})`);
94
+ setTimeout(() => this.connect(), this.config.reconnectDelay);
95
+ }
96
+ };
97
+ this.ws.onerror = (error) => {
98
+ this.isConnecting = false;
99
+ console.error('WebSocket error:', error);
100
+ reject(error);
101
+ };
102
+ });
103
+ });
104
+ }
105
+ /**
106
+ * Disconnect from the WebSocket
107
+ */
108
+ disconnect() {
109
+ if (this.ws) {
110
+ this.ws.close();
111
+ this.ws = null;
112
+ }
113
+ this.subscriptions.clear();
114
+ this.pendingSubscriptions = [];
115
+ }
116
+ /**
117
+ * Subscribe to a channel
118
+ */
119
+ subscribe(message, callback) {
120
+ var _a;
121
+ const id = ++this.subscriptionId;
122
+ const subscriptionMessage = Object.assign(Object.assign({}, message), { id });
123
+ 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' })));
126
+ }
127
+ else {
128
+ // Store pending subscription for when connection is established
129
+ this.pendingSubscriptions.push({ id, message: subscriptionMessage, callback });
130
+ // Auto-connect if not connected
131
+ if (!this.isConnecting && (!this.ws || this.ws.readyState === WebSocket.CLOSED)) {
132
+ this.connect().catch(console.error);
133
+ }
134
+ }
135
+ return {
136
+ unsubscribe: () => {
137
+ var _a;
138
+ this.subscriptions.delete(id);
139
+ 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' })));
141
+ }
142
+ // Remove from pending subscriptions
143
+ this.pendingSubscriptions = this.pendingSubscriptions.filter(sub => sub.id !== id);
144
+ },
145
+ };
146
+ }
147
+ /**
148
+ * Subscribe to all mid prices
149
+ */
150
+ subscribeToAllMids(callback) {
151
+ return this.subscribe({
152
+ subscription: { type: 'allMids' },
153
+ }, callback);
154
+ }
155
+ /**
156
+ * Subscribe to L2 order book for a specific coin
157
+ */
158
+ subscribeToL2Book(coin, callback) {
159
+ return this.subscribe({
160
+ subscription: { type: 'l2Book', coin },
161
+ }, callback);
162
+ }
163
+ /**
164
+ * Subscribe to trades for a specific coin
165
+ */
166
+ subscribeToTrades(coin, callback) {
167
+ return this.subscribe({
168
+ subscription: { type: 'trades', coin },
169
+ }, callback);
170
+ }
171
+ /**
172
+ * Subscribe to candlestick data
173
+ */
174
+ subscribeToCandles(coin, interval, callback) {
175
+ return this.subscribe({
176
+ subscription: { type: 'candle', coin, interval },
177
+ }, callback);
178
+ }
179
+ /**
180
+ * Subscribe to user fills
181
+ */
182
+ subscribeToUserFills(callback) {
183
+ return this.subscribe({
184
+ subscription: { type: 'userFills', user: this.config.masterAddress },
185
+ }, callback);
186
+ }
187
+ /**
188
+ * Subscribe to user order updates
189
+ */
190
+ subscribeToUserOrders(callback) {
191
+ return this.subscribe({
192
+ subscription: { type: 'userEvents', user: this.config.masterAddress },
193
+ }, callback);
194
+ }
195
+ /**
196
+ * Subscribe to user funding updates
197
+ */
198
+ subscribeToUserFunding(callback) {
199
+ return this.subscribe({
200
+ subscription: { type: 'userFundings', user: this.config.masterAddress },
201
+ }, callback);
202
+ }
203
+ /**
204
+ * Subscribe to webData2 - comprehensive user data updates
205
+ * Includes positions, margin summary, open orders, and other user data
206
+ */
207
+ subscribeToWebData2(callback) {
208
+ return this.subscribe({
209
+ subscription: { type: 'webData2', user: this.config.masterAddress },
210
+ }, callback);
211
+ }
212
+ /**
213
+ * Check if WebSocket is connected
214
+ */
215
+ get isConnected() {
216
+ var _a;
217
+ return ((_a = this.ws) === null || _a === void 0 ? void 0 : _a.readyState) === WebSocket.OPEN;
218
+ }
219
+ /**
220
+ * Get current connection state
221
+ */
222
+ get readyState() {
223
+ var _a, _b;
224
+ return (_b = (_a = this.ws) === null || _a === void 0 ? void 0 : _a.readyState) !== null && _b !== void 0 ? _b : WebSocket.CLOSED;
225
+ }
226
+ }
227
+ exports.WebSocketClient = WebSocketClient;
@@ -0,0 +1,53 @@
1
+ import { InfoClient } from './client/info-client';
2
+ import { ExchangeClient } from './client/exchange-client';
3
+ import type { ClearinghouseState } from './types';
4
+ import { WebSocketClient, WebSocketClientConfig } from './client/websocket-client';
5
+ import { SymbolConversion } from './client/symbolConversion';
6
+ export interface HyperliquidSDKConfig {
7
+ masterAddress: string;
8
+ agentPrivateKey?: string;
9
+ agentPublicKey?: string;
10
+ agentName?: string;
11
+ isTestnet?: boolean;
12
+ timeout?: number;
13
+ wsConfig?: WebSocketClientConfig;
14
+ }
15
+ /**
16
+ * Main Hyperliquid SDK class for perpetuals trading
17
+ * Simplified version with only essential APIs
18
+ * if use exchange api, must provide agentPrivateKey, agentPublicKey, agentName
19
+ */
20
+ export declare class HyperliquidSDK {
21
+ readonly info: InfoClient;
22
+ exchange?: ExchangeClient;
23
+ symbolConversion: SymbolConversion;
24
+ readonly ws: WebSocketClient;
25
+ private readonly masterAddress;
26
+ private readonly configParams;
27
+ constructor(config: HyperliquidSDKConfig);
28
+ /**
29
+ * Get wallet address (only available if private key was provided)
30
+ */
31
+ get address(): string;
32
+ updateExchangeAgent(agentPrivateKey: string, agentPublicKey: string, agentName: string): void;
33
+ /**
34
+ * Connect to WebSocket for real-time data
35
+ */
36
+ connectWebSocket(): Promise<void>;
37
+ /**
38
+ * Disconnect from WebSocket
39
+ */
40
+ disconnectWebSocket(): void;
41
+ /**
42
+ * Check if WebSocket is connected
43
+ */
44
+ get isWebSocketConnected(): boolean;
45
+ /**
46
+ * Quick helper: Get account summary with essential info
47
+ */
48
+ getAccountSummary(): Promise<ClearinghouseState>;
49
+ /**
50
+ * Quick helper: Get market overview
51
+ */
52
+ getMarketOverview(): Promise<any>;
53
+ }