@rabby-wallet/hyperliquid-sdk 1.0.8-beta1 → 1.0.8-beta4
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.
|
@@ -21,7 +21,7 @@ export declare class ExchangeClient {
|
|
|
21
21
|
updateExchangeAgent(agentPrivateKey: string, agentPublicKey: string, agentName?: string): void;
|
|
22
22
|
private getAgentPrivateKey;
|
|
23
23
|
/**
|
|
24
|
-
* deprecated
|
|
24
|
+
* @deprecated This method is deprecated. Use the new builder configuration in constructor instead.
|
|
25
25
|
*/
|
|
26
26
|
updateBuilder(address: string, fee: number): Promise<any>;
|
|
27
27
|
updateLeverage(params: UpdateLeverageParams): Promise<any>;
|
|
@@ -29,7 +29,25 @@ 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
|
+
* @param isSpot - Whether this is a spot asset (default false for perps)
|
|
45
|
+
*/
|
|
32
46
|
private getSlippagePx;
|
|
47
|
+
/**
|
|
48
|
+
* Round a number to specified decimal places
|
|
49
|
+
*/
|
|
50
|
+
private roundToDecimals;
|
|
33
51
|
/**
|
|
34
52
|
* Place a market order
|
|
35
53
|
* default slippage is 0.08
|
|
@@ -104,7 +104,7 @@ class ExchangeClient {
|
|
|
104
104
|
return this.agentPrivateKey;
|
|
105
105
|
}
|
|
106
106
|
/**
|
|
107
|
-
* deprecated
|
|
107
|
+
* @deprecated This method is deprecated. Use the new builder configuration in constructor instead.
|
|
108
108
|
*/
|
|
109
109
|
updateBuilder(address, fee) {
|
|
110
110
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -167,12 +167,40 @@ 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
|
+
* @param isSpot - Whether this is a spot asset (default false for perps)
|
|
183
|
+
*/
|
|
184
|
+
getSlippagePx(midPx, slippage, isBuy, szDecimals = 0) {
|
|
185
|
+
let px = parseFloat(midPx);
|
|
186
|
+
if (isNaN(px) || px <= 0) {
|
|
187
|
+
throw new Error('Invalid midPx: must be a positive number');
|
|
188
|
+
}
|
|
189
|
+
// Calculate slippage price
|
|
190
|
+
px *= isBuy ? (1 + slippage) : (1 - slippage);
|
|
191
|
+
// Round to 5 significant figures
|
|
192
|
+
const sigFigRounded = parseFloat(px.toPrecision(5));
|
|
193
|
+
// Round to (6 - szDecimals) decimals for perps
|
|
194
|
+
const maxDecimals = 6 - szDecimals;
|
|
195
|
+
const decimalRounded = this.roundToDecimals(sigFigRounded, maxDecimals);
|
|
196
|
+
return (0, number_1.removeTrailingZeros)(decimalRounded.toFixed(maxDecimals));
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Round a number to specified decimal places
|
|
200
|
+
*/
|
|
201
|
+
roundToDecimals(value, decimals) {
|
|
202
|
+
const multiplier = Math.pow(10, decimals);
|
|
203
|
+
return Math.round(value * multiplier) / multiplier;
|
|
176
204
|
}
|
|
177
205
|
/**
|
|
178
206
|
* Place a market order
|
|
@@ -183,7 +211,8 @@ class ExchangeClient {
|
|
|
183
211
|
return __awaiter(this, void 0, void 0, function* () {
|
|
184
212
|
try {
|
|
185
213
|
const slippage = params.slippage || constants_1.SLIPPAGE;
|
|
186
|
-
const
|
|
214
|
+
const szDecimals = yield this.symbolConversion.getAssetSzDecimals(params.coin);
|
|
215
|
+
const px = this.getSlippagePx((0, number_1.removeTrailingZeros)(params.midPx), slippage, params.isBuy, szDecimals);
|
|
187
216
|
const orders = [{
|
|
188
217
|
coin: params.coin,
|
|
189
218
|
isBuy: params.isBuy,
|
|
@@ -241,7 +270,8 @@ class ExchangeClient {
|
|
|
241
270
|
return __awaiter(this, void 0, void 0, function* () {
|
|
242
271
|
try {
|
|
243
272
|
const slippage = params.slippage || constants_1.SLIPPAGE;
|
|
244
|
-
const
|
|
273
|
+
const szDecimals = yield this.symbolConversion.getAssetSzDecimals(params.coin);
|
|
274
|
+
const px = this.getSlippagePx(params.midPx, slippage, params.isBuy, szDecimals);
|
|
245
275
|
const orders = [{
|
|
246
276
|
coin: params.coin,
|
|
247
277
|
isBuy: params.isBuy,
|
|
@@ -266,6 +296,7 @@ class ExchangeClient {
|
|
|
266
296
|
*/
|
|
267
297
|
multiOrder(params) {
|
|
268
298
|
return __awaiter(this, void 0, void 0, function* () {
|
|
299
|
+
var _a, _b, _c;
|
|
269
300
|
const nonce = Date.now();
|
|
270
301
|
const assetIndexCache = new Map();
|
|
271
302
|
const orderWires = yield Promise.all(params.orders.map((order) => __awaiter(this, void 0, void 0, function* () {
|
|
@@ -295,22 +326,29 @@ class ExchangeClient {
|
|
|
295
326
|
};
|
|
296
327
|
}
|
|
297
328
|
const signature = (0, signer_1.signL1AgentAction)(this.getAgentPrivateKey(), action, this.isTestnet, nonce);
|
|
298
|
-
|
|
329
|
+
const res = yield this.httpClient.exchange({
|
|
299
330
|
action,
|
|
300
331
|
nonce,
|
|
301
332
|
signature,
|
|
302
333
|
});
|
|
334
|
+
(_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) => {
|
|
335
|
+
if (status.error) {
|
|
336
|
+
throw new Error(status.error);
|
|
337
|
+
}
|
|
338
|
+
});
|
|
339
|
+
return res;
|
|
303
340
|
});
|
|
304
341
|
}
|
|
305
342
|
bindTpslByOrderId(params) {
|
|
306
343
|
return __awaiter(this, void 0, void 0, function* () {
|
|
307
344
|
let orders = [];
|
|
345
|
+
const szDecimals = yield this.symbolConversion.getAssetSzDecimals(params.coin);
|
|
308
346
|
if (params.tpTriggerPx) {
|
|
309
347
|
orders.push({
|
|
310
348
|
coin: params.coin,
|
|
311
349
|
isBuy: !params.isBuy,
|
|
312
350
|
sz: '0',
|
|
313
|
-
limitPx: this.getSlippagePx((0, number_1.removeTrailingZeros)(params.tpTriggerPx), constants_1.SLIPPAGE, !params.isBuy),
|
|
351
|
+
limitPx: this.getSlippagePx((0, number_1.removeTrailingZeros)(params.tpTriggerPx), constants_1.SLIPPAGE, !params.isBuy, szDecimals),
|
|
314
352
|
reduceOnly: true,
|
|
315
353
|
orderType: {
|
|
316
354
|
trigger: {
|
|
@@ -326,7 +364,7 @@ class ExchangeClient {
|
|
|
326
364
|
coin: params.coin,
|
|
327
365
|
isBuy: !params.isBuy,
|
|
328
366
|
sz: '0',
|
|
329
|
-
limitPx: this.getSlippagePx((0, number_1.removeTrailingZeros)(params.slTriggerPx), constants_1.SLIPPAGE, !params.isBuy),
|
|
367
|
+
limitPx: this.getSlippagePx((0, number_1.removeTrailingZeros)(params.slTriggerPx), constants_1.SLIPPAGE, !params.isBuy, szDecimals),
|
|
330
368
|
reduceOnly: true,
|
|
331
369
|
orderType: {
|
|
332
370
|
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 index: ${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();
|
package/package.json
CHANGED