@nktkas/hyperliquid 0.13.1 → 0.14.0
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/LICENSE +20 -20
- package/README.md +334 -107
- package/esm/deps/jsr.io/@std/bytes/1.0.5/_types.d.ts +9 -0
- package/esm/deps/jsr.io/@std/bytes/1.0.5/_types.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/bytes/1.0.5/_types.js +2 -0
- package/esm/deps/jsr.io/@std/bytes/{1.0.4 → 1.0.5}/concat.d.ts +3 -1
- package/esm/deps/jsr.io/@std/bytes/1.0.5/concat.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/bytes/{1.0.4 → 1.0.5}/concat.js +1 -1
- package/esm/deps/jsr.io/@std/encoding/1.0.7/_types.d.ts +9 -0
- package/esm/deps/jsr.io/@std/encoding/1.0.7/_types.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/encoding/1.0.7/_types.js +2 -0
- package/esm/deps/jsr.io/@std/encoding/{1.0.6 → 1.0.7}/_validate_binary_like.d.ts.map +1 -1
- package/esm/deps/jsr.io/@std/encoding/{1.0.6 → 1.0.7}/_validate_binary_like.js +1 -1
- package/{script/deps/jsr.io/@std/encoding/1.0.6 → esm/deps/jsr.io/@std/encoding/1.0.7}/hex.d.ts +3 -1
- package/esm/deps/jsr.io/@std/encoding/1.0.7/hex.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/encoding/{1.0.6 → 1.0.7}/hex.js +1 -1
- package/esm/deps/jsr.io/@std/msgpack/1.0.3/_types.d.ts +9 -0
- package/esm/deps/jsr.io/@std/msgpack/1.0.3/_types.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/msgpack/1.0.3/_types.js +2 -0
- package/esm/deps/jsr.io/@std/msgpack/{1.0.2 → 1.0.3}/encode.d.ts +3 -1
- package/esm/deps/jsr.io/@std/msgpack/1.0.3/encode.d.ts.map +1 -0
- package/esm/deps/jsr.io/@std/msgpack/{1.0.2 → 1.0.3}/encode.js +2 -2
- package/esm/mod.d.ts +4 -12
- package/esm/mod.d.ts.map +1 -1
- package/esm/mod.js +2 -2
- package/{script/src/transports → esm/src}/base.d.ts +10 -13
- package/esm/src/base.d.ts.map +1 -0
- package/esm/src/base.js +14 -0
- package/esm/src/clients/event.d.ts +59 -18
- package/esm/src/clients/event.d.ts.map +1 -1
- package/esm/src/clients/event.js +74 -18
- package/esm/src/clients/public.d.ts +348 -53
- package/esm/src/clients/public.d.ts.map +1 -1
- package/esm/src/clients/public.js +349 -50
- package/esm/src/clients/wallet.d.ts +345 -73
- package/esm/src/clients/wallet.d.ts.map +1 -1
- package/esm/src/clients/wallet.js +979 -229
- package/esm/src/signing.d.ts +135 -0
- package/esm/src/signing.d.ts.map +1 -0
- package/esm/src/signing.js +188 -0
- package/esm/src/transports/http/http_transport.d.ts +1 -1
- package/esm/src/transports/http/http_transport.d.ts.map +1 -1
- package/esm/src/transports/http/http_transport.js +1 -1
- package/esm/src/transports/websocket/_hyperliquid_event_target.d.ts +64 -0
- package/esm/src/transports/websocket/_hyperliquid_event_target.d.ts.map +1 -0
- package/esm/src/transports/websocket/_hyperliquid_event_target.js +52 -0
- package/esm/src/transports/websocket/{reconnecting_websocket.d.ts → _reconnecting_websocket.d.ts} +26 -26
- package/esm/src/transports/websocket/_reconnecting_websocket.d.ts.map +1 -0
- package/esm/src/transports/websocket/{reconnecting_websocket.js → _reconnecting_websocket.js} +91 -76
- package/{script/src/transports/websocket/websocket_request_dispatcher.d.ts → esm/src/transports/websocket/_websocket_request_dispatcher.d.ts} +3 -7
- package/esm/src/transports/websocket/_websocket_request_dispatcher.d.ts.map +1 -0
- package/esm/src/transports/websocket/{websocket_request_dispatcher.js → _websocket_request_dispatcher.js} +6 -10
- package/esm/src/transports/websocket/websocket_transport.d.ts +15 -21
- package/esm/src/transports/websocket/websocket_transport.d.ts.map +1 -1
- package/esm/src/transports/websocket/websocket_transport.js +55 -52
- package/esm/src/types/exchange/requests.d.ts +298 -79
- package/esm/src/types/exchange/requests.d.ts.map +1 -1
- package/esm/src/types/exchange/responses.d.ts +38 -38
- package/esm/src/types/exchange/responses.d.ts.map +1 -1
- package/esm/src/types/explorer/requests.d.ts +23 -10
- package/esm/src/types/explorer/requests.d.ts.map +1 -1
- package/esm/src/types/explorer/responses.d.ts +45 -3
- package/esm/src/types/explorer/responses.d.ts.map +1 -1
- package/esm/src/types/info/accounts.d.ts +279 -189
- package/esm/src/types/info/accounts.d.ts.map +1 -1
- package/esm/src/types/info/assets.d.ts +191 -185
- package/esm/src/types/info/assets.d.ts.map +1 -1
- package/esm/src/types/info/delegations.d.ts +117 -0
- package/esm/src/types/info/delegations.d.ts.map +1 -0
- package/esm/src/types/info/orders.d.ts +94 -94
- package/esm/src/types/info/orders.d.ts.map +1 -1
- package/esm/src/types/info/requests.d.ts +192 -64
- package/esm/src/types/info/requests.d.ts.map +1 -1
- package/esm/src/types/info/vaults.d.ts +42 -85
- package/esm/src/types/info/vaults.d.ts.map +1 -1
- package/esm/src/types/mod.d.ts +14 -0
- package/esm/src/types/mod.d.ts.map +1 -0
- package/esm/src/types/subscriptions/requests.d.ts +11 -1
- package/esm/src/types/subscriptions/requests.d.ts.map +1 -1
- package/{script/src/types/subscriptions/common.d.ts → esm/src/types/subscriptions/responses.d.ts} +18 -3
- package/esm/src/types/subscriptions/responses.d.ts.map +1 -0
- package/package.json +20 -4
- package/script/deps/jsr.io/@derzade/typescript-event-target/1.1.1/mod.js +13 -3
- package/script/deps/jsr.io/@derzade/typescript-event-target/1.1.1/src/TypedEventTarget.js +23 -13
- package/script/deps/jsr.io/@noble/hashes/1.7.1/src/_assert.js +55 -45
- package/script/deps/jsr.io/@noble/hashes/1.7.1/src/_u64.js +97 -87
- package/script/deps/jsr.io/@noble/hashes/1.7.1/src/crypto.js +14 -4
- package/script/deps/jsr.io/@noble/hashes/1.7.1/src/sha3.js +288 -278
- package/script/deps/jsr.io/@noble/hashes/1.7.1/src/utils.js +238 -228
- package/script/deps/jsr.io/@std/bytes/1.0.5/_types.d.ts +9 -0
- package/script/deps/jsr.io/@std/bytes/1.0.5/_types.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/bytes/1.0.5/_types.js +13 -0
- package/script/deps/jsr.io/@std/bytes/{1.0.4 → 1.0.5}/concat.d.ts +3 -1
- package/script/deps/jsr.io/@std/bytes/1.0.5/concat.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/bytes/1.0.5/concat.js +45 -0
- package/script/deps/jsr.io/@std/encoding/1.0.7/_types.d.ts +9 -0
- package/script/deps/jsr.io/@std/encoding/1.0.7/_types.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/encoding/1.0.7/_types.js +13 -0
- package/script/deps/jsr.io/@std/encoding/{1.0.6 → 1.0.7}/_validate_binary_like.d.ts.map +1 -1
- package/script/deps/jsr.io/@std/encoding/1.0.7/_validate_binary_like.js +39 -0
- package/{esm/deps/jsr.io/@std/encoding/1.0.6 → script/deps/jsr.io/@std/encoding/1.0.7}/hex.d.ts +3 -1
- package/script/deps/jsr.io/@std/encoding/1.0.7/hex.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/encoding/1.0.7/hex.js +123 -0
- package/script/deps/jsr.io/@std/msgpack/1.0.3/_types.d.ts +9 -0
- package/script/deps/jsr.io/@std/msgpack/1.0.3/_types.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/msgpack/1.0.3/_types.js +13 -0
- package/script/deps/jsr.io/@std/msgpack/{1.0.2 → 1.0.3}/encode.d.ts +3 -1
- package/script/deps/jsr.io/@std/msgpack/1.0.3/encode.d.ts.map +1 -0
- package/script/deps/jsr.io/@std/msgpack/1.0.3/encode.js +250 -0
- package/script/mod.d.ts +4 -12
- package/script/mod.d.ts.map +1 -1
- package/script/mod.js +21 -13
- package/{esm/src/transports → script/src}/base.d.ts +10 -13
- package/script/src/base.d.ts.map +1 -0
- package/script/src/base.js +29 -0
- package/script/src/clients/event.d.ts +59 -18
- package/script/src/clients/event.d.ts.map +1 -1
- package/script/src/clients/event.js +551 -485
- package/script/src/clients/public.d.ts +348 -53
- package/script/src/clients/public.d.ts.map +1 -1
- package/script/src/clients/public.js +1017 -708
- package/script/src/clients/wallet.d.ts +345 -73
- package/script/src/clients/wallet.d.ts.map +1 -1
- package/script/src/clients/wallet.js +1737 -977
- package/script/src/signing.d.ts +135 -0
- package/script/src/signing.d.ts.map +1 -0
- package/script/src/signing.js +203 -0
- package/script/src/transports/http/http_transport.d.ts +1 -1
- package/script/src/transports/http/http_transport.d.ts.map +1 -1
- package/script/src/transports/http/http_transport.js +174 -164
- package/script/src/transports/websocket/_hyperliquid_event_target.d.ts +64 -0
- package/script/src/transports/websocket/_hyperliquid_event_target.d.ts.map +1 -0
- package/script/src/transports/websocket/_hyperliquid_event_target.js +66 -0
- package/script/src/transports/websocket/{reconnecting_websocket.d.ts → _reconnecting_websocket.d.ts} +26 -26
- package/script/src/transports/websocket/_reconnecting_websocket.d.ts.map +1 -0
- package/script/src/transports/websocket/_reconnecting_websocket.js +400 -0
- package/{esm/src/transports/websocket/websocket_request_dispatcher.d.ts → script/src/transports/websocket/_websocket_request_dispatcher.d.ts} +3 -7
- package/script/src/transports/websocket/_websocket_request_dispatcher.d.ts.map +1 -0
- package/script/src/transports/websocket/_websocket_request_dispatcher.js +212 -0
- package/script/src/transports/websocket/websocket_transport.d.ts +15 -21
- package/script/src/transports/websocket/websocket_transport.d.ts.map +1 -1
- package/script/src/transports/websocket/websocket_transport.js +235 -222
- package/script/src/types/exchange/requests.d.ts +298 -79
- package/script/src/types/exchange/requests.d.ts.map +1 -1
- package/script/src/types/exchange/requests.js +12 -2
- package/script/src/types/exchange/responses.d.ts +38 -38
- package/script/src/types/exchange/responses.d.ts.map +1 -1
- package/script/src/types/exchange/responses.js +12 -2
- package/script/src/types/explorer/requests.d.ts +23 -10
- package/script/src/types/explorer/requests.d.ts.map +1 -1
- package/script/src/types/explorer/requests.js +12 -2
- package/script/src/types/explorer/responses.d.ts +45 -3
- package/script/src/types/explorer/responses.d.ts.map +1 -1
- package/script/src/types/explorer/responses.js +12 -2
- package/script/src/types/info/accounts.d.ts +279 -189
- package/script/src/types/info/accounts.d.ts.map +1 -1
- package/script/src/types/info/accounts.js +12 -2
- package/script/src/types/info/assets.d.ts +191 -185
- package/script/src/types/info/assets.d.ts.map +1 -1
- package/script/src/types/info/assets.js +12 -2
- package/script/src/types/info/delegations.d.ts +117 -0
- package/script/src/types/info/delegations.d.ts.map +1 -0
- package/script/src/types/info/delegations.js +12 -0
- package/script/src/types/info/orders.d.ts +94 -94
- package/script/src/types/info/orders.d.ts.map +1 -1
- package/script/src/types/info/orders.js +12 -2
- package/script/src/types/info/requests.d.ts +192 -64
- package/script/src/types/info/requests.d.ts.map +1 -1
- package/script/src/types/info/requests.js +12 -2
- package/script/src/types/info/vaults.d.ts +42 -85
- package/script/src/types/info/vaults.d.ts.map +1 -1
- package/script/src/types/info/vaults.js +12 -2
- package/script/src/types/mod.d.ts +14 -0
- package/script/src/types/mod.d.ts.map +1 -0
- package/script/src/types/mod.js +12 -0
- package/script/src/types/subscriptions/requests.d.ts +11 -1
- package/script/src/types/subscriptions/requests.d.ts.map +1 -1
- package/script/src/types/subscriptions/requests.js +12 -2
- package/{esm/src/types/subscriptions/common.d.ts → script/src/types/subscriptions/responses.d.ts} +18 -3
- package/script/src/types/subscriptions/responses.d.ts.map +1 -0
- package/script/src/types/subscriptions/responses.js +12 -0
- package/esm/deps/jsr.io/@std/bytes/1.0.4/concat.d.ts.map +0 -1
- package/esm/deps/jsr.io/@std/encoding/1.0.6/hex.d.ts.map +0 -1
- package/esm/deps/jsr.io/@std/msgpack/1.0.2/encode.d.ts.map +0 -1
- package/esm/src/transports/base.d.ts.map +0 -1
- package/esm/src/transports/base.js +0 -14
- package/esm/src/transports/websocket/hyperliquid_event_target.d.ts +0 -66
- package/esm/src/transports/websocket/hyperliquid_event_target.d.ts.map +0 -1
- package/esm/src/transports/websocket/hyperliquid_event_target.js +0 -33
- package/esm/src/transports/websocket/reconnecting_websocket.d.ts.map +0 -1
- package/esm/src/transports/websocket/websocket_request_dispatcher.d.ts.map +0 -1
- package/esm/src/types/common.d.ts +0 -3
- package/esm/src/types/common.d.ts.map +0 -1
- package/esm/src/types/exchange/common.d.ts +0 -36
- package/esm/src/types/exchange/common.d.ts.map +0 -1
- package/esm/src/types/explorer/common.d.ts +0 -37
- package/esm/src/types/explorer/common.d.ts.map +0 -1
- package/esm/src/types/subscriptions/common.d.ts.map +0 -1
- package/esm/src/types/subscriptions/common.js +0 -1
- package/esm/src/utils/key_sort.d.ts +0 -21
- package/esm/src/utils/key_sort.d.ts.map +0 -1
- package/esm/src/utils/key_sort.js +0 -124
- package/esm/src/utils/signing.d.ts +0 -109
- package/esm/src/utils/signing.d.ts.map +0 -1
- package/esm/src/utils/signing.js +0 -164
- package/script/deps/jsr.io/@std/bytes/1.0.4/concat.d.ts.map +0 -1
- package/script/deps/jsr.io/@std/bytes/1.0.4/concat.js +0 -35
- package/script/deps/jsr.io/@std/encoding/1.0.6/_validate_binary_like.js +0 -29
- package/script/deps/jsr.io/@std/encoding/1.0.6/hex.d.ts.map +0 -1
- package/script/deps/jsr.io/@std/encoding/1.0.6/hex.js +0 -113
- package/script/deps/jsr.io/@std/msgpack/1.0.2/encode.d.ts.map +0 -1
- package/script/deps/jsr.io/@std/msgpack/1.0.2/encode.js +0 -240
- package/script/src/transports/base.d.ts.map +0 -1
- package/script/src/transports/base.js +0 -18
- package/script/src/transports/websocket/hyperliquid_event_target.d.ts +0 -66
- package/script/src/transports/websocket/hyperliquid_event_target.d.ts.map +0 -1
- package/script/src/transports/websocket/hyperliquid_event_target.js +0 -37
- package/script/src/transports/websocket/reconnecting_websocket.d.ts.map +0 -1
- package/script/src/transports/websocket/reconnecting_websocket.js +0 -374
- package/script/src/transports/websocket/websocket_request_dispatcher.d.ts.map +0 -1
- package/script/src/transports/websocket/websocket_request_dispatcher.js +0 -206
- package/script/src/types/common.d.ts +0 -3
- package/script/src/types/common.d.ts.map +0 -1
- package/script/src/types/common.js +0 -2
- package/script/src/types/exchange/common.d.ts +0 -36
- package/script/src/types/exchange/common.d.ts.map +0 -1
- package/script/src/types/exchange/common.js +0 -2
- package/script/src/types/explorer/common.d.ts +0 -37
- package/script/src/types/explorer/common.d.ts.map +0 -1
- package/script/src/types/explorer/common.js +0 -2
- package/script/src/types/subscriptions/common.d.ts.map +0 -1
- package/script/src/types/subscriptions/common.js +0 -2
- package/script/src/utils/key_sort.d.ts +0 -21
- package/script/src/utils/key_sort.d.ts.map +0 -1
- package/script/src/utils/key_sort.js +0 -127
- package/script/src/utils/signing.d.ts +0 -109
- package/script/src/utils/signing.d.ts.map +0 -1
- package/script/src/utils/signing.js +0 -172
- /package/esm/deps/jsr.io/@std/encoding/{1.0.6 → 1.0.7}/_validate_binary_like.d.ts +0 -0
- /package/esm/src/types/{common.js → info/delegations.js} +0 -0
- /package/esm/src/types/{exchange/common.js → mod.js} +0 -0
- /package/esm/src/types/{explorer/common.js → subscriptions/responses.js} +0 -0
- /package/script/deps/jsr.io/@std/encoding/{1.0.6 → 1.0.7}/_validate_binary_like.d.ts +0 -0
|
@@ -1,991 +1,1751 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
}
|
|
23
|
-
if (errors.length > 0) {
|
|
24
|
-
message += `: ${errors.join(", ")}`;
|
|
25
|
-
}
|
|
1
|
+
(function (factory) {
|
|
2
|
+
if (typeof module === "object" && typeof module.exports === "object") {
|
|
3
|
+
var v = factory(require, exports);
|
|
4
|
+
if (v !== undefined) module.exports = v;
|
|
5
|
+
}
|
|
6
|
+
else if (typeof define === "function" && define.amd) {
|
|
7
|
+
define(["require", "exports", "../base.js", "../signing.js"], factory);
|
|
8
|
+
}
|
|
9
|
+
})(function (require, exports) {
|
|
10
|
+
"use strict";
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.WalletClient = exports.ApiRequestError = void 0;
|
|
13
|
+
const base_js_1 = require("../base.js");
|
|
14
|
+
const signing_js_1 = require("../signing.js");
|
|
15
|
+
// ——————————————— Errors ———————————————
|
|
16
|
+
/** Error thrown when the API returns an error response. */
|
|
17
|
+
class ApiRequestError extends base_js_1.HyperliquidError {
|
|
18
|
+
constructor(response) {
|
|
19
|
+
let message = "Cannot process API request";
|
|
20
|
+
if (response.status === "err") {
|
|
21
|
+
// For ErrorResponse
|
|
22
|
+
message += `: ${response.response}`;
|
|
26
23
|
}
|
|
27
24
|
else {
|
|
28
|
-
if (
|
|
29
|
-
|
|
25
|
+
if ("statuses" in response.response.data) {
|
|
26
|
+
// For OrderResponse, CancelResponse
|
|
27
|
+
const errors = response.response.data.statuses.reduce((acc, status, index) => {
|
|
28
|
+
if (typeof status === "object" && "error" in status) {
|
|
29
|
+
acc.push(`Order ${index} failed: ${status.error}`);
|
|
30
|
+
}
|
|
31
|
+
return acc;
|
|
32
|
+
}, []);
|
|
33
|
+
if (errors.length > 0) {
|
|
34
|
+
message += `: ${errors.join(", ")}`;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
// For TwapOrderResponse, TwapCancelResponse
|
|
39
|
+
if (typeof response.response.data.status === "object" && "error" in response.response.data.status) {
|
|
40
|
+
message += `: ${response.response.data.status.error}`;
|
|
41
|
+
}
|
|
30
42
|
}
|
|
31
43
|
}
|
|
44
|
+
super(message);
|
|
45
|
+
Object.defineProperty(this, "response", {
|
|
46
|
+
enumerable: true,
|
|
47
|
+
configurable: true,
|
|
48
|
+
writable: true,
|
|
49
|
+
value: response
|
|
50
|
+
});
|
|
51
|
+
this.name = "ApiRequestError";
|
|
32
52
|
}
|
|
33
|
-
super(message);
|
|
34
|
-
Object.defineProperty(this, "response", {
|
|
35
|
-
enumerable: true,
|
|
36
|
-
configurable: true,
|
|
37
|
-
writable: true,
|
|
38
|
-
value: response
|
|
39
|
-
});
|
|
40
|
-
this.name = "ApiRequestError";
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
exports.ApiRequestError = ApiRequestError;
|
|
44
|
-
// ———————————————Client———————————————
|
|
45
|
-
/**
|
|
46
|
-
* Wallet client for interacting with the Hyperliquid API.
|
|
47
|
-
* @typeParam T - The transport used to connect to the Hyperliquid API.
|
|
48
|
-
* @typeParam W - The WalletClient/Account ([viem](https://viem.sh/docs/clients/wallet)) or Signer ([ethers.js](https://docs.ethers.io/v6/api/providers/#Signer)) used for signing transactions.
|
|
49
|
-
*/
|
|
50
|
-
class WalletClient {
|
|
51
|
-
/**
|
|
52
|
-
* Initialises a new instance.
|
|
53
|
-
* @param args - The parameters for the client.
|
|
54
|
-
*
|
|
55
|
-
* @example Private key via [viem](https://viem.sh/docs/clients/wallet#local-accounts-private-key-mnemonic-etc)
|
|
56
|
-
* ```ts
|
|
57
|
-
* import * as hl from "@nktkas/hyperliquid";
|
|
58
|
-
* import { privateKeyToAccount } from "viem/accounts";
|
|
59
|
-
*
|
|
60
|
-
* const wallet = privateKeyToAccount("0x...");
|
|
61
|
-
*
|
|
62
|
-
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
63
|
-
* const client = new hl.WalletClient({ wallet, transport });
|
|
64
|
-
* ```
|
|
65
|
-
*
|
|
66
|
-
* @example Private key via [ethers.js](https://docs.ethers.org/v6/api/wallet/#Wallet)
|
|
67
|
-
* ```ts
|
|
68
|
-
* import * as hl from "@nktkas/hyperliquid";
|
|
69
|
-
* import { ethers } from "ethers";
|
|
70
|
-
*
|
|
71
|
-
* const wallet = new ethers.Wallet("0x...");
|
|
72
|
-
*
|
|
73
|
-
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
74
|
-
* const client = new hl.WalletClient({ wallet, transport });
|
|
75
|
-
* ```
|
|
76
|
-
*
|
|
77
|
-
* @example External wallet (e.g. MetaMask) via [viem](https://viem.sh/docs/clients/wallet#optional-hoist-the-account)
|
|
78
|
-
* ```ts
|
|
79
|
-
* import * as hl from "@nktkas/hyperliquid";
|
|
80
|
-
* import { createWalletClient, custom } from "viem";
|
|
81
|
-
* import { arbitrum } from "viem/chains";
|
|
82
|
-
*
|
|
83
|
-
* const [account] = await window.ethereum.request({ method: "eth_requestAccounts" });
|
|
84
|
-
* const wallet = createWalletClient({ account, chain: arbitrum, transport: custom(window.ethereum) });
|
|
85
|
-
*
|
|
86
|
-
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
87
|
-
* const client = new hl.WalletClient({ wallet, transport });
|
|
88
|
-
* ```
|
|
89
|
-
*/
|
|
90
|
-
constructor(args) {
|
|
91
|
-
/** The transport used to connect to the Hyperliquid API. */
|
|
92
|
-
Object.defineProperty(this, "transport", {
|
|
93
|
-
enumerable: true,
|
|
94
|
-
configurable: true,
|
|
95
|
-
writable: true,
|
|
96
|
-
value: void 0
|
|
97
|
-
});
|
|
98
|
-
/** The WalletClient/Account ([viem](https://viem.sh/docs/clients/wallet)) or Signer ([ethers.js](https://docs.ethers.org/v6/api/providers/#Signer)) used for signing transactions. */
|
|
99
|
-
Object.defineProperty(this, "wallet", {
|
|
100
|
-
enumerable: true,
|
|
101
|
-
configurable: true,
|
|
102
|
-
writable: true,
|
|
103
|
-
value: void 0
|
|
104
|
-
});
|
|
105
|
-
/** Specifies whether the client uses testnet. */
|
|
106
|
-
Object.defineProperty(this, "isTestnet", {
|
|
107
|
-
enumerable: true,
|
|
108
|
-
configurable: true,
|
|
109
|
-
writable: true,
|
|
110
|
-
value: void 0
|
|
111
|
-
});
|
|
112
|
-
/** Sets a default vaultAddress to be used if no vaultAddress is explicitly passed to a method. */
|
|
113
|
-
Object.defineProperty(this, "defaultVaultAddress", {
|
|
114
|
-
enumerable: true,
|
|
115
|
-
configurable: true,
|
|
116
|
-
writable: true,
|
|
117
|
-
value: void 0
|
|
118
|
-
});
|
|
119
|
-
this.transport = args.transport;
|
|
120
|
-
this.wallet = args.wallet;
|
|
121
|
-
this.isTestnet = args.isTestnet ?? false;
|
|
122
|
-
this.defaultVaultAddress = args.defaultVaultAddress;
|
|
123
|
-
}
|
|
124
|
-
// ———————————————Actions———————————————
|
|
125
|
-
/**
|
|
126
|
-
* Approve an agent to sign on behalf of the master or sub-accounts.
|
|
127
|
-
* @param args - The parameters for the request.
|
|
128
|
-
* @param signal - An optional abort signal
|
|
129
|
-
* @returns {SuccessResponse} Successful response without specific data.
|
|
130
|
-
* @throws {ApiRequestError} When the API returns an error response.
|
|
131
|
-
*
|
|
132
|
-
* @see {@link https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#approve-an-api-wallet | Hyperliquid GitBook}
|
|
133
|
-
* @example
|
|
134
|
-
* ```ts
|
|
135
|
-
* import * as hl from "@nktkas/hyperliquid";
|
|
136
|
-
* import { privateKeyToAccount } from "viem/accounts";
|
|
137
|
-
*
|
|
138
|
-
* const wallet = privateKeyToAccount("0x...");
|
|
139
|
-
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
140
|
-
* const client = new hl.WalletClient({ wallet, transport });
|
|
141
|
-
*
|
|
142
|
-
* const result = await client.approveAgent({
|
|
143
|
-
* agentAddress: "0x...",
|
|
144
|
-
* agentName: "agentName",
|
|
145
|
-
* });
|
|
146
|
-
*/
|
|
147
|
-
async approveAgent(args, signal) {
|
|
148
|
-
const action = {
|
|
149
|
-
...args,
|
|
150
|
-
type: "approveAgent",
|
|
151
|
-
hyperliquidChain: this.isTestnet ? "Testnet" : "Mainnet",
|
|
152
|
-
signatureChainId: args.signatureChainId ?? this.isTestnet ? "0x66eee" : "0xa4b1",
|
|
153
|
-
nonce: args.nonce ?? Date.now(),
|
|
154
|
-
};
|
|
155
|
-
const signature = await (0, signing_js_1.signUserSignedAction)(this.wallet, action, {
|
|
156
|
-
"HyperliquidTransaction:ApproveAgent": [
|
|
157
|
-
{ name: "hyperliquidChain", type: "string" },
|
|
158
|
-
{ name: "agentAddress", type: "address" },
|
|
159
|
-
{ name: "agentName", type: "string" },
|
|
160
|
-
{ name: "nonce", type: "uint64" },
|
|
161
|
-
],
|
|
162
|
-
}, parseInt(action.signatureChainId, 16));
|
|
163
|
-
const request = {
|
|
164
|
-
action,
|
|
165
|
-
signature,
|
|
166
|
-
nonce: action.nonce,
|
|
167
|
-
};
|
|
168
|
-
const response = await this.transport.request("action", request, signal);
|
|
169
|
-
this._validateResponse(response);
|
|
170
|
-
return response;
|
|
171
|
-
}
|
|
172
|
-
/**
|
|
173
|
-
* Approve a max fee rate for a builder address.
|
|
174
|
-
* @param args - The parameters for the request.
|
|
175
|
-
* @param signal - An optional abort signal.
|
|
176
|
-
* @returns {SuccessResponse} Successful response without specific data.
|
|
177
|
-
* @throws {ApiRequestError} When the API returns an error response.
|
|
178
|
-
*
|
|
179
|
-
* @see {@link https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#approve-a-builder-fee | Hyperliquid GitBook}
|
|
180
|
-
* @example
|
|
181
|
-
* ```ts
|
|
182
|
-
* import * as hl from "@nktkas/hyperliquid";
|
|
183
|
-
* import { privateKeyToAccount } from "viem/accounts";
|
|
184
|
-
*
|
|
185
|
-
* const wallet = privateKeyToAccount("0x...");
|
|
186
|
-
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
187
|
-
* const client = new hl.WalletClient({ wallet, transport });
|
|
188
|
-
*
|
|
189
|
-
* const result = await client.approveBuilderFee({
|
|
190
|
-
* maxFeeRate: "0.01%",
|
|
191
|
-
* builder: "0x...",
|
|
192
|
-
* });
|
|
193
|
-
*/
|
|
194
|
-
async approveBuilderFee(args, signal) {
|
|
195
|
-
const action = {
|
|
196
|
-
...args,
|
|
197
|
-
type: "approveBuilderFee",
|
|
198
|
-
hyperliquidChain: this.isTestnet ? "Testnet" : "Mainnet",
|
|
199
|
-
signatureChainId: args.signatureChainId ?? this.isTestnet ? "0x66eee" : "0xa4b1",
|
|
200
|
-
nonce: args.nonce ?? Date.now(),
|
|
201
|
-
};
|
|
202
|
-
const signature = await (0, signing_js_1.signUserSignedAction)(this.wallet, action, {
|
|
203
|
-
"HyperliquidTransaction:ApproveBuilderFee": [
|
|
204
|
-
{ name: "hyperliquidChain", type: "string" },
|
|
205
|
-
{ name: "maxFeeRate", type: "string" },
|
|
206
|
-
{ name: "builder", type: "address" },
|
|
207
|
-
{ name: "nonce", type: "uint64" },
|
|
208
|
-
],
|
|
209
|
-
}, parseInt(action.signatureChainId, 16));
|
|
210
|
-
const request = {
|
|
211
|
-
action,
|
|
212
|
-
signature,
|
|
213
|
-
nonce: action.nonce,
|
|
214
|
-
};
|
|
215
|
-
const response = await this.transport.request("action", request, signal);
|
|
216
|
-
this._validateResponse(response);
|
|
217
|
-
return response;
|
|
218
|
-
}
|
|
219
|
-
/**
|
|
220
|
-
* Modify multiple orders.
|
|
221
|
-
* @param args - The parameters for the request.
|
|
222
|
-
* @param signal - An optional abort signal.
|
|
223
|
-
* @returns {OrderResponseSuccess} Successful variant of {@link OrderResponse} without error statuses.
|
|
224
|
-
* @throws {ApiRequestError} When the API returns an error response.
|
|
225
|
-
*
|
|
226
|
-
* @see {@link https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#modify-multiple-orders | Hyperliquid GitBook}
|
|
227
|
-
* @example
|
|
228
|
-
* ```ts
|
|
229
|
-
* import * as hl from "@nktkas/hyperliquid";
|
|
230
|
-
* import { privateKeyToAccount } from "viem/accounts";
|
|
231
|
-
*
|
|
232
|
-
* const wallet = privateKeyToAccount("0x...");
|
|
233
|
-
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
234
|
-
* const client = new hl.WalletClient({ wallet, transport });
|
|
235
|
-
*
|
|
236
|
-
* const result = await client.batchModify({
|
|
237
|
-
* modifies: [{
|
|
238
|
-
* oid: 123, // Order ID
|
|
239
|
-
* order: {
|
|
240
|
-
* a: 0, // Asset index
|
|
241
|
-
* b: true, // Buy order
|
|
242
|
-
* p: "31000", // New price
|
|
243
|
-
* s: "0.2", // New size
|
|
244
|
-
* r: false, // Not reduce-only
|
|
245
|
-
* t: {
|
|
246
|
-
* limit: {
|
|
247
|
-
* tif: "Gtc", // Good-til-cancelled
|
|
248
|
-
* },
|
|
249
|
-
* },
|
|
250
|
-
* c: "0x...", // Optional: Client Order ID
|
|
251
|
-
* },
|
|
252
|
-
* }],
|
|
253
|
-
* });
|
|
254
|
-
* ```
|
|
255
|
-
*/
|
|
256
|
-
async batchModify(args, signal) {
|
|
257
|
-
const { vaultAddress = this.defaultVaultAddress, nonce = Date.now(), ...actionArgs } = args;
|
|
258
|
-
const sortedAction = key_sort_js_1.sorters.batchModify({ type: "batchModify", ...actionArgs });
|
|
259
|
-
const signature = await (0, signing_js_1.signL1Action)(this.wallet, this.isTestnet, sortedAction, nonce, vaultAddress);
|
|
260
|
-
const request = {
|
|
261
|
-
action: sortedAction,
|
|
262
|
-
signature,
|
|
263
|
-
nonce,
|
|
264
|
-
vaultAddress,
|
|
265
|
-
};
|
|
266
|
-
const response = await this.transport.request("action", request, signal);
|
|
267
|
-
this._validateResponse(response);
|
|
268
|
-
return response;
|
|
269
|
-
}
|
|
270
|
-
/**
|
|
271
|
-
* Cancel order(s).
|
|
272
|
-
* @param args - The parameters for the request.
|
|
273
|
-
* @param signal - An optional abort signal.
|
|
274
|
-
* @returns {CancelResponseSuccess} Successful variant of {@link CancelResponse} without error statuses.
|
|
275
|
-
* @throws {ApiRequestError} When the API returns an error response.
|
|
276
|
-
*
|
|
277
|
-
* @see {@link https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#cancel-order-s | Hyperliquid GitBook}
|
|
278
|
-
* @example
|
|
279
|
-
* ```ts
|
|
280
|
-
* import * as hl from "@nktkas/hyperliquid";
|
|
281
|
-
* import { privateKeyToAccount } from "viem/accounts";
|
|
282
|
-
*
|
|
283
|
-
* const wallet = privateKeyToAccount("0x...");
|
|
284
|
-
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
285
|
-
* const client = new hl.WalletClient({ wallet, transport });
|
|
286
|
-
*
|
|
287
|
-
* const result = await client.cancel({
|
|
288
|
-
* cancels: [{
|
|
289
|
-
* a: 0, // Asset index
|
|
290
|
-
* o: 123, // Order ID
|
|
291
|
-
* }],
|
|
292
|
-
* });
|
|
293
|
-
* ```
|
|
294
|
-
*/
|
|
295
|
-
async cancel(args, signal) {
|
|
296
|
-
const { vaultAddress = this.defaultVaultAddress, nonce = Date.now(), ...actionArgs } = args;
|
|
297
|
-
const sortedAction = key_sort_js_1.sorters.cancel({ type: "cancel", ...actionArgs });
|
|
298
|
-
const signature = await (0, signing_js_1.signL1Action)(this.wallet, this.isTestnet, sortedAction, nonce, vaultAddress);
|
|
299
|
-
const request = {
|
|
300
|
-
action: sortedAction,
|
|
301
|
-
signature,
|
|
302
|
-
nonce,
|
|
303
|
-
vaultAddress,
|
|
304
|
-
};
|
|
305
|
-
const response = await this.transport.request("action", request, signal);
|
|
306
|
-
this._validateResponse(response);
|
|
307
|
-
return response;
|
|
308
|
-
}
|
|
309
|
-
/**
|
|
310
|
-
* Cancel order(s) by Client Order ID.
|
|
311
|
-
* @param args - The parameters for the request.
|
|
312
|
-
* @param signal - An optional abort signal.
|
|
313
|
-
* @returns {CancelResponseSuccess} Successful variant of {@link CancelResponse} without error statuses.
|
|
314
|
-
* @throws {ApiRequestError} When the API returns an error response.
|
|
315
|
-
*
|
|
316
|
-
* @see {@link https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#cancel-order-s-by-cloid | Hyperliquid GitBook}
|
|
317
|
-
* @example
|
|
318
|
-
* ```ts
|
|
319
|
-
* import * as hl from "@nktkas/hyperliquid";
|
|
320
|
-
* import { privateKeyToAccount } from "viem/accounts";
|
|
321
|
-
*
|
|
322
|
-
* const wallet = privateKeyToAccount("0x...");
|
|
323
|
-
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
324
|
-
* const client = new hl.WalletClient({ wallet, transport });
|
|
325
|
-
*
|
|
326
|
-
* const result = await client.cancelByCloid({
|
|
327
|
-
* cancels: [{
|
|
328
|
-
* asset: 0,
|
|
329
|
-
* cloid: "0x...", // Client Order ID
|
|
330
|
-
* }],
|
|
331
|
-
* });
|
|
332
|
-
* ```
|
|
333
|
-
*/
|
|
334
|
-
async cancelByCloid(args, signal) {
|
|
335
|
-
const { vaultAddress = this.defaultVaultAddress, nonce = Date.now(), ...actionArgs } = args;
|
|
336
|
-
const sortedAction = key_sort_js_1.sorters.cancelByCloid({ type: "cancelByCloid", ...actionArgs });
|
|
337
|
-
const signature = await (0, signing_js_1.signL1Action)(this.wallet, this.isTestnet, sortedAction, nonce, vaultAddress);
|
|
338
|
-
const request = {
|
|
339
|
-
action: sortedAction,
|
|
340
|
-
signature,
|
|
341
|
-
nonce,
|
|
342
|
-
vaultAddress,
|
|
343
|
-
};
|
|
344
|
-
const response = await this.transport.request("action", request, signal);
|
|
345
|
-
this._validateResponse(response);
|
|
346
|
-
return response;
|
|
347
|
-
}
|
|
348
|
-
/**
|
|
349
|
-
* Create a sub-account.
|
|
350
|
-
* @param args - The parameters for the request.
|
|
351
|
-
* @param signal - An optional abort signal.
|
|
352
|
-
* @returns {CreateSubAccountResponse} Response for creating a sub-account.
|
|
353
|
-
* @throws {ApiRequestError} When the API returns an error response.
|
|
354
|
-
*
|
|
355
|
-
* @example
|
|
356
|
-
* ```ts
|
|
357
|
-
* import * as hl from "@nktkas/hyperliquid";
|
|
358
|
-
* import { privateKeyToAccount } from "viem/accounts";
|
|
359
|
-
*
|
|
360
|
-
* const wallet = privateKeyToAccount("0x...");
|
|
361
|
-
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
362
|
-
* const client = new hl.WalletClient({ wallet, transport });
|
|
363
|
-
*
|
|
364
|
-
* const result = await client.createSubAccount({
|
|
365
|
-
* name: "subAccountName",
|
|
366
|
-
* });
|
|
367
|
-
* ```
|
|
368
|
-
*/
|
|
369
|
-
async createSubAccount(args, signal) {
|
|
370
|
-
const { nonce = Date.now(), ...actionArgs } = args;
|
|
371
|
-
const sortedAction = key_sort_js_1.sorters.createSubAccount({ type: "createSubAccount", ...actionArgs });
|
|
372
|
-
const signature = await (0, signing_js_1.signL1Action)(this.wallet, this.isTestnet, sortedAction, nonce);
|
|
373
|
-
const request = {
|
|
374
|
-
action: sortedAction,
|
|
375
|
-
signature,
|
|
376
|
-
nonce,
|
|
377
|
-
};
|
|
378
|
-
const response = await this.transport.request("action", request, signal);
|
|
379
|
-
this._validateResponse(response);
|
|
380
|
-
return response;
|
|
381
|
-
}
|
|
382
|
-
/**
|
|
383
|
-
* Modify an order.
|
|
384
|
-
* @param args - The parameters for the request.
|
|
385
|
-
* @param signal - An optional abort signal.
|
|
386
|
-
* @returns {SuccessResponse} Successful response without specific data.
|
|
387
|
-
* @throws {ApiRequestError} When the API returns an error response.
|
|
388
|
-
*
|
|
389
|
-
* @see {@link https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#modify-an-order | Hyperliquid GitBook}
|
|
390
|
-
* @example
|
|
391
|
-
* ```ts
|
|
392
|
-
* import * as hl from "@nktkas/hyperliquid";
|
|
393
|
-
* import { privateKeyToAccount } from "viem/accounts";
|
|
394
|
-
*
|
|
395
|
-
* const wallet = privateKeyToAccount("0x...");
|
|
396
|
-
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
397
|
-
* const client = new hl.WalletClient({ wallet, transport });
|
|
398
|
-
*
|
|
399
|
-
* const result = await client.modify({
|
|
400
|
-
* oid: 123, // Order ID
|
|
401
|
-
* order: {
|
|
402
|
-
* a: 0, // Asset index
|
|
403
|
-
* b: true, // Buy order
|
|
404
|
-
* p: "31000", // New price
|
|
405
|
-
* s: "0.2", // New size
|
|
406
|
-
* r: false, // Not reduce-only
|
|
407
|
-
* t: {
|
|
408
|
-
* limit: {
|
|
409
|
-
* tif: "Gtc", // Good-til-cancelled
|
|
410
|
-
* },
|
|
411
|
-
* },
|
|
412
|
-
* c: "0x...", // Optional: Client Order ID
|
|
413
|
-
* },
|
|
414
|
-
* });
|
|
415
|
-
* ```
|
|
416
|
-
*/
|
|
417
|
-
async modify(args, signal) {
|
|
418
|
-
const { vaultAddress = this.defaultVaultAddress, nonce = Date.now(), ...actionArgs } = args;
|
|
419
|
-
const sortedAction = key_sort_js_1.sorters.modify({ type: "modify", ...actionArgs });
|
|
420
|
-
const signature = await (0, signing_js_1.signL1Action)(this.wallet, this.isTestnet, sortedAction, nonce, vaultAddress);
|
|
421
|
-
const request = {
|
|
422
|
-
action: sortedAction,
|
|
423
|
-
signature,
|
|
424
|
-
nonce,
|
|
425
|
-
vaultAddress,
|
|
426
|
-
};
|
|
427
|
-
const response = await this.transport.request("action", request, signal);
|
|
428
|
-
this._validateResponse(response);
|
|
429
|
-
return response;
|
|
430
|
-
}
|
|
431
|
-
/**
|
|
432
|
-
* Place an order(s).
|
|
433
|
-
* @param args - The parameters for the request.
|
|
434
|
-
* @param signal - An optional abort signal.
|
|
435
|
-
* @returns {OrderResponseSuccess} Successful variant of {@link OrderResponse} without error statuses.
|
|
436
|
-
* @throws {ApiRequestError} When the API returns an error response.
|
|
437
|
-
*
|
|
438
|
-
* @see {@link https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#place-an-order | Hyperliquid GitBook}
|
|
439
|
-
* @example
|
|
440
|
-
* ```ts
|
|
441
|
-
* import * as hl from "@nktkas/hyperliquid";
|
|
442
|
-
* import { privateKeyToAccount } from "viem/accounts";
|
|
443
|
-
*
|
|
444
|
-
* const wallet = privateKeyToAccount("0x...");
|
|
445
|
-
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
446
|
-
* const client = new hl.WalletClient({ wallet, transport });
|
|
447
|
-
*
|
|
448
|
-
* const result = await client.order({
|
|
449
|
-
* orders: [{
|
|
450
|
-
* a: 0, // Asset index
|
|
451
|
-
* b: true, // Buy order
|
|
452
|
-
* p: "30000", // Price
|
|
453
|
-
* s: "0.1", // Size
|
|
454
|
-
* r: false, // Not reduce-only
|
|
455
|
-
* t: {
|
|
456
|
-
* limit: {
|
|
457
|
-
* tif: "Gtc", // Good-til-cancelled
|
|
458
|
-
* },
|
|
459
|
-
* },
|
|
460
|
-
* c: "0x...", // Optional: Client Order ID
|
|
461
|
-
* }],
|
|
462
|
-
* grouping: "na", // No grouping
|
|
463
|
-
* });
|
|
464
|
-
* ```
|
|
465
|
-
*/
|
|
466
|
-
async order(args, signal) {
|
|
467
|
-
const clonedArgs = structuredClone(args); // Clone to prevent mutation of original object
|
|
468
|
-
const { vaultAddress = this.defaultVaultAddress, nonce = Date.now(), ...actionArgs } = clonedArgs;
|
|
469
|
-
if (actionArgs.builder)
|
|
470
|
-
actionArgs.builder.b = actionArgs.builder.b.toLowerCase();
|
|
471
|
-
const sortedAction = key_sort_js_1.sorters.order({ type: "order", ...actionArgs });
|
|
472
|
-
const signature = await (0, signing_js_1.signL1Action)(this.wallet, this.isTestnet, sortedAction, nonce, vaultAddress);
|
|
473
|
-
const request = {
|
|
474
|
-
action: sortedAction,
|
|
475
|
-
signature,
|
|
476
|
-
nonce,
|
|
477
|
-
vaultAddress,
|
|
478
|
-
};
|
|
479
|
-
const response = await this.transport.request("action", request, signal);
|
|
480
|
-
this._validateResponse(response);
|
|
481
|
-
return response;
|
|
482
|
-
}
|
|
483
|
-
/**
|
|
484
|
-
* Schedule a time to cancel all open orders.
|
|
485
|
-
* @param args - The parameters for the request.
|
|
486
|
-
* @param signal - An optional abort signal.
|
|
487
|
-
* @returns {SuccessResponse} Successful response without specific data.
|
|
488
|
-
* @throws {ApiRequestError} When the API returns an error response.
|
|
489
|
-
*
|
|
490
|
-
* @see {@link https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#schedule-cancel-dead-mans-switch | Hyperliquid GitBook}
|
|
491
|
-
* @example
|
|
492
|
-
* ```ts
|
|
493
|
-
* import * as hl from "@nktkas/hyperliquid";
|
|
494
|
-
* import { privateKeyToAccount } from "viem/accounts";
|
|
495
|
-
*
|
|
496
|
-
* const wallet = privateKeyToAccount("0x...");
|
|
497
|
-
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
498
|
-
* const client = new hl.WalletClient({ wallet, transport });
|
|
499
|
-
*
|
|
500
|
-
* const result = await client.scheduleCancel({
|
|
501
|
-
* time: Date.now() + 3600000, // Schedule cancellation 1 hour from now
|
|
502
|
-
* });
|
|
503
|
-
* ```
|
|
504
|
-
*/
|
|
505
|
-
async scheduleCancel(args = {}, signal) {
|
|
506
|
-
const { vaultAddress = this.defaultVaultAddress, nonce = Date.now(), ...actionArgs } = args;
|
|
507
|
-
const sortedAction = key_sort_js_1.sorters.scheduleCancel({ type: "scheduleCancel", ...actionArgs });
|
|
508
|
-
const signature = await (0, signing_js_1.signL1Action)(this.wallet, this.isTestnet, sortedAction, nonce, vaultAddress);
|
|
509
|
-
const request = {
|
|
510
|
-
action: sortedAction,
|
|
511
|
-
signature,
|
|
512
|
-
nonce,
|
|
513
|
-
vaultAddress,
|
|
514
|
-
};
|
|
515
|
-
const response = await this.transport.request("action", request, signal);
|
|
516
|
-
this._validateResponse(response);
|
|
517
|
-
return response;
|
|
518
|
-
}
|
|
519
|
-
/**
|
|
520
|
-
* Set a referral code.
|
|
521
|
-
* @param args - The parameters for the request.
|
|
522
|
-
* @param signal - An optional abort signal.
|
|
523
|
-
* @returns {SuccessResponse} Successful response without specific data.
|
|
524
|
-
* @throws {ApiRequestError} When the API returns an error response.
|
|
525
|
-
*
|
|
526
|
-
* @example
|
|
527
|
-
* ```ts
|
|
528
|
-
* import * as hl from "@nktkas/hyperliquid";
|
|
529
|
-
* import { privateKeyToAccount } from "viem/accounts";
|
|
530
|
-
*
|
|
531
|
-
* const wallet = privateKeyToAccount("0x...");
|
|
532
|
-
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
533
|
-
* const client = new hl.WalletClient({ wallet, transport });
|
|
534
|
-
*
|
|
535
|
-
* const result = await client.setReferrer({
|
|
536
|
-
* code: "TEST",
|
|
537
|
-
* });
|
|
538
|
-
* ```
|
|
539
|
-
*/
|
|
540
|
-
async setReferrer(args, signal) {
|
|
541
|
-
const { nonce = Date.now(), ...actionArgs } = args;
|
|
542
|
-
const sortedAction = key_sort_js_1.sorters.setReferrer({ type: "setReferrer", ...actionArgs });
|
|
543
|
-
const signature = await (0, signing_js_1.signL1Action)(this.wallet, this.isTestnet, sortedAction, nonce);
|
|
544
|
-
const request = {
|
|
545
|
-
action: sortedAction,
|
|
546
|
-
signature,
|
|
547
|
-
nonce,
|
|
548
|
-
};
|
|
549
|
-
const response = await this.transport.request("action", request, signal);
|
|
550
|
-
this._validateResponse(response);
|
|
551
|
-
return response;
|
|
552
|
-
}
|
|
553
|
-
/**
|
|
554
|
-
* Transfer a spot asset on L1 to another address.
|
|
555
|
-
* @param args - The parameters for the request.
|
|
556
|
-
* @param signal - An optional abort signal.
|
|
557
|
-
* @returns {SuccessResponse} Successful response without specific data.
|
|
558
|
-
* @throws {ApiRequestError} When the API returns an error response.
|
|
559
|
-
*
|
|
560
|
-
* @see {@link https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#l1-spot-transfer | Hyperliquid GitBook}
|
|
561
|
-
* @example
|
|
562
|
-
* ```ts
|
|
563
|
-
* import * as hl from "@nktkas/hyperliquid";
|
|
564
|
-
* import { privateKeyToAccount } from "viem/accounts";
|
|
565
|
-
*
|
|
566
|
-
* const wallet = privateKeyToAccount("0x...");
|
|
567
|
-
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
568
|
-
* const client = new hl.WalletClient({ wallet, transport });
|
|
569
|
-
*
|
|
570
|
-
* const result = await client.spotSend({
|
|
571
|
-
* destination: "0x...",
|
|
572
|
-
* token: "USDC:0xeb62eee3685fc4c43992febcd9e75443",
|
|
573
|
-
* amount: "1",
|
|
574
|
-
* });
|
|
575
|
-
* ```
|
|
576
|
-
*/
|
|
577
|
-
async spotSend(args, signal) {
|
|
578
|
-
const action = {
|
|
579
|
-
...args,
|
|
580
|
-
type: "spotSend",
|
|
581
|
-
hyperliquidChain: this.isTestnet ? "Testnet" : "Mainnet",
|
|
582
|
-
signatureChainId: args.signatureChainId ?? this.isTestnet ? "0x66eee" : "0xa4b1",
|
|
583
|
-
time: args.time ?? Date.now(),
|
|
584
|
-
};
|
|
585
|
-
const signature = await (0, signing_js_1.signUserSignedAction)(this.wallet, action, {
|
|
586
|
-
"HyperliquidTransaction:SpotSend": [
|
|
587
|
-
{ name: "hyperliquidChain", type: "string" },
|
|
588
|
-
{ name: "destination", type: "string" },
|
|
589
|
-
{ name: "token", type: "string" },
|
|
590
|
-
{ name: "amount", type: "string" },
|
|
591
|
-
{ name: "time", type: "uint64" },
|
|
592
|
-
],
|
|
593
|
-
}, parseInt(action.signatureChainId, 16));
|
|
594
|
-
const request = {
|
|
595
|
-
action,
|
|
596
|
-
signature,
|
|
597
|
-
nonce: action.time,
|
|
598
|
-
};
|
|
599
|
-
const response = await this.transport.request("action", request, signal);
|
|
600
|
-
this._validateResponse(response);
|
|
601
|
-
return response;
|
|
602
|
-
}
|
|
603
|
-
/**
|
|
604
|
-
* Transfer between sub-accounts.
|
|
605
|
-
* @param args - The parameters for the request.
|
|
606
|
-
* @param signal - An optional abort signal.
|
|
607
|
-
* @returns {SuccessResponse} Successful response without specific data.
|
|
608
|
-
* @throws {ApiRequestError} When the API returns an error response.
|
|
609
|
-
*
|
|
610
|
-
* @example
|
|
611
|
-
* ```ts
|
|
612
|
-
* import * as hl from "@nktkas/hyperliquid";
|
|
613
|
-
* import { privateKeyToAccount } from "viem/accounts";
|
|
614
|
-
*
|
|
615
|
-
* const wallet = privateKeyToAccount("0x...");
|
|
616
|
-
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
617
|
-
* const client = new hl.WalletClient({ wallet, transport });
|
|
618
|
-
*
|
|
619
|
-
* const result = await client.subAccountTransfer({
|
|
620
|
-
* subAccountUser: "0x...",
|
|
621
|
-
* isDeposit: true,
|
|
622
|
-
* usd: 1000000, // 1 USD in raw units (float amount * 1e6)
|
|
623
|
-
* });
|
|
624
|
-
* ```
|
|
625
|
-
*/
|
|
626
|
-
async subAccountTransfer(args, signal) {
|
|
627
|
-
const { nonce = Date.now(), ...actionArgs } = args;
|
|
628
|
-
const sortedAction = key_sort_js_1.sorters.subAccountTransfer({ type: "subAccountTransfer", ...actionArgs });
|
|
629
|
-
const signature = await (0, signing_js_1.signL1Action)(this.wallet, this.isTestnet, sortedAction, nonce);
|
|
630
|
-
const request = {
|
|
631
|
-
action: sortedAction,
|
|
632
|
-
signature,
|
|
633
|
-
nonce,
|
|
634
|
-
};
|
|
635
|
-
const response = await this.transport.request("action", request, signal);
|
|
636
|
-
this._validateResponse(response);
|
|
637
|
-
return response;
|
|
638
|
-
}
|
|
639
|
-
/**
|
|
640
|
-
* Cancel a TWAP order.
|
|
641
|
-
* @param args - The parameters for the request.
|
|
642
|
-
* @param signal - An optional abort signal.
|
|
643
|
-
* @returns {TwapCancelResponseSuccess} Successful variant of {@link TwapCancelResponse} without error status.
|
|
644
|
-
* @throws {ApiRequestError} When the API returns an error response.
|
|
645
|
-
*
|
|
646
|
-
* @see {@link https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#cancel-a-twap-order | Hyperliquid GitBook}
|
|
647
|
-
* @example
|
|
648
|
-
* ```ts
|
|
649
|
-
* import * as hl from "@nktkas/hyperliquid";
|
|
650
|
-
* import { privateKeyToAccount } from "viem/accounts";
|
|
651
|
-
*
|
|
652
|
-
* const wallet = privateKeyToAccount("0x...");
|
|
653
|
-
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
654
|
-
* const client = new hl.WalletClient({ wallet, transport });
|
|
655
|
-
*
|
|
656
|
-
* const result = await client.twapCancel({
|
|
657
|
-
* a: 0, // Asset index
|
|
658
|
-
* t: 1, // TWAP ID
|
|
659
|
-
* });
|
|
660
|
-
* ```
|
|
661
|
-
*/
|
|
662
|
-
async twapCancel(args, signal) {
|
|
663
|
-
const { vaultAddress = this.defaultVaultAddress, nonce = Date.now(), ...actionArgs } = args;
|
|
664
|
-
const sortedAction = key_sort_js_1.sorters.twapCancel({ type: "twapCancel", ...actionArgs });
|
|
665
|
-
const signature = await (0, signing_js_1.signL1Action)(this.wallet, this.isTestnet, sortedAction, nonce, vaultAddress);
|
|
666
|
-
const request = {
|
|
667
|
-
action: sortedAction,
|
|
668
|
-
signature,
|
|
669
|
-
nonce,
|
|
670
|
-
vaultAddress,
|
|
671
|
-
};
|
|
672
|
-
const response = await this.transport.request("action", request, signal);
|
|
673
|
-
this._validateResponse(response);
|
|
674
|
-
return response;
|
|
675
|
-
}
|
|
676
|
-
/**
|
|
677
|
-
* Place a TWAP order.
|
|
678
|
-
* @param args - The parameters for the request.
|
|
679
|
-
* @param signal - An optional abort signal.
|
|
680
|
-
* @returns {TwapOrderResponseSuccess} Successful variant of {@link TwapOrderResponse} without error status.
|
|
681
|
-
* @throws {ApiRequestError} When the API returns an error response.
|
|
682
|
-
*
|
|
683
|
-
* @see {@link https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#place-a-twap-order | Hyperliquid GitBook}
|
|
684
|
-
* @example
|
|
685
|
-
* ```ts
|
|
686
|
-
* import * as hl from "@nktkas/hyperliquid";
|
|
687
|
-
* import { privateKeyToAccount } from "viem/accounts";
|
|
688
|
-
*
|
|
689
|
-
* const wallet = privateKeyToAccount("0x...");
|
|
690
|
-
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
691
|
-
* const client = new hl.WalletClient({ wallet, transport });
|
|
692
|
-
*
|
|
693
|
-
* const result = await client.twapOrder({
|
|
694
|
-
* a: 0, // Asset index
|
|
695
|
-
* b: true, // Buy order
|
|
696
|
-
* s: "1", // Size
|
|
697
|
-
* r: false, // Not reduce-only
|
|
698
|
-
* m: 10, // Duration in minutes
|
|
699
|
-
* t: true, // Randomize order timing
|
|
700
|
-
* });
|
|
701
|
-
* ```
|
|
702
|
-
*/
|
|
703
|
-
async twapOrder(args, signal) {
|
|
704
|
-
const { vaultAddress = this.defaultVaultAddress, nonce = Date.now(), ...actionArgs } = args;
|
|
705
|
-
const sortedAction = key_sort_js_1.sorters.twapOrder({ type: "twapOrder", twap: actionArgs });
|
|
706
|
-
const signature = await (0, signing_js_1.signL1Action)(this.wallet, this.isTestnet, sortedAction, nonce, vaultAddress);
|
|
707
|
-
const request = {
|
|
708
|
-
action: sortedAction,
|
|
709
|
-
signature,
|
|
710
|
-
nonce,
|
|
711
|
-
vaultAddress,
|
|
712
|
-
};
|
|
713
|
-
const response = await this.transport.request("action", request, signal);
|
|
714
|
-
this._validateResponse(response);
|
|
715
|
-
return response;
|
|
716
53
|
}
|
|
54
|
+
exports.ApiRequestError = ApiRequestError;
|
|
55
|
+
// ——————————————— Client ———————————————
|
|
717
56
|
/**
|
|
718
|
-
*
|
|
719
|
-
* @
|
|
720
|
-
* @
|
|
721
|
-
* @returns {SuccessResponse} Successful response without specific data.
|
|
722
|
-
* @throws {ApiRequestError} When the API returns an error response.
|
|
723
|
-
*
|
|
724
|
-
* @see {@link https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#update-isolated-margin | Hyperliquid GitBook}
|
|
725
|
-
* @example
|
|
726
|
-
* ```ts
|
|
727
|
-
* import * as hl from "@nktkas/hyperliquid";
|
|
728
|
-
* import { privateKeyToAccount } from "viem/accounts";
|
|
729
|
-
*
|
|
730
|
-
* const wallet = privateKeyToAccount("0x...");
|
|
731
|
-
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
732
|
-
* const client = new hl.WalletClient({ wallet, transport });
|
|
733
|
-
*
|
|
734
|
-
* const result = await client.updateIsolatedMargin({
|
|
735
|
-
* asset: 0,
|
|
736
|
-
* isBuy: true, // Add to long position
|
|
737
|
-
* ntli: 1000, // Add 1000 USD margin (integer only)
|
|
738
|
-
* });
|
|
739
|
-
* ```
|
|
57
|
+
* Wallet client for interacting with the Hyperliquid API.
|
|
58
|
+
* @typeParam T The transport used to connect to the Hyperliquid API.
|
|
59
|
+
* @typeParam W The WalletClient/Account ([viem](https://viem.sh/docs/clients/wallet)) or Signer ([ethers.js](https://docs.ethers.io/v6/api/providers/#Signer)) used for signing transactions.
|
|
740
60
|
*/
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
nonce: action.nonce,
|
|
836
|
-
};
|
|
837
|
-
const response = await this.transport.request("action", request, signal);
|
|
838
|
-
this._validateResponse(response);
|
|
839
|
-
return response;
|
|
840
|
-
}
|
|
841
|
-
/**
|
|
842
|
-
* Transfer USDC on L1 to another address.
|
|
843
|
-
* @param args - The parameters for the request.
|
|
844
|
-
* @param signal - An optional abort signal.
|
|
845
|
-
* @returns {SuccessResponse} Successful response without specific data.
|
|
846
|
-
* @throws {ApiRequestError} When the API returns an error response.
|
|
847
|
-
*
|
|
848
|
-
* @see {@link https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#l1-usdc-transfer | Hyperliquid GitBook}
|
|
849
|
-
* @example
|
|
850
|
-
* ```ts
|
|
851
|
-
* import * as hl from "@nktkas/hyperliquid";
|
|
852
|
-
* import { privateKeyToAccount } from "viem/accounts";
|
|
853
|
-
*
|
|
854
|
-
* const wallet = privateKeyToAccount("0x...");
|
|
855
|
-
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
856
|
-
* const client = new hl.WalletClient({ wallet, transport });
|
|
857
|
-
*
|
|
858
|
-
* const result = await client.usdSend({
|
|
859
|
-
* destination: "0x...",
|
|
860
|
-
* amount: "1000",
|
|
861
|
-
* });
|
|
862
|
-
* ```
|
|
863
|
-
*/
|
|
864
|
-
async usdSend(args, signal) {
|
|
865
|
-
const action = {
|
|
866
|
-
...args,
|
|
867
|
-
type: "usdSend",
|
|
868
|
-
hyperliquidChain: this.isTestnet ? "Testnet" : "Mainnet",
|
|
869
|
-
signatureChainId: args.signatureChainId ?? this.isTestnet ? "0x66eee" : "0xa4b1",
|
|
870
|
-
time: args.time ?? Date.now(),
|
|
871
|
-
};
|
|
872
|
-
const signature = await (0, signing_js_1.signUserSignedAction)(this.wallet, action, {
|
|
873
|
-
"HyperliquidTransaction:UsdSend": [
|
|
874
|
-
{ name: "hyperliquidChain", type: "string" },
|
|
875
|
-
{ name: "destination", type: "string" },
|
|
876
|
-
{ name: "amount", type: "string" },
|
|
877
|
-
{ name: "time", type: "uint64" },
|
|
878
|
-
],
|
|
879
|
-
}, parseInt(action.signatureChainId, 16));
|
|
880
|
-
const request = {
|
|
881
|
-
action,
|
|
882
|
-
signature,
|
|
883
|
-
nonce: action.time,
|
|
884
|
-
};
|
|
885
|
-
const response = await this.transport.request("action", request, signal);
|
|
886
|
-
this._validateResponse(response);
|
|
887
|
-
return response;
|
|
888
|
-
}
|
|
889
|
-
/**
|
|
890
|
-
* Transfer funds to/from a vault.
|
|
891
|
-
* @param args - The parameters for the request.
|
|
892
|
-
* @param signal - An optional abort signal.
|
|
893
|
-
* @returns {SuccessResponse} Successful response without specific data.
|
|
894
|
-
* @throws {ApiRequestError} When the API returns an error response.
|
|
895
|
-
*
|
|
896
|
-
* @see {@link https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#deposit-or-withdraw-from-a-vault | Hyperliquid GitBook}
|
|
897
|
-
* @example
|
|
898
|
-
* ```ts
|
|
899
|
-
* import * as hl from "@nktkas/hyperliquid";
|
|
900
|
-
* import { privateKeyToAccount } from "viem/accounts";
|
|
901
|
-
*
|
|
902
|
-
* const wallet = privateKeyToAccount("0x...");
|
|
903
|
-
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
904
|
-
* const client = new hl.WalletClient({ wallet, transport });
|
|
905
|
-
*
|
|
906
|
-
* const result = await client.vaultTransfer({
|
|
907
|
-
* vaultAddress: "0x...",
|
|
908
|
-
* isDeposit: true,
|
|
909
|
-
* usd: 1000000, // 1 USD in raw units (float amount * 1e6)
|
|
910
|
-
* });
|
|
911
|
-
* ```
|
|
912
|
-
*/
|
|
913
|
-
async vaultTransfer(args, signal) {
|
|
914
|
-
const { nonce = Date.now(), ...actionArgs } = args;
|
|
915
|
-
const sortedAction = key_sort_js_1.sorters.vaultTransfer({ type: "vaultTransfer", ...actionArgs });
|
|
916
|
-
const signature = await (0, signing_js_1.signL1Action)(this.wallet, this.isTestnet, sortedAction, nonce);
|
|
917
|
-
const request = {
|
|
918
|
-
action: sortedAction,
|
|
919
|
-
signature,
|
|
920
|
-
nonce,
|
|
921
|
-
};
|
|
922
|
-
const response = await this.transport.request("action", request, signal);
|
|
923
|
-
this._validateResponse(response);
|
|
924
|
-
return response;
|
|
925
|
-
}
|
|
926
|
-
/**
|
|
927
|
-
* Initiate a withdrawal request.
|
|
928
|
-
* @param args - The parameters for the request.
|
|
929
|
-
* @param signal - An optional abort signal.
|
|
930
|
-
* @returns {SuccessResponse} Successful response without specific data.
|
|
931
|
-
* @throws {ApiRequestError} When the API returns an error response.
|
|
932
|
-
*
|
|
933
|
-
* @see {@link https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#initiate-a-withdrawal-request | Hyperliquid GitBook}
|
|
934
|
-
* @example
|
|
935
|
-
* ```ts
|
|
936
|
-
* import * as hl from "@nktkas/hyperliquid";
|
|
937
|
-
* import { privateKeyToAccount } from "viem/accounts";
|
|
938
|
-
*
|
|
939
|
-
* const wallet = privateKeyToAccount("0x...");
|
|
940
|
-
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
941
|
-
* const client = new hl.WalletClient({ wallet, transport });
|
|
942
|
-
*
|
|
943
|
-
* const result = await client.withdraw3({
|
|
944
|
-
* destination: "0x...",
|
|
945
|
-
* amount: "1000",
|
|
946
|
-
* });
|
|
947
|
-
* ```
|
|
948
|
-
*/
|
|
949
|
-
async withdraw3(args, signal) {
|
|
950
|
-
const action = {
|
|
951
|
-
...args,
|
|
952
|
-
type: "withdraw3",
|
|
953
|
-
hyperliquidChain: this.isTestnet ? "Testnet" : "Mainnet",
|
|
954
|
-
signatureChainId: args.signatureChainId ?? this.isTestnet ? "0x66eee" : "0xa4b1",
|
|
955
|
-
time: args.time ?? Date.now(),
|
|
956
|
-
};
|
|
957
|
-
const signature = await (0, signing_js_1.signUserSignedAction)(this.wallet, action, {
|
|
958
|
-
"HyperliquidTransaction:Withdraw": [
|
|
959
|
-
{ name: "hyperliquidChain", type: "string" },
|
|
960
|
-
{ name: "destination", type: "string" },
|
|
961
|
-
{ name: "amount", type: "string" },
|
|
962
|
-
{ name: "time", type: "uint64" },
|
|
963
|
-
],
|
|
964
|
-
}, parseInt(action.signatureChainId, 16));
|
|
965
|
-
const request = {
|
|
966
|
-
action,
|
|
967
|
-
signature,
|
|
968
|
-
nonce: action.time,
|
|
969
|
-
};
|
|
970
|
-
const response = await this.transport.request("action", request, signal);
|
|
971
|
-
this._validateResponse(response);
|
|
972
|
-
return response;
|
|
973
|
-
}
|
|
974
|
-
/** Validate a response from the API. */
|
|
975
|
-
_validateResponse(response) {
|
|
976
|
-
if (response.status === "err") {
|
|
977
|
-
throw new ApiRequestError(response);
|
|
61
|
+
class WalletClient {
|
|
62
|
+
/**
|
|
63
|
+
* Initialises a new instance.
|
|
64
|
+
* @param args - The parameters for the client.
|
|
65
|
+
*
|
|
66
|
+
* @example Private key via [viem](https://viem.sh/docs/clients/wallet#local-accounts-private-key-mnemonic-etc)
|
|
67
|
+
* ```ts
|
|
68
|
+
* import * as hl from "@nktkas/hyperliquid";
|
|
69
|
+
* import { privateKeyToAccount } from "viem/accounts";
|
|
70
|
+
*
|
|
71
|
+
* const wallet = privateKeyToAccount("0x...");
|
|
72
|
+
*
|
|
73
|
+
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
74
|
+
* const client = new hl.WalletClient({ wallet, transport });
|
|
75
|
+
* ```
|
|
76
|
+
*
|
|
77
|
+
* @example Private key via [ethers.js](https://docs.ethers.org/v6/api/wallet/#Wallet) or [ethers.js v5](https://docs.ethers.org/v5/api/signer/#Wallet)
|
|
78
|
+
* ```ts
|
|
79
|
+
* import * as hl from "@nktkas/hyperliquid";
|
|
80
|
+
* import { ethers } from "ethers";
|
|
81
|
+
*
|
|
82
|
+
* const wallet = new ethers.Wallet("0x...");
|
|
83
|
+
*
|
|
84
|
+
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
85
|
+
* const client = new hl.WalletClient({ wallet, transport });
|
|
86
|
+
* ```
|
|
87
|
+
*
|
|
88
|
+
* @example External wallet (e.g. MetaMask) via [viem](https://viem.sh/docs/clients/wallet#optional-hoist-the-account)
|
|
89
|
+
* ```ts
|
|
90
|
+
* import * as hl from "@nktkas/hyperliquid";
|
|
91
|
+
* import { createWalletClient, custom } from "viem";
|
|
92
|
+
*
|
|
93
|
+
* const [account] = await window.ethereum.request({ method: "eth_requestAccounts" });
|
|
94
|
+
* const wallet = createWalletClient({ account, transport: custom(window.ethereum) });
|
|
95
|
+
*
|
|
96
|
+
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
97
|
+
* const client = new hl.WalletClient({ wallet, transport });
|
|
98
|
+
* ```
|
|
99
|
+
*
|
|
100
|
+
* @example External wallet (e.g. MetaMask) via `window.ethereum` directly
|
|
101
|
+
* ```ts
|
|
102
|
+
* import * as hl from "@nktkas/hyperliquid";
|
|
103
|
+
*
|
|
104
|
+
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
105
|
+
* const client = new hl.WalletClient({ wallet: window.ethereum, transport });
|
|
106
|
+
* ```
|
|
107
|
+
*/
|
|
108
|
+
constructor(args) {
|
|
109
|
+
/** The transport used to connect to the Hyperliquid API. */
|
|
110
|
+
Object.defineProperty(this, "transport", {
|
|
111
|
+
enumerable: true,
|
|
112
|
+
configurable: true,
|
|
113
|
+
writable: true,
|
|
114
|
+
value: void 0
|
|
115
|
+
});
|
|
116
|
+
/**
|
|
117
|
+
* The [viem](https://viem.sh/docs/clients/wallet) or [ethers.js](https://docs.ethers.org/v6/api/providers/#Signer)
|
|
118
|
+
* used for signing transactions.
|
|
119
|
+
*/
|
|
120
|
+
Object.defineProperty(this, "wallet", {
|
|
121
|
+
enumerable: true,
|
|
122
|
+
configurable: true,
|
|
123
|
+
writable: true,
|
|
124
|
+
value: void 0
|
|
125
|
+
});
|
|
126
|
+
/** Specifies whether the client uses testnet. */
|
|
127
|
+
Object.defineProperty(this, "isTestnet", {
|
|
128
|
+
enumerable: true,
|
|
129
|
+
configurable: true,
|
|
130
|
+
writable: true,
|
|
131
|
+
value: void 0
|
|
132
|
+
});
|
|
133
|
+
/** Sets a default vaultAddress to be used if no vaultAddress is explicitly passed to a method. */
|
|
134
|
+
Object.defineProperty(this, "defaultVaultAddress", {
|
|
135
|
+
enumerable: true,
|
|
136
|
+
configurable: true,
|
|
137
|
+
writable: true,
|
|
138
|
+
value: void 0
|
|
139
|
+
});
|
|
140
|
+
/**
|
|
141
|
+
* The network that will be used to sign transactions.
|
|
142
|
+
* Must match the network of the {@link wallet}.
|
|
143
|
+
*/
|
|
144
|
+
Object.defineProperty(this, "signatureChainId", {
|
|
145
|
+
enumerable: true,
|
|
146
|
+
configurable: true,
|
|
147
|
+
writable: true,
|
|
148
|
+
value: void 0
|
|
149
|
+
});
|
|
150
|
+
this.transport = args.transport;
|
|
151
|
+
this.wallet = args.wallet;
|
|
152
|
+
this.isTestnet = args.isTestnet ?? false;
|
|
153
|
+
this.defaultVaultAddress = args.defaultVaultAddress;
|
|
154
|
+
this.signatureChainId = args.signatureChainId ?? (this.isTestnet ? "0x66eee" : "0xa4b1");
|
|
978
155
|
}
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
156
|
+
// ———————————————Actions———————————————
|
|
157
|
+
/**
|
|
158
|
+
* Approve an agent to sign on behalf of the master or sub-accounts.
|
|
159
|
+
* @param args - The parameters for the request.
|
|
160
|
+
* @param signal - An optional abort signal
|
|
161
|
+
* @returns Successful response without specific data.
|
|
162
|
+
* @throws {ApiRequestError} When the API returns an error response.
|
|
163
|
+
*
|
|
164
|
+
* @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#approve-an-api-wallet
|
|
165
|
+
* @example
|
|
166
|
+
* ```ts
|
|
167
|
+
* import * as hl from "@nktkas/hyperliquid";
|
|
168
|
+
* import { privateKeyToAccount } from "viem/accounts";
|
|
169
|
+
*
|
|
170
|
+
* const wallet = privateKeyToAccount("0x...");
|
|
171
|
+
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
172
|
+
* const client = new hl.WalletClient({ wallet, transport });
|
|
173
|
+
*
|
|
174
|
+
* const result = await client.approveAgent({
|
|
175
|
+
* agentAddress: "0x...",
|
|
176
|
+
* agentName: "agentName",
|
|
177
|
+
* });
|
|
178
|
+
* ```
|
|
179
|
+
*/
|
|
180
|
+
async approveAgent(args, signal) {
|
|
181
|
+
// Construct an action
|
|
182
|
+
const action = {
|
|
183
|
+
...args,
|
|
184
|
+
type: "approveAgent",
|
|
185
|
+
hyperliquidChain: this.isTestnet ? "Testnet" : "Mainnet",
|
|
186
|
+
signatureChainId: this.signatureChainId,
|
|
187
|
+
nonce: args.nonce ?? Date.now(),
|
|
188
|
+
};
|
|
189
|
+
// Sign the action
|
|
190
|
+
const signature = await (0, signing_js_1.signUserSignedAction)({
|
|
191
|
+
wallet: this.wallet,
|
|
192
|
+
action,
|
|
193
|
+
types: {
|
|
194
|
+
"HyperliquidTransaction:ApproveAgent": [
|
|
195
|
+
{ name: "hyperliquidChain", type: "string" },
|
|
196
|
+
{ name: "agentAddress", type: "address" },
|
|
197
|
+
{ name: "agentName", type: "string" },
|
|
198
|
+
{ name: "nonce", type: "uint64" },
|
|
199
|
+
],
|
|
200
|
+
},
|
|
201
|
+
chainId: parseInt(action.signatureChainId, 16),
|
|
202
|
+
});
|
|
203
|
+
// Send a request
|
|
204
|
+
const request = { action, signature, nonce: action.nonce };
|
|
205
|
+
const response = await this.transport.request("action", request, signal);
|
|
206
|
+
// Validate a response
|
|
207
|
+
this._validateResponse(response);
|
|
208
|
+
return response;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Approve a max fee rate for a builder address.
|
|
212
|
+
* @param args - The parameters for the request.
|
|
213
|
+
* @param signal - An optional abort signal.
|
|
214
|
+
* @returns Successful response without specific data.
|
|
215
|
+
* @throws {ApiRequestError} When the API returns an error response.
|
|
216
|
+
*
|
|
217
|
+
* @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#approve-a-builder-fee
|
|
218
|
+
* @example
|
|
219
|
+
* ```ts
|
|
220
|
+
* import * as hl from "@nktkas/hyperliquid";
|
|
221
|
+
* import { privateKeyToAccount } from "viem/accounts";
|
|
222
|
+
*
|
|
223
|
+
* const wallet = privateKeyToAccount("0x...");
|
|
224
|
+
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
225
|
+
* const client = new hl.WalletClient({ wallet, transport });
|
|
226
|
+
*
|
|
227
|
+
* const result = await client.approveBuilderFee({
|
|
228
|
+
* maxFeeRate: "0.01%",
|
|
229
|
+
* builder: "0x...",
|
|
230
|
+
* });
|
|
231
|
+
* ```
|
|
232
|
+
*/
|
|
233
|
+
async approveBuilderFee(args, signal) {
|
|
234
|
+
// Construct an action
|
|
235
|
+
const action = {
|
|
236
|
+
...args,
|
|
237
|
+
type: "approveBuilderFee",
|
|
238
|
+
hyperliquidChain: this.isTestnet ? "Testnet" : "Mainnet",
|
|
239
|
+
signatureChainId: this.signatureChainId,
|
|
240
|
+
nonce: args.nonce ?? Date.now(),
|
|
241
|
+
};
|
|
242
|
+
// Sign the action
|
|
243
|
+
const signature = await (0, signing_js_1.signUserSignedAction)({
|
|
244
|
+
wallet: this.wallet,
|
|
245
|
+
action,
|
|
246
|
+
types: {
|
|
247
|
+
"HyperliquidTransaction:ApproveBuilderFee": [
|
|
248
|
+
{ name: "hyperliquidChain", type: "string" },
|
|
249
|
+
{ name: "maxFeeRate", type: "string" },
|
|
250
|
+
{ name: "builder", type: "address" },
|
|
251
|
+
{ name: "nonce", type: "uint64" },
|
|
252
|
+
],
|
|
253
|
+
},
|
|
254
|
+
chainId: parseInt(action.signatureChainId, 16),
|
|
255
|
+
});
|
|
256
|
+
// Send a request
|
|
257
|
+
const request = { action, signature, nonce: action.nonce };
|
|
258
|
+
const response = await this.transport.request("action", request, signal);
|
|
259
|
+
// Validate a response
|
|
260
|
+
this._validateResponse(response);
|
|
261
|
+
return response;
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Modify multiple orders.
|
|
265
|
+
* @param args - The parameters for the request.
|
|
266
|
+
* @param signal - An optional abort signal.
|
|
267
|
+
* @returns Successful variant of {@link OrderResponse} without error statuses.
|
|
268
|
+
* @throws {ApiRequestError} When the API returns an error response.
|
|
269
|
+
*
|
|
270
|
+
* @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#modify-multiple-orders
|
|
271
|
+
* @example
|
|
272
|
+
* ```ts
|
|
273
|
+
* import * as hl from "@nktkas/hyperliquid";
|
|
274
|
+
* import { privateKeyToAccount } from "viem/accounts";
|
|
275
|
+
*
|
|
276
|
+
* const wallet = privateKeyToAccount("0x...");
|
|
277
|
+
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
278
|
+
* const client = new hl.WalletClient({ wallet, transport });
|
|
279
|
+
*
|
|
280
|
+
* const result = await client.batchModify({
|
|
281
|
+
* modifies: [{
|
|
282
|
+
* oid: 123, // Order ID
|
|
283
|
+
* order: {
|
|
284
|
+
* a: 0, // Asset index
|
|
285
|
+
* b: true, // Buy order
|
|
286
|
+
* p: "31000", // New price
|
|
287
|
+
* s: "0.2", // New size
|
|
288
|
+
* r: false, // Not reduce-only
|
|
289
|
+
* t: {
|
|
290
|
+
* limit: {
|
|
291
|
+
* tif: "Gtc", // Good-til-cancelled
|
|
292
|
+
* },
|
|
293
|
+
* },
|
|
294
|
+
* c: "0x...", // Optional: Client Order ID
|
|
295
|
+
* },
|
|
296
|
+
* }],
|
|
297
|
+
* });
|
|
298
|
+
* ```
|
|
299
|
+
*/
|
|
300
|
+
async batchModify(args, signal) {
|
|
301
|
+
// Destructure the parameters
|
|
302
|
+
const { vaultAddress = this.defaultVaultAddress, nonce = Date.now(), ...actionArgs } = args;
|
|
303
|
+
// Construct an action
|
|
304
|
+
const action = {
|
|
305
|
+
type: "batchModify",
|
|
306
|
+
modifies: actionArgs.modifies.map((modify) => {
|
|
307
|
+
const sortedModify = {
|
|
308
|
+
oid: modify.oid,
|
|
309
|
+
order: {
|
|
310
|
+
a: modify.order.a,
|
|
311
|
+
b: modify.order.b,
|
|
312
|
+
p: modify.order.p,
|
|
313
|
+
s: modify.order.s,
|
|
314
|
+
r: modify.order.r,
|
|
315
|
+
t: "limit" in modify.order.t
|
|
316
|
+
? {
|
|
317
|
+
limit: {
|
|
318
|
+
tif: modify.order.t.limit.tif,
|
|
319
|
+
},
|
|
320
|
+
}
|
|
321
|
+
: {
|
|
322
|
+
trigger: {
|
|
323
|
+
isMarket: modify.order.t.trigger.isMarket,
|
|
324
|
+
triggerPx: modify.order.t.trigger.triggerPx,
|
|
325
|
+
tpsl: modify.order.t.trigger.tpsl,
|
|
326
|
+
},
|
|
327
|
+
},
|
|
328
|
+
c: modify.order.c,
|
|
329
|
+
},
|
|
330
|
+
};
|
|
331
|
+
if (sortedModify.order.c === undefined)
|
|
332
|
+
delete sortedModify.order.c;
|
|
333
|
+
return sortedModify;
|
|
334
|
+
}),
|
|
335
|
+
};
|
|
336
|
+
// Sign the action
|
|
337
|
+
const signature = await (0, signing_js_1.signL1Action)({
|
|
338
|
+
wallet: this.wallet,
|
|
339
|
+
action,
|
|
340
|
+
nonce,
|
|
341
|
+
isTestnet: this.isTestnet,
|
|
342
|
+
vaultAddress,
|
|
343
|
+
});
|
|
344
|
+
// Send a request
|
|
345
|
+
const request = { action, signature, nonce, vaultAddress };
|
|
346
|
+
const response = await this.transport.request("action", request, signal);
|
|
347
|
+
// Validate a response
|
|
348
|
+
this._validateResponse(response);
|
|
349
|
+
return response;
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Cancel order(s).
|
|
353
|
+
* @param args - The parameters for the request.
|
|
354
|
+
* @param signal - An optional abort signal.
|
|
355
|
+
* @returns Successful variant of {@link CancelResponse} without error statuses.
|
|
356
|
+
* @throws {ApiRequestError} When the API returns an error response.
|
|
357
|
+
*
|
|
358
|
+
* @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#cancel-order-s
|
|
359
|
+
* @example
|
|
360
|
+
* ```ts
|
|
361
|
+
* import * as hl from "@nktkas/hyperliquid";
|
|
362
|
+
* import { privateKeyToAccount } from "viem/accounts";
|
|
363
|
+
*
|
|
364
|
+
* const wallet = privateKeyToAccount("0x...");
|
|
365
|
+
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
366
|
+
* const client = new hl.WalletClient({ wallet, transport });
|
|
367
|
+
*
|
|
368
|
+
* const result = await client.cancel({
|
|
369
|
+
* cancels: [{
|
|
370
|
+
* a: 0, // Asset index
|
|
371
|
+
* o: 123, // Order ID
|
|
372
|
+
* }],
|
|
373
|
+
* });
|
|
374
|
+
* ```
|
|
375
|
+
*/
|
|
376
|
+
async cancel(args, signal) {
|
|
377
|
+
// Destructure the parameters
|
|
378
|
+
const { vaultAddress = this.defaultVaultAddress, nonce = Date.now(), ...actionArgs } = args;
|
|
379
|
+
// Construct an action
|
|
380
|
+
const action = {
|
|
381
|
+
type: "cancel",
|
|
382
|
+
cancels: actionArgs.cancels.map((cancel) => ({
|
|
383
|
+
a: cancel.a,
|
|
384
|
+
o: cancel.o,
|
|
385
|
+
})),
|
|
386
|
+
};
|
|
387
|
+
// Sign the action
|
|
388
|
+
const signature = await (0, signing_js_1.signL1Action)({
|
|
389
|
+
wallet: this.wallet,
|
|
390
|
+
action,
|
|
391
|
+
nonce,
|
|
392
|
+
isTestnet: this.isTestnet,
|
|
393
|
+
vaultAddress,
|
|
394
|
+
});
|
|
395
|
+
// Send a request
|
|
396
|
+
const request = { action, signature, nonce, vaultAddress };
|
|
397
|
+
const response = await this.transport.request("action", request, signal);
|
|
398
|
+
// Validate a response
|
|
399
|
+
this._validateResponse(response);
|
|
400
|
+
return response;
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* Deposit into staking balance.
|
|
404
|
+
* @param args - The parameters for the request.
|
|
405
|
+
* @param signal - An optional abort signal.
|
|
406
|
+
* @returns Successful response without specific data.
|
|
407
|
+
* @throws {ApiRequestError} When the API returns an error response.
|
|
408
|
+
*
|
|
409
|
+
* @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#deposit-into-staking
|
|
410
|
+
* @example
|
|
411
|
+
* ```ts
|
|
412
|
+
* import * as hl from "@nktkas/hyperliquid";
|
|
413
|
+
* import { privateKeyToAccount } from "viem/accounts";
|
|
414
|
+
*
|
|
415
|
+
* const wallet = privateKeyToAccount("0x...");
|
|
416
|
+
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
417
|
+
* const client = new hl.WalletClient({ wallet, transport });
|
|
418
|
+
*
|
|
419
|
+
* const result = await client.cDeposit({ wei: 1 * 1e8 });
|
|
420
|
+
* ```
|
|
421
|
+
*/
|
|
422
|
+
async cDeposit(args, signal) {
|
|
423
|
+
// Construct an action
|
|
424
|
+
const action = {
|
|
425
|
+
...args,
|
|
426
|
+
type: "cDeposit",
|
|
427
|
+
hyperliquidChain: this.isTestnet ? "Testnet" : "Mainnet",
|
|
428
|
+
signatureChainId: this.signatureChainId,
|
|
429
|
+
nonce: args.nonce ?? Date.now(),
|
|
430
|
+
};
|
|
431
|
+
// Sign the action
|
|
432
|
+
const signature = await (0, signing_js_1.signUserSignedAction)({
|
|
433
|
+
wallet: this.wallet,
|
|
434
|
+
action,
|
|
435
|
+
types: {
|
|
436
|
+
"HyperliquidTransaction:CDeposit": [
|
|
437
|
+
{ name: "hyperliquidChain", type: "string" },
|
|
438
|
+
{ name: "wei", type: "uint64" },
|
|
439
|
+
{ name: "nonce", type: "uint64" },
|
|
440
|
+
],
|
|
441
|
+
},
|
|
442
|
+
chainId: parseInt(action.signatureChainId, 16),
|
|
443
|
+
});
|
|
444
|
+
// Send a request
|
|
445
|
+
const request = { action, signature, nonce: action.nonce };
|
|
446
|
+
const response = await this.transport.request("action", request, signal);
|
|
447
|
+
// Validate a response
|
|
448
|
+
this._validateResponse(response);
|
|
449
|
+
return response;
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
452
|
+
* Claim rewards from referral program.
|
|
453
|
+
* @param args - The parameters for the request.
|
|
454
|
+
* @param signal - An optional abort signal.
|
|
455
|
+
* @returns Successful response without specific data.
|
|
456
|
+
* @throws {ApiRequestError} When the API returns an error response.
|
|
457
|
+
*
|
|
458
|
+
* @see null - no documentation
|
|
459
|
+
* @example
|
|
460
|
+
* ```ts
|
|
461
|
+
* import * as hl from "@nktkas/hyperliquid";
|
|
462
|
+
* import { privateKeyToAccount } from "viem/accounts";
|
|
463
|
+
*
|
|
464
|
+
* const wallet = privateKeyToAccount("0x...");
|
|
465
|
+
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
466
|
+
* const client = new hl.WalletClient({ wallet, transport });
|
|
467
|
+
*
|
|
468
|
+
* const result = await client.claimRewards();
|
|
469
|
+
* ```
|
|
470
|
+
*/
|
|
471
|
+
async claimRewards(args = {}, signal) {
|
|
472
|
+
// Destructure the parameters
|
|
473
|
+
const { nonce = Date.now() } = args;
|
|
474
|
+
// Construct an action
|
|
475
|
+
const sortedAction = { type: "claimRewards" };
|
|
476
|
+
// Sign the action
|
|
477
|
+
const signature = await (0, signing_js_1.signL1Action)({
|
|
478
|
+
wallet: this.wallet,
|
|
479
|
+
action: sortedAction,
|
|
480
|
+
nonce,
|
|
481
|
+
isTestnet: this.isTestnet,
|
|
482
|
+
});
|
|
483
|
+
// Send a request
|
|
484
|
+
const request = { action: sortedAction, signature, nonce };
|
|
485
|
+
const response = await this.transport.request("action", request, signal);
|
|
486
|
+
// Validate a response
|
|
487
|
+
this._validateResponse(response);
|
|
488
|
+
return response;
|
|
489
|
+
}
|
|
490
|
+
/**
|
|
491
|
+
* Cancel order(s) by cloid.
|
|
492
|
+
* @param args - The parameters for the request.
|
|
493
|
+
* @param signal - An optional abort signal.
|
|
494
|
+
* @returns Successful variant of {@link CancelResponse} without error statuses.
|
|
495
|
+
* @throws {ApiRequestError} When the API returns an error response.
|
|
496
|
+
*
|
|
497
|
+
* @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#cancel-order-s-by-cloid
|
|
498
|
+
* @example
|
|
499
|
+
* ```ts
|
|
500
|
+
* import * as hl from "@nktkas/hyperliquid";
|
|
501
|
+
* import { privateKeyToAccount } from "viem/accounts";
|
|
502
|
+
*
|
|
503
|
+
* const wallet = privateKeyToAccount("0x...");
|
|
504
|
+
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
505
|
+
* const client = new hl.WalletClient({ wallet, transport });
|
|
506
|
+
*
|
|
507
|
+
* const result = await client.cancelByCloid({
|
|
508
|
+
* cancels: [{
|
|
509
|
+
* asset: 0,
|
|
510
|
+
* cloid: "0x...", // Client Order ID
|
|
511
|
+
* }],
|
|
512
|
+
* });
|
|
513
|
+
* ```
|
|
514
|
+
*/
|
|
515
|
+
async cancelByCloid(args, signal) {
|
|
516
|
+
// Destructure the parameters
|
|
517
|
+
const { vaultAddress = this.defaultVaultAddress, nonce = Date.now(), ...actionArgs } = args;
|
|
518
|
+
// Construct an action
|
|
519
|
+
const action = {
|
|
520
|
+
type: "cancelByCloid",
|
|
521
|
+
cancels: actionArgs.cancels.map((cancel) => ({
|
|
522
|
+
asset: cancel.asset,
|
|
523
|
+
cloid: cancel.cloid,
|
|
524
|
+
})),
|
|
525
|
+
};
|
|
526
|
+
// Sign the action
|
|
527
|
+
const signature = await (0, signing_js_1.signL1Action)({
|
|
528
|
+
wallet: this.wallet,
|
|
529
|
+
action,
|
|
530
|
+
nonce,
|
|
531
|
+
isTestnet: this.isTestnet,
|
|
532
|
+
vaultAddress,
|
|
533
|
+
});
|
|
534
|
+
// Send a request
|
|
535
|
+
const request = { action, signature, nonce, vaultAddress };
|
|
536
|
+
const response = await this.transport.request("action", request, signal);
|
|
537
|
+
// Validate a response
|
|
538
|
+
this._validateResponse(response);
|
|
539
|
+
return response;
|
|
540
|
+
}
|
|
541
|
+
/**
|
|
542
|
+
* Withdraw from staking balance.
|
|
543
|
+
* @param args - The parameters for the request.
|
|
544
|
+
* @param signal - An optional abort signal.
|
|
545
|
+
* @returns Successful response without specific data.
|
|
546
|
+
* @throws {ApiRequestError} When the API returns an error response.
|
|
547
|
+
*
|
|
548
|
+
* @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#withdraw-from-staking
|
|
549
|
+
* @example
|
|
550
|
+
* ```ts
|
|
551
|
+
* import * as hl from "@nktkas/hyperliquid";
|
|
552
|
+
* import { privateKeyToAccount } from "viem/accounts";
|
|
553
|
+
*
|
|
554
|
+
* const wallet = privateKeyToAccount("0x...");
|
|
555
|
+
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
556
|
+
* const client = new hl.WalletClient({ wallet, transport });
|
|
557
|
+
*
|
|
558
|
+
* const result = await client.cWithdraw({ wei: 1 * 1e8 });
|
|
559
|
+
* ```
|
|
560
|
+
*/
|
|
561
|
+
async cWithdraw(args, signal) {
|
|
562
|
+
// Construct an action
|
|
563
|
+
const action = {
|
|
564
|
+
...args,
|
|
565
|
+
type: "cWithdraw",
|
|
566
|
+
hyperliquidChain: this.isTestnet ? "Testnet" : "Mainnet",
|
|
567
|
+
signatureChainId: this.signatureChainId,
|
|
568
|
+
nonce: args.nonce ?? Date.now(),
|
|
569
|
+
};
|
|
570
|
+
// Sign the action
|
|
571
|
+
const signature = await (0, signing_js_1.signUserSignedAction)({
|
|
572
|
+
wallet: this.wallet,
|
|
573
|
+
action,
|
|
574
|
+
types: {
|
|
575
|
+
"HyperliquidTransaction:CWithdraw": [
|
|
576
|
+
{ name: "hyperliquidChain", type: "string" },
|
|
577
|
+
{ name: "wei", type: "uint64" },
|
|
578
|
+
{ name: "nonce", type: "uint64" },
|
|
579
|
+
],
|
|
580
|
+
},
|
|
581
|
+
chainId: parseInt(action.signatureChainId, 16),
|
|
582
|
+
});
|
|
583
|
+
// Send a request
|
|
584
|
+
const request = { action, signature, nonce: action.nonce };
|
|
585
|
+
const response = await this.transport.request("action", request, signal);
|
|
586
|
+
// Validate a response
|
|
587
|
+
this._validateResponse(response);
|
|
588
|
+
return response;
|
|
589
|
+
}
|
|
590
|
+
/**
|
|
591
|
+
* Configure block type for EVM transactions.
|
|
592
|
+
* @param args - The parameters for the request.
|
|
593
|
+
* @param signal - An optional abort signal.
|
|
594
|
+
* @returns Response for creating a sub-account.
|
|
595
|
+
* @throws {ApiRequestError} When the API returns an error response.
|
|
596
|
+
*
|
|
597
|
+
* @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/evm/dual-block-architecture
|
|
598
|
+
* @example
|
|
599
|
+
* ```ts
|
|
600
|
+
* import * as hl from "@nktkas/hyperliquid";
|
|
601
|
+
* import { privateKeyToAccount } from "viem/accounts";
|
|
602
|
+
*
|
|
603
|
+
* const wallet = privateKeyToAccount("0x...");
|
|
604
|
+
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
605
|
+
* const client = new hl.WalletClient({ wallet, transport });
|
|
606
|
+
*
|
|
607
|
+
* const result = await client.evmUserModify({ usingBigBlocks: true });
|
|
608
|
+
* ```
|
|
609
|
+
*/
|
|
610
|
+
async evmUserModify(args, signal) {
|
|
611
|
+
// Destructure the parameters
|
|
612
|
+
const { nonce = Date.now(), ...actionArgs } = args;
|
|
613
|
+
// Construct an action
|
|
614
|
+
const action = {
|
|
615
|
+
type: "evmUserModify",
|
|
616
|
+
usingBigBlocks: actionArgs.usingBigBlocks,
|
|
617
|
+
};
|
|
618
|
+
// Sign the action
|
|
619
|
+
const signature = await (0, signing_js_1.signL1Action)({
|
|
620
|
+
wallet: this.wallet,
|
|
621
|
+
action,
|
|
622
|
+
nonce,
|
|
623
|
+
isTestnet: this.isTestnet,
|
|
624
|
+
});
|
|
625
|
+
// Send a request
|
|
626
|
+
const request = { action, signature, nonce };
|
|
627
|
+
const response = await this.transport.request("action", request, signal);
|
|
628
|
+
// Validate a response
|
|
629
|
+
this._validateResponse(response);
|
|
630
|
+
return response;
|
|
631
|
+
}
|
|
632
|
+
/**
|
|
633
|
+
* Create a sub-account.
|
|
634
|
+
* @param args - The parameters for the request.
|
|
635
|
+
* @param signal - An optional abort signal.
|
|
636
|
+
* @returns Response for creating a sub-account.
|
|
637
|
+
* @throws {ApiRequestError} When the API returns an error response.
|
|
638
|
+
*
|
|
639
|
+
* @see null - no documentation
|
|
640
|
+
* @example
|
|
641
|
+
* ```ts
|
|
642
|
+
* import * as hl from "@nktkas/hyperliquid";
|
|
643
|
+
* import { privateKeyToAccount } from "viem/accounts";
|
|
644
|
+
*
|
|
645
|
+
* const wallet = privateKeyToAccount("0x...");
|
|
646
|
+
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
647
|
+
* const client = new hl.WalletClient({ wallet, transport });
|
|
648
|
+
*
|
|
649
|
+
* const result = await client.createSubAccount({ name: "subAccountName" });
|
|
650
|
+
* ```
|
|
651
|
+
*/
|
|
652
|
+
async createSubAccount(args, signal) {
|
|
653
|
+
// Destructure the parameters
|
|
654
|
+
const { nonce = Date.now(), ...actionArgs } = args;
|
|
655
|
+
// Construct an action
|
|
656
|
+
const action = {
|
|
657
|
+
type: "createSubAccount",
|
|
658
|
+
name: actionArgs.name,
|
|
659
|
+
};
|
|
660
|
+
// Sign the action
|
|
661
|
+
const signature = await (0, signing_js_1.signL1Action)({
|
|
662
|
+
wallet: this.wallet,
|
|
663
|
+
action,
|
|
664
|
+
nonce,
|
|
665
|
+
isTestnet: this.isTestnet,
|
|
666
|
+
});
|
|
667
|
+
// Send a request
|
|
668
|
+
const request = { action, signature, nonce };
|
|
669
|
+
const response = await this.transport.request("action", request, signal);
|
|
670
|
+
// Validate a response
|
|
671
|
+
this._validateResponse(response);
|
|
672
|
+
return response;
|
|
983
673
|
}
|
|
984
|
-
|
|
985
|
-
|
|
674
|
+
/**
|
|
675
|
+
* Modify an order.
|
|
676
|
+
* @param args - The parameters for the request.
|
|
677
|
+
* @param signal - An optional abort signal.
|
|
678
|
+
* @returns Successful response without specific data.
|
|
679
|
+
* @throws {ApiRequestError} When the API returns an error response.
|
|
680
|
+
*
|
|
681
|
+
* @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#modify-an-order
|
|
682
|
+
* @example
|
|
683
|
+
* ```ts
|
|
684
|
+
* import * as hl from "@nktkas/hyperliquid";
|
|
685
|
+
* import { privateKeyToAccount } from "viem/accounts";
|
|
686
|
+
*
|
|
687
|
+
* const wallet = privateKeyToAccount("0x...");
|
|
688
|
+
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
689
|
+
* const client = new hl.WalletClient({ wallet, transport });
|
|
690
|
+
*
|
|
691
|
+
* const result = await client.modify({
|
|
692
|
+
* oid: 123, // Order ID
|
|
693
|
+
* order: {
|
|
694
|
+
* a: 0, // Asset index
|
|
695
|
+
* b: true, // Buy order
|
|
696
|
+
* p: "31000", // New price
|
|
697
|
+
* s: "0.2", // New size
|
|
698
|
+
* r: false, // Not reduce-only
|
|
699
|
+
* t: {
|
|
700
|
+
* limit: {
|
|
701
|
+
* tif: "Gtc", // Good-til-cancelled
|
|
702
|
+
* },
|
|
703
|
+
* },
|
|
704
|
+
* c: "0x...", // Optional: Client Order ID
|
|
705
|
+
* },
|
|
706
|
+
* });
|
|
707
|
+
* ```
|
|
708
|
+
*/
|
|
709
|
+
async modify(args, signal) {
|
|
710
|
+
// Destructure the parameters
|
|
711
|
+
const { vaultAddress = this.defaultVaultAddress, nonce = Date.now(), ...actionArgs } = args;
|
|
712
|
+
// Construct an action
|
|
713
|
+
const action = {
|
|
714
|
+
type: "modify",
|
|
715
|
+
oid: actionArgs.oid,
|
|
716
|
+
order: {
|
|
717
|
+
a: actionArgs.order.a,
|
|
718
|
+
b: actionArgs.order.b,
|
|
719
|
+
p: actionArgs.order.p,
|
|
720
|
+
s: actionArgs.order.s,
|
|
721
|
+
r: actionArgs.order.r,
|
|
722
|
+
t: "limit" in actionArgs.order.t
|
|
723
|
+
? {
|
|
724
|
+
limit: {
|
|
725
|
+
tif: actionArgs.order.t.limit.tif,
|
|
726
|
+
},
|
|
727
|
+
}
|
|
728
|
+
: {
|
|
729
|
+
trigger: {
|
|
730
|
+
isMarket: actionArgs.order.t.trigger.isMarket,
|
|
731
|
+
triggerPx: actionArgs.order.t.trigger.triggerPx,
|
|
732
|
+
tpsl: actionArgs.order.t.trigger.tpsl,
|
|
733
|
+
},
|
|
734
|
+
},
|
|
735
|
+
c: actionArgs.order.c,
|
|
736
|
+
},
|
|
737
|
+
};
|
|
738
|
+
if (action.order.c === undefined)
|
|
739
|
+
delete action.order.c;
|
|
740
|
+
// Sign the action
|
|
741
|
+
const signature = await (0, signing_js_1.signL1Action)({
|
|
742
|
+
wallet: this.wallet,
|
|
743
|
+
action,
|
|
744
|
+
nonce,
|
|
745
|
+
isTestnet: this.isTestnet,
|
|
746
|
+
vaultAddress,
|
|
747
|
+
});
|
|
748
|
+
// Send a request
|
|
749
|
+
const request = { action, signature, nonce, vaultAddress };
|
|
750
|
+
const response = await this.transport.request("action", request, signal);
|
|
751
|
+
// Validate a response
|
|
752
|
+
this._validateResponse(response);
|
|
753
|
+
return response;
|
|
754
|
+
}
|
|
755
|
+
/**
|
|
756
|
+
* Place an order(s).
|
|
757
|
+
* @param args - The parameters for the request.
|
|
758
|
+
* @param signal - An optional abort signal.
|
|
759
|
+
* @returns Successful variant of {@link OrderResponse} without error statuses.
|
|
760
|
+
* @throws {ApiRequestError} When the API returns an error response.
|
|
761
|
+
*
|
|
762
|
+
* @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#place-an-order
|
|
763
|
+
* @example
|
|
764
|
+
* ```ts
|
|
765
|
+
* import * as hl from "@nktkas/hyperliquid";
|
|
766
|
+
* import { privateKeyToAccount } from "viem/accounts";
|
|
767
|
+
*
|
|
768
|
+
* const wallet = privateKeyToAccount("0x...");
|
|
769
|
+
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
770
|
+
* const client = new hl.WalletClient({ wallet, transport });
|
|
771
|
+
*
|
|
772
|
+
* const result = await client.order({
|
|
773
|
+
* orders: [{
|
|
774
|
+
* a: 0, // Asset index
|
|
775
|
+
* b: true, // Buy order
|
|
776
|
+
* p: "30000", // Price
|
|
777
|
+
* s: "0.1", // Size
|
|
778
|
+
* r: false, // Not reduce-only
|
|
779
|
+
* t: {
|
|
780
|
+
* limit: {
|
|
781
|
+
* tif: "Gtc", // Good-til-cancelled
|
|
782
|
+
* },
|
|
783
|
+
* },
|
|
784
|
+
* c: "0x...", // Optional: Client Order ID
|
|
785
|
+
* }],
|
|
786
|
+
* grouping: "na", // No grouping
|
|
787
|
+
* });
|
|
788
|
+
* ```
|
|
789
|
+
*/
|
|
790
|
+
async order(args, signal) {
|
|
791
|
+
// Destructure the parameters
|
|
792
|
+
const { vaultAddress = this.defaultVaultAddress, nonce = Date.now(), ...actionArgs } = args;
|
|
793
|
+
// Construct an action
|
|
794
|
+
const action = {
|
|
795
|
+
type: "order",
|
|
796
|
+
orders: actionArgs.orders.map((order) => {
|
|
797
|
+
const sortedOrder = {
|
|
798
|
+
a: order.a,
|
|
799
|
+
b: order.b,
|
|
800
|
+
p: order.p,
|
|
801
|
+
s: order.s,
|
|
802
|
+
r: order.r,
|
|
803
|
+
t: "limit" in order.t
|
|
804
|
+
? {
|
|
805
|
+
limit: {
|
|
806
|
+
tif: order.t.limit.tif,
|
|
807
|
+
},
|
|
808
|
+
}
|
|
809
|
+
: {
|
|
810
|
+
trigger: {
|
|
811
|
+
isMarket: order.t.trigger.isMarket,
|
|
812
|
+
triggerPx: order.t.trigger.triggerPx,
|
|
813
|
+
tpsl: order.t.trigger.tpsl,
|
|
814
|
+
},
|
|
815
|
+
},
|
|
816
|
+
c: order.c,
|
|
817
|
+
};
|
|
818
|
+
if (order.c === undefined)
|
|
819
|
+
delete sortedOrder.c;
|
|
820
|
+
return sortedOrder;
|
|
821
|
+
}),
|
|
822
|
+
grouping: actionArgs.grouping,
|
|
823
|
+
builder: actionArgs.builder
|
|
824
|
+
? {
|
|
825
|
+
b: actionArgs.builder.b.toLowerCase(),
|
|
826
|
+
f: actionArgs.builder.f,
|
|
827
|
+
}
|
|
828
|
+
: actionArgs.builder,
|
|
829
|
+
};
|
|
830
|
+
if (action.builder === undefined)
|
|
831
|
+
delete action.builder;
|
|
832
|
+
// Sign the action
|
|
833
|
+
const signature = await (0, signing_js_1.signL1Action)({
|
|
834
|
+
wallet: this.wallet,
|
|
835
|
+
action,
|
|
836
|
+
nonce,
|
|
837
|
+
isTestnet: this.isTestnet,
|
|
838
|
+
vaultAddress,
|
|
839
|
+
});
|
|
840
|
+
// Send a request
|
|
841
|
+
const request = { action, signature, nonce, vaultAddress };
|
|
842
|
+
const response = await this.transport.request("action", request, signal);
|
|
843
|
+
// Validate a response
|
|
844
|
+
this._validateResponse(response);
|
|
845
|
+
return response;
|
|
846
|
+
}
|
|
847
|
+
/**
|
|
848
|
+
* Schedule a time to cancel all open orders.
|
|
849
|
+
* @param args - The parameters for the request.
|
|
850
|
+
* @param signal - An optional abort signal.
|
|
851
|
+
* @returns Successful response without specific data.
|
|
852
|
+
* @throws {ApiRequestError} When the API returns an error response.
|
|
853
|
+
*
|
|
854
|
+
* @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#schedule-cancel-dead-mans-switch
|
|
855
|
+
* @example
|
|
856
|
+
* ```ts
|
|
857
|
+
* import * as hl from "@nktkas/hyperliquid";
|
|
858
|
+
* import { privateKeyToAccount } from "viem/accounts";
|
|
859
|
+
*
|
|
860
|
+
* const wallet = privateKeyToAccount("0x...");
|
|
861
|
+
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
862
|
+
* const client = new hl.WalletClient({ wallet, transport });
|
|
863
|
+
*
|
|
864
|
+
* const result = await client.scheduleCancel({ time: Date.now() + 3600000 });
|
|
865
|
+
* ```
|
|
866
|
+
*/
|
|
867
|
+
async scheduleCancel(args = {}, signal) {
|
|
868
|
+
// Destructure the parameters
|
|
869
|
+
const { vaultAddress = this.defaultVaultAddress, nonce = Date.now(), ...actionArgs } = args;
|
|
870
|
+
// Construct an action
|
|
871
|
+
const action = {
|
|
872
|
+
type: "scheduleCancel",
|
|
873
|
+
time: actionArgs.time,
|
|
874
|
+
};
|
|
875
|
+
if (action.time === undefined)
|
|
876
|
+
delete action.time;
|
|
877
|
+
// Sign the action
|
|
878
|
+
const signature = await (0, signing_js_1.signL1Action)({
|
|
879
|
+
wallet: this.wallet,
|
|
880
|
+
action,
|
|
881
|
+
nonce,
|
|
882
|
+
isTestnet: this.isTestnet,
|
|
883
|
+
vaultAddress,
|
|
884
|
+
});
|
|
885
|
+
// Send a request
|
|
886
|
+
const request = { action, signature, nonce, vaultAddress };
|
|
887
|
+
const response = await this.transport.request("action", request, signal);
|
|
888
|
+
// Validate a response
|
|
889
|
+
this._validateResponse(response);
|
|
890
|
+
return response;
|
|
891
|
+
}
|
|
892
|
+
/**
|
|
893
|
+
* Set the display name in the leaderboard.
|
|
894
|
+
* @param args - The parameters for the request.
|
|
895
|
+
* @param signal - An optional abort signal.
|
|
896
|
+
* @returns Successful response without specific data.
|
|
897
|
+
* @throws {ApiRequestError} When the API returns an error response.
|
|
898
|
+
*
|
|
899
|
+
* @see null - no documentation
|
|
900
|
+
* @example
|
|
901
|
+
* ```ts
|
|
902
|
+
* import * as hl from "@nktkas/hyperliquid";
|
|
903
|
+
* import { privateKeyToAccount } from "viem/accounts";
|
|
904
|
+
*
|
|
905
|
+
* const wallet = privateKeyToAccount("0x...");
|
|
906
|
+
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
907
|
+
* const client = new hl.WalletClient({ wallet, transport });
|
|
908
|
+
*
|
|
909
|
+
* const result = await client.setDisplayName({ displayName: "My Name" });
|
|
910
|
+
* ```
|
|
911
|
+
*/
|
|
912
|
+
async setDisplayName(args, signal) {
|
|
913
|
+
// Destructure the parameters
|
|
914
|
+
const { nonce = Date.now(), ...actionArgs } = args;
|
|
915
|
+
// Construct an action
|
|
916
|
+
const action = {
|
|
917
|
+
type: "setDisplayName",
|
|
918
|
+
displayName: actionArgs.displayName,
|
|
919
|
+
};
|
|
920
|
+
// Sign the action
|
|
921
|
+
const signature = await (0, signing_js_1.signL1Action)({
|
|
922
|
+
wallet: this.wallet,
|
|
923
|
+
action,
|
|
924
|
+
nonce,
|
|
925
|
+
isTestnet: this.isTestnet,
|
|
926
|
+
});
|
|
927
|
+
// Send a request
|
|
928
|
+
const request = { action, signature, nonce };
|
|
929
|
+
const response = await this.transport.request("action", request, signal);
|
|
930
|
+
// Validate a response
|
|
931
|
+
this._validateResponse(response);
|
|
932
|
+
return response;
|
|
933
|
+
}
|
|
934
|
+
/**
|
|
935
|
+
* Set a referral code.
|
|
936
|
+
* @param args - The parameters for the request.
|
|
937
|
+
* @param signal - An optional abort signal.
|
|
938
|
+
* @returns Successful response without specific data.
|
|
939
|
+
* @throws {ApiRequestError} When the API returns an error response.
|
|
940
|
+
*
|
|
941
|
+
* @see null - no documentation
|
|
942
|
+
* @example
|
|
943
|
+
* ```ts
|
|
944
|
+
* import * as hl from "@nktkas/hyperliquid";
|
|
945
|
+
* import { privateKeyToAccount } from "viem/accounts";
|
|
946
|
+
*
|
|
947
|
+
* const wallet = privateKeyToAccount("0x...");
|
|
948
|
+
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
949
|
+
* const client = new hl.WalletClient({ wallet, transport });
|
|
950
|
+
*
|
|
951
|
+
* const result = await client.setReferrer({ code: "TEST" });
|
|
952
|
+
* ```
|
|
953
|
+
*/
|
|
954
|
+
async setReferrer(args, signal) {
|
|
955
|
+
// Destructure the parameters
|
|
956
|
+
const { nonce = Date.now(), ...actionArgs } = args;
|
|
957
|
+
// Construct an action
|
|
958
|
+
const action = {
|
|
959
|
+
type: "setReferrer",
|
|
960
|
+
code: actionArgs.code,
|
|
961
|
+
};
|
|
962
|
+
// Sign the action
|
|
963
|
+
const signature = await (0, signing_js_1.signL1Action)({
|
|
964
|
+
wallet: this.wallet,
|
|
965
|
+
action,
|
|
966
|
+
nonce,
|
|
967
|
+
isTestnet: this.isTestnet,
|
|
968
|
+
});
|
|
969
|
+
// Send a request
|
|
970
|
+
const request = { action, signature, nonce };
|
|
971
|
+
const response = await this.transport.request("action", request, signal);
|
|
972
|
+
// Validate a response
|
|
973
|
+
this._validateResponse(response);
|
|
974
|
+
return response;
|
|
975
|
+
}
|
|
976
|
+
/**
|
|
977
|
+
* Transfer a spot asset on L1 to another address.
|
|
978
|
+
* @param args - The parameters for the request.
|
|
979
|
+
* @param signal - An optional abort signal.
|
|
980
|
+
* @returns Successful response without specific data.
|
|
981
|
+
* @throws {ApiRequestError} When the API returns an error response.
|
|
982
|
+
*
|
|
983
|
+
* @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#l1-spot-transfer
|
|
984
|
+
* @example
|
|
985
|
+
* ```ts
|
|
986
|
+
* import * as hl from "@nktkas/hyperliquid";
|
|
987
|
+
* import { privateKeyToAccount } from "viem/accounts";
|
|
988
|
+
*
|
|
989
|
+
* const wallet = privateKeyToAccount("0x...");
|
|
990
|
+
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
991
|
+
* const client = new hl.WalletClient({ wallet, transport });
|
|
992
|
+
*
|
|
993
|
+
* const result = await client.spotSend({
|
|
994
|
+
* destination: "0x...",
|
|
995
|
+
* token: "USDC:0xeb62eee3685fc4c43992febcd9e75443",
|
|
996
|
+
* amount: "1",
|
|
997
|
+
* });
|
|
998
|
+
* ```
|
|
999
|
+
*/
|
|
1000
|
+
async spotSend(args, signal) {
|
|
1001
|
+
// Construct an action
|
|
1002
|
+
const action = {
|
|
1003
|
+
...args,
|
|
1004
|
+
type: "spotSend",
|
|
1005
|
+
hyperliquidChain: this.isTestnet ? "Testnet" : "Mainnet",
|
|
1006
|
+
signatureChainId: this.signatureChainId,
|
|
1007
|
+
time: args.time ?? Date.now(),
|
|
1008
|
+
};
|
|
1009
|
+
// Sign the action
|
|
1010
|
+
const signature = await (0, signing_js_1.signUserSignedAction)({
|
|
1011
|
+
wallet: this.wallet,
|
|
1012
|
+
action,
|
|
1013
|
+
types: {
|
|
1014
|
+
"HyperliquidTransaction:SpotSend": [
|
|
1015
|
+
{ name: "hyperliquidChain", type: "string" },
|
|
1016
|
+
{ name: "destination", type: "string" },
|
|
1017
|
+
{ name: "token", type: "string" },
|
|
1018
|
+
{ name: "amount", type: "string" },
|
|
1019
|
+
{ name: "time", type: "uint64" },
|
|
1020
|
+
],
|
|
1021
|
+
},
|
|
1022
|
+
chainId: parseInt(action.signatureChainId, 16),
|
|
1023
|
+
});
|
|
1024
|
+
// Send a request
|
|
1025
|
+
const request = { action, signature, nonce: action.time };
|
|
1026
|
+
const response = await this.transport.request("action", request, signal);
|
|
1027
|
+
// Validate a response
|
|
1028
|
+
this._validateResponse(response);
|
|
1029
|
+
return response;
|
|
1030
|
+
}
|
|
1031
|
+
/**
|
|
1032
|
+
* Opt Out of Spot Dusting.
|
|
1033
|
+
* @param args - The parameters for the request.
|
|
1034
|
+
* @param signal - An optional abort signal.
|
|
1035
|
+
* @returns Successful response without specific data.
|
|
1036
|
+
* @throws {ApiRequestError} When the API returns an error response.
|
|
1037
|
+
*
|
|
1038
|
+
* @see null - no documentation
|
|
1039
|
+
* @example
|
|
1040
|
+
* ```ts
|
|
1041
|
+
* import * as hl from "@nktkas/hyperliquid";
|
|
1042
|
+
* import { privateKeyToAccount } from "viem/accounts";
|
|
1043
|
+
*
|
|
1044
|
+
* const wallet = privateKeyToAccount("0x...");
|
|
1045
|
+
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
1046
|
+
* const client = new hl.WalletClient({ wallet, transport });
|
|
1047
|
+
*
|
|
1048
|
+
* const result = await client.spotUser({
|
|
1049
|
+
* toggleSpotDusting: { optOut: false },
|
|
1050
|
+
* });
|
|
1051
|
+
* ```
|
|
1052
|
+
*/
|
|
1053
|
+
async spotUser(args, signal) {
|
|
1054
|
+
// Destructure the parameters
|
|
1055
|
+
const { nonce = Date.now(), ...actionArgs } = args;
|
|
1056
|
+
// Construct an action
|
|
1057
|
+
const action = {
|
|
1058
|
+
type: "spotUser",
|
|
1059
|
+
toggleSpotDusting: {
|
|
1060
|
+
optOut: actionArgs.toggleSpotDusting.optOut,
|
|
1061
|
+
},
|
|
1062
|
+
};
|
|
1063
|
+
// Sign the action
|
|
1064
|
+
const signature = await (0, signing_js_1.signL1Action)({
|
|
1065
|
+
wallet: this.wallet,
|
|
1066
|
+
action,
|
|
1067
|
+
nonce,
|
|
1068
|
+
isTestnet: this.isTestnet,
|
|
1069
|
+
});
|
|
1070
|
+
// Send a request
|
|
1071
|
+
const request = { action, signature, nonce };
|
|
1072
|
+
const response = await this.transport.request("action", request, signal);
|
|
1073
|
+
// Validate a response
|
|
1074
|
+
this._validateResponse(response);
|
|
1075
|
+
return response;
|
|
1076
|
+
}
|
|
1077
|
+
/**
|
|
1078
|
+
* Transfer between sub-accounts (spot).
|
|
1079
|
+
* @param args - The parameters for the request.
|
|
1080
|
+
* @param signal - An optional abort signal.
|
|
1081
|
+
* @returns Successful response without specific data.
|
|
1082
|
+
* @throws {ApiRequestError} When the API returns an error response.
|
|
1083
|
+
*
|
|
1084
|
+
* @see null - no documentation
|
|
1085
|
+
* @example
|
|
1086
|
+
* ```ts
|
|
1087
|
+
* import * as hl from "@nktkas/hyperliquid";
|
|
1088
|
+
* import { privateKeyToAccount } from "viem/accounts";
|
|
1089
|
+
*
|
|
1090
|
+
* const wallet = privateKeyToAccount("0x...");
|
|
1091
|
+
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
1092
|
+
* const client = new hl.WalletClient({ wallet, transport });
|
|
1093
|
+
*
|
|
1094
|
+
* const result = await client.subAccountSpotTransfer({
|
|
1095
|
+
* subAccountUser: "0x...",
|
|
1096
|
+
* isDeposit: true,
|
|
1097
|
+
* token: "USDC:0xeb62eee3685fc4c43992febcd9e75443",
|
|
1098
|
+
* amount: "1",
|
|
1099
|
+
* });
|
|
1100
|
+
* ```
|
|
1101
|
+
*/
|
|
1102
|
+
async subAccountSpotTransfer(args, signal) {
|
|
1103
|
+
// Destructure the parameters
|
|
1104
|
+
const { nonce = Date.now(), ...actionArgs } = args;
|
|
1105
|
+
// Construct an action
|
|
1106
|
+
const action = {
|
|
1107
|
+
type: "subAccountSpotTransfer",
|
|
1108
|
+
subAccountUser: actionArgs.subAccountUser,
|
|
1109
|
+
isDeposit: actionArgs.isDeposit,
|
|
1110
|
+
token: actionArgs.token,
|
|
1111
|
+
amount: actionArgs.amount,
|
|
1112
|
+
};
|
|
1113
|
+
// Sign the action
|
|
1114
|
+
const signature = await (0, signing_js_1.signL1Action)({
|
|
1115
|
+
wallet: this.wallet,
|
|
1116
|
+
action,
|
|
1117
|
+
nonce,
|
|
1118
|
+
isTestnet: this.isTestnet,
|
|
1119
|
+
});
|
|
1120
|
+
// Send a request
|
|
1121
|
+
const request = { action, signature, nonce };
|
|
1122
|
+
const response = await this.transport.request("action", request, signal);
|
|
1123
|
+
// Validate a response
|
|
1124
|
+
this._validateResponse(response);
|
|
1125
|
+
return response;
|
|
1126
|
+
}
|
|
1127
|
+
/**
|
|
1128
|
+
* Transfer between sub-accounts (perpetual).
|
|
1129
|
+
* @param args - The parameters for the request.
|
|
1130
|
+
* @param signal - An optional abort signal.
|
|
1131
|
+
* @returns Successful response without specific data.
|
|
1132
|
+
* @throws {ApiRequestError} When the API returns an error response.
|
|
1133
|
+
*
|
|
1134
|
+
* @see null - no documentation
|
|
1135
|
+
* @example
|
|
1136
|
+
* ```ts
|
|
1137
|
+
* import * as hl from "@nktkas/hyperliquid";
|
|
1138
|
+
* import { privateKeyToAccount } from "viem/accounts";
|
|
1139
|
+
*
|
|
1140
|
+
* const wallet = privateKeyToAccount("0x...");
|
|
1141
|
+
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
1142
|
+
* const client = new hl.WalletClient({ wallet, transport });
|
|
1143
|
+
*
|
|
1144
|
+
* const result = await client.subAccountTransfer({
|
|
1145
|
+
* subAccountUser: "0x...",
|
|
1146
|
+
* isDeposit: true,
|
|
1147
|
+
* usd: 1 * 1e6,
|
|
1148
|
+
* });
|
|
1149
|
+
* ```
|
|
1150
|
+
*/
|
|
1151
|
+
async subAccountTransfer(args, signal) {
|
|
1152
|
+
// Destructure the parameters
|
|
1153
|
+
const { nonce = Date.now(), ...actionArgs } = args;
|
|
1154
|
+
// Construct an action
|
|
1155
|
+
const action = {
|
|
1156
|
+
type: "subAccountTransfer",
|
|
1157
|
+
subAccountUser: actionArgs.subAccountUser,
|
|
1158
|
+
isDeposit: actionArgs.isDeposit,
|
|
1159
|
+
usd: actionArgs.usd,
|
|
1160
|
+
};
|
|
1161
|
+
// Sign the action
|
|
1162
|
+
const signature = await (0, signing_js_1.signL1Action)({
|
|
1163
|
+
wallet: this.wallet,
|
|
1164
|
+
action,
|
|
1165
|
+
nonce,
|
|
1166
|
+
isTestnet: this.isTestnet,
|
|
1167
|
+
});
|
|
1168
|
+
// Send a request
|
|
1169
|
+
const request = { action, signature, nonce };
|
|
1170
|
+
const response = await this.transport.request("action", request, signal);
|
|
1171
|
+
// Validate a response
|
|
1172
|
+
this._validateResponse(response);
|
|
1173
|
+
return response;
|
|
1174
|
+
}
|
|
1175
|
+
/**
|
|
1176
|
+
* Delegate or undelegate stake from a validator.
|
|
1177
|
+
* @param args - The parameters for the request.
|
|
1178
|
+
* @param signal - An optional abort signal.
|
|
1179
|
+
* @returns Successful response without specific data.
|
|
1180
|
+
* @throws {ApiRequestError} When the API returns an error response.
|
|
1181
|
+
*
|
|
1182
|
+
* @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#delegate-or-undelegate-stake-from-validator
|
|
1183
|
+
* @example
|
|
1184
|
+
* ```ts
|
|
1185
|
+
* import * as hl from "@nktkas/hyperliquid";
|
|
1186
|
+
* import { privateKeyToAccount } from "viem/accounts";
|
|
1187
|
+
*
|
|
1188
|
+
* const wallet = privateKeyToAccount("0x...");
|
|
1189
|
+
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
1190
|
+
* const client = new hl.WalletClient({ wallet, transport });
|
|
1191
|
+
*
|
|
1192
|
+
* const result = await client.tokenDelegate({
|
|
1193
|
+
* validator: "0x...",
|
|
1194
|
+
* isUndelegate: true,
|
|
1195
|
+
* wei: 1 * 1e8,
|
|
1196
|
+
* });
|
|
1197
|
+
* ```
|
|
1198
|
+
*/
|
|
1199
|
+
async tokenDelegate(args, signal) {
|
|
1200
|
+
// Construct an action
|
|
1201
|
+
const action = {
|
|
1202
|
+
...args,
|
|
1203
|
+
type: "tokenDelegate",
|
|
1204
|
+
hyperliquidChain: this.isTestnet ? "Testnet" : "Mainnet",
|
|
1205
|
+
signatureChainId: this.signatureChainId,
|
|
1206
|
+
nonce: args.nonce ?? Date.now(),
|
|
1207
|
+
};
|
|
1208
|
+
// Sign the action
|
|
1209
|
+
const signature = await (0, signing_js_1.signUserSignedAction)({
|
|
1210
|
+
wallet: this.wallet,
|
|
1211
|
+
action,
|
|
1212
|
+
types: {
|
|
1213
|
+
"HyperliquidTransaction:TokenDelegate": [
|
|
1214
|
+
{ name: "hyperliquidChain", type: "string" },
|
|
1215
|
+
{ name: "validator", type: "address" },
|
|
1216
|
+
{ name: "wei", type: "uint64" },
|
|
1217
|
+
{ name: "isUndelegate", type: "bool" },
|
|
1218
|
+
{ name: "nonce", type: "uint64" },
|
|
1219
|
+
],
|
|
1220
|
+
},
|
|
1221
|
+
chainId: parseInt(action.signatureChainId, 16),
|
|
1222
|
+
});
|
|
1223
|
+
// Send a request
|
|
1224
|
+
const request = { action, signature, nonce: action.nonce };
|
|
1225
|
+
const response = await this.transport.request("action", request, signal);
|
|
1226
|
+
// Validate a response
|
|
1227
|
+
this._validateResponse(response);
|
|
1228
|
+
return response;
|
|
1229
|
+
}
|
|
1230
|
+
/**
|
|
1231
|
+
* Cancel a TWAP order.
|
|
1232
|
+
* @param args - The parameters for the request.
|
|
1233
|
+
* @param signal - An optional abort signal.
|
|
1234
|
+
* @returns Successful variant of {@link TwapCancelResponse} without error status.
|
|
1235
|
+
* @throws {ApiRequestError} When the API returns an error response.
|
|
1236
|
+
*
|
|
1237
|
+
* @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#cancel-a-twap-order
|
|
1238
|
+
* @example
|
|
1239
|
+
* ```ts
|
|
1240
|
+
* import * as hl from "@nktkas/hyperliquid";
|
|
1241
|
+
* import { privateKeyToAccount } from "viem/accounts";
|
|
1242
|
+
*
|
|
1243
|
+
* const wallet = privateKeyToAccount("0x...");
|
|
1244
|
+
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
1245
|
+
* const client = new hl.WalletClient({ wallet, transport });
|
|
1246
|
+
*
|
|
1247
|
+
* const result = await client.twapCancel({
|
|
1248
|
+
* a: 0, // Asset index
|
|
1249
|
+
* t: 1, // TWAP ID
|
|
1250
|
+
* });
|
|
1251
|
+
* ```
|
|
1252
|
+
*/
|
|
1253
|
+
async twapCancel(args, signal) {
|
|
1254
|
+
// Destructure the parameters
|
|
1255
|
+
const { vaultAddress = this.defaultVaultAddress, nonce = Date.now(), ...actionArgs } = args;
|
|
1256
|
+
// Construct an action
|
|
1257
|
+
const action = {
|
|
1258
|
+
type: "twapCancel",
|
|
1259
|
+
a: actionArgs.a,
|
|
1260
|
+
t: actionArgs.t,
|
|
1261
|
+
};
|
|
1262
|
+
// Sign the action
|
|
1263
|
+
const signature = await (0, signing_js_1.signL1Action)({
|
|
1264
|
+
wallet: this.wallet,
|
|
1265
|
+
action,
|
|
1266
|
+
nonce,
|
|
1267
|
+
isTestnet: this.isTestnet,
|
|
1268
|
+
vaultAddress,
|
|
1269
|
+
});
|
|
1270
|
+
// Send a request
|
|
1271
|
+
const request = { action, signature, nonce, vaultAddress };
|
|
1272
|
+
const response = await this.transport.request("action", request, signal);
|
|
1273
|
+
// Validate a response
|
|
1274
|
+
this._validateResponse(response);
|
|
1275
|
+
return response;
|
|
1276
|
+
}
|
|
1277
|
+
/**
|
|
1278
|
+
* Place a TWAP order.
|
|
1279
|
+
* @param args - The parameters for the request.
|
|
1280
|
+
* @param signal - An optional abort signal.
|
|
1281
|
+
* @returns Successful variant of {@link TwapOrderResponse} without error status.
|
|
1282
|
+
* @throws {ApiRequestError} When the API returns an error response.
|
|
1283
|
+
*
|
|
1284
|
+
* @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#place-a-twap-order
|
|
1285
|
+
* @example
|
|
1286
|
+
* ```ts
|
|
1287
|
+
* import * as hl from "@nktkas/hyperliquid";
|
|
1288
|
+
* import { privateKeyToAccount } from "viem/accounts";
|
|
1289
|
+
*
|
|
1290
|
+
* const wallet = privateKeyToAccount("0x...");
|
|
1291
|
+
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
1292
|
+
* const client = new hl.WalletClient({ wallet, transport });
|
|
1293
|
+
*
|
|
1294
|
+
* const result = await client.twapOrder({
|
|
1295
|
+
* a: 0, // Asset index
|
|
1296
|
+
* b: true, // Buy order
|
|
1297
|
+
* s: "1", // Size
|
|
1298
|
+
* r: false, // Not reduce-only
|
|
1299
|
+
* m: 10, // Duration in minutes
|
|
1300
|
+
* t: true, // Randomize order timing
|
|
1301
|
+
* });
|
|
1302
|
+
* ```
|
|
1303
|
+
*/
|
|
1304
|
+
async twapOrder(args, signal) {
|
|
1305
|
+
// Destructure the parameters
|
|
1306
|
+
const { vaultAddress = this.defaultVaultAddress, nonce = Date.now(), ...actionArgs } = args;
|
|
1307
|
+
// Construct an action
|
|
1308
|
+
const action = {
|
|
1309
|
+
type: "twapOrder",
|
|
1310
|
+
twap: {
|
|
1311
|
+
a: actionArgs.a,
|
|
1312
|
+
b: actionArgs.b,
|
|
1313
|
+
s: actionArgs.s,
|
|
1314
|
+
r: actionArgs.r,
|
|
1315
|
+
m: actionArgs.m,
|
|
1316
|
+
t: actionArgs.t,
|
|
1317
|
+
},
|
|
1318
|
+
};
|
|
1319
|
+
// Sign the action
|
|
1320
|
+
const signature = await (0, signing_js_1.signL1Action)({
|
|
1321
|
+
wallet: this.wallet,
|
|
1322
|
+
action,
|
|
1323
|
+
nonce,
|
|
1324
|
+
isTestnet: this.isTestnet,
|
|
1325
|
+
vaultAddress,
|
|
1326
|
+
});
|
|
1327
|
+
// Send a request
|
|
1328
|
+
const request = { action, signature, nonce, vaultAddress };
|
|
1329
|
+
const response = await this.transport.request("action", request, signal);
|
|
1330
|
+
// Validate a response
|
|
1331
|
+
this._validateResponse(response);
|
|
1332
|
+
return response;
|
|
1333
|
+
}
|
|
1334
|
+
/**
|
|
1335
|
+
* Update isolated margin for a position.
|
|
1336
|
+
* @param args - The parameters for the request.
|
|
1337
|
+
* @param signal - An optional abort signal.
|
|
1338
|
+
* @returns Successful response without specific data.
|
|
1339
|
+
* @throws {ApiRequestError} When the API returns an error response.
|
|
1340
|
+
*
|
|
1341
|
+
* @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#update-isolated-margin
|
|
1342
|
+
* @example
|
|
1343
|
+
* ```ts
|
|
1344
|
+
* import * as hl from "@nktkas/hyperliquid";
|
|
1345
|
+
* import { privateKeyToAccount } from "viem/accounts";
|
|
1346
|
+
*
|
|
1347
|
+
* const wallet = privateKeyToAccount("0x...");
|
|
1348
|
+
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
1349
|
+
* const client = new hl.WalletClient({ wallet, transport });
|
|
1350
|
+
*
|
|
1351
|
+
* const result = await client.updateIsolatedMargin({
|
|
1352
|
+
* asset: 0,
|
|
1353
|
+
* isBuy: true, // Add to long position
|
|
1354
|
+
* ntli: 1, // Add 1 USD margin (integer only)
|
|
1355
|
+
* });
|
|
1356
|
+
* ```
|
|
1357
|
+
*/
|
|
1358
|
+
async updateIsolatedMargin(args, signal) {
|
|
1359
|
+
// Destructure the parameters
|
|
1360
|
+
const { vaultAddress = this.defaultVaultAddress, nonce = Date.now(), ...actionArgs } = args;
|
|
1361
|
+
// Construct an action
|
|
1362
|
+
const action = {
|
|
1363
|
+
type: "updateIsolatedMargin",
|
|
1364
|
+
asset: actionArgs.asset,
|
|
1365
|
+
isBuy: actionArgs.isBuy,
|
|
1366
|
+
ntli: actionArgs.ntli,
|
|
1367
|
+
};
|
|
1368
|
+
// Sign the action
|
|
1369
|
+
const signature = await (0, signing_js_1.signL1Action)({
|
|
1370
|
+
wallet: this.wallet,
|
|
1371
|
+
action,
|
|
1372
|
+
nonce,
|
|
1373
|
+
isTestnet: this.isTestnet,
|
|
1374
|
+
vaultAddress,
|
|
1375
|
+
});
|
|
1376
|
+
// Send a request
|
|
1377
|
+
const request = { action, signature, nonce, vaultAddress };
|
|
1378
|
+
const response = await this.transport.request("action", request, signal);
|
|
1379
|
+
// Validate a response
|
|
1380
|
+
this._validateResponse(response);
|
|
1381
|
+
return response;
|
|
1382
|
+
}
|
|
1383
|
+
/**
|
|
1384
|
+
* Update leverage for cross or isolated margin.
|
|
1385
|
+
* @param args - The parameters for the request.
|
|
1386
|
+
* @param signal - An optional abort signal.
|
|
1387
|
+
* @returns Successful response without specific data.
|
|
1388
|
+
* @throws {ApiRequestError} When the API returns an error response.
|
|
1389
|
+
*
|
|
1390
|
+
* @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#update-leverage
|
|
1391
|
+
* @example
|
|
1392
|
+
* ```ts
|
|
1393
|
+
* import * as hl from "@nktkas/hyperliquid";
|
|
1394
|
+
* import { privateKeyToAccount } from "viem/accounts";
|
|
1395
|
+
*
|
|
1396
|
+
* const wallet = privateKeyToAccount("0x...");
|
|
1397
|
+
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
1398
|
+
* const client = new hl.WalletClient({ wallet, transport });
|
|
1399
|
+
*
|
|
1400
|
+
* const result = await client.updateLeverage({
|
|
1401
|
+
* asset: 0,
|
|
1402
|
+
* isCross: true,
|
|
1403
|
+
* leverage: 5,
|
|
1404
|
+
* });
|
|
1405
|
+
* ```
|
|
1406
|
+
*/
|
|
1407
|
+
async updateLeverage(args, signal) {
|
|
1408
|
+
// Destructure the parameters
|
|
1409
|
+
const { vaultAddress = this.defaultVaultAddress, nonce = Date.now(), ...actionArgs } = args;
|
|
1410
|
+
// Construct an action
|
|
1411
|
+
const action = {
|
|
1412
|
+
type: "updateLeverage",
|
|
1413
|
+
asset: actionArgs.asset,
|
|
1414
|
+
isCross: actionArgs.isCross,
|
|
1415
|
+
leverage: actionArgs.leverage,
|
|
1416
|
+
};
|
|
1417
|
+
// Sign the action
|
|
1418
|
+
const signature = await (0, signing_js_1.signL1Action)({
|
|
1419
|
+
wallet: this.wallet,
|
|
1420
|
+
action,
|
|
1421
|
+
nonce,
|
|
1422
|
+
isTestnet: this.isTestnet,
|
|
1423
|
+
vaultAddress,
|
|
1424
|
+
});
|
|
1425
|
+
// Send a request
|
|
1426
|
+
const request = { action, signature, nonce, vaultAddress };
|
|
1427
|
+
const response = await this.transport.request("action", request, signal);
|
|
1428
|
+
// Validate a response
|
|
1429
|
+
this._validateResponse(response);
|
|
1430
|
+
return response;
|
|
1431
|
+
}
|
|
1432
|
+
/**
|
|
1433
|
+
* Transfer funds between Spot and Perp accounts.
|
|
1434
|
+
* @param args - The parameters for the request.
|
|
1435
|
+
* @param signal - An optional abort signal.
|
|
1436
|
+
* @returns Successful response without specific data.
|
|
1437
|
+
* @throws {ApiRequestError} When the API returns an error response.
|
|
1438
|
+
*
|
|
1439
|
+
* @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#transfer-from-spot-account-to-perp-account-and-vice-versa
|
|
1440
|
+
* @example
|
|
1441
|
+
* ```ts
|
|
1442
|
+
* import * as hl from "@nktkas/hyperliquid";
|
|
1443
|
+
* import { privateKeyToAccount } from "viem/accounts";
|
|
1444
|
+
*
|
|
1445
|
+
* const wallet = privateKeyToAccount("0x...");
|
|
1446
|
+
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
1447
|
+
* const client = new hl.WalletClient({ wallet, transport });
|
|
1448
|
+
*
|
|
1449
|
+
* const result = await client.usdClassTransfer({
|
|
1450
|
+
* amount: "1",
|
|
1451
|
+
* toPerp: true, // Transfer from Spot to Perp
|
|
1452
|
+
* });
|
|
1453
|
+
* ```
|
|
1454
|
+
*/
|
|
1455
|
+
async usdClassTransfer(args, signal) {
|
|
1456
|
+
// Construct an action
|
|
1457
|
+
const action = {
|
|
1458
|
+
...args,
|
|
1459
|
+
type: "usdClassTransfer",
|
|
1460
|
+
hyperliquidChain: this.isTestnet ? "Testnet" : "Mainnet",
|
|
1461
|
+
signatureChainId: this.signatureChainId,
|
|
1462
|
+
nonce: args.nonce ?? Date.now(),
|
|
1463
|
+
};
|
|
1464
|
+
// Sign the action
|
|
1465
|
+
const signature = await (0, signing_js_1.signUserSignedAction)({
|
|
1466
|
+
wallet: this.wallet,
|
|
1467
|
+
action,
|
|
1468
|
+
types: {
|
|
1469
|
+
"HyperliquidTransaction:UsdClassTransfer": [
|
|
1470
|
+
{ name: "hyperliquidChain", type: "string" },
|
|
1471
|
+
{ name: "amount", type: "string" },
|
|
1472
|
+
{ name: "toPerp", type: "bool" },
|
|
1473
|
+
{ name: "nonce", type: "uint64" },
|
|
1474
|
+
],
|
|
1475
|
+
},
|
|
1476
|
+
chainId: parseInt(action.signatureChainId, 16),
|
|
1477
|
+
});
|
|
1478
|
+
// Send a request
|
|
1479
|
+
const request = { action, signature, nonce: action.nonce };
|
|
1480
|
+
const response = await this.transport.request("action", request, signal);
|
|
1481
|
+
// Validate a response
|
|
1482
|
+
this._validateResponse(response);
|
|
1483
|
+
return response;
|
|
1484
|
+
}
|
|
1485
|
+
/**
|
|
1486
|
+
* Transfer USDC on L1 to another address.
|
|
1487
|
+
* @param args - The parameters for the request.
|
|
1488
|
+
* @param signal - An optional abort signal.
|
|
1489
|
+
* @returns Successful response without specific data.
|
|
1490
|
+
* @throws {ApiRequestError} When the API returns an error response.
|
|
1491
|
+
*
|
|
1492
|
+
* @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#l1-usdc-transfer
|
|
1493
|
+
* @example
|
|
1494
|
+
* ```ts
|
|
1495
|
+
* import * as hl from "@nktkas/hyperliquid";
|
|
1496
|
+
* import { privateKeyToAccount } from "viem/accounts";
|
|
1497
|
+
*
|
|
1498
|
+
* const wallet = privateKeyToAccount("0x...");
|
|
1499
|
+
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
1500
|
+
* const client = new hl.WalletClient({ wallet, transport });
|
|
1501
|
+
*
|
|
1502
|
+
* const result = await client.usdSend({
|
|
1503
|
+
* destination: "0x...",
|
|
1504
|
+
* amount: "1",
|
|
1505
|
+
* });
|
|
1506
|
+
* ```
|
|
1507
|
+
*/
|
|
1508
|
+
async usdSend(args, signal) {
|
|
1509
|
+
// Construct an action
|
|
1510
|
+
const action = {
|
|
1511
|
+
...args,
|
|
1512
|
+
type: "usdSend",
|
|
1513
|
+
hyperliquidChain: this.isTestnet ? "Testnet" : "Mainnet",
|
|
1514
|
+
signatureChainId: this.signatureChainId,
|
|
1515
|
+
time: args.time ?? Date.now(),
|
|
1516
|
+
};
|
|
1517
|
+
// Sign the action
|
|
1518
|
+
const signature = await (0, signing_js_1.signUserSignedAction)({
|
|
1519
|
+
wallet: this.wallet,
|
|
1520
|
+
action,
|
|
1521
|
+
types: {
|
|
1522
|
+
"HyperliquidTransaction:UsdSend": [
|
|
1523
|
+
{ name: "hyperliquidChain", type: "string" },
|
|
1524
|
+
{ name: "destination", type: "string" },
|
|
1525
|
+
{ name: "amount", type: "string" },
|
|
1526
|
+
{ name: "time", type: "uint64" },
|
|
1527
|
+
],
|
|
1528
|
+
},
|
|
1529
|
+
chainId: parseInt(action.signatureChainId, 16),
|
|
1530
|
+
});
|
|
1531
|
+
// Send a request
|
|
1532
|
+
const request = { action, signature, nonce: action.time };
|
|
1533
|
+
const response = await this.transport.request("action", request, signal);
|
|
1534
|
+
// Validate a response
|
|
1535
|
+
this._validateResponse(response);
|
|
1536
|
+
return response;
|
|
1537
|
+
}
|
|
1538
|
+
/**
|
|
1539
|
+
* Distribute funds from a vault between followers.
|
|
1540
|
+
* @param args - The parameters for the request.
|
|
1541
|
+
* @param signal - An optional abort signal.
|
|
1542
|
+
* @returns Successful response without specific data.
|
|
1543
|
+
* @throws {ApiRequestError} When the API returns an error response.
|
|
1544
|
+
*
|
|
1545
|
+
* @see null - no documentation
|
|
1546
|
+
* @example
|
|
1547
|
+
* ```ts
|
|
1548
|
+
* import * as hl from "@nktkas/hyperliquid";
|
|
1549
|
+
* import { privateKeyToAccount } from "viem/accounts";
|
|
1550
|
+
*
|
|
1551
|
+
* const wallet = privateKeyToAccount("0x...");
|
|
1552
|
+
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
1553
|
+
* const client = new hl.WalletClient({ wallet, transport });
|
|
1554
|
+
*
|
|
1555
|
+
* const result = await client.vaultDistribute({
|
|
1556
|
+
* vaultAddress: "0x...",
|
|
1557
|
+
* usd: 10 * 1e6,
|
|
1558
|
+
* });
|
|
1559
|
+
* ```
|
|
1560
|
+
*/
|
|
1561
|
+
async vaultDistribute(args, signal) {
|
|
1562
|
+
// Destructure the parameters
|
|
1563
|
+
const { nonce = Date.now(), ...actionArgs } = args;
|
|
1564
|
+
// Construct an action
|
|
1565
|
+
const action = {
|
|
1566
|
+
type: "vaultDistribute",
|
|
1567
|
+
vaultAddress: actionArgs.vaultAddress,
|
|
1568
|
+
usd: actionArgs.usd,
|
|
1569
|
+
};
|
|
1570
|
+
// Sign the action
|
|
1571
|
+
const signature = await (0, signing_js_1.signL1Action)({
|
|
1572
|
+
wallet: this.wallet,
|
|
1573
|
+
action,
|
|
1574
|
+
nonce,
|
|
1575
|
+
isTestnet: this.isTestnet,
|
|
1576
|
+
});
|
|
1577
|
+
// Send a request
|
|
1578
|
+
const request = { action, signature, nonce };
|
|
1579
|
+
const response = await this.transport.request("action", request, signal);
|
|
1580
|
+
// Validate a response
|
|
1581
|
+
this._validateResponse(response);
|
|
1582
|
+
return response;
|
|
1583
|
+
}
|
|
1584
|
+
/**
|
|
1585
|
+
* Modify a vault's configuration.
|
|
1586
|
+
* @param args - The parameters for the request.
|
|
1587
|
+
* @param signal - An optional abort signal.
|
|
1588
|
+
* @returns Successful response without specific data.
|
|
1589
|
+
* @throws {ApiRequestError} When the API returns an error response.
|
|
1590
|
+
*
|
|
1591
|
+
* @see null - no documentation
|
|
1592
|
+
* @example
|
|
1593
|
+
* ```ts
|
|
1594
|
+
* import * as hl from "@nktkas/hyperliquid";
|
|
1595
|
+
* import { privateKeyToAccount } from "viem/accounts";
|
|
1596
|
+
*
|
|
1597
|
+
* const wallet = privateKeyToAccount("0x...");
|
|
1598
|
+
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
1599
|
+
* const client = new hl.WalletClient({ wallet, transport });
|
|
1600
|
+
*
|
|
1601
|
+
* const result = await client.vaultModify({
|
|
1602
|
+
* vaultAddress: "0x...",
|
|
1603
|
+
* allowDeposits: true,
|
|
1604
|
+
* alwaysCloseOnWithdraw: false,
|
|
1605
|
+
* });
|
|
1606
|
+
* ```
|
|
1607
|
+
*/
|
|
1608
|
+
async vaultModify(args, signal) {
|
|
1609
|
+
// Destructure the parameters
|
|
1610
|
+
const { nonce = Date.now(), ...actionArgs } = args;
|
|
1611
|
+
// Construct an action
|
|
1612
|
+
const action = {
|
|
1613
|
+
type: "vaultModify",
|
|
1614
|
+
vaultAddress: actionArgs.vaultAddress,
|
|
1615
|
+
allowDeposits: actionArgs.allowDeposits,
|
|
1616
|
+
alwaysCloseOnWithdraw: actionArgs.alwaysCloseOnWithdraw,
|
|
1617
|
+
};
|
|
1618
|
+
// Sign the action
|
|
1619
|
+
const signature = await (0, signing_js_1.signL1Action)({
|
|
1620
|
+
wallet: this.wallet,
|
|
1621
|
+
action,
|
|
1622
|
+
nonce,
|
|
1623
|
+
isTestnet: this.isTestnet,
|
|
1624
|
+
});
|
|
1625
|
+
// Send a request
|
|
1626
|
+
const request = { action, signature, nonce };
|
|
1627
|
+
const response = await this.transport.request("action", request, signal);
|
|
1628
|
+
// Validate a response
|
|
1629
|
+
this._validateResponse(response);
|
|
1630
|
+
return response;
|
|
1631
|
+
}
|
|
1632
|
+
/**
|
|
1633
|
+
* Add or remove funds from a vault.
|
|
1634
|
+
* @param args - The parameters for the request.
|
|
1635
|
+
* @param signal - An optional abort signal.
|
|
1636
|
+
* @returns Successful response without specific data.
|
|
1637
|
+
* @throws {ApiRequestError} When the API returns an error response.
|
|
1638
|
+
*
|
|
1639
|
+
* @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#deposit-or-withdraw-from-a-vault
|
|
1640
|
+
* @example
|
|
1641
|
+
* ```ts
|
|
1642
|
+
* import * as hl from "@nktkas/hyperliquid";
|
|
1643
|
+
* import { privateKeyToAccount } from "viem/accounts";
|
|
1644
|
+
*
|
|
1645
|
+
* const wallet = privateKeyToAccount("0x...");
|
|
1646
|
+
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
1647
|
+
* const client = new hl.WalletClient({ wallet, transport });
|
|
1648
|
+
*
|
|
1649
|
+
* const result = await client.vaultTransfer({
|
|
1650
|
+
* vaultAddress: "0x...",
|
|
1651
|
+
* isDeposit: true,
|
|
1652
|
+
* usd: 10 * 1e6,
|
|
1653
|
+
* });
|
|
1654
|
+
* ```
|
|
1655
|
+
*/
|
|
1656
|
+
async vaultTransfer(args, signal) {
|
|
1657
|
+
// Destructure the parameters
|
|
1658
|
+
const { nonce = Date.now(), ...actionArgs } = args;
|
|
1659
|
+
// Construct an action
|
|
1660
|
+
const action = {
|
|
1661
|
+
type: "vaultTransfer",
|
|
1662
|
+
vaultAddress: actionArgs.vaultAddress,
|
|
1663
|
+
isDeposit: actionArgs.isDeposit,
|
|
1664
|
+
usd: actionArgs.usd,
|
|
1665
|
+
};
|
|
1666
|
+
// Sign the action
|
|
1667
|
+
const signature = await (0, signing_js_1.signL1Action)({
|
|
1668
|
+
wallet: this.wallet,
|
|
1669
|
+
action,
|
|
1670
|
+
nonce,
|
|
1671
|
+
isTestnet: this.isTestnet,
|
|
1672
|
+
});
|
|
1673
|
+
// Send a request
|
|
1674
|
+
const request = { action, signature, nonce };
|
|
1675
|
+
const response = await this.transport.request("action", request, signal);
|
|
1676
|
+
// Validate a response
|
|
1677
|
+
this._validateResponse(response);
|
|
1678
|
+
return response;
|
|
1679
|
+
}
|
|
1680
|
+
/**
|
|
1681
|
+
* Initiate a withdrawal request.
|
|
1682
|
+
* @param args - The parameters for the request.
|
|
1683
|
+
* @param signal - An optional abort signal.
|
|
1684
|
+
* @returns Successful response without specific data.
|
|
1685
|
+
* @throws {ApiRequestError} When the API returns an error response.
|
|
1686
|
+
*
|
|
1687
|
+
* @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#initiate-a-withdrawal-request
|
|
1688
|
+
* @example
|
|
1689
|
+
* ```ts
|
|
1690
|
+
* import * as hl from "@nktkas/hyperliquid";
|
|
1691
|
+
* import { privateKeyToAccount } from "viem/accounts";
|
|
1692
|
+
*
|
|
1693
|
+
* const wallet = privateKeyToAccount("0x...");
|
|
1694
|
+
* const transport = new hl.HttpTransport(); // or WebSocketTransport
|
|
1695
|
+
* const client = new hl.WalletClient({ wallet, transport });
|
|
1696
|
+
*
|
|
1697
|
+
* const result = await client.withdraw3({
|
|
1698
|
+
* destination: "0x...",
|
|
1699
|
+
* amount: "1",
|
|
1700
|
+
* });
|
|
1701
|
+
* ```
|
|
1702
|
+
*/
|
|
1703
|
+
async withdraw3(args, signal) {
|
|
1704
|
+
// Construct an action
|
|
1705
|
+
const action = {
|
|
1706
|
+
...args,
|
|
1707
|
+
type: "withdraw3",
|
|
1708
|
+
hyperliquidChain: this.isTestnet ? "Testnet" : "Mainnet",
|
|
1709
|
+
signatureChainId: this.signatureChainId,
|
|
1710
|
+
time: args.time ?? Date.now(),
|
|
1711
|
+
};
|
|
1712
|
+
// Sign the action
|
|
1713
|
+
const signature = await (0, signing_js_1.signUserSignedAction)({
|
|
1714
|
+
wallet: this.wallet,
|
|
1715
|
+
action,
|
|
1716
|
+
types: {
|
|
1717
|
+
"HyperliquidTransaction:Withdraw": [
|
|
1718
|
+
{ name: "hyperliquidChain", type: "string" },
|
|
1719
|
+
{ name: "destination", type: "string" },
|
|
1720
|
+
{ name: "amount", type: "string" },
|
|
1721
|
+
{ name: "time", type: "uint64" },
|
|
1722
|
+
],
|
|
1723
|
+
},
|
|
1724
|
+
chainId: parseInt(action.signatureChainId, 16),
|
|
1725
|
+
});
|
|
1726
|
+
// Send a request
|
|
1727
|
+
const request = { action, signature, nonce: action.time };
|
|
1728
|
+
const response = await this.transport.request("action", request, signal);
|
|
1729
|
+
// Validate a response
|
|
1730
|
+
this._validateResponse(response);
|
|
1731
|
+
return response;
|
|
1732
|
+
}
|
|
1733
|
+
/** Validate a response from the API. */
|
|
1734
|
+
_validateResponse(response) {
|
|
1735
|
+
if (response.status === "err") {
|
|
986
1736
|
throw new ApiRequestError(response);
|
|
987
1737
|
}
|
|
1738
|
+
else if (response.response.type === "order" || response.response.type === "cancel") {
|
|
1739
|
+
if (response.response.data.statuses.some((status) => typeof status === "object" && "error" in status)) {
|
|
1740
|
+
throw new ApiRequestError(response);
|
|
1741
|
+
}
|
|
1742
|
+
}
|
|
1743
|
+
else if (response.response.type === "twapOrder" || response.response.type === "twapCancel") {
|
|
1744
|
+
if (typeof response.response.data.status === "object" && "error" in response.response.data.status) {
|
|
1745
|
+
throw new ApiRequestError(response);
|
|
1746
|
+
}
|
|
1747
|
+
}
|
|
988
1748
|
}
|
|
989
1749
|
}
|
|
990
|
-
|
|
991
|
-
|
|
1750
|
+
exports.WalletClient = WalletClient;
|
|
1751
|
+
});
|