@rabby-wallet/hyperliquid-sdk 1.0.8 → 1.0.9
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.
|
@@ -29,7 +29,24 @@ export declare class ExchangeClient {
|
|
|
29
29
|
* Place a single order
|
|
30
30
|
*/
|
|
31
31
|
placeOrder(params: PlaceOrderParams): Promise<OrderResponse>;
|
|
32
|
+
/**
|
|
33
|
+
* Calculate slippage price for market orders following Hyperliquid price rules
|
|
34
|
+
* Based on official Python SDK logic
|
|
35
|
+
*
|
|
36
|
+
* Rules:
|
|
37
|
+
* - Round to 5 significant figures
|
|
38
|
+
* - Round to (6 - szDecimals) decimal places for perps
|
|
39
|
+
*
|
|
40
|
+
* @param midPx - Middle price as string
|
|
41
|
+
* @param slippage - Slippage rate (e.g., 0.08 for 8%)
|
|
42
|
+
* @param isBuy - True for buy orders, false for sell orders
|
|
43
|
+
* @param szDecimals - Size decimals from meta endpoint (default 0)
|
|
44
|
+
*/
|
|
32
45
|
private getSlippagePx;
|
|
46
|
+
/**
|
|
47
|
+
* Round a number to specified decimal places
|
|
48
|
+
*/
|
|
49
|
+
private roundToDecimals;
|
|
33
50
|
/**
|
|
34
51
|
* Place a market order
|
|
35
52
|
* default slippage is 0.08
|
|
@@ -167,12 +167,39 @@ class ExchangeClient {
|
|
|
167
167
|
});
|
|
168
168
|
});
|
|
169
169
|
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
170
|
+
/**
|
|
171
|
+
* Calculate slippage price for market orders following Hyperliquid price rules
|
|
172
|
+
* Based on official Python SDK logic
|
|
173
|
+
*
|
|
174
|
+
* Rules:
|
|
175
|
+
* - Round to 5 significant figures
|
|
176
|
+
* - Round to (6 - szDecimals) decimal places for perps
|
|
177
|
+
*
|
|
178
|
+
* @param midPx - Middle price as string
|
|
179
|
+
* @param slippage - Slippage rate (e.g., 0.08 for 8%)
|
|
180
|
+
* @param isBuy - True for buy orders, false for sell orders
|
|
181
|
+
* @param szDecimals - Size decimals from meta endpoint (default 0)
|
|
182
|
+
*/
|
|
183
|
+
getSlippagePx(midPx, slippage, isBuy, szDecimals = 0) {
|
|
184
|
+
let px = parseFloat(midPx);
|
|
185
|
+
if (isNaN(px) || px <= 0) {
|
|
186
|
+
throw new Error('Invalid midPx: must be a positive number');
|
|
187
|
+
}
|
|
188
|
+
// Calculate slippage price
|
|
189
|
+
px *= isBuy ? (1 + slippage) : (1 - slippage);
|
|
190
|
+
// Round to 5 significant figures
|
|
191
|
+
const sigFigRounded = parseFloat(px.toPrecision(5));
|
|
192
|
+
// Round to (6 - szDecimals) decimals for perps
|
|
193
|
+
const maxDecimals = 6 - szDecimals;
|
|
194
|
+
const decimalRounded = this.roundToDecimals(sigFigRounded, maxDecimals);
|
|
195
|
+
return (0, number_1.removeTrailingZeros)(decimalRounded.toFixed(maxDecimals));
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Round a number to specified decimal places
|
|
199
|
+
*/
|
|
200
|
+
roundToDecimals(value, decimals) {
|
|
201
|
+
const multiplier = Math.pow(10, decimals);
|
|
202
|
+
return Math.round(value * multiplier) / multiplier;
|
|
176
203
|
}
|
|
177
204
|
/**
|
|
178
205
|
* Place a market order
|
|
@@ -183,7 +210,8 @@ class ExchangeClient {
|
|
|
183
210
|
return __awaiter(this, void 0, void 0, function* () {
|
|
184
211
|
try {
|
|
185
212
|
const slippage = params.slippage || constants_1.SLIPPAGE;
|
|
186
|
-
const
|
|
213
|
+
const szDecimals = yield this.symbolConversion.getAssetSzDecimals(params.coin);
|
|
214
|
+
const px = this.getSlippagePx((0, number_1.removeTrailingZeros)(params.midPx), slippage, params.isBuy, szDecimals);
|
|
187
215
|
const orders = [{
|
|
188
216
|
coin: params.coin,
|
|
189
217
|
isBuy: params.isBuy,
|
|
@@ -241,7 +269,8 @@ class ExchangeClient {
|
|
|
241
269
|
return __awaiter(this, void 0, void 0, function* () {
|
|
242
270
|
try {
|
|
243
271
|
const slippage = params.slippage || constants_1.SLIPPAGE;
|
|
244
|
-
const
|
|
272
|
+
const szDecimals = yield this.symbolConversion.getAssetSzDecimals(params.coin);
|
|
273
|
+
const px = this.getSlippagePx(params.midPx, slippage, params.isBuy, szDecimals);
|
|
245
274
|
const orders = [{
|
|
246
275
|
coin: params.coin,
|
|
247
276
|
isBuy: params.isBuy,
|
|
@@ -266,6 +295,7 @@ class ExchangeClient {
|
|
|
266
295
|
*/
|
|
267
296
|
multiOrder(params) {
|
|
268
297
|
return __awaiter(this, void 0, void 0, function* () {
|
|
298
|
+
var _a, _b, _c;
|
|
269
299
|
const nonce = Date.now();
|
|
270
300
|
const assetIndexCache = new Map();
|
|
271
301
|
const orderWires = yield Promise.all(params.orders.map((order) => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -295,22 +325,29 @@ class ExchangeClient {
|
|
|
295
325
|
};
|
|
296
326
|
}
|
|
297
327
|
const signature = (0, signer_1.signL1AgentAction)(this.getAgentPrivateKey(), action, this.isTestnet, nonce);
|
|
298
|
-
|
|
328
|
+
const res = yield this.httpClient.exchange({
|
|
299
329
|
action,
|
|
300
330
|
nonce,
|
|
301
331
|
signature,
|
|
302
332
|
});
|
|
333
|
+
(_c = (_b = (_a = res === null || res === void 0 ? void 0 : res.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.statuses) === null || _c === void 0 ? void 0 : _c.forEach((status, index) => {
|
|
334
|
+
if (status.error) {
|
|
335
|
+
throw new Error(status.error);
|
|
336
|
+
}
|
|
337
|
+
});
|
|
338
|
+
return res;
|
|
303
339
|
});
|
|
304
340
|
}
|
|
305
341
|
bindTpslByOrderId(params) {
|
|
306
342
|
return __awaiter(this, void 0, void 0, function* () {
|
|
307
343
|
let orders = [];
|
|
344
|
+
const szDecimals = yield this.symbolConversion.getAssetSzDecimals(params.coin);
|
|
308
345
|
if (params.tpTriggerPx) {
|
|
309
346
|
orders.push({
|
|
310
347
|
coin: params.coin,
|
|
311
348
|
isBuy: !params.isBuy,
|
|
312
349
|
sz: '0',
|
|
313
|
-
limitPx: this.getSlippagePx((0, number_1.removeTrailingZeros)(params.tpTriggerPx), constants_1.SLIPPAGE, !params.isBuy),
|
|
350
|
+
limitPx: this.getSlippagePx((0, number_1.removeTrailingZeros)(params.tpTriggerPx), constants_1.SLIPPAGE, !params.isBuy, szDecimals),
|
|
314
351
|
reduceOnly: true,
|
|
315
352
|
orderType: {
|
|
316
353
|
trigger: {
|
|
@@ -326,7 +363,7 @@ class ExchangeClient {
|
|
|
326
363
|
coin: params.coin,
|
|
327
364
|
isBuy: !params.isBuy,
|
|
328
365
|
sz: '0',
|
|
329
|
-
limitPx: this.getSlippagePx((0, number_1.removeTrailingZeros)(params.slTriggerPx), constants_1.SLIPPAGE, !params.isBuy),
|
|
366
|
+
limitPx: this.getSlippagePx((0, number_1.removeTrailingZeros)(params.slTriggerPx), constants_1.SLIPPAGE, !params.isBuy, szDecimals),
|
|
330
367
|
reduceOnly: true,
|
|
331
368
|
orderType: {
|
|
332
369
|
trigger: {
|
|
@@ -2,6 +2,7 @@ import { HttpClientConfig } from "./http-client";
|
|
|
2
2
|
import { InfoClient } from "./info-client";
|
|
3
3
|
export declare class SymbolConversion {
|
|
4
4
|
private assetToIndexMap;
|
|
5
|
+
private assetSzDecimalsMap;
|
|
5
6
|
private httpClient;
|
|
6
7
|
private initialized;
|
|
7
8
|
private infoClient?;
|
|
@@ -10,6 +11,7 @@ export declare class SymbolConversion {
|
|
|
10
11
|
private ensureInitialized;
|
|
11
12
|
private refreshAssetMaps;
|
|
12
13
|
getAssetIndex(assetSymbol: string): Promise<number>;
|
|
14
|
+
getAssetSzDecimals(assetSymbol: string): Promise<number>;
|
|
13
15
|
getAllAssets(): Promise<{
|
|
14
16
|
perp: string[];
|
|
15
17
|
}>;
|
|
@@ -15,6 +15,7 @@ const http_client_1 = require("./http-client");
|
|
|
15
15
|
class SymbolConversion {
|
|
16
16
|
constructor(config, infoClient) {
|
|
17
17
|
this.assetToIndexMap = new Map();
|
|
18
|
+
this.assetSzDecimalsMap = new Map();
|
|
18
19
|
this.initialized = false;
|
|
19
20
|
this.infoClient = infoClient;
|
|
20
21
|
this.httpClient = new http_client_1.HttpClient({
|
|
@@ -64,9 +65,11 @@ class SymbolConversion {
|
|
|
64
65
|
throw new Error('Invalid perpetual metadata response');
|
|
65
66
|
}
|
|
66
67
|
this.assetToIndexMap.clear();
|
|
68
|
+
this.assetSzDecimalsMap.clear();
|
|
67
69
|
// Handle perpetual assets
|
|
68
70
|
perpMeta[0].universe.forEach((asset, index) => {
|
|
69
71
|
this.assetToIndexMap.set(asset.name, index);
|
|
72
|
+
this.assetSzDecimalsMap.set(asset.name, asset.szDecimals);
|
|
70
73
|
});
|
|
71
74
|
}
|
|
72
75
|
catch (error) {
|
|
@@ -84,6 +87,16 @@ class SymbolConversion {
|
|
|
84
87
|
return index;
|
|
85
88
|
});
|
|
86
89
|
}
|
|
90
|
+
getAssetSzDecimals(assetSymbol) {
|
|
91
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
92
|
+
yield this.ensureInitialized();
|
|
93
|
+
const szDecimals = this.assetSzDecimalsMap.get(assetSymbol);
|
|
94
|
+
if (szDecimals === undefined) {
|
|
95
|
+
throw new Error(`Unknown asset szDecimals: ${assetSymbol}`);
|
|
96
|
+
}
|
|
97
|
+
return szDecimals;
|
|
98
|
+
});
|
|
99
|
+
}
|
|
87
100
|
getAllAssets() {
|
|
88
101
|
return __awaiter(this, void 0, void 0, function* () {
|
|
89
102
|
yield this.ensureInitialized();
|