• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

nktkas / hyperliquid / 15678306478

16 Jun 2025 10:24AM UTC coverage: 97.211% (-0.2%) from 97.414%
15678306478

push

github

nktkas
docs(readme): update private key usage examples to remove mention of other wallet libraries

434 of 476 branches covered (91.18%)

Branch coverage included in aggregate %.

4307 of 4401 relevant lines covered (97.86%)

310.83 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.51
/src/clients/multiSign.ts
1
import { keccak_256 } from "@noble/hashes/sha3";
149✔
2
import { getPublicKey } from "@noble/secp256k1";
149✔
3
import { encodeHex } from "@std/encoding/hex";
149✔
4
import type { Hex } from "../base.ts";
5
import type { IRequestTransport } from "../transports/base.ts";
6
import type {
7
    ApproveAgentRequest,
8
    ApproveBuilderFeeRequest,
9
    BaseExchangeRequest,
10
    BatchModifyRequest,
11
    CancelByCloidRequest,
12
    CancelRequest,
13
    CDepositRequest,
14
    ClaimRewardsRequest,
15
    ConvertToMultiSigUserRequest,
16
    CreateSubAccountRequest,
17
    CreateVaultRequest,
18
    CSignerActionRequest_JailSelf,
19
    CSignerActionRequest_UnjailSelf,
20
    CValidatorActionRequest_ChangeProfile,
21
    CValidatorActionRequest_Register,
22
    CValidatorActionRequest_Unregister,
23
    CWithdrawRequest,
24
    EvmUserModifyRequest,
25
    ModifyRequest,
26
    OrderRequest,
27
    PerpDeployRequest_RegisterAsset,
28
    PerpDeployRequest_SetOracle,
29
    PerpDexClassTransferRequest,
30
    RegisterReferrerRequest,
31
    ReserveRequestWeightRequest,
32
    ScheduleCancelRequest,
33
    SetDisplayNameRequest,
34
    SetReferrerRequest,
35
    SpotDeployRequest_Genesis,
36
    SpotDeployRequest_RegisterHyperliquidity,
37
    SpotDeployRequest_RegisterSpot,
38
    SpotDeployRequest_RegisterToken2,
39
    SpotDeployRequest_SetDeployerTradingFeeShare,
40
    SpotDeployRequest_UserGenesis,
41
    SpotSendRequest,
42
    SpotUserRequest,
43
    SubAccountSpotTransferRequest,
44
    SubAccountTransferRequest,
45
    TokenDelegateRequest,
46
    TwapCancelRequest,
47
    TwapOrderRequest,
48
    UpdateIsolatedMarginRequest,
49
    UpdateLeverageRequest,
50
    UsdClassTransferRequest,
51
    UsdSendRequest,
52
    VaultDistributeRequest,
53
    VaultModifyRequest,
54
    VaultTransferRequest,
55
    Withdraw3Request,
56
} from "../types/exchange/requests.ts";
57
import type { CreateSubAccountResponse, CreateVaultResponse, SuccessResponse } from "../types/exchange/responses.ts";
58
import {
149✔
59
    type AbstractEthersSigner,
60
    type AbstractEthersV5Signer,
61
    type AbstractViemWalletClient,
62
    type AbstractWallet,
63
    type AbstractWindowEthereum,
64
    actionSorter,
149✔
65
    isAbstractEthersSigner,
149✔
66
    isAbstractEthersV5Signer,
149✔
67
    isAbstractViemWalletClient,
149✔
68
    isAbstractWindowEthereum,
149✔
69
    isValidPrivateKey,
149✔
70
    type Signature,
71
    signL1Action,
149✔
72
    signUserSignedAction,
149✔
73
    userSignedActionEip712Types,
149✔
74
} from "../signing/mod.ts";
149✔
75
import {
149✔
76
    type CancelResponseSuccess,
77
    type CSignerActionParameters,
78
    type CSignerActionParameters_JailSelf,
79
    type CSignerActionParameters_UnjailSelf,
80
    type CValidatorActionParameters,
81
    type CValidatorActionParameters_ChangeProfile,
82
    type CValidatorActionParameters_Register,
83
    type CValidatorActionParameters_Unregister,
84
    ExchangeClient,
149✔
85
    type ExchangeClientParameters,
86
    type OrderResponseSuccess,
87
    type PerpDeployParameters,
88
    type PerpDeployParameters_RegisterAsset,
89
    type PerpDeployParameters_SetOracle,
90
    type ScheduleCancelParameters,
91
    type SpotDeployParameters,
92
    type SpotDeployParameters_Genesis,
93
    type SpotDeployParameters_RegisterHyperliquidity,
94
    type SpotDeployParameters_RegisterSpot,
95
    type SpotDeployParameters_RegisterToken2,
96
    type SpotDeployParameters_SetDeployerTradingFeeShare,
97
    type SpotDeployParameters_UserGenesis,
98
    type TwapCancelResponseSuccess,
99
    type TwapOrderResponseSuccess,
100
} from "./exchange.ts";
149✔
101

102
/** Parameters for the {@linkcode MultiSignClient} constructor. */
103
export interface MultiSignClientParameters<
104
    T extends IRequestTransport = IRequestTransport,
105
    S extends readonly [AbstractWalletWithAddress, ...AbstractWallet[]] = [
106
        AbstractWalletWithAddress,
107
        ...AbstractWallet[],
108
    ],
109
> extends Omit<ExchangeClientParameters<T, S[0]>, "wallet"> {
110
    /** The multi-signature account address. */
111
    multiSignAddress: Hex;
112
    /** Array of wallets used for multi-signature operations. The first wallet acts as the leader. */
113
    signers: S;
114
}
115

116
/** Abstract interface for a wallet that can sign typed data and has wallet address. */
117
export type AbstractWalletWithAddress =
118
    | Hex // Private key
119
    | AbstractViemWalletClientWithAddress
120
    | AbstractEthersSignerWithAddress
121
    | AbstractEthersV5SignerWithAddress
122
    | AbstractWindowEthereum;
123

124
/** Abstract interface for a [viem wallet](https://viem.sh/docs/clients/wallet) with wallet address. */
125
export interface AbstractViemWalletClientWithAddress extends AbstractViemWalletClient {
126
    address: Hex;
127
}
128

129
/** Abstract interface for an [ethers.js signer](https://docs.ethers.org/v6/api/providers/#Signer) with wallet address. */
130
export interface AbstractEthersSignerWithAddress extends AbstractEthersSigner {
131
    getAddress(): Promise<string>;
132
}
133

134
/** Abstract interface for an [ethers.js v5 signer](https://docs.ethers.org/v5/api/signer/) with wallet address. */
135
export interface AbstractEthersV5SignerWithAddress extends AbstractEthersV5Signer {
136
    getAddress(): Promise<string>;
137
}
138

139
/**
140
 * Multi-signature exchange client for interacting with the Hyperliquid API.
141
 * @typeParam T The transport used to connect to the Hyperliquid API.
142
 * @typeParam S Array of wallets where the first wallet acts as the leader.
143
 */
144
export class MultiSignClient<
149✔
145
    T extends IRequestTransport = IRequestTransport,
146
    S extends readonly [AbstractWalletWithAddress, ...AbstractWallet[]] = [
147
        AbstractWalletWithAddress,
148
        ...AbstractWallet[],
149
    ],
