@deeeed/hyperliquid-node20
Version:
Unofficial Hyperliquid API SDK for all major JS runtimes, written in TypeScript. Fork with Node.js 20.18.0+ compatibility.
1,297 lines (1,296 loc) • 67.5 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ExchangeClient = exports.ApiRequestError = void 0;
const base_js_1 = require("../base.js");
const mod_js_1 = require("../signing/mod.js");
/** Error thrown when the API returns an error response. */
class ApiRequestError extends base_js_1.HyperliquidError {
response;
constructor(response) {
let message;
if (response.status === "err") {
// ErrorResponse
message = response.response;
}
else {
if ("statuses" in response.response.data) {
// OrderResponse | CancelResponse
const errors = response.response.data.statuses.reduce((acc, status, index) => {
if (typeof status === "object" && "error" in status) {
acc.push(`Order ${index}: ${status.error}`);
}
return acc;
}, []);
if (errors.length > 0) {
message = errors.join(", ");
}
}
else {
// TwapOrderResponse | TwapCancelResponse
if (typeof response.response.data.status === "object" && "error" in response.response.data.status) {
message = response.response.data.status.error;
}
}
}
super(message || "An unknown error occurred while processing an API request. See `response` for more details.");
this.response = response;
this.name = "ApiRequestError";
}
}
exports.ApiRequestError = ApiRequestError;
/** Nonce manager for generating unique nonces for signing transactions. */
class NonceManager {
/** The last nonce used for signing transactions. */
lastNonce = 0;
/**
* Gets the next nonce for signing transactions.
* @returns The next nonce.
*/
getNonce() {
let nonce = Date.now();
if (nonce <= this.lastNonce) {
nonce = ++this.lastNonce;
}
else {
this.lastNonce = nonce;
}
return nonce;
}
}
/**
* Exchange client for interacting with the Hyperliquid API.
* @typeParam T The transport used to connect to the Hyperliquid API.
* @typeParam W The wallet used for signing transactions.
*/
class ExchangeClient {
transport;
wallet;
isTestnet;
defaultVaultAddress;
defaultExpiresAfter;
signatureChainId;
nonceManager;
/**
* Initialises a new instance.
* @param args - The parameters for the client.
*
* @example Private key directly
* ```ts
* import * as hl from "@nktkas/hyperliquid";
*
* const privateKey = "0x...";
*
* const transport = new hl.HttpTransport(); // or `WebSocketTransport`
* const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
* ```
*
* @example [Viem](https://viem.sh/docs/clients/wallet#local-accounts-private-key-mnemonic-etc)
* ```ts
* import * as hl from "@nktkas/hyperliquid";
* import { privateKeyToAccount } from "viem/accounts";
*
* const account = privateKeyToAccount("0x...");
*
* const transport = new hl.HttpTransport(); // or `WebSocketTransport`
* const exchClient = new hl.ExchangeClient({ wallet: account, transport });
* ```
*
* @example [ethers.js](https://docs.ethers.org/v6/api/wallet/#Wallet) or [ethers.js v5](https://docs.ethers.org/v5/api/signer/#Wallet)
* ```ts
* import * as hl from "@nktkas/hyperliquid";
* import { ethers } from "ethers";
*
* const wallet = new ethers.Wallet("0x...");
*
* const transport = new hl.HttpTransport(); // or `WebSocketTransport`
* const exchClient = new hl.ExchangeClient({ wallet, transport });
* ```
*
* @example External wallet (e.g. MetaMask) via [viem](https://viem.sh/docs/clients/wallet)
* ```ts
* import * as hl from "@nktkas/hyperliquid";
* import { createWalletClient, custom } from "viem";
*
* const ethereum = (window as any).ethereum;
* const [account] = await ethereum.request({ method: "eth_requestAccounts" });
* const wallet = createWalletClient({ account, transport: custom(ethereum) });
*
* const transport = new hl.HttpTransport(); // or `WebSocketTransport`
* const exchClient = new hl.ExchangeClient({ wallet, transport });
* ```
*
* @example External wallet (e.g. MetaMask) via [`window.ethereum`](https://eips.ethereum.org/EIPS/eip-1193)
* ```ts
* import * as hl from "@nktkas/hyperliquid";
*
* const ethereum = (window as any).ethereum;
* const transport = new hl.HttpTransport(); // or `WebSocketTransport`
* const exchClient = new hl.ExchangeClient({ wallet: ethereum, transport });
* ```
*/
constructor(args) {
this.transport = args.transport;
this.wallet = args.wallet;
this.isTestnet = args.isTestnet ?? false;
this.defaultVaultAddress = args.defaultVaultAddress;
this.defaultExpiresAfter = args.defaultExpiresAfter;
this.signatureChainId = args.signatureChainId ?? this._guessSignatureChainId;
this.nonceManager = args.nonceManager ?? new NonceManager().getNonce;
}
/**
* Approve an agent to sign on behalf of the master account.
* @param args - The parameters for the request.
* @param signal - An optional [AbortSignal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal).
* @returns Successful response without specific data.
*
* @throws {ApiRequestError} When the API returns an unsuccessful response.
* @throws {TransportError} When the transport layer throws an error.
*
* @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#approve-an-api-wallet
* @example
* ```ts
* import * as hl from "@nktkas/hyperliquid";
*
* const privateKey = "0x..."; // or `viem`, `ethers`
* const transport = new hl.HttpTransport(); // or `WebSocketTransport`
* const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
*
* await exchClient.approveAgent({ agentAddress: "0x...", agentName: "..." });
* ```
*/
async approveAgent(args, signal) {
const { ...actionArgs } = args;
return this._executeAction({
action: {
type: "approveAgent",
hyperliquidChain: this._getHyperliquidChain(),
signatureChainId: await this._getSignatureChainId(),
nonce: await this.nonceManager(),
...actionArgs,
},
}, signal);
}
/**
* Approve a maximum fee rate for a builder.
* @param args - The parameters for the request.
* @param signal - An optional [AbortSignal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal).
* @returns Successful response without specific data.
*
* @throws {ApiRequestError} When the API returns an unsuccessful response.
* @throws {TransportError} When the transport layer throws an error.
*
* @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#approve-a-builder-fee
* @example
* ```ts
* import * as hl from "@nktkas/hyperliquid";
*
* const privateKey = "0x..."; // or `viem`, `ethers`
* const transport = new hl.HttpTransport(); // or `WebSocketTransport`
* const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
*
* await exchClient.approveBuilderFee({ maxFeeRate: "0.01%", builder: "0x..." });
* ```
*/
async approveBuilderFee(args, signal) {
const { ...actionArgs } = args;
return this._executeAction({
action: {
type: "approveBuilderFee",
hyperliquidChain: this._getHyperliquidChain(),
signatureChainId: await this._getSignatureChainId(),
nonce: await this.nonceManager(),
...actionArgs,
},
}, signal);
}
/**
* Modify multiple orders.
* @param args - The parameters for the request.
* @param signal - An optional [AbortSignal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal).
* @returns Successful variant of {@link OrderResponse} without error statuses.
*
* @throws {ApiRequestError} When the API returns an unsuccessful response.
* @throws {TransportError} When the transport layer throws an error.
*
* @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#modify-multiple-orders
* @example
* ```ts
* import * as hl from "@nktkas/hyperliquid";
*
* const privateKey = "0x..."; // or `viem`, `ethers`
* const transport = new hl.HttpTransport(); // or `WebSocketTransport`
* const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
*
* const data = await exchClient.batchModify({
* modifies: [
* {
* oid: 123,
* order: {
* a: 0,
* b: true,
* p: "31000",
* s: "0.2",
* r: false,
* t: { limit: { tif: "Gtc" } },
* },
* },
* ],
* });
* ```
*/
async batchModify(args, signal) {
const { vaultAddress, expiresAfter, ...actionArgs } = args;
return this._executeAction({
action: {
type: "batchModify",
...actionArgs,
},
vaultAddress: vaultAddress ?? this.defaultVaultAddress,
expiresAfter: expiresAfter ?? await this._getDefaultExpiresAfter(),
}, signal);
}
/**
* Cancel order(s).
* @param args - The parameters for the request.
* @param signal - An optional [AbortSignal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal).
* @returns Successful variant of {@link CancelResponse} without error statuses.
*
* @throws {ApiRequestError} When the API returns an unsuccessful response.
* @throws {TransportError} When the transport layer throws an error.
*
* @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#cancel-order-s
* @example
* ```ts
* import * as hl from "@nktkas/hyperliquid";
*
* const privateKey = "0x..."; // or `viem`, `ethers`
* const transport = new hl.HttpTransport(); // or `WebSocketTransport`
* const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
*
* const data = await exchClient.cancel({
* cancels: [
* { a: 0, o: 123 },
* ],
* });
* ```
*/
async cancel(args, signal) {
const { vaultAddress, expiresAfter, ...actionArgs } = args;
return this._executeAction({
action: {
type: "cancel",
...actionArgs,
},
vaultAddress: vaultAddress ?? this.defaultVaultAddress,
expiresAfter: expiresAfter ?? await this._getDefaultExpiresAfter(),
}, signal);
}
/**
* Cancel order(s) by cloid.
* @param args - The parameters for the request.
* @param signal - An optional [AbortSignal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal).
* @returns Successful variant of {@link CancelResponse} without error statuses.
*
* @throws {ApiRequestError} When the API returns an unsuccessful response.
* @throws {TransportError} When the transport layer throws an error.
*
* @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#cancel-order-s-by-cloid
* @example
* ```ts
* import * as hl from "@nktkas/hyperliquid";
*
* const privateKey = "0x..."; // or `viem`, `ethers`
* const transport = new hl.HttpTransport(); // or `WebSocketTransport`
* const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
*
* const data = await exchClient.cancelByCloid({
* cancels: [
* { asset: 0, cloid: "0x..." },
* ],
* });
* ```
*/
async cancelByCloid(args, signal) {
const { vaultAddress, expiresAfter, ...actionArgs } = args;
return this._executeAction({
action: {
type: "cancelByCloid",
...actionArgs,
},
vaultAddress: vaultAddress ?? this.defaultVaultAddress,
expiresAfter: expiresAfter ?? await this._getDefaultExpiresAfter(),
}, signal);
}
/**
* Transfer native token from the user's spot account into staking for delegating to validators.
* @param args - The parameters for the request.
* @param signal - An optional [AbortSignal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal).
* @returns Successful response without specific data.
*
* @throws {ApiRequestError} When the API returns an unsuccessful response.
* @throws {TransportError} When the transport layer throws an error.
*
* @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#deposit-into-staking
* @example
* ```ts
* import * as hl from "@nktkas/hyperliquid";
*
* const privateKey = "0x..."; // or `viem`, `ethers`
* const transport = new hl.HttpTransport(); // or `WebSocketTransport`
* const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
*
* await exchClient.cDeposit({ wei: 1 * 1e8 });
* ```
*/
async cDeposit(args, signal) {
const { ...actionArgs } = args;
return this._executeAction({
action: {
type: "cDeposit",
hyperliquidChain: this._getHyperliquidChain(),
signatureChainId: await this._getSignatureChainId(),
nonce: await this.nonceManager(),
...actionArgs,
},
}, signal);
}
/**
* Claim rewards from referral program.
* @param args - The parameters for the request.
* @param signal - An optional [AbortSignal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal).
* @returns Successful response without specific data.
*
* @throws {ApiRequestError} When the API returns an unsuccessful response.
* @throws {TransportError} When the transport layer throws an error.
*
* @see null
* @example
* ```ts
* import * as hl from "@nktkas/hyperliquid";
*
* const privateKey = "0x..."; // or `viem`, `ethers`
* const transport = new hl.HttpTransport(); // or `WebSocketTransport`
* const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
*
* await exchClient.claimRewards();
* ```
*/
claimRewards(signal) {
return this._executeAction({
action: {
type: "claimRewards",
},
}, signal);
}
/**
* Convert a single-signature account to a multi-signature account or vice versa.
* @param args - The parameters for the request.
* @param signal - An optional [AbortSignal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal).
* @returns Successful response without specific data.
*
* @throws {ApiRequestError} When the API returns an unsuccessful response.
* @throws {TransportError} When the transport layer throws an error.
*
* @see https://hyperliquid.gitbook.io/hyperliquid-docs/hypercore/multi-sig
* @example
* ```ts
* import * as hl from "@nktkas/hyperliquid";
*
* const privateKey = "0x..."; // or `viem`, `ethers`
* const transport = new hl.HttpTransport(); // or `WebSocketTransport`
* const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
*
* // Convert to multi-sig user
* await exchClient.convertToMultiSigUser({
* authorizedUsers: ["0x...", "0x...", "0x..."],
* threshold: 2,
* });
*
* // Convert to single-sig user
* await exchClient.convertToMultiSigUser(null);
* ```
*/
async convertToMultiSigUser(args, signal) {
const actionArgs = args;
return this._executeAction({
action: {
type: "convertToMultiSigUser",
hyperliquidChain: this._getHyperliquidChain(),
signatureChainId: await this._getSignatureChainId(),
nonce: await this.nonceManager(),
signers: JSON.stringify(actionArgs),
},
}, signal);
}
/**
* Create a sub-account.
* @param args - The parameters for the request.
* @param signal - An optional [AbortSignal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal).
* @returns Response for creating a sub-account.
*
* @throws {ApiRequestError} When the API returns an unsuccessful response.
* @throws {TransportError} When the transport layer throws an error.
*
* @see null
* @example
* ```ts
* import * as hl from "@nktkas/hyperliquid";
*
* const privateKey = "0x..."; // or `viem`, `ethers`
* const transport = new hl.HttpTransport(); // or `WebSocketTransport`
* const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
*
* const data = await exchClient.createSubAccount({ name: "..." });
* ```
*/
createSubAccount(args, signal) {
const { ...actionArgs } = args;
return this._executeAction({
action: {
type: "createSubAccount",
...actionArgs,
},
}, signal);
}
/**
* Create a vault.
* @param args - The parameters for the request.
* @param signal - An optional [AbortSignal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal).
* @returns Response for creating a vault.
*
* @throws {ApiRequestError} When the API returns an unsuccessful response.
* @throws {TransportError} When the transport layer throws an error.
*
* @see null
* @example
* ```ts
* import * as hl from "@nktkas/hyperliquid";
*
* const privateKey = "0x..."; // or `viem`, `ethers`
* const transport = new hl.HttpTransport(); // or `WebSocketTransport`
* const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
*
* const data = await exchClient.createVault({
* name: "...",
* description: "...",
* initialUsd: 100 * 1e6,
* nonce: Date.now(),
* });
* ```
*/
createVault(args, signal) {
const { ...actionArgs } = args;
return this._executeAction({
action: {
type: "createVault",
...actionArgs,
},
}, signal);
}
/**
* Jail or unjail self as a validator signer.
* @param args - The parameters for the request.
* @param signal - An optional [AbortSignal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal).
* @returns Successful response without specific data.
*
* @throws {ApiRequestError} When the API returns an unsuccessful response.
* @throws {TransportError} When the transport layer throws an error.
*
* @see null
* @example
* ```ts
* import * as hl from "@nktkas/hyperliquid";
*
* const privateKey = "0x..."; // or `viem`, `ethers`
* const transport = new hl.HttpTransport(); // or `WebSocketTransport`
* const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
*
* // Jail self
* await exchClient.cSignerAction({ jailSelf: null });
*
* // Unjail self
* await exchClient.cSignerAction({ unjailSelf: null });
* ```
*/
async cSignerAction(args, signal) {
const { expiresAfter, ...actionArgs } = args;
return this._executeAction({
action: {
type: "CSignerAction",
...actionArgs,
},
expiresAfter: expiresAfter ?? await this._getDefaultExpiresAfter(),
}, signal);
}
/**
* Action related to validator management.
* @param args - The parameters for the request.
* @param signal - An optional [AbortSignal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal).
* @returns Successful response without specific data.
*
* @throws {ApiRequestError} When the API returns an unsuccessful response.
* @throws {TransportError} When the transport layer throws an error.
*
* @see null
* @example
* ```ts
* import * as hl from "@nktkas/hyperliquid";
*
* const privateKey = "0x..."; // or `viem`, `ethers`
* const transport = new hl.HttpTransport(); // or `WebSocketTransport`
* const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
*
* // Change validator profile
* await exchClient.cValidatorAction({
* changeProfile: {
* name: "...",
* description: "...",
* unjailed: true,
* }
* });
*
* // Register a new validator
* await exchClient.cValidatorAction({
* register: {
* profile: {
* node_ip: { Ip: "1.2.3.4" },
* name: "...",
* description: "...",
* delegations_disabled: true,
* commission_bps: 1,
* signer: "0x...",
* },
* unjailed: false,
* initial_wei: 1,
* },
* });
*
* // Unregister a validator
* await exchClient.cValidatorAction({ unregister: null });
* ```
*/
async cValidatorAction(args, signal) {
const { expiresAfter, ...actionArgs } = args;
return this._executeAction({
action: {
type: "CValidatorAction",
...actionArgs,
},
expiresAfter: expiresAfter ?? await this._getDefaultExpiresAfter(),
}, signal);
}
/**
* Transfer native token from staking into the user's spot account.
* @param args - The parameters for the request.
* @param signal - An optional [AbortSignal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal).
* @returns Successful response without specific data.
*
* @throws {ApiRequestError} When the API returns an unsuccessful response.
* @throws {TransportError} When the transport layer throws an error.
*
* @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#withdraw-from-staking
* @example
* ```ts
* import * as hl from "@nktkas/hyperliquid";
*
* const privateKey = "0x..."; // or `viem`, `ethers`
* const transport = new hl.HttpTransport(); // or `WebSocketTransport`
* const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
*
* await exchClient.cWithdraw({ wei: 1 * 1e8 });
* ```
*/
async cWithdraw(args, signal) {
const { ...actionArgs } = args;
return this._executeAction({
action: {
type: "cWithdraw",
hyperliquidChain: this._getHyperliquidChain(),
signatureChainId: await this._getSignatureChainId(),
nonce: await this.nonceManager(),
...actionArgs,
},
}, signal);
}
/**
* Configure block type for EVM transactions.
* @param args - The parameters for the request.
* @param signal - An optional [AbortSignal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal).
* @returns Response for creating a sub-account.
*
* @throws {ApiRequestError} When the API returns an unsuccessful response.
* @throws {TransportError} When the transport layer throws an error.
*
* @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/evm/dual-block-architecture
* @example
* ```ts
* import * as hl from "@nktkas/hyperliquid";
*
* const privateKey = "0x..."; // or `viem`, `ethers`
* const transport = new hl.HttpTransport(); // or `WebSocketTransport`
* const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
*
* const data = await exchClient.evmUserModify({ usingBigBlocks: true });
* ```
*/
evmUserModify(args, signal) {
const { ...actionArgs } = args;
return this._executeAction({
action: {
type: "evmUserModify",
...actionArgs,
},
}, signal);
}
/**
* Modify an order.
* @param args - The parameters for the request.
* @param signal - An optional [AbortSignal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal).
* @returns Successful response without specific data.
*
* @throws {ApiRequestError} When the API returns an unsuccessful response.
* @throws {TransportError} When the transport layer throws an error.
*
* @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#modify-an-order
* @example
* ```ts
* import * as hl from "@nktkas/hyperliquid";
*
* const privateKey = "0x..."; // or `viem`, `ethers`
* const transport = new hl.HttpTransport(); // or `WebSocketTransport`
* const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
*
* await exchClient.modify({
* oid: 123,
* order: {
* a: 0,
* b: true,
* p: "31000",
* s: "0.2",
* r: false,
* t: { limit: { tif: "Gtc" } },
* c: "0x...",
* },
* });
* ```
*/
async modify(args, signal) {
const { vaultAddress, expiresAfter, ...actionArgs } = args;
return this._executeAction({
action: {
type: "modify",
...actionArgs,
},
vaultAddress: vaultAddress ?? this.defaultVaultAddress,
expiresAfter: expiresAfter ?? await this._getDefaultExpiresAfter(),
}, signal);
}
/**
* A multi-signature request.
* @param args - The parameters for the request.
* @param signal - An optional [AbortSignal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal).
* @returns Any successful response.
*
* @throws {ApiRequestError} When the API returns an unsuccessful response.
* @throws {TransportError} When the transport layer throws an error.
*
* @see https://hyperliquid.gitbook.io/hyperliquid-docs/hypercore/multi-sig
* @example
* ```ts
* import * as hl from "@nktkas/hyperliquid";
* import { actionSorter, signL1Action } from "@nktkas/hyperliquid/signing";
* import { privateKeyToAccount } from "viem/accounts";
*
* const wallet = privateKeyToAccount("0x..."); // or any other wallet libraries
* const multiSigUser = "0x...";
*
* const transport = new hl.HttpTransport(); // or `WebSocketTransport`
* const exchClient = new hl.ExchangeClient({ wallet, transport });
*
* const nonce = Date.now();
* const action = {
* type: "scheduleCancel",
* time: Date.now() + 10000,
* } as const;
*
* // Create the required number of signatures
* const signature = await signL1Action({
* wallet,
* action: [multiSigUser.toLowerCase(), wallet.address.toLowerCase(), actionSorter[action.type](action)],
* nonce,
* });
*
* const data = await exchClient.multiSig({
* signatures: [signature],
* payload: {
* multiSigUser,
* outerSigner: wallet.address,
* action,
* },
* nonce,
* });
* ```
*/
async multiSig(args, signal) {
const { vaultAddress, expiresAfter, nonce, ...actionArgs } = args;
return this._executeAction({
action: {
type: "multiSig",
signatureChainId: await this._getSignatureChainId(),
...actionArgs,
},
vaultAddress: vaultAddress ?? this.defaultVaultAddress,
expiresAfter: expiresAfter ?? await this._getDefaultExpiresAfter(),
multiSigNonce: nonce,
}, signal);
}
/**
* Place an order(s).
* @param args - The parameters for the request.
* @param signal - An optional [AbortSignal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal).
* @returns Successful variant of {@link OrderResponse} without error statuses.
*
* @throws {ApiRequestError} When the API returns an unsuccessful response.
* @throws {TransportError} When the transport layer throws an error.
*
* @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#place-an-order
* @example
* ```ts
* import * as hl from "@nktkas/hyperliquid";
*
* const privateKey = "0x..."; // or `viem`, `ethers`
* const transport = new hl.HttpTransport(); // or `WebSocketTransport`
* const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
*
* const data = await exchClient.order({
* orders: [
* {
* a: 0,
* b: true,
* p: "30000",
* s: "0.1",
* r: false,
* t: { limit: { tif: "Gtc" } },
* c: "0x...",
* },
* ],
* grouping: "na",
* });
* ```
*/
async order(args, signal) {
const { vaultAddress, expiresAfter, ...actionArgs } = args;
return this._executeAction({
action: {
type: "order",
...actionArgs,
},
vaultAddress: vaultAddress ?? this.defaultVaultAddress,
expiresAfter: expiresAfter ?? await this._getDefaultExpiresAfter(),
}, signal);
}
/**
* Deploying HIP-3 assets.
* @param args - The parameters for the request.
* @param signal - An optional [AbortSignal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal).
* @returns Successful response without specific data.
*
* @throws {ApiRequestError} When the API returns an unsuccessful response.
* @throws {TransportError} When the transport layer throws an error.
*
* @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/deploying-hip-3-assets
* @example
* ```ts
* import * as hl from "@nktkas/hyperliquid";
*
* const privateKey = "0x..."; // or `viem`, `ethers`
* const transport = new hl.HttpTransport(); // or `WebSocketTransport`
* const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
*
* await exchClient.perpDeploy({
* registerAsset: {
* maxGas: 1000000,
* assetRequest: {
* coin: "USDC",
* szDecimals: 8,
* oraclePx: "1",
* marginTableId: 1,
* onlyIsolated: false,
* },
* dex: "test",
* },
* });
* ```
*/
perpDeploy(args, signal) {
const { ...actionArgs } = args;
return this._executeAction({
action: {
type: "perpDeploy",
...actionArgs,
},
}, signal);
}
/**
* Transfer funds between Spot account and Perp dex account.
* @param args - The parameters for the request.
* @param signal - An optional [AbortSignal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal).
* @returns Successful response without specific data.
*
* @throws {ApiRequestError} When the API returns an unsuccessful response.
* @throws {TransportError} When the transport layer throws an error.
*
* @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#transfer-from-spot-account-to-perp-account-and-vice-versa
* @example
* ```ts
* import * as hl from "@nktkas/hyperliquid";
*
* const privateKey = "0x..."; // or `viem`, `ethers`
* const transport = new hl.HttpTransport(); // or `WebSocketTransport`
* const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
*
* await exchClient.perpDexClassTransfer({ dex: "test", token: "USDC", amount: "1", toPerp: true });
* ```
*/
async perpDexClassTransfer(args, signal) {
const { ...actionArgs } = args;
return this._executeAction({
action: {
type: "PerpDexClassTransfer",
hyperliquidChain: this._getHyperliquidChain(),
signatureChainId: await this._getSignatureChainId(),
nonce: await this.nonceManager(),
...actionArgs,
},
}, signal);
}
/**
* Transfer collateral tokens between different perp dexes for the same user.
* @param args - The parameters for the request.
* @param signal - An optional [AbortSignal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal).
* @returns Successful response without specific data.
*
* @throws {ApiRequestError} When the API returns an unsuccessful response.
* @throws {TransportError} When the transport layer throws an error.
*
* @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#transfer-from-perp-account-to-perp-account-for-builder-deployed-dex
* @example
* ```ts
* import * as hl from "@nktkas/hyperliquid";
*
* const privateKey = "0x..."; // or `viem`, `ethers`
* const transport = new hl.HttpTransport(); // or `WebSocketTransport`
* const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
*
* await exchClient.perpDexTransfer({ sourceDex: "", destinationDex: "test", amount: "1" });
* ```
*/
async perpDexTransfer(args, signal) {
const { ...actionArgs } = args;
return this._executeAction({
action: {
type: "PerpDexTransfer",
hyperliquidChain: this._getHyperliquidChain(),
signatureChainId: await this._getSignatureChainId(),
nonce: await this.nonceManager(),
...actionArgs,
},
}, signal);
}
/**
* Create a referral code.
* @param args - The parameters for the request.
* @param signal - An optional [AbortSignal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal).
* @returns Successful response without specific data.
*
* @throws {ApiRequestError} When the API returns an unsuccessful response.
* @throws {TransportError} When the transport layer throws an error.
*
* @see null
* @example
* ```ts
* import * as hl from "@nktkas/hyperliquid";
*
* const privateKey = "0x..."; // or `viem`, `ethers`
* const transport = new hl.HttpTransport(); // or `WebSocketTransport`
* const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
*
* await exchClient.registerReferrer({ code: "..." });
* ```
*/
registerReferrer(args, signal) {
const { ...actionArgs } = args;
return this._executeAction({
action: {
type: "registerReferrer",
...actionArgs,
},
}, signal);
}
/**
* Reserve additional rate-limited actions for a fee.
* @param args - The parameters for the request.
* @param signal - An optional [AbortSignal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal).
* @returns Successful response without specific data.
*
* @throws {ApiRequestError} When the API returns an unsuccessful response.
* @throws {TransportError} When the transport layer throws an error.
*
* @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#reserve-additional-actions
* @example
* ```ts
* import * as hl from "@nktkas/hyperliquid";
*
* const privateKey = "0x..."; // or `viem`, `ethers`
* const transport = new hl.HttpTransport(); // or `WebSocketTransport`
* const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
*
* await exchClient.reserveRequestWeight({ weight: 10 });
* ```
*/
async reserveRequestWeight(args, signal) {
const { expiresAfter, ...actionArgs } = args;
return this._executeAction({
action: {
type: "reserveRequestWeight",
...actionArgs,
},
expiresAfter: expiresAfter ?? await this._getDefaultExpiresAfter(),
}, signal);
}
async scheduleCancel(args_or_signal, maybeSignal) {
const args = args_or_signal instanceof AbortSignal ? {} : args_or_signal ?? {};
const signal = args_or_signal instanceof AbortSignal ? args_or_signal : maybeSignal;
const { vaultAddress, expiresAfter, ...actionArgs } = args;
return this._executeAction({
action: {
type: "scheduleCancel",
...actionArgs,
},
vaultAddress: vaultAddress ?? this.defaultVaultAddress,
expiresAfter: expiresAfter ?? await this._getDefaultExpiresAfter(),
}, signal);
}
/**
* Set the display name in the leaderboard.
* @param args - The parameters for the request.
* @param signal - An optional [AbortSignal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal).
* @returns Successful response without specific data.
*
* @throws {ApiRequestError} When the API returns an unsuccessful response.
* @throws {TransportError} When the transport layer throws an error.
*
* @see null
* @example
* ```ts
* import * as hl from "@nktkas/hyperliquid";
*
* const privateKey = "0x..."; // or `viem`, `ethers`
* const transport = new hl.HttpTransport(); // or `WebSocketTransport`
* const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
*
* await exchClient.setDisplayName({ displayName: "..." });
* ```
*/
setDisplayName(args, signal) {
const { ...actionArgs } = args;
return this._executeAction({
action: {
type: "setDisplayName",
...actionArgs,
},
}, signal);
}
/**
* Set a referral code.
* @param args - The parameters for the request.
* @param signal - An optional [AbortSignal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal).
* @returns Successful response without specific data.
*
* @throws {ApiRequestError} When the API returns an unsuccessful response.
* @throws {TransportError} When the transport layer throws an error.
*
* @see null
* @example
* ```ts
* import * as hl from "@nktkas/hyperliquid";
*
* const privateKey = "0x..."; // or `viem`, `ethers`
* const transport = new hl.HttpTransport(); // or `WebSocketTransport`
* const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
*
* await exchClient.setReferrer({ code: "..." });
* ```
*/
setReferrer(args, signal) {
const { ...actionArgs } = args;
return this._executeAction({
action: {
type: "setReferrer",
...actionArgs,
},
}, signal);
}
/**
* Deploying HIP-1 and HIP-2 assets.
* @param args - The parameters for the request.
* @param signal - An optional [AbortSignal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal).
* @returns Successful response without specific data.
*
* @throws {ApiRequestError} When the API returns an unsuccessful response.
* @throws {TransportError} When the transport layer throws an error.
*
* @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/deploying-hip-1-and-hip-2-assets
* @example
* ```ts
* import * as hl from "@nktkas/hyperliquid";
*
* const privateKey = "0x..."; // or `viem`, `ethers`
* const transport = new hl.HttpTransport(); // or `WebSocketTransport`
* const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
*
* await exchClient.spotDeploy({
* registerToken2: {
* spec: {
* name: "USDC",
* szDecimals: 8,
* weiDecimals: 8,
* },
* maxGas: 1000000,
* fullName: "USD Coin",
* },
* });
* ```
*/
spotDeploy(args, signal) {
const { ...actionArgs } = args;
return this._executeAction({
action: {
type: "spotDeploy",
...actionArgs,
},
}, signal);
}
/**
* Send spot assets to another address.
* @param args - The parameters for the request.
* @param signal - An optional [AbortSignal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal).
* @returns Successful response without specific data.
*
* @throws {ApiRequestError} When the API returns an unsuccessful response.
* @throws {TransportError} When the transport layer throws an error.
*
* @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#core-spot-transfer
* @example
* ```ts
* import * as hl from "@nktkas/hyperliquid";
*
* const privateKey = "0x..."; // or `viem`, `ethers`
* const transport = new hl.HttpTransport(); // or `WebSocketTransport`
* const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
*
* await exchClient.spotSend({
* destination: "0x...",
* token: "USDC:0xeb62eee3685fc4c43992febcd9e75443",
* amount: "1",
* });
* ```
*/
async spotSend(args, signal) {
const { ...actionArgs } = args;
return this._executeAction({
action: {
type: "spotSend",
hyperliquidChain: this._getHyperliquidChain(),
signatureChainId: await this._getSignatureChainId(),
time: await this.nonceManager(),
...actionArgs,
},
}, signal);
}
/**
* Modify a sub-account's.
* @param args - The parameters for the request.
* @param signal - An optional [AbortSignal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal).
* @returns Successful response without specific data.
*
* @throws {ApiRequestError} When the API returns an unsuccessful response.
* @throws {TransportError} When the transport layer throws an error.
*
* @see null
* @example
* ```ts
* import * as hl from "@nktkas/hyperliquid";
*
* const privateKey = "0x..."; // or `viem`, `ethers`
* const transport = new hl.HttpTransport(); // or `WebSocketTransport`
* const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
*
* await exchClient.subAccountModify({ subAccountUser: "0x...", name: "..." });
* ```
*/
subAccountModify(args, signal) {
const { ...actionArgs } = args;
return this._executeAction({
action: {
type: "subAccountModify",
...actionArgs,
},
}, signal);
}
/**
* Opt Out of Spot Dusting.
* @param args - The parameters for the request.
* @param signal - An optional [AbortSignal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal).
* @returns Successful response without specific data.
*
* @throws {ApiRequestError} When the API returns an unsuccessful response.
* @throws {TransportError} When the transport layer throws an error.
*
* @see null
* @example
* ```ts
* import * as hl from "@nktkas/hyperliquid";
*
* const privateKey = "0x..."; // or `viem`, `ethers`
* const transport = new hl.HttpTransport(); // or `WebSocketTransport`
* const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
*
* await exchClient.spotUser({ toggleSpotDusting: { optOut: false } });
* ```
*/
spotUser(args, signal) {
const { ...actionArgs } = args;
return this._executeAction({
action: {
type: "spotUser",
...actionArgs,
},
}, signal);
}
/**
* Transfer between sub-accounts (spot).
* @param args - The parameters for the request.
* @param signal - An optional [AbortSignal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal).
* @returns Successful response without specific data.
*
* @throws {ApiRequestError} When the API returns an unsuccessful response.
* @throws {TransportError} When the transport layer throws an error.
*
* @see null
* @example
* ```ts
* import * as hl from "@nktkas/hyperliquid";
*
* const privateKey = "0x..."; // or `viem`, `ethers`
* const transport = new hl.HttpTransport(); // or `WebSocketTransport`
* const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
*
* await exchClient.subAccountSpotTransfer({
* subAccountUser: "0x...",
* isDeposit: true,
* token: "USDC:0xeb62eee3685fc4c43992febcd9e75443",
* amount: "1",
* });
* ```
*/
subAccountSpotTransfer(args, signal) {
const { ...actionArgs } = args;
return this._executeAction({
action: {
type: "subAccountSpotTransfer",
...actionArgs,
},
}, signal);
}
/**
* Transfer between sub-accounts (perpetual).
* @param args - The parameters for the request.
* @param signal - An optional [AbortSignal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal).
* @returns Successful response without specific data.
*
* @throws {ApiRequestError} When the API returns an unsuccessful response.
* @throws {TransportError} When the transport layer throws an error.
*
* @see null
* @example
* ```ts
* import * as hl from "@nktkas/hyperliquid";
*
* const privateKey = "0x..."; // or `viem`, `ethers`
* const transport = new hl.HttpTransport(); // or `WebSocketTransport`
* const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
*
* await exchClient.subAccountTransfer({ subAccountUser: "0x...", isDeposit: true, usd: 1 * 1e6 });
* ```
*/
subAccountTransfer(args, signal) {
const { ...actionArgs } = args;
return this._executeAction({
action: {
type: "subAccountTransfer",
...actionArgs,
},
}, signal);
}
/**
* Delegate or undelegate native tokens to or from a validator.
* @param args - The parameters for the request.
* @param signal - An optional [AbortSignal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal).
* @returns Successful response without specific data.
*
* @throws {ApiRequestError} When the API returns an unsuccessful response.
* @throws {TransportError} When the transport layer throws an error.
*
* @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#delegate-or-undelegate-stake-from-validator
* @example
* ```ts
* import * as hl from "@nktkas/hyperliquid";
*
* const privateKey = "0x..."; // or `viem`, `ethers`
* const transport = new hl.HttpTransport(); // or `WebSocketTransport`
* const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
*
* await exchClient.tokenDelegate({ validator: "0x...", isUndelegate: true, wei: 1 * 1e8 });
* ```
*/
async tokenDelegate(args, signal) {
const { ...actionArgs } = args;
return this._executeAction({
action: {
type: "tokenDelegate",
hyperliquidChain: this._getHyperliquidChain(),
signatureChainId: await this._getSignatureChainId(),
nonce: await this.nonceManager(),
...actionArgs,
},
}, signal);
}
/**
* Cancel a TWAP order.
* @param args - The parameters for the request.
* @param signal - An optional [AbortSignal](https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal).
* @returns Successful variant of {@link TwapCancelResponse} without error status.
*
* @throws {ApiRequestError} When the API returns an unsuccessful response.
* @throws {TransportError} When the transport layer throws an error.
*
* @see https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/exchange-endpoint#cancel-a-twap-order
* @example
* ```ts
* import * as hl from "@nktkas/hyperliquid";
*
* const privateKey = "0x..."; // or `viem`, `ethers`
* const transport = new hl.HttpTransport(); // or `WebSocketTransport`
* const exchClient = new hl.ExchangeClient({ wallet: privateKey, transport });
*
* const data = await exchClient.twapCancel({ a: 0, t: 1 });
* ```
*/
async twapCancel(args, signal) {
const { vaultAddress, expiresAfter, ...actionArgs } = args;
return this._executeAction({
action: {
type: "twapCancel",
...actionArgs,
},