@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.
- package/README.md +138 -0
- package/dist/client/exchange-client.d.ts +89 -0
- package/dist/client/exchange-client.js +521 -0
- package/dist/client/http-client.d.ts +26 -0
- package/dist/client/http-client.js +75 -0
- package/dist/client/info-client.d.ts +49 -0
- package/dist/client/info-client.js +140 -0
- package/dist/client/symbolConversion.d.ts +14 -0
- package/dist/client/symbolConversion.js +91 -0
- package/dist/client/websocket-client.d.ts +82 -0
- package/dist/client/websocket-client.js +227 -0
- package/dist/hyperliquid-sdk.d.ts +53 -0
- package/dist/hyperliquid-sdk.js +105 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +42 -0
- package/dist/types/constants.d.ts +67 -0
- package/dist/types/constants.js +80 -0
- package/dist/types/index.d.ts +342 -0
- package/dist/types/index.js +2 -0
- package/dist/utils/signer.d.ts +35 -0
- package/dist/utils/signer.js +134 -0
- package/package.json +36 -0
|
@@ -0,0 +1,521 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
36
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
37
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
38
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
39
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
40
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
41
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
exports.ExchangeClient = void 0;
|
|
46
|
+
const ethUtil = __importStar(require("@ethereumjs/util"));
|
|
47
|
+
const http_client_1 = require("./http-client");
|
|
48
|
+
const constants_1 = require("../types/constants");
|
|
49
|
+
const signer_1 = require("../utils/signer");
|
|
50
|
+
/**
|
|
51
|
+
* Client for executing trades on Hyperliquid (perpetuals only)
|
|
52
|
+
* Only includes essential trading APIs as specified
|
|
53
|
+
*/
|
|
54
|
+
class ExchangeClient {
|
|
55
|
+
constructor(config) {
|
|
56
|
+
this.masterAddress = config.masterAddress;
|
|
57
|
+
this.httpClient = new http_client_1.HttpClient({
|
|
58
|
+
isTestnet: config.isTestnet,
|
|
59
|
+
timeout: config.timeout,
|
|
60
|
+
});
|
|
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';
|
|
64
|
+
this.isTestnet = config.isTestnet || false;
|
|
65
|
+
this.symbolConversion = config.symbolConversion;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Get the wallet address
|
|
69
|
+
*/
|
|
70
|
+
get address() {
|
|
71
|
+
return this.masterAddress;
|
|
72
|
+
}
|
|
73
|
+
// 50 = '0.05%'
|
|
74
|
+
updateBuilder(address, fee) {
|
|
75
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
76
|
+
if (fee < 0 || fee > 100) {
|
|
77
|
+
throw new Error('Fee must be between 0 and 100');
|
|
78
|
+
}
|
|
79
|
+
this.builder = {
|
|
80
|
+
address: address.toLowerCase(),
|
|
81
|
+
fee,
|
|
82
|
+
};
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
updateLeverage(params) {
|
|
86
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
87
|
+
const nonce = Date.now();
|
|
88
|
+
const action = {
|
|
89
|
+
type: constants_1.ExchangeType.UPDATE_LEVERAGE,
|
|
90
|
+
asset: yield this.symbolConversion.getAssetIndex(params.coin),
|
|
91
|
+
isCross: params.isCross || false,
|
|
92
|
+
leverage: params.leverage,
|
|
93
|
+
};
|
|
94
|
+
const signature = (0, signer_1.signL1AgentAction)(this.agentPrivateKey, action, this.isTestnet, nonce);
|
|
95
|
+
return this.httpClient.exchange({
|
|
96
|
+
action,
|
|
97
|
+
nonce,
|
|
98
|
+
signature,
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Place a single order
|
|
104
|
+
*/
|
|
105
|
+
placeOrder(params) {
|
|
106
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
107
|
+
const nonce = Date.now();
|
|
108
|
+
const orderWire = {
|
|
109
|
+
a: yield this.symbolConversion.getAssetIndex(params.coin),
|
|
110
|
+
b: params.isBuy,
|
|
111
|
+
p: params.limitPx,
|
|
112
|
+
s: params.sz,
|
|
113
|
+
r: params.reduceOnly || false,
|
|
114
|
+
t: params.orderType || { limit: { tif: 'Gtc' } },
|
|
115
|
+
};
|
|
116
|
+
const action = {
|
|
117
|
+
type: constants_1.ExchangeType.ORDER,
|
|
118
|
+
orders: [orderWire],
|
|
119
|
+
grouping: 'na',
|
|
120
|
+
};
|
|
121
|
+
if (this.builder) {
|
|
122
|
+
action.builder = {
|
|
123
|
+
b: this.builder.address,
|
|
124
|
+
f: this.builder.fee,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
const signature = (0, signer_1.signL1AgentAction)(this.agentPrivateKey, action, this.isTestnet, nonce);
|
|
128
|
+
return this.httpClient.exchange({
|
|
129
|
+
action,
|
|
130
|
+
nonce,
|
|
131
|
+
signature,
|
|
132
|
+
});
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
getSlippagePx(midPx, slippage, isBuy) {
|
|
136
|
+
var _a;
|
|
137
|
+
const decimals = ((_a = midPx.toString().split('.')[1]) === null || _a === void 0 ? void 0 : _a.length) || 0;
|
|
138
|
+
const prepDecimals = Math.max(0, decimals - 1);
|
|
139
|
+
const px = isBuy ? (Number(midPx) * (1 + slippage)).toFixed(prepDecimals) : (Number(midPx) * (1 - slippage)).toFixed(prepDecimals);
|
|
140
|
+
return px;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Place a market order
|
|
144
|
+
* default slippage is 0.08
|
|
145
|
+
* need to update leverage before place order
|
|
146
|
+
*/
|
|
147
|
+
marketOrderOpen(params) {
|
|
148
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
149
|
+
try {
|
|
150
|
+
const slippage = params.slippage || constants_1.SLIPPAGE;
|
|
151
|
+
const px = this.getSlippagePx(params.midPx, slippage, params.isBuy);
|
|
152
|
+
const orders = [{
|
|
153
|
+
coin: params.coin,
|
|
154
|
+
isBuy: params.isBuy,
|
|
155
|
+
sz: params.size,
|
|
156
|
+
limitPx: px,
|
|
157
|
+
reduceOnly: false,
|
|
158
|
+
orderType: { limit: { tif: 'Ioc' } },
|
|
159
|
+
}];
|
|
160
|
+
if (params.tpTriggerPx) {
|
|
161
|
+
const tpOrder = {
|
|
162
|
+
coin: params.coin,
|
|
163
|
+
isBuy: !params.isBuy,
|
|
164
|
+
sz: params.size,
|
|
165
|
+
limitPx: params.tpTriggerPx,
|
|
166
|
+
reduceOnly: true,
|
|
167
|
+
orderType: {
|
|
168
|
+
trigger: {
|
|
169
|
+
isMarket: true,
|
|
170
|
+
triggerPx: params.tpTriggerPx,
|
|
171
|
+
tpsl: 'tp',
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
};
|
|
175
|
+
orders.push(tpOrder);
|
|
176
|
+
}
|
|
177
|
+
if (params.slTriggerPx) {
|
|
178
|
+
const slOrder = {
|
|
179
|
+
coin: params.coin,
|
|
180
|
+
isBuy: !params.isBuy,
|
|
181
|
+
sz: params.size,
|
|
182
|
+
limitPx: params.slTriggerPx,
|
|
183
|
+
reduceOnly: true,
|
|
184
|
+
orderType: {
|
|
185
|
+
trigger: {
|
|
186
|
+
isMarket: true,
|
|
187
|
+
triggerPx: params.slTriggerPx,
|
|
188
|
+
tpsl: 'sl',
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
orders.push(slOrder);
|
|
193
|
+
}
|
|
194
|
+
const res = yield this.multiOrder({
|
|
195
|
+
orders,
|
|
196
|
+
});
|
|
197
|
+
return res;
|
|
198
|
+
}
|
|
199
|
+
catch (error) {
|
|
200
|
+
throw error;
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
marketOrderClose(params) {
|
|
205
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
206
|
+
try {
|
|
207
|
+
const slippage = params.slippage || constants_1.SLIPPAGE;
|
|
208
|
+
const px = this.getSlippagePx(params.midPx, slippage, params.isBuy);
|
|
209
|
+
const orders = [{
|
|
210
|
+
coin: params.coin,
|
|
211
|
+
isBuy: params.isBuy,
|
|
212
|
+
sz: params.size,
|
|
213
|
+
limitPx: px,
|
|
214
|
+
reduceOnly: true,
|
|
215
|
+
orderType: { limit: { tif: 'Ioc' } },
|
|
216
|
+
}];
|
|
217
|
+
const res = yield this.multiOrder({
|
|
218
|
+
orders,
|
|
219
|
+
});
|
|
220
|
+
return res;
|
|
221
|
+
}
|
|
222
|
+
catch (error) {
|
|
223
|
+
throw error;
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Place multiple orders at once
|
|
229
|
+
*/
|
|
230
|
+
multiOrder(params) {
|
|
231
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
232
|
+
const nonce = Date.now();
|
|
233
|
+
const assetIndexCache = new Map();
|
|
234
|
+
const orderWires = yield Promise.all(params.orders.map((order) => __awaiter(this, void 0, void 0, function* () {
|
|
235
|
+
let assetIndex = assetIndexCache.get(order.coin);
|
|
236
|
+
if (assetIndex === undefined) {
|
|
237
|
+
assetIndex = yield this.symbolConversion.getAssetIndex(order.coin);
|
|
238
|
+
assetIndexCache.set(order.coin, assetIndex);
|
|
239
|
+
}
|
|
240
|
+
return {
|
|
241
|
+
a: assetIndex,
|
|
242
|
+
b: order.isBuy,
|
|
243
|
+
p: order.limitPx,
|
|
244
|
+
s: order.sz,
|
|
245
|
+
r: order.reduceOnly || false,
|
|
246
|
+
t: order.orderType || { limit: { tif: 'Gtc' } },
|
|
247
|
+
};
|
|
248
|
+
})));
|
|
249
|
+
const action = {
|
|
250
|
+
type: constants_1.ExchangeType.ORDER,
|
|
251
|
+
orders: orderWires,
|
|
252
|
+
grouping: params.grouping || 'na',
|
|
253
|
+
};
|
|
254
|
+
if (this.builder) {
|
|
255
|
+
action.builder = {
|
|
256
|
+
b: this.builder.address,
|
|
257
|
+
f: this.builder.fee,
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
const signature = (0, signer_1.signL1AgentAction)(this.agentPrivateKey, action, this.isTestnet, nonce);
|
|
261
|
+
return this.httpClient.exchange({
|
|
262
|
+
action,
|
|
263
|
+
nonce,
|
|
264
|
+
signature,
|
|
265
|
+
});
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
bindTpslByOrderId(params) {
|
|
269
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
270
|
+
let orders = [];
|
|
271
|
+
if (params.tpTriggerPx) {
|
|
272
|
+
orders.push({
|
|
273
|
+
coin: params.coin,
|
|
274
|
+
isBuy: !params.isBuy,
|
|
275
|
+
sz: '0',
|
|
276
|
+
limitPx: this.getSlippagePx(params.tpTriggerPx, constants_1.SLIPPAGE, !params.isBuy),
|
|
277
|
+
reduceOnly: true,
|
|
278
|
+
orderType: {
|
|
279
|
+
trigger: {
|
|
280
|
+
isMarket: true,
|
|
281
|
+
triggerPx: params.tpTriggerPx,
|
|
282
|
+
tpsl: 'tp',
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
if (params.slTriggerPx) {
|
|
288
|
+
orders.push({
|
|
289
|
+
coin: params.coin,
|
|
290
|
+
isBuy: !params.isBuy,
|
|
291
|
+
sz: '0',
|
|
292
|
+
limitPx: this.getSlippagePx(params.slTriggerPx, constants_1.SLIPPAGE, !params.isBuy),
|
|
293
|
+
reduceOnly: true,
|
|
294
|
+
orderType: {
|
|
295
|
+
trigger: {
|
|
296
|
+
isMarket: true,
|
|
297
|
+
triggerPx: params.slTriggerPx,
|
|
298
|
+
tpsl: 'sl',
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
if (orders.length === 0) {
|
|
304
|
+
throw new Error('Must have at least one tp or sl');
|
|
305
|
+
}
|
|
306
|
+
return this.multiOrder({
|
|
307
|
+
orders,
|
|
308
|
+
grouping: 'positionTpsl'
|
|
309
|
+
});
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* Cancel order(s)
|
|
314
|
+
*/
|
|
315
|
+
cancelOrder(params) {
|
|
316
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
317
|
+
const nonce = Date.now();
|
|
318
|
+
const cancels = yield Promise.all(params.map((param) => __awaiter(this, void 0, void 0, function* () {
|
|
319
|
+
const assetIndex = yield this.symbolConversion.getAssetIndex(param.coin);
|
|
320
|
+
return {
|
|
321
|
+
a: assetIndex,
|
|
322
|
+
o: param.oid,
|
|
323
|
+
};
|
|
324
|
+
})));
|
|
325
|
+
const action = {
|
|
326
|
+
type: constants_1.ExchangeType.CANCEL,
|
|
327
|
+
cancels: cancels,
|
|
328
|
+
};
|
|
329
|
+
const signature = (0, signer_1.signL1AgentAction)(this.agentPrivateKey, action, this.isTestnet, nonce);
|
|
330
|
+
return this.httpClient.exchange({
|
|
331
|
+
action,
|
|
332
|
+
nonce,
|
|
333
|
+
signature,
|
|
334
|
+
});
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
/**
|
|
338
|
+
* Modify an existing order
|
|
339
|
+
*/
|
|
340
|
+
modifyOrder(params) {
|
|
341
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
342
|
+
const nonce = Date.now();
|
|
343
|
+
const modify = {
|
|
344
|
+
oid: params.oid,
|
|
345
|
+
order: {
|
|
346
|
+
a: yield this.symbolConversion.getAssetIndex(params.coin),
|
|
347
|
+
b: params.isBuy,
|
|
348
|
+
p: params.limitPx,
|
|
349
|
+
s: params.sz,
|
|
350
|
+
r: params.reduceOnly || false,
|
|
351
|
+
t: params.orderType || { limit: { tif: 'Gtc' } },
|
|
352
|
+
},
|
|
353
|
+
};
|
|
354
|
+
const action = {
|
|
355
|
+
type: constants_1.ExchangeType.MODIFY,
|
|
356
|
+
modifies: [modify],
|
|
357
|
+
};
|
|
358
|
+
const signature = (0, signer_1.signL1AgentAction)(this.agentPrivateKey, action, this.isTestnet, nonce);
|
|
359
|
+
return this.httpClient.exchange({
|
|
360
|
+
action,
|
|
361
|
+
nonce,
|
|
362
|
+
signature,
|
|
363
|
+
});
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Set referrer for 10% fee
|
|
368
|
+
*/
|
|
369
|
+
setReferrer(code) {
|
|
370
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
371
|
+
const nonce = Date.now();
|
|
372
|
+
try {
|
|
373
|
+
const action = {
|
|
374
|
+
type: constants_1.ExchangeType.SET_REFERRER,
|
|
375
|
+
code,
|
|
376
|
+
};
|
|
377
|
+
const signature = (0, signer_1.signL1AgentAction)(this.agentPrivateKey, action, this.isTestnet, nonce);
|
|
378
|
+
return this.httpClient.exchange({
|
|
379
|
+
action,
|
|
380
|
+
nonce,
|
|
381
|
+
signature,
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
catch (error) {
|
|
385
|
+
throw error;
|
|
386
|
+
}
|
|
387
|
+
});
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* Prepare approve agent data for main wallet signing
|
|
391
|
+
* Returns typed data that needs to be signed by the main wallet
|
|
392
|
+
*/
|
|
393
|
+
prepareApproveAgent() {
|
|
394
|
+
const nonce = Date.now();
|
|
395
|
+
const action = {
|
|
396
|
+
type: constants_1.ExchangeType.APPROVE_AGENT,
|
|
397
|
+
hyperliquidChain: this.isTestnet ? 'Testnet' : 'Mainnet',
|
|
398
|
+
signatureChainId: this.isTestnet ? '0x66eee' : '0xa4b1',
|
|
399
|
+
agentAddress: this.agentPublicKey,
|
|
400
|
+
agentName: this.agentName, // no name is temp, and has name is persist in backend
|
|
401
|
+
nonce,
|
|
402
|
+
};
|
|
403
|
+
const { domain, types, primaryType, message } = (0, signer_1.prepareMasterSignData)({
|
|
404
|
+
action,
|
|
405
|
+
payloadTypes: [
|
|
406
|
+
{ name: 'hyperliquidChain', type: 'string' },
|
|
407
|
+
{ name: 'agentAddress', type: 'address' },
|
|
408
|
+
{ name: 'agentName', type: 'string' },
|
|
409
|
+
{ name: 'nonce', type: 'uint64' },
|
|
410
|
+
],
|
|
411
|
+
primaryType: 'HyperliquidTransaction:ApproveAgent',
|
|
412
|
+
isMainnet: !this.isTestnet,
|
|
413
|
+
});
|
|
414
|
+
return {
|
|
415
|
+
domain,
|
|
416
|
+
types,
|
|
417
|
+
primaryType,
|
|
418
|
+
message,
|
|
419
|
+
nonce,
|
|
420
|
+
};
|
|
421
|
+
}
|
|
422
|
+
/**
|
|
423
|
+
* Send approve agent request with main wallet signature
|
|
424
|
+
* nonce must be the same as the nonce in the prepareApproveAgent
|
|
425
|
+
*/
|
|
426
|
+
sendApproveAgent(params) {
|
|
427
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
428
|
+
const splitSignature = (0, signer_1.splitSig)(params.signature);
|
|
429
|
+
return this.httpClient.exchange({
|
|
430
|
+
action: params.action,
|
|
431
|
+
nonce: params.nonce,
|
|
432
|
+
signature: splitSignature,
|
|
433
|
+
});
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
/**
|
|
437
|
+
* Prepare approve builder fee data for main wallet signing
|
|
438
|
+
* Returns typed data that needs to be signed by the main wallet
|
|
439
|
+
* maxFee : max fee rate = '0.1%'
|
|
440
|
+
*/
|
|
441
|
+
prepareApproveBuilderFee(params) {
|
|
442
|
+
const nonce = Date.now();
|
|
443
|
+
const action = {
|
|
444
|
+
type: constants_1.ExchangeType.APPROVE_BUILDER_FEE,
|
|
445
|
+
hyperliquidChain: this.isTestnet ? 'Testnet' : 'Mainnet',
|
|
446
|
+
signatureChainId: this.isTestnet ? '0x66eee' : '0x42161',
|
|
447
|
+
builder: params.builder.toLowerCase(),
|
|
448
|
+
maxFee: params.maxFee || '0.1%',
|
|
449
|
+
nonce,
|
|
450
|
+
};
|
|
451
|
+
const { domain, types, primaryType, message } = (0, signer_1.prepareMasterSignData)({
|
|
452
|
+
action,
|
|
453
|
+
payloadTypes: [
|
|
454
|
+
{ name: 'type', type: 'string' },
|
|
455
|
+
{ name: 'hyperliquidChain', type: 'string' },
|
|
456
|
+
{ name: 'signatureChainId', type: 'string' },
|
|
457
|
+
{ name: 'builder', type: 'string' },
|
|
458
|
+
{ name: 'maxFee', type: 'string' },
|
|
459
|
+
{ name: 'nonce', type: 'uint64' },
|
|
460
|
+
],
|
|
461
|
+
primaryType: 'HyperliquidTransaction:ApproveBuilderFee',
|
|
462
|
+
isMainnet: !this.isTestnet,
|
|
463
|
+
});
|
|
464
|
+
return {
|
|
465
|
+
domain,
|
|
466
|
+
types,
|
|
467
|
+
primaryType,
|
|
468
|
+
message,
|
|
469
|
+
nonce,
|
|
470
|
+
};
|
|
471
|
+
}
|
|
472
|
+
/**
|
|
473
|
+
* Send approve builder fee request with main wallet signature
|
|
474
|
+
* nonce must be the same as the nonce in the prepareApproveBuilderFee
|
|
475
|
+
* signature is the signature of the main wallet by the prepareApproveBuilderFee action
|
|
476
|
+
*/
|
|
477
|
+
sendApproveBuilderFee(params) {
|
|
478
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
479
|
+
return this.httpClient.exchange({
|
|
480
|
+
action: params.action,
|
|
481
|
+
nonce: params.nonce,
|
|
482
|
+
signature: params.signature,
|
|
483
|
+
});
|
|
484
|
+
});
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* Withdraw funds to L1 need use master wallet
|
|
488
|
+
*/
|
|
489
|
+
prepareWithdraw(params) {
|
|
490
|
+
const nonce = Date.now();
|
|
491
|
+
const action = {
|
|
492
|
+
type: constants_1.ExchangeType.WITHDRAW,
|
|
493
|
+
hyperliquidChain: this.isTestnet ? 'Testnet' : 'Mainnet',
|
|
494
|
+
signatureChainId: this.isTestnet ? '0x66eee' : '0x42161',
|
|
495
|
+
destination: params.destination,
|
|
496
|
+
amount: params.amount,
|
|
497
|
+
time: Date.now(),
|
|
498
|
+
};
|
|
499
|
+
const { domain, types, primaryType, message } = (0, signer_1.prepareMasterSignData)({
|
|
500
|
+
action,
|
|
501
|
+
payloadTypes: [
|
|
502
|
+
{ name: 'type', type: 'string' },
|
|
503
|
+
{ name: 'hyperliquidChain', type: 'string' },
|
|
504
|
+
{ name: 'signatureChainId', type: 'string' },
|
|
505
|
+
{ name: 'destination', type: 'string' },
|
|
506
|
+
{ name: 'amount', type: 'string' },
|
|
507
|
+
{ name: 'time', type: 'uint64' },
|
|
508
|
+
],
|
|
509
|
+
primaryType: 'HyperliquidTransaction:Withdraw',
|
|
510
|
+
isMainnet: !this.isTestnet,
|
|
511
|
+
});
|
|
512
|
+
return {
|
|
513
|
+
domain,
|
|
514
|
+
types,
|
|
515
|
+
primaryType,
|
|
516
|
+
message,
|
|
517
|
+
nonce,
|
|
518
|
+
};
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
exports.ExchangeClient = ExchangeClient;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export interface HttpClientConfig {
|
|
2
|
+
baseURL?: string;
|
|
3
|
+
timeout?: number;
|
|
4
|
+
isTestnet?: boolean;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Simple HTTP client for Hyperliquid API requests
|
|
8
|
+
* No rate limiting - designed for frontend usage
|
|
9
|
+
*/
|
|
10
|
+
export declare class HttpClient {
|
|
11
|
+
private readonly baseURL;
|
|
12
|
+
private readonly timeout;
|
|
13
|
+
constructor(config?: HttpClientConfig);
|
|
14
|
+
/**
|
|
15
|
+
* Make a POST request using fetch
|
|
16
|
+
*/
|
|
17
|
+
private request;
|
|
18
|
+
/**
|
|
19
|
+
* Make a request to the info endpoint
|
|
20
|
+
*/
|
|
21
|
+
info<T = any>(data: any): Promise<T>;
|
|
22
|
+
/**
|
|
23
|
+
* Make a request to the exchange endpoint
|
|
24
|
+
*/
|
|
25
|
+
exchange<T = any>(data: any): Promise<T>;
|
|
26
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
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.HttpClient = void 0;
|
|
13
|
+
const constants_1 = require("../types/constants");
|
|
14
|
+
/**
|
|
15
|
+
* Simple HTTP client for Hyperliquid API requests
|
|
16
|
+
* No rate limiting - designed for frontend usage
|
|
17
|
+
*/
|
|
18
|
+
class HttpClient {
|
|
19
|
+
constructor(config = {}) {
|
|
20
|
+
this.baseURL = config.baseURL || (config.isTestnet ? constants_1.BASE_URLS.TESTNET : constants_1.BASE_URLS.PRODUCTION);
|
|
21
|
+
this.timeout = config.timeout || 10000;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Make a POST request using fetch
|
|
25
|
+
*/
|
|
26
|
+
request(endpoint, data) {
|
|
27
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
28
|
+
const controller = new AbortController();
|
|
29
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
30
|
+
try {
|
|
31
|
+
const response = yield fetch(`${this.baseURL}${endpoint}`, {
|
|
32
|
+
method: 'POST',
|
|
33
|
+
headers: {
|
|
34
|
+
'Content-Type': 'application/json',
|
|
35
|
+
},
|
|
36
|
+
body: JSON.stringify(data),
|
|
37
|
+
signal: controller.signal,
|
|
38
|
+
});
|
|
39
|
+
clearTimeout(timeoutId);
|
|
40
|
+
if (!response.ok) {
|
|
41
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
|
|
42
|
+
}
|
|
43
|
+
const result = yield response.json();
|
|
44
|
+
return result;
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
clearTimeout(timeoutId);
|
|
48
|
+
if (error instanceof Error) {
|
|
49
|
+
if (error.name === 'AbortError') {
|
|
50
|
+
throw new Error('Request timeout');
|
|
51
|
+
}
|
|
52
|
+
throw new Error(`API Error: ${error.message}`);
|
|
53
|
+
}
|
|
54
|
+
throw new Error('Unknown API error');
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Make a request to the info endpoint
|
|
60
|
+
*/
|
|
61
|
+
info(data) {
|
|
62
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
63
|
+
return this.request(constants_1.ENDPOINTS.INFO, data);
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Make a request to the exchange endpoint
|
|
68
|
+
*/
|
|
69
|
+
exchange(data) {
|
|
70
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
71
|
+
return this.request(constants_1.ENDPOINTS.EXCHANGE, data);
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
exports.HttpClient = HttpClient;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { Meta, AssetCtx, ClearinghouseState, UserFills, CandleSnapshot, AllMids, ExtraAgent, OpenOrder, FeeResponse } from '../types';
|
|
2
|
+
import { SymbolConversion } from './symbolConversion';
|
|
3
|
+
export interface InfoClientConfig {
|
|
4
|
+
isTestnet?: boolean;
|
|
5
|
+
timeout?: number;
|
|
6
|
+
masterAddress: string;
|
|
7
|
+
symbolConversion: SymbolConversion;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Client for querying Hyperliquid info endpoints (perpetuals only)
|
|
11
|
+
* Only includes essential APIs as specified
|
|
12
|
+
*/
|
|
13
|
+
export declare class InfoClient {
|
|
14
|
+
private readonly httpClient;
|
|
15
|
+
private readonly masterAddress;
|
|
16
|
+
private readonly symbolConversion;
|
|
17
|
+
constructor(config: InfoClientConfig);
|
|
18
|
+
/**
|
|
19
|
+
* Get all mid prices for all assets
|
|
20
|
+
*/
|
|
21
|
+
getAllMids(): Promise<AllMids>;
|
|
22
|
+
/**
|
|
23
|
+
* Get metadata and asset contexts
|
|
24
|
+
*/
|
|
25
|
+
metaAndAssetCtxs(): Promise<[Meta, AssetCtx[]]>;
|
|
26
|
+
getClearingHouseState(): Promise<ClearinghouseState>;
|
|
27
|
+
getFrontendOpenOrders(): Promise<OpenOrder[]>;
|
|
28
|
+
/**
|
|
29
|
+
* Get user's fill history
|
|
30
|
+
*/
|
|
31
|
+
getUserFills(): Promise<UserFills>;
|
|
32
|
+
/**
|
|
33
|
+
* Get candlestick data snapshot
|
|
34
|
+
* Supported intervals: "1m", "3m", "5m", "15m", "30m", "1h", "2h", "4h", "8h", "12h", "1d", "3d", "1w", "1M"
|
|
35
|
+
*/
|
|
36
|
+
candleSnapshot(coin: string, interval: string, startTime?: number, endTime?: number): Promise<CandleSnapshot>;
|
|
37
|
+
/**
|
|
38
|
+
* Check builder fee approval status
|
|
39
|
+
*/
|
|
40
|
+
checkBuilderFeeApproval(builder: string): Promise<any>;
|
|
41
|
+
/**
|
|
42
|
+
* Get user fees information
|
|
43
|
+
*/
|
|
44
|
+
getUsersFees(): Promise<FeeResponse>;
|
|
45
|
+
/**
|
|
46
|
+
* Get user's approved persistent agents
|
|
47
|
+
*/
|
|
48
|
+
extraAgents(): Promise<ExtraAgent[]>;
|
|
49
|
+
}
|