@nktkas/hyperliquid
Version:
Unofficial Hyperliquid API SDK for all major JS runtimes, written in TypeScript and provided with tests
1,188 lines • 78.1 kB
JavaScript
(function (factory) {
if (typeof module === "object" && typeof module.exports === "object") {
var v = factory(require, exports);
if (v !== undefined) module.exports = v;
}
else if (typeof define === "function" && define.amd) {
define(["require", "exports", "../base.js", "../signing/mod.js"], factory);
}
})(function (require, exports) {
"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
* ```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 Private key via [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 wallet = privateKeyToAccount("0x...");
*
* const transport = new hl.HttpTransport(); // or `WebSocketTransport`
* const exchClient = new hl.ExchangeClient({ wallet, transport });
* ```
*
* @example Private key via [ethers.js](https://docs.ethers.org/v6/api/wallet/#Wallet) or [ethers.js v5](https://docs.ethers.org/v5/api/signer/#Wallet)
* ```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#optional-hoist-the-account)
* ```ts
* import * as hl from "@nktkas/hyperliquid";
* import { createWalletClient, custom } from "viem";
*
* const [account] = await window.ethereum.request({ method: "eth_requestAccounts" });
* const wallet = createWalletClient({ account, transport: custom(window.ethereum) });
*
* const transport = new hl.HttpTransport(); // or `WebSocketTransport`
* const exchClient = new hl.ExchangeClient({ wallet, transport });
* ```
*
* @example External wallet (e.g. MetaMask) via `window.ethereum` directly
* ```ts
* import * as hl from "@nktkas/hyperliquid";
*
* const transport = new hl.HttpTransport(); // or `WebSocketTransport`
* const exchClient = new hl.ExchangeClient({ wallet: window.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 abort signal
* @returns Successful response without specific data.
* @throws {ApiRequestError} When the API returns an error response.
*
* @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 });
*
* const data = await exchClient.approveAgent({ agentAddress: "0x...", agentName: "agentName" });
* ```
*/
async approveAgent(args, signal) {
// Destructure the parameters
const { ...actionArgs } = args;
// Construct an action
const nonce = await this.nonceManager();
const action = {
...actionArgs,
agentName: args.agentName ?? "",
type: "approveAgent",
hyperliquidChain: this._getHyperliquidChain(),
signatureChainId: await this._getSignatureChainId(),
nonce,
};
// Sign the action
const signature = await (0, mod_js_1.signUserSignedAction)({
wallet: this.wallet,
action,
types: mod_js_1.userSignedActionEip712Types[action.type],
chainId: parseInt(action.signatureChainId, 16),
});
if (action.agentName === "")
action.agentName = null;
// Send a request
return await this._request({ action, signature, nonce }, signal);
}
/**
* Approve a maximum fee rate for a builder.
* @param args - The parameters for the request.
* @param signal - An optional abort signal.
* @returns Successful response without specific data.
* @throws {ApiRequestError} When the API returns an error response.
*
* @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 });
*
* const data = await exchClient.approveBuilderFee({ maxFeeRate: "0.01%", builder: "0x..." });
* ```
*/
async approveBuilderFee(args, signal) {
// Destructure the parameters
const { ...actionArgs } = args;
// Construct an action
const nonce = await this.nonceManager();
const action = {
...actionArgs,
type: "approveBuilderFee",
hyperliquidChain: this._getHyperliquidChain(),
signatureChainId: await this._getSignatureChainId(),
nonce,
};
// Sign the action
const signature = await (0, mod_js_1.signUserSignedAction)({
wallet: this.wallet,
action,
types: mod_js_1.userSignedActionEip712Types[action.type],
chainId: parseInt(action.signatureChainId, 16),
});
// Send a request
return await this._request({ action, signature, nonce }, signal);
}
/**
* Modify multiple orders.
* @param args - The parameters for the request.
* @param signal - An optional abort signal.
* @returns Successful variant of {@link OrderResponse} without error statuses.
* @throws {ApiRequestError} When the API returns an error response.
*
* @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, // Asset index
* b: true, // Buy order
* p: "31000", // New price
* s: "0.2", // New size
* r: false, // Not reduce-only
* t: {
* limit: {
* tif: "Gtc", // Good-til-cancelled
* },
* },
* c: "0x...", // Client Order ID (optional)
* },
* }],
* });
* ```
*/
async batchModify(args, signal) {
// Destructure the parameters
const { vaultAddress = this.defaultVaultAddress, expiresAfter = await this._getDefaultExpiresAfter(), ...actionArgs } = args;
// Construct an action
const nonce = await this.nonceManager();
const action = {
type: "batchModify",
...actionArgs,
};
// Sign the action
const signature = await (0, mod_js_1.signL1Action)({
wallet: this.wallet,
action: mod_js_1.actionSorter[action.type](action),
nonce,
isTestnet: this.isTestnet,
vaultAddress,
expiresAfter,
});
// Send a request
return await this._request({ action, signature, nonce, vaultAddress, expiresAfter }, signal);
}
/**
* Cancel order(s).
* @param args - The parameters for the request.
* @param signal - An optional abort signal.
* @returns Successful variant of {@link CancelResponse} without error statuses.
* @throws {ApiRequestError} When the API returns an error response.
*
* @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, // Asset index
* o: 123, // Order ID
* }],
* });
* ```
*/
async cancel(args, signal) {
// Destructure the parameters
const { vaultAddress = this.defaultVaultAddress, expiresAfter = await this._getDefaultExpiresAfter(), ...actionArgs } = args;
// Construct an action
const nonce = await this.nonceManager();
const action = {
type: "cancel",
...actionArgs,
};
// Sign the action
const signature = await (0, mod_js_1.signL1Action)({
wallet: this.wallet,
action: mod_js_1.actionSorter[action.type](action),
nonce,
isTestnet: this.isTestnet,
vaultAddress,
expiresAfter,
});
// Send a request
return await this._request({ action, signature, nonce, vaultAddress, expiresAfter }, signal);
}
/**
* Cancel order(s) by cloid.
* @param args - The parameters for the request.
* @param signal - An optional abort signal.
* @returns Successful variant of {@link CancelResponse} without error statuses.
* @throws {ApiRequestError} When the API returns an error response.
*
* @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) {
// Destructure the parameters
const { vaultAddress = this.defaultVaultAddress, expiresAfter = await this._getDefaultExpiresAfter(), ...actionArgs } = args;
// Construct an action
const nonce = await this.nonceManager();
const action = {
type: "cancelByCloid",
...actionArgs,
};
// Sign the action
const signature = await (0, mod_js_1.signL1Action)({
wallet: this.wallet,
action: mod_js_1.actionSorter[action.type](action),
nonce,
isTestnet: this.isTestnet,
vaultAddress,
expiresAfter,
});
// Send a request
return await this._request({ action, signature, nonce, vaultAddress, expiresAfter }, 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 abort signal.
* @returns Successful response without specific data.
* @throws {ApiRequestError} When the API returns an error response.
*
* @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 });
*
* const data = await exchClient.cDeposit({ wei: 1 * 1e8 });
* ```
*/
async cDeposit(args, signal) {
// Destructure the parameters
const { ...actionArgs } = args;
// Construct an action
const nonce = await this.nonceManager();
const action = {
...actionArgs,
type: "cDeposit",
hyperliquidChain: this._getHyperliquidChain(),
signatureChainId: await this._getSignatureChainId(),
nonce,
};
// Sign the action
const signature = await (0, mod_js_1.signUserSignedAction)({
wallet: this.wallet,
action,
types: mod_js_1.userSignedActionEip712Types[action.type],
chainId: parseInt(action.signatureChainId, 16),
});
// Send a request
return await this._request({ action, signature, nonce }, signal);
}
/**
* Claim rewards from referral program.
* @param args - The parameters for the request.
* @param signal - An optional abort signal.
* @returns Successful response without specific data.
* @throws {ApiRequestError} When the API returns an error response.
*
* @see null - no documentation
* @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.claimRewards();
* ```
*/
async claimRewards(signal) {
// Construct an action
const nonce = await this.nonceManager();
const action = {
type: "claimRewards",
};
// Sign the action
const signature = await (0, mod_js_1.signL1Action)({
wallet: this.wallet,
action: mod_js_1.actionSorter[action.type](action),
nonce,
isTestnet: this.isTestnet,
});
// Send a request
return await this._request({ action, signature, nonce }, 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 abort signal.
* @returns Successful response without specific data.
* @throws {ApiRequestError} When the API returns an error response.
*
* @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 });
*
* const data = await exchClient.convertToMultiSigUser({ // convert to multi-sig user
* authorizedUsers: ["0x...", "0x...", "0x..."],
* threshold: 2,
* });
* ```
*/
async convertToMultiSigUser(args, signal) {
// Destructure the parameters
const actionArgs = args;
// Construct an action
const nonce = await this.nonceManager();
const action = {
type: "convertToMultiSigUser",
hyperliquidChain: this._getHyperliquidChain(),
signatureChainId: await this._getSignatureChainId(),
signers: JSON.stringify(actionArgs),
nonce,
};
// Sign the action
const signature = await (0, mod_js_1.signUserSignedAction)({
wallet: this.wallet,
action,
types: mod_js_1.userSignedActionEip712Types[action.type],
chainId: parseInt(action.signatureChainId, 16),
});
// Send a request
return await this._request({ action, signature, nonce }, signal);
}
/**
* Create a sub-account.
* @param args - The parameters for the request.
* @param signal - An optional abort signal.
* @returns Response for creating a sub-account.
* @throws {ApiRequestError} When the API returns an error response.
*
* @see null - no documentation
* @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: "subAccountName" });
* ```
*/
async createSubAccount(args, signal) {
// Destructure the parameters
const { ...actionArgs } = args;
// Construct an action
const nonce = await this.nonceManager();
const action = {
type: "createSubAccount",
...actionArgs,
};
// Sign the action
const signature = await (0, mod_js_1.signL1Action)({
wallet: this.wallet,
action: mod_js_1.actionSorter[action.type](action),
nonce,
isTestnet: this.isTestnet,
});
// Send a request
return await this._request({ action, signature, nonce }, signal);
}
/**
* Create a vault.
* @param args - The parameters for the request.
* @param signal - An optional abort signal.
* @returns Response for creating a vault.
* @throws {ApiRequestError} When the API returns an error response.
*
* @see null - no documentation
* @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: "VaultName",
* description: "Vault description",
* initialUsd: 100 * 1e6,
* });
* ```
*/
async createVault(args, signal) {
// Destructure the parameters
const { ...actionArgs } = args;
// Construct an action
const nonce = await this.nonceManager();
const action = {
type: "createVault",
nonce,
...actionArgs,
};
// Sign the action
const signature = await (0, mod_js_1.signL1Action)({
wallet: this.wallet,
action: mod_js_1.actionSorter[action.type](action),
nonce,
isTestnet: this.isTestnet,
});
// Send a request
return await this._request({ action, signature, nonce }, signal);
}
async cSignerAction(args, signal) {
// Destructure the parameters
const { expiresAfter = await this._getDefaultExpiresAfter(), ...actionArgs } = args;
// Construct an action
const nonce = await this.nonceManager();
const action = {
type: "CSignerAction",
...actionArgs,
};
// Sign the action
const signature = await (0, mod_js_1.signL1Action)({
wallet: this.wallet,
action: mod_js_1.actionSorter[action.type](action),
nonce,
isTestnet: this.isTestnet,
expiresAfter,
});
// Send a request
return await this._request({ action, signature, nonce, expiresAfter }, signal);
}
async cValidatorAction(args, signal) {
// Destructure the parameters
const { expiresAfter = await this._getDefaultExpiresAfter(), ...actionArgs } = args;
// Construct an action
const nonce = await this.nonceManager();
const action = {
type: "CValidatorAction",
...actionArgs,
};
// Sign the action
const signature = await (0, mod_js_1.signL1Action)({
wallet: this.wallet,
action: mod_js_1.actionSorter[action.type](action),
nonce,
isTestnet: this.isTestnet,
expiresAfter,
});
// Send a request
return await this._request({ action, signature, nonce, expiresAfter }, signal);
}
/**
* Transfer native token from staking into the user's spot account.
* @param args - The parameters for the request.
* @param signal - An optional abort signal.
* @returns Successful response without specific data.
* @throws {ApiRequestError} When the API returns an error response.
*
* @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 });
*
* const data = await exchClient.cWithdraw({ wei: 1 * 1e8 });
* ```
*/
async cWithdraw(args, signal) {
// Destructure the parameters
const { ...actionArgs } = args;
// Construct an action
const nonce = await this.nonceManager();
const action = {
...actionArgs,
type: "cWithdraw",
hyperliquidChain: this._getHyperliquidChain(),
signatureChainId: await this._getSignatureChainId(),
nonce,
};
// Sign the action
const signature = await (0, mod_js_1.signUserSignedAction)({
wallet: this.wallet,
action,
types: mod_js_1.userSignedActionEip712Types[action.type],
chainId: parseInt(action.signatureChainId, 16),
});
// Send a request
return await this._request({ action, signature, nonce }, signal);
}
/**
* Configure block type for EVM transactions.
* @param args - The parameters for the request.
* @param signal - An optional abort signal.
* @returns Response for creating a sub-account.
* @throws {ApiRequestError} When the API returns an error response.
*
* @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 });
* ```
*/
async evmUserModify(args, signal) {
// Destructure the parameters
const { ...actionArgs } = args;
// Construct an action
const nonce = await this.nonceManager();
const action = {
type: "evmUserModify",
...actionArgs,
};
// Sign the action
const signature = await (0, mod_js_1.signL1Action)({
wallet: this.wallet,
action: mod_js_1.actionSorter[action.type](action),
nonce,
isTestnet: this.isTestnet,
});
// Send a request
return await this._request({ action, signature, nonce }, signal);
}
/**
* Modify an order.
* @param args - The parameters for the request.
* @param signal - An optional abort signal.
* @returns Successful response without specific data.
* @throws {ApiRequestError} When the API returns an error response.
*
* @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 });
*
* const data = await exchClient.modify({
* oid: 123,
* order: {
* a: 0, // Asset index
* b: true, // Buy order
* p: "31000", // New price
* s: "0.2", // New size
* r: false, // Not reduce-only
* t: {
* limit: {
* tif: "Gtc", // Good-til-cancelled
* },
* },
* c: "0x...", // Client Order ID (optional)
* },
* });
* ```
*/
async modify(args, signal) {
// Destructure the parameters
const { vaultAddress = this.defaultVaultAddress, expiresAfter = await this._getDefaultExpiresAfter(), ...actionArgs } = args;
// Construct an action
const nonce = await this.nonceManager();
const action = {
type: "modify",
...actionArgs,
};
// Sign the action
const signature = await (0, mod_js_1.signL1Action)({
wallet: this.wallet,
action: mod_js_1.actionSorter[action.type](action),
nonce,
isTestnet: this.isTestnet,
vaultAddress,
expiresAfter,
});
// Send a request
return await this._request({ action, signature, nonce, vaultAddress, expiresAfter }, signal);
}
/**
* A multi-signature request.
* @param args - The parameters for the request.
* @param signal - An optional abort signal.
* @returns Successful response without specific data.
* @throws {ApiRequestError} When the API returns an error response.
*
* @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 });
*
* const multiSigUser = "0x..."; // Multi-sig user address
*
* const nonce = Date.now();
* const action = { type: "scheduleCancel", time: Date.now() + 10000 };
*
* const signature = await hl.signL1Action({
* wallet,
* action: [multiSigUser.toLowerCase(), signer1.address.toLowerCase(), action],
* nonce,
* isTestnet: true,
* });
*
* const data = await exchClient.multiSig({
* signatures: [signature],
* payload: {
* multiSigUser,
* outerSigner: wallet.address,
* action,
* },
* nonce,
* });
* ```
*/
async multiSig(args, signal) {
// Destructure the parameters
const { vaultAddress = this.defaultVaultAddress, expiresAfter = await this._getDefaultExpiresAfter(), nonce, ...actionArgs } = args;
// Construct an action
const action = {
type: "multiSig",
signatureChainId: await this._getSignatureChainId(),
...actionArgs,
};
// Sign the action
const actionForMultiSig = mod_js_1.actionSorter[action.type](action);
delete actionForMultiSig.type;
const signature = await (0, mod_js_1.signMultiSigAction)({
wallet: this.wallet,
action: actionForMultiSig,
nonce,
vaultAddress,
expiresAfter,
hyperliquidChain: this._getHyperliquidChain(),
signatureChainId: action.signatureChainId,
});
// Send a request
return await this._request({ action, signature, nonce, vaultAddress, expiresAfter }, signal);
}
/**
* Place an order(s).
* @param args - The parameters for the request.
* @param signal - An optional abort signal.
* @returns Successful variant of {@link OrderResponse} without error statuses.
* @throws {ApiRequestError} When the API returns an error response.
*
* @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, // Asset index
* b: true, // Buy order
* p: "30000", // Price
* s: "0.1", // Size
* r: false, // Not reduce-only
* t: {
* limit: {
* tif: "Gtc", // Good-til-cancelled
* },
* },
* c: "0x...", // Client Order ID (optional)
* }],
* grouping: "na", // No grouping
* });
* ```
*/
async order(args, signal) {
// Destructure the parameters
const { vaultAddress = this.defaultVaultAddress, expiresAfter = await this._getDefaultExpiresAfter(), ...actionArgs } = args;
// Construct an action
const nonce = await this.nonceManager();
const action = {
type: "order",
...actionArgs,
};
// Sign the action
const signature = await (0, mod_js_1.signL1Action)({
wallet: this.wallet,
action: mod_js_1.actionSorter[action.type](action),
nonce,
isTestnet: this.isTestnet,
vaultAddress,
expiresAfter,
});
// Send a request
return await this._request({ action, signature, nonce, vaultAddress, expiresAfter }, signal);
}
async perpDeploy(args, signal) {
// Destructure the parameters
const { ...actionArgs } = args;
// Construct an action
const nonce = await this.nonceManager();
const action = {
type: "perpDeploy",
...actionArgs,
};
// Sign the action
const signature = await (0, mod_js_1.signL1Action)({
wallet: this.wallet,
action: mod_js_1.actionSorter[action.type](action),
nonce,
isTestnet: this.isTestnet,
});
// Send a request
return await this._request({ action, signature, nonce }, signal);
}
/**
* Transfer funds between Spot account and Perp dex account.
* @param args - The parameters for the request.
* @param signal - An optional abort signal.
* @returns Successful response without specific data.
* @throws {ApiRequestError} When the API returns an error response.
*
* @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 });
*
* const data = await exchClient.perpDexClassTransfer({
* dex: "test",
* token: "USDC",
* amount: "1",
* toPerp: true,
* });
* ```
*/
async perpDexClassTransfer(args, signal) {
// Destructure the parameters
const { ...actionArgs } = args;
// Construct an action
const nonce = await this.nonceManager();
const action = {
...actionArgs,
type: "PerpDexClassTransfer",
hyperliquidChain: this._getHyperliquidChain(),
signatureChainId: await this._getSignatureChainId(),
nonce,
};
// Sign the action
const signature = await (0, mod_js_1.signUserSignedAction)({
wallet: this.wallet,
action,
types: mod_js_1.userSignedActionEip712Types[action.type],
chainId: parseInt(action.signatureChainId, 16),
});
// Send a request
return await this._request({ action, signature, nonce }, signal);
}
/**
* Create a referral code.
* @param args - The parameters for the request.
* @param signal - An optional abort signal.
* @returns Successful response without specific data.
* @throws {ApiRequestError} When the API returns an error response.
*
* @see null - no documentation
* @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.registerReferrer({ code: "TEST" });
* ```
*/
async registerReferrer(args, signal) {
// Destructure the parameters
const { ...actionArgs } = args;
// Construct an action
const nonce = await this.nonceManager();
const action = {
type: "registerReferrer",
...actionArgs,
};
// Sign the action
const signature = await (0, mod_js_1.signL1Action)({
wallet: this.wallet,
action: mod_js_1.actionSorter[action.type](action),
nonce,
isTestnet: this.isTestnet,
});
// Send a request
return await this._request({ action, signature, nonce }, signal);
}
/**
* Reserve additional rate-limited actions for a fee.
* @param args - The parameters for the request.
* @param signal - An optional abort signal.
* @returns Successful response without specific data.
* @throws {ApiRequestError} When the API returns an error response.
*
* @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 });
*
* const data = await exchClient.reserveRequestWeight({ weight: 10 });
* ```
*/
async reserveRequestWeight(args, signal) {
// Destructure the parameters
const { expiresAfter = await this._getDefaultExpiresAfter(), ...actionArgs } = args;
// Construct an action
const nonce = await this.nonceManager();
const action = {
type: "reserveRequestWeight",
...actionArgs,
};
// Sign the action
const signature = await (0, mod_js_1.signL1Action)({
wallet: this.wallet,
action: mod_js_1.actionSorter[action.type](action),
nonce,
isTestnet: this.isTestnet,
expiresAfter,
});
// Send a request
return await this._request({ action, signature, nonce, expiresAfter }, 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;
// Destructure the parameters
const { vaultAddress = this.defaultVaultAddress, expiresAfter = await this._getDefaultExpiresAfter(), ...actionArgs } = args;
// Construct an action
const nonce = await this.nonceManager();
const action = {
type: "scheduleCancel",
...actionArgs,
};
// Sign the action
const signature = await (0, mod_js_1.signL1Action)({
wallet: this.wallet,
action: mod_js_1.actionSorter[action.type](action),
nonce,
isTestnet: this.isTestnet,
vaultAddress,
expiresAfter,
});
// Send a request
return await this._request({ action, signature, nonce, vaultAddress, expiresAfter }, signal);
}
/**
* Set the display name in the leaderboard.
* @param args - The parameters for the request.
* @param signal - An optional abort signal.
* @returns Successful response without specific data.
* @throws {ApiRequestError} When the API returns an error response.
*
* @see null - no documentation
* @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.setDisplayName({ displayName: "My Name" });
* ```
*/
async setDisplayName(args, signal) {
// Destructure the parameters
const { ...actionArgs } = args;
// Construct an action
const nonce = await this.nonceManager();
const action = {
type: "setDisplayName",
...actionArgs,
};
// Sign the action
const signature = await (0, mod_js_1.signL1Action)({
wallet: this.wallet,
action: mod_js_1.actionSorter[action.type](action),
nonce,
isTestnet: this.isTestnet,
});
// Send a request
return await this._request({ action, signature, nonce }, signal);
}
/**
* Set a referral code.
* @param args - The parameters for the request.
* @param signal - An optional abort signal.
* @returns Successful response without specific data.
* @throws {ApiRequestError} When the API returns an error response.
*
* @see null - no documentation
* @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.setReferrer({ code: "TEST" });
* ```
*/
async setReferrer(args, signal) {
// Destructure the parameters
const { ...actionArgs } = args;
// Construct an action
const nonce = await this.nonceManager();
const action = {
type: "setReferrer",
...actionArgs,
};
// Sign the action
const signature = await (0, mod_js_1.signL1Action)({
wallet: this.wallet,
action: mod_js_1.actionSorter[action.type](action),
nonce,
isTestnet: this.isTestnet,
});
// Send a request
return await this._request({ action, signature, nonce }, signal);
}
async spotDeploy(args, signal) {
// Destructure the parameters
const { ...actionArgs } = args;
// Construct an action
const nonce = await this.nonceManager();
const action = {
type: "spotDeploy",
...actionArgs,
};
// Sign the action
const signature = await (0, mod_js_1.signL1Action)({
wallet: this.wallet,
action: mod_js_1.actionSorter[action.type](action),
nonce,
isTestnet: this.isTestnet,
});
// Send a request
return await this._request({ action, signature, nonce }, signal);
}
/**
* Send spot assets to another address.
* @param args - The parameters for the request.
* @param signal - An optional abort signal.
* @returns Successful response without specific data.
* @throws {ApiRequestError} When the API returns an error response.
*
* @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 });
*
* const data = await exchClient.spotSend({
* destination: "0x...",
* token: "USDC:0xeb62eee3685fc4c43992febcd9e75443",
* amount: "1",
* });
* ```
*/
async spotSend(args, signal) {
// Destructure the parameters
const { ...actionArgs } = args;
// Construct an action
const nonce = await this.nonceManager();
const action = {
...actionArgs,
type: "spotSend",
hyperliquidChain: this._getHyperliquidChain(),
signatureChainId: await this._getSignatureChainId(),
time: nonce,
};
// Sign the action
const signature = await (0, mod_js_1.signUserSignedAction)({
wallet: this.wallet,
action,
types: mod_js_1.userSignedActionEip712Types[action.type],
chainId: parseInt(action.signatureChainId, 16),
});
// Send a request
return await this._request({ action, signature, nonce }, signal);
}
/**
* Opt Out of Spot Dusting.
* @param args - The parameters for the request.
* @param signal - An optional abort signal.
* @returns Successful response without specific data.
* @throws {ApiRequestError} When the API returns an error response.
*
* @see null - no documentation
* @example
* ```ts
* import * as hl from "@nktkas/hyperliquid";
*
* const privateKe