150
> extends ExchangeClient<T, S[0]> implements MultiSignClientParameters<T, S> {
149✔
151
    multiSignAddress: Hex;
149✔
152
    signers: S;
149✔
153

154
    /**
155
     * @multisign Is the first wallet from {@linkcode signers}.
156
     */
157
    declare wallet: S[0];
158

159
    /**
160
     * Initialises a new multi-signature client instance.
161
     * @param args - The parameters for the multi-signature client.
162
     *
163
     * @example
164
     * ```ts
165
     * import * as hl from "@nktkas/hyperliquid";
166
     *
167
     * const multiSignAddress = "0x...";
168
     * const signers = [
169
     *   "0x...", // Private key; or any other wallet libraries
170
     * ] as const;
171
     *
172
     * const transport = new hl.HttpTransport();
173
     * const multiSignClient = new hl.MultiSignClient({ transport, multiSignAddress, signers });
174
     * ```
175
     */
176
    constructor(args: MultiSignClientParameters<T, S>) {
149✔
177
        super({ ...args, wallet: args.signers[0] });
752✔
178
        this.multiSignAddress = args.multiSignAddress;
188✔
179
        this.signers = args.signers;
188✔
180

181
        Object.defineProperty(this, "wallet", {
188✔
182
            get() {
188✔
183
                return this.signers[0];
861✔
184
            },
188✔
185
            set(value) {
×
186
                this.signers[0] = value;
×
187
            },
×
188
            enumerable: true,
188✔
189
            configurable: true,
188✔
190
        });
188✔
191
    }
188✔
192

193
    /**
194
     * @param args - The parameters for the request.
195
     * @param signal - An optional abort signal
196
     * @returns Successful response without specific data.
197
     * @throws {ApiRequestError} When the API returns an error response.
198
     *
199
     * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#approve-an-api-wallet
200
     * @example
201
     * ```ts
202
     * import * as hl from "@nktkas/hyperliquid";
203
     *
204
     * const multiSignAddress = "0x...";
205
     * const signers = [
206
     *   "0x...", // Private key; or any other wallet libraries
207
     * ] as const;
208
     *
209
     * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
210
     * const multiSignClient = new hl.MultiSignClient({ transport, multiSignAddress, signers });
211
     *
212
     * const data = await multiSignClient.approveAgent({ agentAddress: "0x...", agentName: "agentName" });
213
     * ```
214
     */
215
    override async approveAgent(
149✔
216
        ...[args, signal]: Parameters<ExchangeClient["approveAgent"]>
149✔
217
    ): ReturnType<ExchangeClient["approveAgent"]> {
149✔
218
        // Destructure the parameters
219
        const { ...actionArgs } = args;
153✔
220

221
        // Construct an action
222
        const nonce = await this.nonceManager();
153✔
223
        const action: ApproveAgentRequest["action"] = {
153✔
224
            ...actionArgs,
153✔
225
            agentName: args.agentName ?? "",
153✔
226
            type: "approveAgent",
153✔
227
            hyperliquidChain: this._getHyperliquidChain(),
153✔
228
            signatureChainId: await this._getSignatureChainId(),
153✔
229
            nonce,
153✔
230
        };
153✔
231

232
        // Sign the action
233
        const sortedAction = actionSorter[action.type](action);
153✔
234
        const outerSigner = await this._getWalletAddress(this.signers[0]);
153✔
235

236
        const signatures = await this._multiSignUserSignedAction(sortedAction, outerSigner);
153✔
237
        if (sortedAction.agentName === "") sortedAction.agentName = null;
153✔
238

239
        // Send a multi-sig action
240
        return super.multiSig({
153✔
241
            signatures,
153✔
242
            payload: {
153✔
243
                multiSigUser: this.multiSignAddress,
153✔
244
                outerSigner,
153✔
245
                action: sortedAction,
153✔
246
            },
153✔
247
            nonce,
153✔
248
        }, signal);
153✔
249
    }
153✔
250

251
    /**
252
     * @param args - The parameters for the request.
253
     * @param signal - An optional abort signal.
254
     * @returns Successful response without specific data.
255
     * @throws {ApiRequestError} When the API returns an error response.
256
     *
257
     * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#approve-a-builder-fee
258
     * @example
259
     * ```ts
260
     * import * as hl from "@nktkas/hyperliquid";
261
     *
262
     * const multiSignAddress = "0x...";
263
     * const signers = [
264
     *   "0x...", // Private key; or any other wallet libraries
265
     * ] as const;
266
     *
267
     * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
268
     * const multiSignClient = new hl.MultiSignClient({ transport, multiSignAddress, signers });
269
     *
270
     * const data = await multiSignClient.approveBuilderFee({ maxFeeRate: "0.01%", builder: "0x..." });
271
     * ```
272
     */
273
    override async approveBuilderFee(
149✔
274
        ...[args, signal]: Parameters<ExchangeClient["approveBuilderFee"]>
149✔
275
    ): ReturnType<ExchangeClient["approveBuilderFee"]> {
149✔
276
        // Destructure the parameters
277
        const { ...actionArgs } = args;
150✔
278

279
        // Construct an action
280
        const nonce = await this.nonceManager();
150✔
281
        const action: ApproveBuilderFeeRequest["action"] = {
150✔
282
            ...actionArgs,
150✔
283
            type: "approveBuilderFee",
150✔
284
            hyperliquidChain: this._getHyperliquidChain(),
150✔
285
            signatureChainId: await this._getSignatureChainId(),
150✔
286
            nonce,
150✔
287
        };
150✔
288

289
        // Sign the action
290
        const sortedAction = actionSorter[action.type](action);
150✔
291
        const outerSigner = await this._getWalletAddress(this.signers[0]);
150✔
292

293
        const signatures = await this._multiSignUserSignedAction(sortedAction, outerSigner);
150✔
294

295
        // Send a multi-sig action
296
        return super.multiSig({
150✔
297
            signatures,
150✔
298
            payload: {
150✔
299
                multiSigUser: this.multiSignAddress,
150✔
300
                outerSigner,
150✔
301
                action: sortedAction,
150✔
302
            },
150✔
303
            nonce,
150✔
304
        }, signal);
150✔
305
    }
150✔
306

307
    /**
308
     * @param args - The parameters for the request.
309
     * @param signal - An optional abort signal.
310
     * @returns Successful variant of {@link OrderResponse} without error statuses.
311
     * @throws {ApiRequestError} When the API returns an error response.
312
     *
313
     * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#modify-multiple-orders
314
     * @example
315
     * ```ts
316
     * import * as hl from "@nktkas/hyperliquid";
317
     *
318
     * const multiSignAddress = "0x...";
319
     * const signers = [
320
     *   "0x...", // Private key; or any other wallet libraries
321
     * ] as const;
322
     *
323
     * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
324
     * const multiSignClient = new hl.MultiSignClient({ transport, multiSignAddress, signers });
325
     *
326
     * const data = await multiSignClient.batchModify({
327
     *   modifies: [{
328
     *     oid: 123,
329
     *     order: {
330
     *       a: 0, // Asset index
331
     *       b: true, // Buy order
332
     *       p: "31000", // New price
333
     *       s: "0.2", // New size
334
     *       r: false, // Not reduce-only
335
     *       t: {
336
     *         limit: {
337
     *           tif: "Gtc", // Good-til-cancelled
338
     *         },
339
     *       },
340
     *       c: "0x...", // Client Order ID (optional)
341
     *     },
342
     *   }],
343
     * });
344
     * ```
345
     */
346
    override async batchModify(
149✔
347
        ...[args, signal]: Parameters<ExchangeClient["batchModify"]>
149✔
348
    ): ReturnType<ExchangeClient["batchModify"]> {
149✔
349
        // Destructure the parameters
350
        const {
155✔
351
            vaultAddress = this.defaultVaultAddress,
155✔
352
            expiresAfter = await this._getDefaultExpiresAfter(),
155✔
353
            ...actionArgs
155✔
354
        } = args;
155✔
355

356
        // Construct an action
357
        const nonce = await this.nonceManager();
160✔
358
        const action: BatchModifyRequest["action"] = {
155✔
359
            type: "batchModify",
155✔
360
            ...actionArgs,
155✔
361
        };
155✔
362

363
        // Send a multi-sig action
364
        const sortedAction = actionSorter[action.type](action);
155✔
365
        const outerSigner = await this._getWalletAddress(this.signers[0]);
155✔
366

367
        const signatures = await this._multiSignL1Action({
155✔
368
            action: sortedAction,
155✔
369
            nonce,
155✔
370
            outerSigner,
155✔
371
            vaultAddress,
155✔
372
            expiresAfter,
155✔
373
        });
155✔
374

375
        // Send a multi-sig action
376
        return super.multiSig({
155✔
377
            signatures,
155✔
378
            payload: {
155✔
379
                multiSigUser: this.multiSignAddress,
155✔
380
                outerSigner,
155✔
381
                action: sortedAction,
155✔
382
            },
155✔
383
            nonce,
155✔
384
            vaultAddress,
155✔
385
            expiresAfter,
155✔
386
        }, signal);
155✔
387
    }
155✔
388

389
    /**
390
     * @param args - The parameters for the request.
391
     * @param signal - An optional abort signal.
392
     * @returns Successful variant of {@link CancelResponse} without error statuses.
393
     * @throws {ApiRequestError} When the API returns an error response.
394
     *
395
     * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#cancel-order-s
396
     * @example
397
     * ```ts
398
     * import * as hl from "@nktkas/hyperliquid";
399
     *
400
     * const multiSignAddress = "0x...";
401
     * const signers = [
402
     *   "0x...", // Private key; or any other wallet libraries
403
     * ] as const;
404
     *
405
     * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
406
     * const multiSignClient = new hl.MultiSignClient({ transport, multiSignAddress, signers });
407
     *
408
     * const data = await multiSignClient.cancel({
409
     *   cancels: [{
410
     *     a: 0, // Asset index
411
     *     o: 123, // Order ID
412
     *   }],
413
     * });
414
     * ```
415
     */
416
    override async cancel(
149✔
417
        ...[args, signal]: Parameters<ExchangeClient["cancel"]>
149✔
418
    ): ReturnType<ExchangeClient["cancel"]> {
149✔
419
        // Destructure the parameters
420
        const {
154✔
421
            vaultAddress = this.defaultVaultAddress,
154✔
422
            expiresAfter = await this._getDefaultExpiresAfter(),
154✔
423
            ...actionArgs
154✔
424
        } = args;
154✔
425

426
        // Construct an action
427
        const nonce = await this.nonceManager();
158✔
428
        const action: CancelRequest["action"] = {
154✔
429
            type: "cancel",
154✔
430
            ...actionArgs,
154✔
431
        };
154✔
432

433
        // Send a multi-sig action
434
        const sortedAction = actionSorter[action.type](action);
154✔
435
        const outerSigner = await this._getWalletAddress(this.signers[0]);
154✔
436

437
        const signatures = await this._multiSignL1Action({
154✔
438
            action: sortedAction,
154✔
439
            nonce,
154✔
440
            outerSigner,
154✔
441
            vaultAddress,
154✔
442
            expiresAfter,
154✔
443
        });
154✔
444

445
        // Send a multi-sig action
446
        return super.multiSig({
154✔
447
            signatures,
154✔
448
            payload: {
154✔
449
                multiSigUser: this.multiSignAddress,
154✔
450
                outerSigner,
154✔
451
                action: sortedAction,
154✔
452
            },
154✔
453
            nonce,
154✔
454
            vaultAddress,
154✔
455
            expiresAfter,
154✔
456
        }, signal);
154✔
457
    }
154✔
458

459
    /**
460
     * @param args - The parameters for the request.
461
     * @param signal - An optional abort signal.
462
     * @returns Successful variant of {@link CancelResponse} without error statuses.
463
     * @throws {ApiRequestError} When the API returns an error response.
464
     *
465
     * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#cancel-order-s-by-cloid
466
     * @example
467
     * ```ts
468
     * import * as hl from "@nktkas/hyperliquid";
469
     *
470
     * const multiSignAddress = "0x...";
471
     * const signers = [
472
     *   "0x...", // Private key; or any other wallet libraries
473
     * ] as const;
474
     *
475
     * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
476
     * const multiSignClient = new hl.MultiSignClient({ transport, multiSignAddress, signers });
477
     *
478
     * const data = await multiSignClient.cancelByCloid({
479
     *   cancels: [
480
     *     { asset: 0, cloid: "0x..." },
481
     *   ],
482
     * });
483
     * ```
484
     */
485
    override async cancelByCloid(
149✔
486
        ...[args, signal]: Parameters<ExchangeClient["cancelByCloid"]>
149✔
487
    ): ReturnType<ExchangeClient["cancelByCloid"]> {
149✔
488
        // Destructure the parameters
489
        const {
151✔
490
            vaultAddress = this.defaultVaultAddress,
151✔
491
            expiresAfter = await this._getDefaultExpiresAfter(),
151✔
492
            ...actionArgs
151✔
493
        } = args;
151✔
494

495
        // Construct an action
496
        const nonce = await this.nonceManager();
152✔
497
        const action: CancelByCloidRequest["action"] = {
151✔
498
            type: "cancelByCloid",
151✔
499
            ...actionArgs,
151✔
500
        };
151✔
501

502
        // Send a multi-sig action
503
        const sortedAction = actionSorter[action.type](action);
151✔
504
        const outerSigner = await this._getWalletAddress(this.signers[0]);
151✔
505

506
        const signatures = await this._multiSignL1Action({
151✔
507
            action: sortedAction,
151✔
508
            nonce,
151✔
509
            outerSigner,
151✔
510
            vaultAddress,
151✔
511
            expiresAfter,
151✔
512
        });
151✔
513

514
        // Send a multi-sig action
515
        return super.multiSig({
151✔
516
            signatures,
151✔
517
            payload: {
151✔
518
                multiSigUser: this.multiSignAddress,
151✔
519
                outerSigner,
151✔
520
                action: sortedAction,
151✔
521
            },
151✔
522
            nonce,
151✔
523
            vaultAddress,
151✔
524
            expiresAfter,
151✔
525
        }, signal);
151✔
526
    }
151✔
527

528
    /**
529
     * @param args - The parameters for the request.
530
     * @param signal - An optional abort signal.
531
     * @returns Successful response without specific data.
532
     * @throws {ApiRequestError} When the API returns an error response.
533
     *
534
     * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#deposit-into-staking
535
     * @example
536
     * ```ts
537
     * import * as hl from "@nktkas/hyperliquid";
538
     *
539
     * const multiSignAddress = "0x...";
540
     * const signers = [
541
     *   "0x...", // Private key; or any other wallet libraries
542
     * ] as const;
543
     *
544
     * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
545
     * const multiSignClient = new hl.MultiSignClient({ transport, multiSignAddress, signers });
546
     *
547
     * const data = await multiSignClient.cDeposit({ wei: 1 * 1e8 });
548
     * ```
549
     */
550
    override async cDeposit(
149✔
551
        ...[args, signal]: Parameters<ExchangeClient["cDeposit"]>
149✔
552
    ): ReturnType<ExchangeClient["cDeposit"]> {
149✔
553
        // Destructure the parameters
554
        const { ...actionArgs } = args;
150✔
555

556
        // Construct an action
557
        const nonce = await this.nonceManager();
150✔
558
        const action: CDepositRequest["action"] = {
150✔
559
            ...actionArgs,
150✔
560
            type: "cDeposit",
150✔
561
            hyperliquidChain: this._getHyperliquidChain(),
150✔
562
            signatureChainId: await this._getSignatureChainId(),
150✔
563
            nonce,
150✔
564
        };
150✔
565

566
        // Sign the action
567
        const sortedAction = actionSorter[action.type](action);
150✔
568
        const outerSigner = await this._getWalletAddress(this.signers[0]);
150✔
569

570
        const signatures = await this._multiSignUserSignedAction(sortedAction, outerSigner);
150✔
571

572
        // Send a multi-sig action
573
        return super.multiSig({
150✔
574
            signatures,
150✔
575
            payload: {
150✔
576
                multiSigUser: this.multiSignAddress,
150✔
577
                outerSigner,
150✔
578
                action: sortedAction,
150✔
579
            },
150✔
580
            nonce,
150✔
581
        }, signal);
150✔
582
    }
150✔
583

584
    /**
585
     * @param args - The parameters for the request.
586
     * @param signal - An optional abort signal.
587
     * @returns Successful response without specific data.
588
     * @throws {ApiRequestError} When the API returns an error response.
589
     *
590
     * @see null - no documentation
591
     * @example
592
     * ```ts
593
     * import * as hl from "@nktkas/hyperliquid";
594
     *
595
     * const multiSignAddress = "0x...";
596
     * const signers = [
597
     *   "0x...", // Private key; or any other wallet libraries
598
     * ] as const;
599
     *
600
     * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
601
     * const multiSignClient = new hl.MultiSignClient({ transport, multiSignAddress, signers });
602
     *
603
     * const data = await multiSignClient.claimRewards();
604
     * ```
605
     */
606
    override async claimRewards(
149✔
607
        ...[signal]: Parameters<ExchangeClient["claimRewards"]>
149✔
608
    ): ReturnType<ExchangeClient["claimRewards"]> {
149✔
609
        // Construct an action
610
        const nonce = await this.nonceManager();
150✔
611
        const action: ClaimRewardsRequest["action"] = {
150✔
612
            type: "claimRewards",
150✔
613
        };
150✔
614

615
        // Send a multi-sig action
616
        const sortedAction = actionSorter[action.type](action);
150✔
617
        const outerSigner = await this._getWalletAddress(this.signers[0]);
150✔
618

619
        const signatures = await this._multiSignL1Action({ action: sortedAction, nonce, outerSigner });
750✔
620

621
        // Send a multi-sig action
622
        return super.multiSig({
150✔
623
            signatures,
150✔
624
            payload: {
150✔
625
                multiSigUser: this.multiSignAddress,
150✔
626
                outerSigner,
150✔
627
                action: sortedAction,
150✔
628
            },
150✔
629
            nonce,
150✔
630
        }, signal);
150✔
631
    }
150✔
632

633
    /**
634
     * @param args - The parameters for the request.
635
     * @param signal - An optional abort signal.
636
     * @returns Successful response without specific data.
637
     * @throws {ApiRequestError} When the API returns an error response.
638
     *
639
     * @see https://hyperliquid.gitbook.io/hyperliquid-docs/hypercore/multi-sig
640
     * @example
641
     * ```ts
642
     * import * as hl from "@nktkas/hyperliquid";
643
     *
644
     * const multiSignAddress = "0x...";
645
     * const signers = [
646
     *   "0x...", // Private key; or any other wallet libraries
647
     * ] as const;
648
     *
649
     * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
650
     * const multiSignClient = new hl.MultiSignClient({ transport, multiSignAddress, signers });
651
     *
652
     * const data = await multiSignClient.convertToMultiSigUser({ // convert to normal user
653
     *   authorizedUsers: [],
654
     *   threshold: 0,
655
     * });
656
     * ```
657
     */
658
    override async convertToMultiSigUser(
149✔
659
        ...[args, signal]: Parameters<ExchangeClient["convertToMultiSigUser"]>
149✔
660
    ): ReturnType<ExchangeClient["convertToMultiSigUser"]> {
149✔
661
        // Destructure the parameters
662
        const actionArgs = args;
150✔
663

664
        // Construct an action
665
        const nonce = await this.nonceManager();
150✔
666
        const action: ConvertToMultiSigUserRequest["action"] = {
150✔
667
            type: "convertToMultiSigUser",
150✔
668
            hyperliquidChain: this._getHyperliquidChain(),
150✔
669
            signatureChainId: await this._getSignatureChainId(),
150✔
670
            signers: JSON.stringify(actionArgs),
150✔
671
            nonce,
150✔
672
        };
150✔
673

674
        // Sign the action
675
        const sortedAction = actionSorter[action.type](action);
150✔
676
        const outerSigner = await this._getWalletAddress(this.signers[0]);
150✔
677

678
        const signatures = await this._multiSignUserSignedAction(sortedAction, outerSigner);
150✔
679

680
        // Send a multi-sig action
681
        return super.multiSig({
150✔
682
            signatures,
150✔
683
            payload: {
150✔
684
                multiSigUser: this.multiSignAddress,
150✔
685
                outerSigner,
150✔
686
                action: sortedAction,
150✔
687
            },
150✔
688
            nonce,
150✔
689
        }, signal);
150✔
690
    }
150✔
691

692
    /**
693
     * @param args - The parameters for the request.
694
     * @param signal - An optional abort signal.
695
     * @returns Response for creating a sub-account.
696
     * @throws {ApiRequestError} When the API returns an error response.
697
     *
698
     * @see null - no documentation
699
     * @example
700
     * ```ts
701
     * import * as hl from "@nktkas/hyperliquid";
702
     *
703
     * const multiSignAddress = "0x...";
704
     * const signers = [
705
     *   "0x...", // Private key; or any other wallet libraries
706
     * ] as const;
707
     *
708
     * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
709
     * const multiSignClient = new hl.MultiSignClient({ transport, multiSignAddress, signers });
710
     *
711
     * const data = await multiSignClient.createSubAccount({ name: "subAccountName" });
712
     * ```
713
     */
714
    override async createSubAccount(
149✔
715
        ...[args, signal]: Parameters<ExchangeClient["createSubAccount"]>
149✔
716
    ): ReturnType<ExchangeClient["createSubAccount"]> {
149✔
717
        // Destructure the parameters
718
        const { ...actionArgs } = args;
150✔
719

720
        // Construct an action
721
        const nonce = await this.nonceManager();
150✔
722
        const action: CreateSubAccountRequest["action"] = {
150✔
723
            type: "createSubAccount",
150✔
724
            ...actionArgs,
150✔
725
        };
150✔
726

727
        // Send a multi-sig action
728
        const sortedAction = actionSorter[action.type](action);
150✔
729
        const outerSigner = await this._getWalletAddress(this.signers[0]);
150✔
730

731
        const signatures = await this._multiSignL1Action({ action: sortedAction, nonce, outerSigner });
750✔
732

733
        // Send a multi-sig action
734
        return super.multiSig({
150✔
735
            signatures,
150✔
736
            payload: {
150✔
737
                multiSigUser: this.multiSignAddress,
150✔
738
                outerSigner,
150✔
739
                action: sortedAction,
150✔
740
            },
150✔
741
            nonce,
150✔
742
        }, signal);
150✔
743
    }
150✔
744

745
    /**
746
     * @param args - The parameters for the request.
747
     * @param signal - An optional abort signal.
748
     * @returns Response for creating a vault.
749
     * @throws {ApiRequestError} When the API returns an error response.
750
     *
751
     * @see null - no documentation
752
     * @example
753
     * ```ts
754
     * import * as hl from "@nktkas/hyperliquid";
755
     *
756
     * const multiSignAddress = "0x...";
757
     * const signers = [
758
     *   "0x...", // Private key; or any other wallet libraries
759
     * ] as const;
760
     *
761
     * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
762
     * const multiSignClient = new hl.MultiSignClient({ transport, multiSignAddress, signers });
763
     *
764
     * const data = await multiSignClient.createVault({
765
     *   name: "VaultName",
766
     *   description: "Vault description",
767
     *   initialUsd: 100 * 1e6,
768
     * });
769
     * ```
770
     */
771
    override async createVault(
149✔
772
        ...[args, signal]: Parameters<ExchangeClient["createVault"]>
149✔
773
    ): ReturnType<ExchangeClient["createVault"]> {
149✔
774
        // Destructure the parameters
775
        const { ...actionArgs } = args;
150✔
776

777
        // Construct an action
778
        const nonce = await this.nonceManager();
150✔
779
        const action: CreateVaultRequest["action"] = {
150✔
780
            type: "createVault",
150✔
781
            nonce,
150✔
782
            ...actionArgs,
150✔
783
        };
150✔
784

785
        // Send a multi-sig action
786
        const sortedAction = actionSorter[action.type](action);
150✔
787
        const outerSigner = await this._getWalletAddress(this.signers[0]);
150✔
788

789
        const signatures = await this._multiSignL1Action({ action: sortedAction, nonce, outerSigner });
750✔
790

791
        // Send a multi-sig action
792
        return super.multiSig({
150✔
793
            signatures,
150✔
794
            payload: {
150✔
795
                multiSigUser: this.multiSignAddress,
150✔
796
                outerSigner,
150✔
797
                action: sortedAction,
150✔
798
            },
150✔
799
            nonce,
150✔
800
        }, signal);
150✔
801
    }
150✔
802

803
    /**
804
     * @param args - The parameters for the request.
805
     * @param signal - An optional abort signal.
806
     * @returns Successful response without specific data.
807
     * @throws {ApiRequestError} When the API returns an error response.
808
     *
809
     * @see null - no documentation
810
     * @example
811
     * ```ts
812
     * import * as hl from "@nktkas/hyperliquid";
813
     *
814
     * const multiSignAddress = "0x...";
815
     * const signers = [
816
     *   "0x...", // Private key; or any other wallet libraries
817
     * ] as const;
818
     *
819
     * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
820
     * const multiSignClient = new hl.MultiSignClient({ transport, multiSignAddress, signers });
821
     *
822
     * // Jail self
823
     * const data = await multiSignClient.cSignerAction({ jailSelf: null });
824
     *
825
     * // Unjail self
826
     * const data = await multiSignClient.cSignerAction({ unjailSelf: null });
827
     * ```
828
     */
829
    override async cSignerAction(
830
        args: CSignerActionParameters_JailSelf,
831
        signal?: AbortSignal,
832
    ): ReturnType<ExchangeClient["cSignerAction"]>;
833
    override async cSignerAction(
834
        args: CSignerActionParameters_UnjailSelf,
835
        signal?: AbortSignal,
836
    ): ReturnType<ExchangeClient["cSignerAction"]>;
837
    override async cSignerAction(
149✔
838
        args: CSignerActionParameters,
149✔
839
        signal?: AbortSignal,
149✔
840
    ): ReturnType<ExchangeClient["cSignerAction"]> {
149✔
841
        // Destructure the parameters
842
        const {
151✔
843
            expiresAfter = await this._getDefaultExpiresAfter(),
151✔
844
            ...actionArgs
151✔
845
        } = args;
151✔
846

847
        // Construct an action
848
        const nonce = await this.nonceManager();
151✔
849
        const action: CSignerActionRequest_JailSelf["action"] | CSignerActionRequest_UnjailSelf["action"] = {
151✔
850
            type: "CSignerAction",
151✔
851
            ...actionArgs,
151✔
852
        };
151✔
853

854
        // Send a multi-sig action
855
        const sortedAction = actionSorter[action.type](action);
151✔
856
        const outerSigner = await this._getWalletAddress(this.signers[0]);
151✔
857

858
        const signatures = await this._multiSignL1Action({ action: sortedAction, nonce, outerSigner, expiresAfter });
906✔
859

860
        // Send a multi-sig action
861
        return super.multiSig({
151✔
862
            signatures,
151✔
863
            payload: {
151✔
864
                multiSigUser: this.multiSignAddress,
151✔
865
                outerSigner,
151✔
866
                action: sortedAction,
151✔
867
            },
151✔
868
            nonce,
151✔
869
            expiresAfter,
151✔
870
        }, signal);
151✔
871
    }
151✔
872

873
    /**
874
     * @param args - The parameters for the request.
875
     * @param signal - An optional abort signal.
876
     * @returns Successful response without specific data.
877
     * @throws {ApiRequestError} When the API returns an error response.
878
     *
879
     * @example
880
     * ```ts
881
     * import * as hl from "@nktkas/hyperliquid";
882
     *
883
     * const multiSignAddress = "0x...";
884
     * const signers = [
885
     *   "0x...", // Private key; or any other wallet libraries
886
     * ] as const;
887
     *
888
     * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
889
     * const multiSignClient = new hl.MultiSignClient({ transport, multiSignAddress, signers });
890
     *
891
     * // Change validator profile
892
     * const data = await multiSignClient.cValidatorAction({
893
     *   changeProfile: {
894
     *     name: "My Validator",
895
     *     description: "Validator description",
896
     *     unjailed: true,
897
     *   }
898
     * });
899
     * ```
900
     */
901
    override async cValidatorAction(
902
        args: CValidatorActionParameters_ChangeProfile,
903
        signal?: AbortSignal,
904
    ): ReturnType<ExchangeClient["cSignerAction"]>;
905
    override async cValidatorAction(
906
        args: CValidatorActionParameters_Register,
907
        signal?: AbortSignal,
908
    ): ReturnType<ExchangeClient["cSignerAction"]>;
909
    override async cValidatorAction(
910
        args: CValidatorActionParameters_Unregister,
911
        signal?: AbortSignal,
912
    ): ReturnType<ExchangeClient["cSignerAction"]>;
913
    override async cValidatorAction(
149✔
914
        args: CValidatorActionParameters,
149✔
915
        signal?: AbortSignal,
149✔
916
    ): ReturnType<ExchangeClient["cSignerAction"]> {
149✔
917
        // Destructure the parameters
918
        const {
152✔
919
            expiresAfter = await this._getDefaultExpiresAfter(),
152✔
920
            ...actionArgs
152✔
921
        } = args;
152✔
922

923
        // Construct an action
924
        const nonce = await this.nonceManager();
152✔
925
        const action:
152✔
926
            | CValidatorActionRequest_ChangeProfile["action"]
927
            | CValidatorActionRequest_Register["action"]
928
            | CValidatorActionRequest_Unregister["action"] = {
152✔
929
                type: "CValidatorAction",
152✔
930
                ...actionArgs,
152✔
931
            };
152✔
932

933
        // Send a multi-sig action
934
        const sortedAction = actionSorter[action.type](action);
152✔
935
        const outerSigner = await this._getWalletAddress(this.signers[0]);
152✔
936

937
        const signatures = await this._multiSignL1Action({ action: sortedAction, nonce, outerSigner, expiresAfter });
912✔
938

939
        // Send a multi-sig action
940
        return super.multiSig({
152✔
941
            signatures,
152✔
942
            payload: {
152✔
943
                multiSigUser: this.multiSignAddress,
152✔
944
                outerSigner,
152✔
945
                action: sortedAction,
152✔
946
            },
152✔
947
            nonce,
152✔
948
            expiresAfter,
152✔
949
        }, signal);
152✔
950
    }
152✔
951

952
    /**
953
     * @param args - The parameters for the request.
954
     * @param signal - An optional abort signal.
955
     * @returns Successful response without specific data.
956
     * @throws {ApiRequestError} When the API returns an error response.
957
     *
958
     * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#withdraw-from-staking
959
     * @example
960
     * ```ts
961
     * import * as hl from "@nktkas/hyperliquid";
962
     *
963
     * const multiSignAddress = "0x...";
964
     * const signers = [
965
     *   "0x...", // Private key; or any other wallet libraries
966
     * ] as const;
967
     *
968
     * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
969
     * const multiSignClient = new hl.MultiSignClient({ transport, multiSignAddress, signers });
970
     *
971
     * const data = await multiSignClient.cWithdraw({ wei: 1 * 1e8 });
972
     * ```
973
     */
974
    override async cWithdraw(
149✔
975
        ...[args, signal]: Parameters<ExchangeClient["cWithdraw"]>
149✔
976
    ): ReturnType<ExchangeClient["cWithdraw"]> {
149✔
977
        // Destructure the parameters
978
        const { ...actionArgs } = args;
150✔
979

980
        // Construct an action
981
        const nonce = await this.nonceManager();
150✔
982
        const action: CWithdrawRequest["action"] = {
150✔
983
            ...actionArgs,
150✔
984
            type: "cWithdraw",
150✔
985
            hyperliquidChain: this._getHyperliquidChain(),
150✔
986
            signatureChainId: await this._getSignatureChainId(),
150✔
987
            nonce,
150✔
988
        };
150✔
989

990
        // Sign the action
991
        const sortedAction = actionSorter[action.type](action);
150✔
992
        const outerSigner = await this._getWalletAddress(this.signers[0]);
150✔
993

994
        const signatures = await this._multiSignUserSignedAction(sortedAction, outerSigner);
150✔
995

996
        // Send a multi-sig action
997
        return super.multiSig({
150✔
998
            signatures,
150✔
999
            payload: {
150✔
1000
                multiSigUser: this.multiSignAddress,
150✔
1001
                outerSigner,
150✔
1002
                action: sortedAction,
150✔
1003
            },
150✔
1004
            nonce,
150✔
1005
        }, signal);
150✔
1006
    }
150✔
1007

1008
    /**
1009
     * @param args - The parameters for the request.
1010
     * @param signal - An optional abort signal.
1011
     * @returns Response for creating a sub-account.
1012
     * @throws {ApiRequestError} When the API returns an error response.
1013
     *
1014
     * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/evm/dual-block-architecture
1015
     * @example
1016
     * ```ts
1017
     * import * as hl from "@nktkas/hyperliquid";
1018
     *
1019
     * const multiSignAddress = "0x...";
1020
     * const signers = [
1021
     *   "0x...", // Private key; or any other wallet libraries
1022
     * ] as const;
1023
     *
1024
     * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1025
     * const multiSignClient = new hl.MultiSignClient({ transport, multiSignAddress, signers });
1026
     *
1027
     * const data = await multiSignClient.evmUserModify({ usingBigBlocks: true });
1028
     * ```
1029
     */
1030
    override async evmUserModify(
149✔
1031
        ...[args, signal]: Parameters<ExchangeClient["evmUserModify"]>
149✔
1032
    ): ReturnType<ExchangeClient["evmUserModify"]> {
149✔
1033
        // Destructure the parameters
1034
        const { ...actionArgs } = args;
151✔
1035

1036
        // Construct an action
1037
        const nonce = await this.nonceManager();
151✔
1038
        const action: EvmUserModifyRequest["action"] = {
151✔
1039
            type: "evmUserModify",
151✔
1040
            ...actionArgs,
151✔
1041
        };
151✔
1042

1043
        // Send a multi-sig action
1044
        const sortedAction = actionSorter[action.type](action);
151✔
1045
        const outerSigner = await this._getWalletAddress(this.signers[0]);
151✔
1046

1047
        const signatures = await this._multiSignL1Action({ action: sortedAction, nonce, outerSigner });
755✔
1048

1049
        // Send a multi-sig action
1050
        return super.multiSig({
151✔
1051
            signatures,
151✔
1052
            payload: {
151✔
1053
                multiSigUser: this.multiSignAddress,
151✔
1054
                outerSigner,
151✔
1055
                action: sortedAction,
151✔
1056
            },
151✔
1057
            nonce,
151✔
1058
        }, signal);
151✔
1059
    }
151✔
1060

1061
    /**
1062
     * @param args - The parameters for the request.
1063
     * @param signal - An optional abort signal.
1064
     * @returns Successful response without specific data.
1065
     * @throws {ApiRequestError} When the API returns an error response.
1066
     *
1067
     * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#modify-an-order
1068
     * @example
1069
     * ```ts
1070
     * import * as hl from "@nktkas/hyperliquid";
1071
     *
1072
     * const multiSignAddress = "0x...";
1073
     * const signers = [
1074
     *   "0x...", // Private key; or any other wallet libraries
1075
     * ] as const;
1076
     *
1077
     * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1078
     * const multiSignClient = new hl.MultiSignClient({ transport, multiSignAddress, signers });
1079
     *
1080
     * const data = await multiSignClient.modify({
1081
     *   oid: 123,
1082
     *   order: {
1083
     *     a: 0, // Asset index
1084
     *     b: true, // Buy order
1085
     *     p: "31000", // New price
1086
     *     s: "0.2", // New size
1087
     *     r: false, // Not reduce-only
1088
     *     t: {
1089
     *       limit: {
1090
     *         tif: "Gtc", // Good-til-cancelled
1091
     *       },
1092
     *     },
1093
     *     c: "0x...", // Client Order ID (optional)
1094
     *   },
1095
     * });
1096
     * ```
1097
     */
1098
    override async modify(
149✔
1099
        ...[args, signal]: Parameters<ExchangeClient["modify"]>
149✔
1100
    ): ReturnType<ExchangeClient["modify"]> {
149✔
1101
        // Destructure the parameters
1102
        const {
153✔
1103
            vaultAddress = this.defaultVaultAddress,
153✔
1104
            expiresAfter = await this._getDefaultExpiresAfter(),
153✔
1105
            ...actionArgs
153✔
1106
        } = args;
153✔
1107

1108
        // Construct an action
1109
        const nonce = await this.nonceManager();
156✔
1110
        const action: ModifyRequest["action"] = {
153✔
1111
            type: "modify",
153✔
1112
            ...actionArgs,
153✔
1113
        };
153✔
1114

1115
        // Send a multi-sig action
1116
        const sortedAction = actionSorter[action.type](action);
153✔
1117
        const outerSigner = await this._getWalletAddress(this.signers[0]);
153✔
1118

1119
        const signatures = await this._multiSignL1Action({
153✔
1120
            action: sortedAction,
153✔
1121
            nonce,
153✔
1122
            outerSigner,
153✔
1123
            vaultAddress,
153✔
1124
            expiresAfter,
153✔
1125
        });
153✔
1126

1127
        // Send a multi-sig action
1128
        return super.multiSig({
153✔
1129
            signatures,
153✔
1130
            payload: {
153✔
1131
                multiSigUser: this.multiSignAddress,
153✔
1132
                outerSigner,
153✔
1133
                action: sortedAction,
153✔
1134
            },
153✔
1135
            nonce,
153✔
1136
            vaultAddress,
153✔
1137
            expiresAfter,
153✔
1138
        }, signal);
153✔
1139
    }
153✔
1140

1141
    /**
1142
     * @multisign Not implemented
1143
     */
1144
    override multiSig<
×
1145
        T extends
1146
            | SuccessResponse
1147
            | CancelResponseSuccess
1148
            | CreateSubAccountResponse
1149
            | CreateVaultResponse
1150
            | OrderResponseSuccess
1151
            | TwapOrderResponseSuccess
1152
            | TwapCancelResponseSuccess,
1153
    >(
1154
        ...[_args, _signal]: Parameters<ExchangeClient["multiSig"]>
×
1155
    ): Promise<T> {
×
1156
        throw new Error("Not implemented"); // FIXME
×
1157
    }
×
1158

1159
    /**
1160
     * @param args - The parameters for the request.
1161
     * @param signal - An optional abort signal.
1162
     * @returns Successful variant of {@link OrderResponse} without error statuses.
1163
     * @throws {ApiRequestError} When the API returns an error response.
1164
     *
1165
     * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#place-an-order
1166
     * @example
1167
     * ```ts
1168
     * import * as hl from "@nktkas/hyperliquid";
1169
     *
1170
     * const multiSignAddress = "0x...";
1171
     * const signers = [
1172
     *   "0x...", // Private key; or any other wallet libraries
1173
     * ] as const;
1174
     *
1175
     * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1176
     * const multiSignClient = new hl.MultiSignClient({ transport, multiSignAddress, signers });
1177
     *
1178
     * const data = await multiSignClient.order({
1179
     *   orders: [{
1180
     *     a: 0, // Asset index
1181
     *     b: true, // Buy order
1182
     *     p: "30000", // Price
1183
     *     s: "0.1", // Size
1184
     *     r: false, // Not reduce-only
1185
     *     t: {
1186
     *       limit: {
1187
     *         tif: "Gtc", // Good-til-cancelled
1188
     *       },
1189
     *     },
1190
     *     c: "0x...", // Client Order ID (optional)
1191
     *   }],
1192
     *   grouping: "na", // No grouping
1193
     * });
1194
     * ```
1195
     */
1196
    override async order(
149✔
1197
        ...[args, signal]: Parameters<ExchangeClient["order"]>
149✔
1198
    ): ReturnType<ExchangeClient["order"]> {
149✔
1199
        // Destructure the parameters
1200
        const {
175✔
1201
            vaultAddress = this.defaultVaultAddress,
175✔
1202
            expiresAfter = await this._getDefaultExpiresAfter(),
175✔
1203
            ...actionArgs
175✔
1204
        } = args;
175✔
1205

1206
        // Construct an action
1207
        const nonce = await this.nonceManager();
200✔
1208
        const action: OrderRequest["action"] = {
175✔
1209
            type: "order",
175✔
1210
            ...actionArgs,
175✔
1211
        };
175✔
1212

1213
        // Send a multi-sig action
1214
        const sortedAction = actionSorter[action.type](action);
175✔
1215
        const outerSigner = await this._getWalletAddress(this.signers[0]);
175✔
1216

1217
        const signatures = await this._multiSignL1Action({
175✔
1218
            action: sortedAction,
175✔
1219
            nonce,
175✔
1220
            outerSigner,
175✔
1221
            vaultAddress,
175✔
1222
            expiresAfter,
175✔
1223
        });
175✔
1224

1225
        // Send a multi-sig action
1226
        return super.multiSig({
175✔
1227
            signatures,
175✔
1228
            payload: {
175✔
1229
                multiSigUser: this.multiSignAddress,
175✔
1230
                outerSigner,
175✔
1231
                action: sortedAction,
175✔
1232
            },
175✔
1233
            nonce,
175✔
1234
            vaultAddress,
175✔
1235
            expiresAfter,
175✔
1236
        }, signal);
175✔
1237
    }
175✔
1238

1239
    /**
1240
     * @param args - The parameters for the request.
1241
     * @param signal - An optional abort signal.
1242
     * @returns Successful response without specific data.
1243
     * @throws {ApiRequestError} When the API returns an error response.
1244
     *
1245
     * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/deploying-hip-3-assets
1246
     * @example
1247
     * ```ts
1248
     * import * as hl from "@nktkas/hyperliquid";
1249
     *
1250
     * const multiSignAddress = "0x...";
1251
     * const signers = [
1252
     *   "0x...", // Private key; or any other wallet libraries
1253
     * ] as const;
1254
     *
1255
     * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1256
     * const multiSignClient = new hl.MultiSignClient({ transport, multiSignAddress, signers });
1257
     *
1258
     * const data = await multiSignClient.perpDeploy({
1259
     *   registerAsset: {
1260
     *     maxGas: 1000000,
1261
     *     assetRequest: {
1262
     *       coin: "USDC",
1263
     *       szDecimals: 8,
1264
     *       oraclePx: "1",
1265
     *       marginTableId: 1,
1266
     *       onlyIsolated: false,
1267
     *     },
1268
     *     dex: "test",
1269
     *   },
1270
     * });
1271
     * ```
1272
     */
1273
    override async perpDeploy(
1274
        args: PerpDeployParameters_RegisterAsset,
1275
        signal?: AbortSignal,
1276
    ): ReturnType<ExchangeClient["perpDeploy"]>;
1277
    override async perpDeploy(
1278
        args: PerpDeployParameters_SetOracle,
1279
        signal?: AbortSignal,
1280
    ): ReturnType<ExchangeClient["perpDeploy"]>;
1281
    override async perpDeploy(
149✔
1282
        args: PerpDeployParameters,
149✔
1283
        signal?: AbortSignal,
149✔
1284
    ): ReturnType<ExchangeClient["perpDeploy"]> {
149✔
1285
        // Destructure the parameters
1286
        const { ...actionArgs } = args;
152✔
1287

1288
        // Construct an action
1289
        const nonce = await this.nonceManager();
152✔
1290
        const action: PerpDeployRequest_RegisterAsset["action"] | PerpDeployRequest_SetOracle["action"] = {
152✔
1291
            type: "perpDeploy",
152✔
1292
            ...actionArgs,
152✔
1293
        };
152✔
1294

1295
        // Send a multi-sig action
1296
        const sortedAction = actionSorter[action.type](action);
152✔
1297
        const outerSigner = await this._getWalletAddress(this.signers[0]);
152✔
1298

1299
        const signatures = await this._multiSignL1Action({ action: sortedAction, nonce, outerSigner });
760✔
1300

1301
        // Send a multi-sig action
1302
        return super.multiSig({
152✔
1303
            signatures,
152✔
1304
            payload: {
152✔
1305
                multiSigUser: this.multiSignAddress,
152✔
1306
                outerSigner,
152✔
1307
                action: sortedAction,
152✔
1308
            },
152✔
1309
            nonce,
152✔
1310
        }, signal);
152✔
1311
    }
152✔
1312

1313
    /**
1314
     * @param args - The parameters for the request.
1315
     * @param signal - An optional abort signal.
1316
     * @returns Successful response without specific data.
1317
     * @throws {ApiRequestError} When the API returns an error response.
1318
     *
1319
     * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#transfer-from-spot-account-to-perp-account-and-vice-versa
1320
     * @example
1321
     * ```ts
1322
     * import * as hl from "@nktkas/hyperliquid";
1323
     *
1324
     * const multiSignAddress = "0x...";
1325
     * const signers = [
1326
     *   "0x...", // Private key; or any other wallet libraries
1327
     * ] as const;
1328
     *
1329
     * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1330
     * const multiSignClient = new hl.MultiSignClient({ transport, multiSignAddress, signers });
1331
     *
1332
     * const data = await multiSignClient.perpDexClassTransfer({
1333
     *   dex: "test",
1334
     *   token: "USDC",
1335
     *   amount: "1",
1336
     *   toPerp: true,
1337
     * });
1338
     * ```
1339
     */
1340
    override async perpDexClassTransfer(
149✔
1341
        ...[args, signal]: Parameters<ExchangeClient["perpDexClassTransfer"]>
149✔
1342
    ): ReturnType<ExchangeClient["perpDexClassTransfer"]> {
149✔
1343
        // Destructure the parameters
1344
        const { ...actionArgs } = args;
151✔
1345

1346
        // Construct an action
1347
        const nonce = await this.nonceManager();
151✔
1348
        const action: PerpDexClassTransferRequest["action"] = {
151✔
1349
            ...actionArgs,
151✔
1350
            type: "PerpDexClassTransfer",
151✔
1351
            hyperliquidChain: this._getHyperliquidChain(),
151✔
1352
            signatureChainId: await this._getSignatureChainId(),
151✔
1353
            nonce,
151✔
1354
        };
151✔
1355

1356
        // Sign the action
1357
        const sortedAction = actionSorter[action.type](action);
151✔
1358
        const outerSigner = await this._getWalletAddress(this.signers[0]);
151✔
1359

1360
        const signatures = await this._multiSignUserSignedAction(sortedAction, outerSigner);
151✔
1361

1362
        // Send a multi-sig action
1363
        return super.multiSig({
151✔
1364
            signatures,
151✔
1365
            payload: {
151✔
1366
                multiSigUser: this.multiSignAddress,
151✔
1367
                outerSigner,
151✔
1368
                action: sortedAction,
151✔
1369
            },
151✔
1370
            nonce,
151✔
1371
        }, signal);
151✔
1372
    }
151✔
1373

1374
    /**
1375
     * @param args - The parameters for the request.
1376
     * @param signal - An optional abort signal.
1377
     * @returns Successful response without specific data.
1378
     * @throws {ApiRequestError} When the API returns an error response.
1379
     *
1380
     * @see null - no documentation
1381
     * @example
1382
     * ```ts
1383
     * import * as hl from "@nktkas/hyperliquid";
1384
     *
1385
     * const multiSignAddress = "0x...";
1386
     * const signers = [
1387
     *   "0x...", // Private key; or any other wallet libraries
1388
     * ] as const;
1389
     *
1390
     * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1391
     * const multiSignClient = new hl.MultiSignClient({ transport, multiSignAddress, signers });
1392
     *
1393
     * const data = await multiSignClient.registerReferrer({ code: "TEST" });
1394
     * ```
1395
     */
1396
    override async registerReferrer(
149✔
1397
        ...[args, signal]: Parameters<ExchangeClient["registerReferrer"]>
149✔
1398
    ): ReturnType<ExchangeClient["registerReferrer"]> {
149✔
1399
        // Destructure the parameters
1400
        const { ...actionArgs } = args;
150✔
1401

1402
        // Construct an action
1403
        const nonce = await this.nonceManager();
150✔
1404
        const action: RegisterReferrerRequest["action"] = {
150✔
1405
            type: "registerReferrer",
150✔
1406
            ...actionArgs,
150✔
1407
        };
150✔
1408

1409
        // Send a multi-sig action
1410
        const sortedAction = actionSorter[action.type](action);
150✔
1411
        const outerSigner = await this._getWalletAddress(this.signers[0]);
150✔
1412

1413
        const signatures = await this._multiSignL1Action({ action: sortedAction, nonce, outerSigner });
750✔
1414

1415
        // Send a multi-sig action
1416
        return super.multiSig({
150✔
1417
            signatures,
150✔
1418
            payload: {
150✔
1419
                multiSigUser: this.multiSignAddress,
150✔
1420
                outerSigner,
150✔
1421
                action: sortedAction,
150✔
1422
            },
150✔
1423
            nonce,
150✔
1424
        }, signal);
150✔
1425
    }
150✔
1426

1427
    /**
1428
     * @param args - The parameters for the request.
1429
     * @param signal - An optional abort signal.
1430
     * @returns Successful response without specific data.
1431
     * @throws {ApiRequestError} When the API returns an error response.
1432
     *
1433
     * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#reserve-additional-actions
1434
     * @example
1435
     * ```ts
1436
     * import * as hl from "@nktkas/hyperliquid";
1437
     *
1438
     * const multiSignAddress = "0x...";
1439
     * const signers = [
1440
     *   "0x...", // Private key; or any other wallet libraries
1441
     * ] as const;
1442
     *
1443
     * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1444
     * const multiSignClient = new hl.MultiSignClient({ transport, multiSignAddress, signers });
1445
     *
1446
     * const data = await multiSignClient.reserveRequestWeight({ weight: 10 });
1447
     * ```
1448
     */
1449
    override async reserveRequestWeight(
149✔
1450
        ...[args, signal]: Parameters<ExchangeClient["reserveRequestWeight"]>
149✔
1451
    ): ReturnType<ExchangeClient["reserveRequestWeight"]> {
149✔
1452
        // Destructure the parameters
1453
        const {
151✔
1454
            expiresAfter = await this._getDefaultExpiresAfter(),
151✔
1455
            ...actionArgs
151✔
1456
        } = args;
151✔
1457

1458
        // Construct an action
1459
        const nonce = await this.nonceManager();
152✔
1460
        const action: ReserveRequestWeightRequest["action"] = {
151✔
1461
            type: "reserveRequestWeight",
151✔
1462
            ...actionArgs,
151✔
1463
        };
151✔
1464

1465
        // Send a multi-sig action
1466
        const sortedAction = actionSorter[action.type](action);
151✔
1467
        const outerSigner = await this._getWalletAddress(this.signers[0]);
151✔
1468

1469
        const signatures = await this._multiSignL1Action({ action: sortedAction, nonce, outerSigner, expiresAfter });
906✔
1470

1471
        // Send a multi-sig action
1472
        return super.multiSig({
151✔
1473
            signatures,
151✔
1474
            payload: {
151✔
1475
                multiSigUser: this.multiSignAddress,
151✔
1476
                outerSigner,
151✔
1477
                action: sortedAction,
151✔
1478
            },
151✔
1479
            nonce,
151✔
1480
            expiresAfter,
151✔
1481
        }, signal);
151✔
1482
    }
151✔
1483

1484
    /**
1485
     * @param args - The parameters for the request.
1486
     * @param signal - An optional abort signal.
1487
     * @returns Successful response without specific data.
1488
     * @throws {ApiRequestError} When the API returns an error response.
1489
     *
1490
     * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#schedule-cancel-dead-mans-switch
1491
     * @example
1492
     * ```ts
1493
     * import * as hl from "@nktkas/hyperliquid";
1494
     *
1495
     * const multiSignAddress = "0x...";
1496
     * const signers = [
1497
     *   "0x...", // Private key; or any other wallet libraries
1498
     * ] as const;
1499
     *
1500
     * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1501
     * const multiSignClient = new hl.MultiSignClient({ transport, multiSignAddress, signers });
1502
     *
1503
     * const data = await multiSignClient.scheduleCancel({ time: Date.now() + 3600000 });
1504
     * ```
1505
     */
1506
    override async scheduleCancel(
1507
        args?: ScheduleCancelParameters,
1508
        signal?: AbortSignal,
1509
    ): ReturnType<ExchangeClient["scheduleCancel"]>;
1510
    override async scheduleCancel(
1511
        signal?: AbortSignal,
1512
    ): ReturnType<ExchangeClient["scheduleCancel"]>;
1513
    override async scheduleCancel(
149✔
1514
        args_or_signal?: ScheduleCancelParameters | AbortSignal,
149✔
1515
        maybeSignal?: AbortSignal,
149✔
1516
    ): ReturnType<ExchangeClient["scheduleCancel"]> {
149✔
1517
        const args = args_or_signal instanceof AbortSignal ? {} : args_or_signal ?? {};
×
1518
        const signal = args_or_signal instanceof AbortSignal ? args_or_signal : maybeSignal;
×
1519

1520
        // Destructure the parameters
1521
        const {
151✔
1522
            vaultAddress = this.defaultVaultAddress,
151✔
1523
            expiresAfter = await this._getDefaultExpiresAfter(),
151✔
1524
            ...actionArgs
151✔
1525
        } = args;
151✔
1526

1527
        // Construct an action
1528
        const nonce = await this.nonceManager();
152✔
1529
        const action: ScheduleCancelRequest["action"] = {
151✔
1530
            type: "scheduleCancel",
151✔
1531
            ...actionArgs,
151✔
1532
        };
151✔
1533

1534
        // Send a multi-sig action
1535
        const sortedAction = actionSorter[action.type](action);
151✔
1536
        const outerSigner = await this._getWalletAddress(this.signers[0]);
151✔
1537

1538
        const signatures = await this._multiSignL1Action({
151✔
1539
            action: sortedAction,
151✔
1540
            nonce,
151✔
1541
            outerSigner,
151✔
1542
            vaultAddress,
151✔
1543
            expiresAfter,
151✔
1544
        });
151✔
1545

1546
        // Send a multi-sig action
1547
        return super.multiSig({
151✔
1548
            signatures,
151✔
1549
            payload: {
151✔
1550
                multiSigUser: this.multiSignAddress,
151✔
1551
                outerSigner,
151✔
1552
                action: sortedAction,
151✔
1553
            },
151✔
1554
            nonce,
151✔
1555
            vaultAddress,
151✔
1556
            expiresAfter,
151✔
1557
        }, signal);
151✔
1558
    }
151✔
1559

1560
    /**
1561
     * @param args - The parameters for the request.
1562
     * @param signal - An optional abort signal.
1563
     * @returns Successful response without specific data.
1564
     * @throws {ApiRequestError} When the API returns an error response.
1565
     *
1566
     * @see null - no documentation
1567
     * @example
1568
     * ```ts
1569
     * import * as hl from "@nktkas/hyperliquid";
1570
     *
1571
     * const multiSignAddress = "0x...";
1572
     * const signers = [
1573
     *   "0x...", // Private key; or any other wallet libraries
1574
     * ] as const;
1575
     *
1576
     * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1577
     * const multiSignClient = new hl.MultiSignClient({ transport, multiSignAddress, signers });
1578
     *
1579
     * const data = await multiSignClient.setDisplayName({ displayName: "My Name" });
1580
     * ```
1581
     */
1582
    override async setDisplayName(
149✔
1583
        ...[args, signal]: Parameters<ExchangeClient["setDisplayName"]>
149✔
1584
    ): ReturnType<ExchangeClient["setDisplayName"]> {
149✔
1585
        // Destructure the parameters
1586
        const { ...actionArgs } = args;
150✔
1587

1588
        // Construct an action
1589
        const nonce = await this.nonceManager();
150✔
1590
        const action: SetDisplayNameRequest["action"] = {
150✔
1591
            type: "setDisplayName",
150✔
1592
            ...actionArgs,
150✔
1593
        };
150✔
1594

1595
        // Send a multi-sig action
1596
        const sortedAction = actionSorter[action.type](action);
150✔
1597
        const outerSigner = await this._getWalletAddress(this.signers[0]);
150✔
1598

1599
        const signatures = await this._multiSignL1Action({ action: sortedAction, nonce, outerSigner });
750✔
1600

1601
        // Send a multi-sig action
1602
        return super.multiSig({
150✔
1603
            signatures,
150✔
1604
            payload: {
150✔
1605
                multiSigUser: this.multiSignAddress,
150✔
1606
                outerSigner,
150✔
1607
                action: sortedAction,
150✔
1608
            },
150✔
1609
            nonce,
150✔
1610
        }, signal);
150✔
1611
    }
150✔
1612

1613
    /**
1614
     * @param args - The parameters for the request.
1615
     * @param signal - An optional abort signal.
1616
     * @returns Successful response without specific data.
1617
     * @throws {ApiRequestError} When the API returns an error response.
1618
     *
1619
     * @see null - no documentation
1620
     * @example
1621
     * ```ts
1622
     * import * as hl from "@nktkas/hyperliquid";
1623
     *
1624
     * const multiSignAddress = "0x...";
1625
     * const signers = [
1626
     *   "0x...", // Private key; or any other wallet libraries
1627
     * ] as const;
1628
     *
1629
     * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1630
     * const multiSignClient = new hl.MultiSignClient({ transport, multiSignAddress, signers });
1631
     *
1632
     * const data = await multiSignClient.setReferrer({ code: "TEST" });
1633
     * ```
1634
     */
1635
    override async setReferrer(
149✔
1636
        ...[args, signal]: Parameters<ExchangeClient["setReferrer"]>
149✔
1637
    ): ReturnType<ExchangeClient["setReferrer"]> {
149✔
1638
        // Destructure the parameters
1639
        const { ...actionArgs } = args;
150✔
1640

1641
        // Construct an action
1642
        const nonce = await this.nonceManager();
150✔
1643
        const action: SetReferrerRequest["action"] = {
150✔
1644
            type: "setReferrer",
150✔
1645
            ...actionArgs,
150✔
1646
        };
150✔
1647

1648
        // Send a multi-sig action
1649
        const sortedAction = actionSorter[action.type](action);
150✔
1650
        const outerSigner = await this._getWalletAddress(this.signers[0]);
150✔
1651

1652
        const signatures = await this._multiSignL1Action({ action: sortedAction, nonce, outerSigner });
750✔
1653

1654
        // Send a multi-sig action
1655
        return super.multiSig({
150✔
1656
            signatures,
150✔
1657
            payload: {
150✔
1658
                multiSigUser: this.multiSignAddress,
150✔
1659
                outerSigner,
150✔
1660
                action: sortedAction,
150✔
1661
            },
150✔
1662
            nonce,
150✔
1663
        }, signal);
150✔
1664
    }
150✔
1665

1666
    /**
1667
     * @param args - The parameters for the request.
1668
     * @param signal - An optional abort signal.
1669
     * @returns Successful response without specific data.
1670
     * @throws {ApiRequestError} When the API returns an error response.
1671
     *
1672
     * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/deploying-hip-1-and-hip-2-assets
1673
     * @example
1674
     * ```ts
1675
     * import * as hl from "@nktkas/hyperliquid";
1676
     *
1677
     * const multiSignAddress = "0x...";
1678
     * const signers = [
1679
     *   "0x...", // Private key; or any other wallet libraries
1680
     * ] as const;
1681
     *
1682
     * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1683
     * const multiSignClient = new hl.MultiSignClient({ transport, multiSignAddress, signers });
1684
     *
1685
     * const data = await multiSignClient.spotDeploy({
1686
     *   registerToken2: {
1687
     *     spec: {
1688
     *       name: "USDC",
1689
     *       szDecimals: 8,
1690
     *       weiDecimals: 8,
1691
     *     },
1692
     *     maxGas: 1000000,
1693
     *     fullName: "USD Coin",
1694
     *   },
1695
     * });
1696
     * ```
1697
     */
1698
    override async spotDeploy(
1699
        args: SpotDeployParameters_Genesis,
1700
        signal?: AbortSignal,
1701
    ): ReturnType<ExchangeClient["spotDeploy"]>;
1702
    override async spotDeploy(
1703
        args: SpotDeployParameters_RegisterHyperliquidity,
1704
        signal?: AbortSignal,
1705
    ): ReturnType<ExchangeClient["spotDeploy"]>;
1706
    override async spotDeploy(
1707
        args: SpotDeployParameters_RegisterSpot,
1708
        signal?: AbortSignal,
1709
    ): ReturnType<ExchangeClient["spotDeploy"]>;
1710
    override async spotDeploy(
1711
        args: SpotDeployParameters_RegisterToken2,
1712
        signal?: AbortSignal,
1713
    ): ReturnType<ExchangeClient["spotDeploy"]>;
1714
    override async spotDeploy(
1715
        args: SpotDeployParameters_SetDeployerTradingFeeShare,
1716
        signal?: AbortSignal,
1717
    ): ReturnType<ExchangeClient["spotDeploy"]>;
1718
    override async spotDeploy(
1719
        args: SpotDeployParameters_UserGenesis,
1720
        signal?: AbortSignal,
1721
    ): ReturnType<ExchangeClient["spotDeploy"]>;
1722
    override async spotDeploy(
149✔
1723
        args: SpotDeployParameters,
149✔
1724
        signal?: AbortSignal,
149✔
1725
    ): ReturnType<ExchangeClient["spotDeploy"]> {
149✔
1726
        // Destructure the parameters
1727
        const { ...actionArgs } = args;
159✔
1728

1729
        // Construct an action
1730
        const nonce = await this.nonceManager();
159✔
1731
        const action:
159✔
1732
            | SpotDeployRequest_RegisterToken2["action"]
1733
            | SpotDeployRequest_UserGenesis["action"]
1734
            | SpotDeployRequest_Genesis["action"]
1735
            | SpotDeployRequest_RegisterSpot["action"]
1736
            | SpotDeployRequest_RegisterHyperliquidity["action"]
1737
            | SpotDeployRequest_SetDeployerTradingFeeShare["action"] = {
159✔
1738
                type: "spotDeploy",
159✔
1739
                ...actionArgs,
159✔
1740
            };
159✔
1741

1742
        // Send a multi-sig action
1743
        const sortedAction = actionSorter[action.type](action);
159✔
1744
        const outerSigner = await this._getWalletAddress(this.signers[0]);
159✔
1745

1746
        const signatures = await this._multiSignL1Action({ action: sortedAction, nonce, outerSigner });
795✔
1747

1748
        // Send a multi-sig action
1749
        return super.multiSig({
159✔
1750
            signatures,
159✔
1751
            payload: {
159✔
1752
                multiSigUser: this.multiSignAddress,
159✔
1753
                outerSigner,
159✔
1754
                action: sortedAction,
159✔
1755
            },
159✔
1756
            nonce,
159✔
1757
        }, signal);
159✔
1758
    }
159✔
1759

1760
    /**
1761
     * @param args - The parameters for the request.
1762
     * @param signal - An optional abort signal.
1763
     * @returns Successful response without specific data.
1764
     * @throws {ApiRequestError} When the API returns an error response.
1765
     *
1766
     * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#core-spot-transfer
1767
     * @example
1768
     * ```ts
1769
     * import * as hl from "@nktkas/hyperliquid";
1770
     *
1771
     * const multiSignAddress = "0x...";
1772
     * const signers = [
1773
     *   "0x...", // Private key; or any other wallet libraries
1774
     * ] as const;
1775
     *
1776
     * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1777
     * const multiSignClient = new hl.MultiSignClient({ transport, multiSignAddress, signers });
1778
     *
1779
     * const data = await multiSignClient.spotSend({
1780
     *   destination: "0x...",
1781
     *   token: "USDC:0xeb62eee3685fc4c43992febcd9e75443",
1782
     *   amount: "1",
1783
     * });
1784
     * ```
1785
     */
1786
    override async spotSend(
149✔
1787
        ...[args, signal]: Parameters<ExchangeClient["spotSend"]>
149✔
1788
    ): ReturnType<ExchangeClient["spotSend"]> {
149✔
1789
        // Destructure the parameters
1790
        const { ...actionArgs } = args;
150✔
1791

1792
        // Construct an action
1793
        const nonce = await this.nonceManager();
150✔
1794
        const action: SpotSendRequest["action"] = {
150✔
1795
            ...actionArgs,
150✔
1796
            type: "spotSend",
150✔
1797
            hyperliquidChain: this._getHyperliquidChain(),
150✔
1798
            signatureChainId: await this._getSignatureChainId(),
150✔
1799
            time: nonce,
150✔
1800
        };
150✔
1801

1802
        // Sign the action
1803
        const sortedAction = actionSorter[action.type](action);
150✔
1804
        const outerSigner = await this._getWalletAddress(this.signers[0]);
150✔
1805

1806
        const signatures = await this._multiSignUserSignedAction(sortedAction, outerSigner);
150✔
1807

1808
        // Send a multi-sig action
1809
        return super.multiSig({
150✔
1810
            signatures,
150✔
1811
            payload: {
150✔
1812
                multiSigUser: this.multiSignAddress,
150✔
1813
                outerSigner,
150✔
1814
                action: sortedAction,
150✔
1815
            },
150✔
1816
            nonce,
150✔
1817
        }, signal);
150✔
1818
    }
150✔
1819

1820
    /**
1821
     * @param args - The parameters for the request.
1822
     * @param signal - An optional abort signal.
1823
     * @returns Successful response without specific data.
1824
     * @throws {ApiRequestError} When the API returns an error response.
1825
     *
1826
     * @see null - no documentation
1827
     * @example
1828
     * ```ts
1829
     * import * as hl from "@nktkas/hyperliquid";
1830
     *
1831
     * const multiSignAddress = "0x...";
1832
     * const signers = [
1833
     *   "0x...", // Private key; or any other wallet libraries
1834
     * ] as const;
1835
     *
1836
     * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1837
     * const multiSignClient = new hl.MultiSignClient({ transport, multiSignAddress, signers });
1838
     *
1839
     * const data = await multiSignClient.spotUser({ toggleSpotDusting: { optOut: false } });
1840
     * ```
1841
     */
1842
    override async spotUser(
149✔
1843
        ...[args, signal]: Parameters<ExchangeClient["spotUser"]>
149✔
1844
    ): ReturnType<ExchangeClient["spotUser"]> {
149✔
1845
        // Destructure the parameters
1846
        const { ...actionArgs } = args;
151✔
1847

1848
        // Construct an action
1849
        const nonce = await this.nonceManager();
151✔
1850
        const action: SpotUserRequest["action"] = {
151✔
1851
            type: "spotUser",
151✔
1852
            ...actionArgs,
151✔
1853
        };
151✔
1854

1855
        // Send a multi-sig action
1856
        const sortedAction = actionSorter[action.type](action);
151✔
1857
        const outerSigner = await this._getWalletAddress(this.signers[0]);
151✔
1858

1859
        const signatures = await this._multiSignL1Action({ action: sortedAction, nonce, outerSigner });
755✔
1860

1861
        // Send a multi-sig action
1862
        return super.multiSig({
151✔
1863
            signatures,
151✔
1864
            payload: {
151✔
1865
                multiSigUser: this.multiSignAddress,
151✔
1866
                outerSigner,
151✔
1867
                action: sortedAction,
151✔
1868
            },
151✔
1869
            nonce,
151✔
1870
        }, signal);
151✔
1871
    }
151✔
1872

1873
    /**
1874
     * @param args - The parameters for the request.
1875
     * @param signal - An optional abort signal.
1876
     * @returns Successful response without specific data.
1877
     * @throws {ApiRequestError} When the API returns an error response.
1878
     *
1879
     * @see null - no documentation
1880
     * @example
1881
     * ```ts
1882
     * import * as hl from "@nktkas/hyperliquid";
1883
     *
1884
     * const multiSignAddress = "0x...";
1885
     * const signers = [
1886
     *   "0x...", // Private key; or any other wallet libraries
1887
     * ] as const;
1888
     *
1889
     * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1890
     * const multiSignClient = new hl.MultiSignClient({ transport, multiSignAddress, signers });
1891
     *
1892
     * const data = await multiSignClient.subAccountSpotTransfer({
1893
     *   subAccountUser: "0x...",
1894
     *   isDeposit: true,
1895
     *   token: "USDC:0xeb62eee3685fc4c43992febcd9e75443",
1896
     *   amount: "1",
1897
     * });
1898
     * ```
1899
     */
1900
    override async subAccountSpotTransfer(
149✔
1901
        ...[args, signal]: Parameters<ExchangeClient["subAccountSpotTransfer"]>
149✔
1902
    ): ReturnType<ExchangeClient["subAccountSpotTransfer"]> {
149✔
1903
        // Destructure the parameters
1904
        const { ...actionArgs } = args;
151✔
1905

1906
        // Construct an action
1907
        const nonce = await this.nonceManager();
151✔
1908
        const action: SubAccountSpotTransferRequest["action"] = {
151✔
1909
            type: "subAccountSpotTransfer",
151✔
1910
            ...actionArgs,
151✔
1911
        };
151✔
1912

1913
        // Send a multi-sig action
1914
        const sortedAction = actionSorter[action.type](action);
151✔
1915
        const outerSigner = await this._getWalletAddress(this.signers[0]);
151✔
1916

1917
        const signatures = await this._multiSignL1Action({ action: sortedAction, nonce, outerSigner });
755✔
1918

1919
        // Send a multi-sig action
1920
        return super.multiSig({
151✔
1921
            signatures,
151✔
1922
            payload: {
151✔
1923
                multiSigUser: this.multiSignAddress,
151✔
1924
                outerSigner,
151✔
1925
                action: sortedAction,
151✔
1926
            },
151✔
1927
            nonce,
151✔
1928
        }, signal);
151✔
1929
    }
151✔
1930

1931
    /**
1932
     * @param args - The parameters for the request.
1933
     * @param signal - An optional abort signal.
1934
     * @returns Successful response without specific data.
1935
     * @throws {ApiRequestError} When the API returns an error response.
1936
     *
1937
     * @see null - no documentation
1938
     * @example
1939
     * ```ts
1940
     * import * as hl from "@nktkas/hyperliquid";
1941
     *
1942
     * const multiSignAddress = "0x...";
1943
     * const signers = [
1944
     *   "0x...", // Private key; or any other wallet libraries
1945
     * ] as const;
1946
     *
1947
     * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
1948
     * const multiSignClient = new hl.MultiSignClient({ transport, multiSignAddress, signers });
1949
     *
1950
     * const data = await multiSignClient.subAccountTransfer({
1951
     *   subAccountUser: "0x...",
1952
     *   isDeposit: true,
1953
     *   usd: 1 * 1e6,
1954
     * });
1955
     * ```
1956
     */
1957
    override async subAccountTransfer(
149✔
1958
        ...[args, signal]: Parameters<ExchangeClient["subAccountTransfer"]>
149✔
1959
    ): ReturnType<ExchangeClient["subAccountTransfer"]> {
149✔
1960
        // Destructure the parameters
1961
        const { ...actionArgs } = args;
151✔
1962

1963
        // Construct an action
1964
        const nonce = await this.nonceManager();
151✔
1965
        const action: SubAccountTransferRequest["action"] = {
151✔
1966
            type: "subAccountTransfer",
151✔
1967
            ...actionArgs,
151✔
1968
        };
151✔
1969

1970
        // Send a multi-sig action
1971
        const sortedAction = actionSorter[action.type](action);
151✔
1972
        const outerSigner = await this._getWalletAddress(this.signers[0]);
151✔
1973

1974
        const signatures = await this._multiSignL1Action({ action: sortedAction, nonce, outerSigner });
755✔
1975

1976
        // Send a multi-sig action
1977
        return super.multiSig({
151✔
1978
            signatures,
151✔
1979
            payload: {
151✔
1980
                multiSigUser: this.multiSignAddress,
151✔
1981
                outerSigner,
151✔
1982
                action: sortedAction,
151✔
1983
            },
151✔
1984
            nonce,
151✔
1985
        }, signal);
151✔
1986
    }
151✔
1987

1988
    /**
1989
     * @param args - The parameters for the request.
1990
     * @param signal - An optional abort signal.
1991
     * @returns Successful response without specific data.
1992
     * @throws {ApiRequestError} When the API returns an error response.
1993
     *
1994
     * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#delegate-or-undelegate-stake-from-validator
1995
     * @example
1996
     * ```ts
1997
     * import * as hl from "@nktkas/hyperliquid";
1998
     *
1999
     * const multiSignAddress = "0x...";
2000
     * const signers = [
2001
     *   "0x...", // Private key; or any other wallet libraries
2002
     * ] as const;
2003
     *
2004
     * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
2005
     * const multiSignClient = new hl.MultiSignClient({ transport, multiSignAddress, signers });
2006
     *
2007
     * const data = await multiSignClient.tokenDelegate({
2008
     *   validator: "0x...",
2009
     *   isUndelegate: true,
2010
     *   wei: 1 * 1e8,
2011
     * });
2012
     * ```
2013
     */
2014
    override async tokenDelegate(
149✔
2015
        ...[args, signal]: Parameters<ExchangeClient["tokenDelegate"]>
149✔
2016
    ): ReturnType<ExchangeClient["tokenDelegate"]> {
149✔
2017
        // Destructure the parameters
2018
        const { ...actionArgs } = args;
151✔
2019

2020
        // Construct an action
2021
        const nonce = await this.nonceManager();
151✔
2022
        const action: TokenDelegateRequest["action"] = {
151✔
2023
            ...actionArgs,
151✔
2024
            type: "tokenDelegate",
151✔
2025
            hyperliquidChain: this._getHyperliquidChain(),
151✔
2026
            signatureChainId: await this._getSignatureChainId(),
151✔
2027
            nonce,
151✔
2028
        };
151✔
2029

2030
        // Sign the action
2031
        const sortedAction = actionSorter[action.type](action);
151✔
2032
        const outerSigner = await this._getWalletAddress(this.signers[0]);
151✔
2033

2034
        const signatures = await this._multiSignUserSignedAction(sortedAction, outerSigner);
151✔
2035

2036
        // Send a multi-sig action
2037
        return super.multiSig({
151✔
2038
            signatures,
151✔
2039
            payload: {
151✔
2040
                multiSigUser: this.multiSignAddress,
151✔
2041
                outerSigner,
151✔
2042
                action: sortedAction,
151✔
2043
            },
151✔
2044
            nonce,
151✔
2045
        }, signal);
151✔
2046
    }
151✔
2047

2048
    /**
2049
     * @param args - The parameters for the request.
2050
     * @param signal - An optional abort signal.
2051
     * @returns Successful variant of {@link TwapCancelResponse} without error status.
2052
     * @throws {ApiRequestError} When the API returns an error response.
2053
     *
2054
     * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#cancel-a-twap-order
2055
     * @example
2056
     * ```ts
2057
     * import * as hl from "@nktkas/hyperliquid";
2058
     *
2059
     * const multiSignAddress = "0x...";
2060
     * const signers = [
2061
     *   "0x...", // Private key; or any other wallet libraries
2062
     * ] as const;
2063
     *
2064
     * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
2065
     * const multiSignClient = new hl.MultiSignClient({ transport, multiSignAddress, signers });
2066
     *
2067
     * const data = await multiSignClient.twapCancel({
2068
     *   a: 0, // Asset index
2069
     *   t: 1, // TWAP ID
2070
     * });
2071
     * ```
2072
     */
2073
    override async twapCancel(
149✔
2074
        ...[args, signal]: Parameters<ExchangeClient["twapCancel"]>
149✔
2075
    ): ReturnType<ExchangeClient["twapCancel"]> {
149✔
2076
        // Destructure the parameters
2077
        const {
153✔
2078
            vaultAddress = this.defaultVaultAddress,
153✔
2079
            expiresAfter = await this._getDefaultExpiresAfter(),
153✔
2080
            ...actionArgs
153✔
2081
        } = args;
153✔
2082

2083
        // Construct an action
2084
        const nonce = await this.nonceManager();
156✔
2085
        const action: TwapCancelRequest["action"] = {
153✔
2086
            type: "twapCancel",
153✔
2087
            ...actionArgs,
153✔
2088
        };
153✔
2089

2090
        // Send a multi-sig action
2091
        const sortedAction = actionSorter[action.type](action);
153✔
2092
        const outerSigner = await this._getWalletAddress(this.signers[0]);
153✔
2093

2094
        const signatures = await this._multiSignL1Action({
153✔
2095
            action: sortedAction,
153✔
2096
            nonce,
153✔
2097
            outerSigner,
153✔
2098
            vaultAddress,
153✔
2099
            expiresAfter,
153✔
2100
        });
153✔
2101

2102
        // Send a multi-sig action
2103
        return super.multiSig({
153✔
2104
            signatures,
153✔
2105
            payload: {
153✔
2106
                multiSigUser: this.multiSignAddress,
153✔
2107
                outerSigner,
153✔
2108
                action: sortedAction,
153✔
2109
            },
153✔
2110
            nonce,
153✔
2111
            vaultAddress,
153✔
2112
            expiresAfter,
153✔
2113
        }, signal);
153✔
2114
    }
153✔
2115

2116
    /**
2117
     * @param args - The parameters for the request.
2118
     * @param signal - An optional abort signal.
2119
     * @returns Successful variant of {@link TwapOrderResponse} without error status.
2120
     * @throws {ApiRequestError} When the API returns an error response.
2121
     *
2122
     * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#place-a-twap-order
2123
     * @example
2124
     * ```ts
2125
     * import * as hl from "@nktkas/hyperliquid";
2126
     *
2127
     * const multiSignAddress = "0x...";
2128
     * const signers = [
2129
     *   "0x...", // Private key; or any other wallet libraries
2130
     * ] as const;
2131
     *
2132
     * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
2133
     * const multiSignClient = new hl.MultiSignClient({ transport, multiSignAddress, signers });
2134
     *
2135
     * const data = await multiSignClient.twapOrder({
2136
     *   a: 0, // Asset index
2137
     *   b: true, // Buy order
2138
     *   s: "1", // Size
2139
     *   r: false, // Not reduce-only
2140
     *   m: 10, // Duration in minutes
2141
     *   t: true, // Randomize order timing
2142
     * });
2143
     * ```
2144
     */
2145
    override async twapOrder(
149✔
2146
        ...[args, signal]: Parameters<ExchangeClient["twapOrder"]>
149✔
2147
    ): ReturnType<ExchangeClient["twapOrder"]> {
149✔
2148
        // Destructure the parameters
2149
        const {
153✔
2150
            vaultAddress = this.defaultVaultAddress,
153✔
2151
            expiresAfter = await this._getDefaultExpiresAfter(),
153✔
2152
            ...actionArgs
153✔
2153
        } = args;
153✔
2154

2155
        // Construct an action
2156
        const nonce = await this.nonceManager();
156✔
2157
        const action: TwapOrderRequest["action"] = {
153✔
2158
            type: "twapOrder",
153✔
2159
            twap: {
153✔
2160
                ...actionArgs,
153✔
2161
            },
153✔
2162
        };
153✔
2163

2164
        // Send a multi-sig action
2165
        const sortedAction = actionSorter[action.type](action);
153✔
2166
        const outerSigner = await this._getWalletAddress(this.signers[0]);
153✔
2167

2168
        const signatures = await this._multiSignL1Action({
153✔
2169
            action: sortedAction,
153✔
2170
            nonce,
153✔
2171
            outerSigner,
153✔
2172
            vaultAddress,
153✔
2173
            expiresAfter,
153✔
2174
        });
153✔
2175

2176
        // Send a multi-sig action
2177
        return super.multiSig({
153✔
2178
            signatures,
153✔
2179
            payload: {
153✔
2180
                multiSigUser: this.multiSignAddress,
153✔
2181
                outerSigner,
153✔
2182
                action: sortedAction,
153✔
2183
            },
153✔
2184
            nonce,
153✔
2185
            vaultAddress,
153✔
2186
            expiresAfter,
153✔
2187
        }, signal);
153✔
2188
    }
153✔
2189

2190
    /**
2191
     * @param args - The parameters for the request.
2192
     * @param signal - An optional abort signal.
2193
     * @returns Successful response without specific data.
2194
     * @throws {ApiRequestError} When the API returns an error response.
2195
     *
2196
     * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#update-isolated-margin
2197
     * @example
2198
     * ```ts
2199
     * import * as hl from "@nktkas/hyperliquid";
2200
     *
2201
     * const multiSignAddress = "0x...";
2202
     * const signers = [
2203
     *   "0x...", // Private key; or any other wallet libraries
2204
     * ] as const;
2205
     *
2206
     * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
2207
     * const multiSignClient = new hl.MultiSignClient({ transport, multiSignAddress, signers });
2208
     *
2209
     * const data = await multiSignClient.updateIsolatedMargin({
2210
     *   asset: 0,
2211
     *   isBuy: true,
2212
     *   ntli: 1 * 1e6,
2213
     * });
2214
     * ```
2215
     */
2216
    override async updateIsolatedMargin(
149✔
2217
        ...[args, signal]: Parameters<ExchangeClient["updateIsolatedMargin"]>
149✔
2218
    ): ReturnType<ExchangeClient["updateIsolatedMargin"]> {
149✔
2219
        // Destructure the parameters
2220
        const {
151✔
2221
            vaultAddress = this.defaultVaultAddress,
151✔
2222
            expiresAfter = await this._getDefaultExpiresAfter(),
151✔
2223
            ...actionArgs
151✔
2224
        } = args;
151✔
2225

2226
        // Construct an action
2227
        const nonce = await this.nonceManager();
152✔
2228
        const action: UpdateIsolatedMarginRequest["action"] = {
151✔
2229
            type: "updateIsolatedMargin",
151✔
2230
            ...actionArgs,
151✔
2231
        };
151✔
2232

2233
        // Send a multi-sig action
2234
        const sortedAction = actionSorter[action.type](action);
151✔
2235
        const outerSigner = await this._getWalletAddress(this.signers[0]);
151✔
2236

2237
        const signatures = await this._multiSignL1Action({
151✔
2238
            action: sortedAction,
151✔
2239
            nonce,
151✔
2240
            outerSigner,
151✔
2241
            vaultAddress,
151✔
2242
            expiresAfter,
151✔
2243
        });
151✔
2244

2245
        // Send a multi-sig action
2246
        return super.multiSig({
151✔
2247
            signatures,
151✔
2248
            payload: {
151✔
2249
                multiSigUser: this.multiSignAddress,
151✔
2250
                outerSigner,
151✔
2251
                action: sortedAction,
151✔
2252
            },
151✔
2253
            nonce,
151✔
2254
            vaultAddress,
151✔
2255
            expiresAfter,
151✔
2256
        }, signal);
151✔
2257
    }
151✔
2258

2259
    /**
2260
     * @param args - The parameters for the request.
2261
     * @param signal - An optional abort signal.
2262
     * @returns Successful response without specific data.
2263
     * @throws {ApiRequestError} When the API returns an error response.
2264
     *
2265
     * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#update-leverage
2266
     * @example
2267
     * ```ts
2268
     * import * as hl from "@nktkas/hyperliquid";
2269
     *
2270
     * const multiSignAddress = "0x...";
2271
     * const signers = [
2272
     *   "0x...", // Private key; or any other wallet libraries
2273
     * ] as const;
2274
     *
2275
     * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
2276
     * const multiSignClient = new hl.MultiSignClient({ transport, multiSignAddress, signers });
2277
     *
2278
     * const data = await multiSignClient.updateLeverage({
2279
     *   asset: 0,
2280
     *   isCross: true,
2281
     *   leverage: 5,
2282
     * });
2283
     * ```
2284
     */
2285
    override async updateLeverage(
149✔
2286
        ...[args, signal]: Parameters<ExchangeClient["updateLeverage"]>
149✔
2287
    ): ReturnType<ExchangeClient["updateLeverage"]> {
149✔
2288
        // Destructure the parameters
2289
        const {
156✔
2290
            vaultAddress = this.defaultVaultAddress,
156✔
2291
            expiresAfter = await this._getDefaultExpiresAfter(),
156✔
2292
            ...actionArgs
156✔
2293
        } = args;
156✔
2294

2295
        // Construct an action
2296
        const nonce = await this.nonceManager();
162✔
2297
        const action: UpdateLeverageRequest["action"] = {
156✔
2298
            type: "updateLeverage",
156✔
2299
            ...actionArgs,
156✔
2300
        };
156✔
2301

2302
        // Send a multi-sig action
2303
        const sortedAction = actionSorter[action.type](action);
156✔
2304
        const outerSigner = await this._getWalletAddress(this.signers[0]);
156✔
2305

2306
        const signatures = await this._multiSignL1Action({
156✔
2307
            action: sortedAction,
156✔
2308
            nonce,
156✔
2309
            outerSigner,
156✔
2310
            vaultAddress,
156✔
2311
            expiresAfter,
156✔
2312
        });
156✔
2313

2314
        // Send a multi-sig action
2315
        return super.multiSig({
156✔
2316
            signatures,
156✔
2317
            payload: {
156✔
2318
                multiSigUser: this.multiSignAddress,
156✔
2319
                outerSigner,
156✔
2320
                action: sortedAction,
156✔
2321
            },
156✔
2322
            nonce,
156✔
2323
            vaultAddress,
156✔
2324
            expiresAfter,
156✔
2325
        }, signal);
156✔
2326
    }
156✔
2327

2328
    /**
2329
     * @param args - The parameters for the request.
2330
     * @param signal - An optional abort signal.
2331
     * @returns Successful response without specific data.
2332
     * @throws {ApiRequestError} When the API returns an error response.
2333
     *
2334
     * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#transfer-from-spot-account-to-perp-account-and-vice-versa
2335
     * @example
2336
     * ```ts
2337
     * import * as hl from "@nktkas/hyperliquid";
2338
     *
2339
     * const multiSignAddress = "0x...";
2340
     * const signers = [
2341
     *   "0x...", // Private key; or any other wallet libraries
2342
     * ] as const;
2343
     *
2344
     * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
2345
     * const multiSignClient = new hl.MultiSignClient({ transport, multiSignAddress, signers });
2346
     *
2347
     * const data = await multiSignClient.usdClassTransfer({ amount: "1", toPerp: true });
2348
     * ```
2349
     */
2350
    override async usdClassTransfer(
149✔
2351
        ...[args, signal]: Parameters<ExchangeClient["usdClassTransfer"]>
149✔
2352
    ): ReturnType<ExchangeClient["usdClassTransfer"]> {
149✔
2353
        // Destructure the parameters
2354
        const { ...actionArgs } = args;
151✔
2355

2356
        // Construct an action
2357
        const nonce = await this.nonceManager();
151✔
2358
        const action: UsdClassTransferRequest["action"] = {
151✔
2359
            ...actionArgs,
151✔
2360
            type: "usdClassTransfer",
151✔
2361
            hyperliquidChain: this._getHyperliquidChain(),
151✔
2362
            signatureChainId: await this._getSignatureChainId(),
151✔
2363
            nonce,
151✔
2364
        };
151✔
2365

2366
        // Sign the action
2367
        const sortedAction = actionSorter[action.type](action);
151✔
2368
        const outerSigner = await this._getWalletAddress(this.signers[0]);
151✔
2369

2370
        const signatures = await this._multiSignUserSignedAction(sortedAction, outerSigner);
151✔
2371

2372
        // Send a multi-sig action
2373
        return super.multiSig({
151✔
2374
            signatures,
151✔
2375
            payload: {
151✔
2376
                multiSigUser: this.multiSignAddress,
151✔
2377
                outerSigner,
151✔
2378
                action: sortedAction,
151✔
2379
            },
151✔
2380
            nonce,
151✔
2381
        }, signal);
151✔
2382
    }
151✔
2383

2384
    /**
2385
     * @param args - The parameters for the request.
2386
     * @param signal - An optional abort signal.
2387
     * @returns Successful response without specific data.
2388
     * @throws {ApiRequestError} When the API returns an error response.
2389
     *
2390
     * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#core-usdc-transfer
2391
     * @example
2392
     * ```ts
2393
     * import * as hl from "@nktkas/hyperliquid";
2394
     *
2395
     * const multiSignAddress = "0x...";
2396
     * const signers = [
2397
     *   "0x...", // Private key; or any other wallet libraries
2398
     * ] as const;
2399
     *
2400
     * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
2401
     * const multiSignClient = new hl.MultiSignClient({ transport, multiSignAddress, signers });
2402
     *
2403
     * const data = await multiSignClient.usdSend({ destination: "0x...", amount: "1" });
2404
     * ```
2405
     */
2406
    override async usdSend(
149✔
2407
        ...[args, signal]: Parameters<ExchangeClient["usdSend"]>
149✔
2408
    ): ReturnType<ExchangeClient["usdSend"]> {
149✔
2409
        // Destructure the parameters
2410
        const { ...actionArgs } = args;
150✔
2411

2412
        // Construct an action
2413
        const nonce = await this.nonceManager();
150✔
2414
        const action: UsdSendRequest["action"] = {
150✔
2415
            ...actionArgs,
150✔
2416
            type: "usdSend",
150✔
2417
            hyperliquidChain: this._getHyperliquidChain(),
150✔
2418
            signatureChainId: await this._getSignatureChainId(),
150✔
2419
            time: nonce,
150✔
2420
        };
150✔
2421

2422
        // Sign the action
2423
        const sortedAction = actionSorter[action.type](action);
150✔
2424
        const outerSigner = await this._getWalletAddress(this.signers[0]);
150✔
2425

2426
        const signatures = await this._multiSignUserSignedAction(sortedAction, outerSigner);
150✔
2427

2428
        // Send a multi-sig action
2429
        return super.multiSig({
150✔
2430
            signatures,
150✔
2431
            payload: {
150✔
2432
                multiSigUser: this.multiSignAddress,
150✔
2433
                outerSigner,
150✔
2434
                action: sortedAction,
150✔
2435
            },
150✔
2436
            nonce,
150✔
2437
        }, signal);
150✔
2438
    }
150✔
2439

2440
    /**
2441
     * @param args - The parameters for the request.
2442
     * @param signal - An optional abort signal.
2443
     * @returns Successful response without specific data.
2444
     * @throws {ApiRequestError} When the API returns an error response.
2445
     *
2446
     * @see null - no documentation
2447
     * @example
2448
     * ```ts
2449
     * import * as hl from "@nktkas/hyperliquid";
2450
     *
2451
     * const multiSignAddress = "0x...";
2452
     * const signers = [
2453
     *   "0x...", // Private key; or any other wallet libraries
2454
     * ] as const;
2455
     *
2456
     * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
2457
     * const multiSignClient = new hl.MultiSignClient({ transport, multiSignAddress, signers });
2458
     *
2459
     * const data = await multiSignClient.vaultDistribute({ vaultAddress: "0x...", usd: 10 * 1e6 });
2460
     * ```
2461
     */
2462
    override async vaultDistribute(
149✔
2463
        ...[args, signal]: Parameters<ExchangeClient["vaultDistribute"]>
149✔
2464
    ): ReturnType<ExchangeClient["vaultDistribute"]> {
149✔
2465
        // Destructure the parameters
2466
        const { ...actionArgs } = args;
150✔
2467

2468
        // Construct an action
2469
        const nonce = await this.nonceManager();
150✔
2470
        const action: VaultDistributeRequest["action"] = {
150✔
2471
            type: "vaultDistribute",
150✔
2472
            ...actionArgs,
150✔
2473
        };
150✔
2474

2475
        // Send a multi-sig action
2476
        const sortedAction = actionSorter[action.type](action);
150✔
2477
        const outerSigner = await this._getWalletAddress(this.signers[0]);
150✔
2478

2479
        const signatures = await this._multiSignL1Action({ action: sortedAction, nonce, outerSigner });
750✔
2480

2481
        // Send a multi-sig action
2482
        return super.multiSig({
150✔
2483
            signatures,
150✔
2484
            payload: {
150✔
2485
                multiSigUser: this.multiSignAddress,
150✔
2486
                outerSigner,
150✔
2487
                action: sortedAction,
150✔
2488
            },
150✔
2489
            nonce,
150✔
2490
        }, signal);
150✔
2491
    }
150✔
2492

2493
    /**
2494
     * @param args - The parameters for the request.
2495
     * @param signal - An optional abort signal.
2496
     * @returns Successful response without specific data.
2497
     * @throws {ApiRequestError} When the API returns an error response.
2498
     *
2499
     * @see null - no documentation
2500
     * @example
2501
     * ```ts
2502
     * import * as hl from "@nktkas/hyperliquid";
2503
     *
2504
     * const multiSignAddress = "0x...";
2505
     * const signers = [
2506
     *   "0x...", // Private key; or any other wallet libraries
2507
     * ] as const;
2508
     *
2509
     * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
2510
     * const multiSignClient = new hl.MultiSignClient({ transport, multiSignAddress, signers });
2511
     *
2512
     * const data = await multiSignClient.vaultModify({
2513
     *   vaultAddress: "0x...",
2514
     *   allowDeposits: true,
2515
     *   alwaysCloseOnWithdraw: false,
2516
     * });
2517
     * ```
2518
     */
2519
    override async vaultModify(
149✔
2520
        ...[args, signal]: Parameters<ExchangeClient["vaultModify"]>
149✔
2521
    ): ReturnType<ExchangeClient["vaultModify"]> {
149✔
2522
        // Destructure the parameters
2523
        const { ...actionArgs } = args;
154✔
2524

2525
        // Construct an action
2526
        const nonce = await this.nonceManager();
154✔
2527
        const action: VaultModifyRequest["action"] = {
154✔
2528
            type: "vaultModify",
154✔
2529
            ...actionArgs,
154✔
2530
        };
154✔
2531

2532
        // Send a multi-sig action
2533
        const sortedAction = actionSorter[action.type](action);
154✔
2534
        const outerSigner = await this._getWalletAddress(this.signers[0]);
154✔
2535

2536
        const signatures = await this._multiSignL1Action({ action: sortedAction, nonce, outerSigner });
770✔
2537

2538
        // Send a multi-sig action
2539
        return super.multiSig({
154✔
2540
            signatures,
154✔
2541
            payload: {
154✔
2542
                multiSigUser: this.multiSignAddress,
154✔
2543
                outerSigner,
154✔
2544
                action: sortedAction,
154✔
2545
            },
154✔
2546
            nonce,
154✔
2547
        }, signal);
154✔
2548
    }
154✔
2549

2550
    /**
2551
     * @param args - The parameters for the request.
2552
     * @param signal - An optional abort signal.
2553
     * @returns Successful response without specific data.
2554
     * @throws {ApiRequestError} When the API returns an error response.
2555
     *
2556
     * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#deposit-or-withdraw-from-a-vault
2557
     * @example
2558
     * ```ts
2559
     * import * as hl from "@nktkas/hyperliquid";
2560
     *
2561
     * const multiSignAddress = "0x...";
2562
     * const signers = [
2563
     *   "0x...", // Private key; or any other wallet libraries
2564
     * ] as const;
2565
     *
2566
     * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
2567
     * const multiSignClient = new hl.MultiSignClient({ transport, multiSignAddress, signers });
2568
     *
2569
     * const data = await multiSignClient.vaultTransfer({
2570
     *   vaultAddress: "0x...",
2571
     *   isDeposit: true,
2572
     *   usd: 10 * 1e6,
2573
     * });
2574
     * ```
2575
     */
2576
    override async vaultTransfer(
149✔
2577
        ...[args, signal]: Parameters<ExchangeClient["vaultTransfer"]>
149✔
2578
    ): ReturnType<ExchangeClient["vaultTransfer"]> {
149✔
2579
        // Destructure the parameters
2580
        const {
151✔
2581
            expiresAfter = await this._getDefaultExpiresAfter(),
151✔
2582
            ...actionArgs
151✔
2583
        } = args;
151✔
2584

2585
        // Construct an action
2586
        const nonce = await this.nonceManager();
152✔
2587
        const action: VaultTransferRequest["action"] = {
151✔
2588
            type: "vaultTransfer",
151✔
2589
            ...actionArgs,
151✔
2590
        };
151✔
2591

2592
        // Send a multi-sig action
2593
        const sortedAction = actionSorter[action.type](action);
151✔
2594
        const outerSigner = await this._getWalletAddress(this.signers[0]);
151✔
2595

2596
        const signatures = await this._multiSignL1Action({ action: sortedAction, nonce, outerSigner, expiresAfter });
906✔
2597

2598
        // Send a multi-sig action
2599
        return super.multiSig({
151✔
2600
            signatures,
151✔
2601
            payload: {
151✔
2602
                multiSigUser: this.multiSignAddress,
151✔
2603
                outerSigner,
151✔
2604
                action: sortedAction,
151✔
2605
            },
151✔
2606
            nonce,
151✔
2607
            expiresAfter,
151✔
2608
        }, signal);
151✔
2609
    }
151✔
2610

2611
    /**
2612
     * @param args - The parameters for the request.
2613
     * @param signal - An optional abort signal.
2614
     * @returns Successful response without specific data.
2615
     * @throws {ApiRequestError} When the API returns an error response.
2616
     *
2617
     * @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#initiate-a-withdrawal-request
2618
     * @example
2619
     * ```ts
2620
     * import * as hl from "@nktkas/hyperliquid";
2621
     *
2622
     * const multiSignAddress = "0x...";
2623
     * const signers = [
2624
     *   "0x...", // Private key; or any other wallet libraries
2625
     * ] as const;
2626
     *
2627
     * const transport = new hl.HttpTransport(); // or `WebSocketTransport`
2628
     * const multiSignClient = new hl.MultiSignClient({ transport, multiSignAddress, signers });
2629
     *
2630
     * const data = await multiSignClient.withdraw3({ destination: "0x...", amount: "1" });
2631
     * ```
2632
     */
2633
    override async withdraw3(
149✔
2634
        ...[args, signal]: Parameters<ExchangeClient["withdraw3"]>
149✔
2635
    ): ReturnType<ExchangeClient["withdraw3"]> {
149✔
2636
        // Destructure the parameters
2637
        const { ...actionArgs } = args;
150✔
2638

2639
        // Construct an action
2640
        const nonce = await this.nonceManager();
150✔
2641
        const action: Withdraw3Request["action"] = {
150✔
2642
            ...actionArgs,
150✔
2643
            type: "withdraw3",
150✔
2644
            hyperliquidChain: this._getHyperliquidChain(),
150✔
2645
            signatureChainId: await this._getSignatureChainId(),
150✔
2646
            time: nonce,
150✔
2647
        };
150✔
2648

2649
        // Sign the action
2650
        const sortedAction = actionSorter[action.type](action);
150✔
2651
        const outerSigner = await this._getWalletAddress(this.signers[0]);
150✔
2652

2653
        const signatures = await this._multiSignUserSignedAction(sortedAction, outerSigner);
150✔
2654

2655
        // Send a multi-sig action
2656
        return super.multiSig({
150✔
2657
            signatures,
150✔
2658
            payload: {
150✔
2659
                multiSigUser: this.multiSignAddress,
150✔
2660
                outerSigner,
150✔
2661
                action: sortedAction,
150✔
2662
            },
150✔
2663
            nonce,
150✔
2664
        }, signal);
150✔
2665
    }
150✔
2666

2667
    /** Extracts the wallet address from different wallet types. */
2668
    protected async _getWalletAddress(wallet: AbstractWalletWithAddress): Promise<`0x${string}`> {
149✔
2669
        if (isValidPrivateKey(wallet)) {
270✔
2670
            return privateKeyToAddress(wallet);
270✔
2671
        } else if (isAbstractViemWalletClient(wallet)) {
×
2672
            return wallet.address;
×
2673
        } else if (isAbstractEthersSigner(wallet) || isAbstractEthersV5Signer(wallet)) {
×
2674
            return await wallet.getAddress() as Hex;
×
2675
        } else if (isAbstractWindowEthereum(wallet)) {
×
2676
            const accounts = await wallet.request({ method: "eth_requestAccounts", params: [] });
×
2677
            if (!Array.isArray(accounts) || accounts.length === 0) {
×
2678
                throw new Error("No Ethereum accounts available");
×
2679
            }
×
2680
            return accounts[0] as Hex;
×
2681
        } else {
×
2682
            throw new Error("Unsupported wallet for getting address");
×
2683
        }
×
2684
    }
270✔
2685

2686
    /** Signs L1 action with all signers for multi-signature operations. */
2687
    protected _multiSignL1Action(args: {
149✔
2688
        action: BaseExchangeRequest["action"];
2689
        nonce: number;
2690
        outerSigner: Hex;
2691
        vaultAddress?: Hex;
2692
        expiresAfter?: number;
2693
    }): Promise<Signature[]> {
149✔
2694
        const { action, nonce, outerSigner, vaultAddress, expiresAfter } = args;
253✔
2695
        return Promise.all(this.signers.map((signer) => {
253✔
2696
            return signL1Action({
357✔
2697
                wallet: signer,
357✔
2698
                action: [this.multiSignAddress.toLowerCase(), outerSigner.toLowerCase(), action],
1,785✔
2699
                nonce,
357✔
2700
                isTestnet: this.isTestnet,
357✔
2701
                vaultAddress,
357✔
2702
                expiresAfter,
357✔
2703
            });
357✔
2704
        }));
253✔
2705
    }
253✔
2706

2707
    /** Signs user-signed action with all signers for multi-signature operations. */
2708
    protected _multiSignUserSignedAction(
149✔
2709
        action:
149✔
2710
            & BaseExchangeRequest["action"]
2711
            & {
2712
                type: keyof typeof userSignedActionEip712Types;
2713
                signatureChainId: string;
2714
            }
2715
            & (
2716
                | { nonce: number; time?: undefined }
2717
                | { time: number; nonce?: undefined }
2718
            ),
149✔
2719
        outerSigner: Hex,
149✔
2720
    ): Promise<Signature[]> {
149✔
2721
        return Promise.all(this.signers.map((signer) => {
166✔
2722
            const types = structuredClone(userSignedActionEip712Types[action.type]); // for safe mutation
183✔
2723
            Object.values(types)[0].splice( // array mutation
183✔
2724
                1, // after `hyperliquidChain`
183✔
2725
                0, // do not remove any elements
183✔
2726
                { name: "payloadMultiSigUser", type: "address" },
732✔
2727
                { name: "outerSigner", type: "address" },
732✔
2728
            );
2729
            return signUserSignedAction({
183✔
2730
                wallet: signer,
183✔
2731
                action: {
183✔
2732
                    ...action,
183✔
2733
                    payloadMultiSigUser: this.multiSignAddress,
183✔
2734
                    outerSigner,
183✔
2735
                },
183✔
2736
                types,
183✔
2737
                chainId: parseInt(action.signatureChainId, 16),
183✔
2738
            });
183✔
2739
        }));
166✔
2740
    }
166✔
2741
}
149✔
2742

2743
/** Converts a private key to an Ethereum address. */
2744
function privateKeyToAddress(privateKey: string): Hex {
149✔
2745
    const cleanKey = privateKey.startsWith("0x") ? privateKey.slice(2) : privateKey;
×
2746

2747
    const publicKey = getPublicKey(cleanKey, false);
270✔
2748
    const publicKeyWithoutPrefix = publicKey.slice(1);
270✔
2749

2750
    const hash = keccak_256(publicKeyWithoutPrefix);
270✔
2751

2752
    const addressBytes = hash.slice(-20);
270✔
2753
    const address = encodeHex(addressBytes);
270✔
2754

2755
    return `0x${address}`;
270✔
2756
}
270✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc