UNPKG

@nktkas/hyperliquid

Version:

Unofficial Hyperliquid API SDK for all major JS runtimes, written in TypeScript and provided with tests

251 lines 8.22 kB
/** * This module contains functions for generating Hyperliquid transaction signatures * and interfaces to various wallet implementations. * * @example * ```ts * import { signL1Action } from "@nktkas/hyperliquid/signing"; * * const action = { * type: "cancel", * cancels: [{ a: 0, o: 12345 }], * }; * const nonce = Date.now(); * * const signature = await signL1Action({ * wallet, * action, * nonce, * isTestnet: true, // Change to false for mainnet * }); * ``` * @example * ```ts * import { signUserSignedAction } from "@nktkas/hyperliquid/signing"; * * const action = { * type: "approveAgent", * hyperliquidChain: "Testnet", // "Mainnet" or "Testnet" * signatureChainId: "0x66eee", * nonce: Date.now(), * agentAddress: "0x...", * agentName: "Agent", * }; * * const signature = await signUserSignedAction({ * wallet, * action, * types: { * "HyperliquidTransaction:ApproveAgent": [ * { name: "hyperliquidChain", type: "string" }, * { name: "agentAddress", type: "address" }, * { name: "agentName", type: "string" }, * { name: "nonce", type: "uint64" }, * ], * }, * chainId: parseInt(action.signatureChainId, 16), * }); * ``` * * @module */ import { type ValueMap, type ValueType } from "../../deps/jsr.io/@std/msgpack/1.0.3/encode.js"; import { type AbstractEthersSigner, type AbstractEthersV5Signer, isAbstractEthersSigner, isAbstractEthersV5Signer } from "./_ethers.js"; import { isValidPrivateKey } from "./_private_key.js"; import { type AbstractViemWalletClient, isAbstractViemWalletClient } from "./_viem.js"; import { type AbstractWindowEthereum, isAbstractWindowEthereum } from "./_window.js"; import type { Hex } from "../base.js"; export { type AbstractEthersSigner, type AbstractEthersV5Signer, type AbstractViemWalletClient, type AbstractWindowEthereum, type Hex, isAbstractEthersSigner, isAbstractEthersV5Signer, isAbstractViemWalletClient, isAbstractWindowEthereum, isValidPrivateKey, type ValueMap, type ValueType, }; export * from "./_sorter.js"; /** Abstract interface for a wallet that can sign typed data. */ export type AbstractWallet = Hex | AbstractViemWalletClient | AbstractEthersSigner | AbstractEthersV5Signer | AbstractWindowEthereum; export interface Signature { r: Hex; s: Hex; v: number; } /** * Create a hash of the L1 action. * * Note: Hash generation depends on the order of the action keys. * * @param action - The action to be hashed. * @param nonce - Unique request identifier (recommended current timestamp in ms). * @param vaultAddress - Optional vault address used in the action. * @param expiresAfter - Optional expiration time of the action in milliseconds since the epoch. * @returns The hash of the action. */ export declare function createL1ActionHash(action: ValueType, nonce: number, vaultAddress?: Hex, expiresAfter?: number): Hex; /** * Sign an L1 action. * * Note: Signature generation depends on the order of the action keys. * @param args - Arguments for signing the action. * @returns The signature components r, s, and v. * @example * ```ts * import { signL1Action } from "@nktkas/hyperliquid/signing"; * * const privateKey = "0x..."; // or `viem`, `ethers` * * const action = { * type: "cancel", * cancels: [ * { a: 0, o: 12345 }, // Asset index and order ID * ], * }; * const nonce = Date.now(); * * const signature = await signL1Action({ * wallet: privateKey, * action, * nonce, * isTestnet: true, // Change to false for mainnet * }); * * const response = await fetch("https://api.hyperliquid-testnet.xyz/exchange", { * method: "POST", * headers: { "Content-Type": "application/json" }, * body: JSON.stringify({ action, signature, nonce }), * }); * const body = await response.json(); * ``` */ export declare function signL1Action(args: { /** Wallet to sign the action. */ wallet: AbstractWallet; /** The action to be signed. */ action: ValueType; /** Unique request identifier (recommended current timestamp in ms). */ nonce: number; /** Indicates if the action is for the testnet. Default is `false`. */ isTestnet?: boolean; /** Optional vault address used in the action. */ vaultAddress?: Hex; /** Optional expiration time of the action in milliseconds since the epoch. */ expiresAfter?: number; }): Promise<Signature>; /** * Sign a user-signed action. * * Note: Signature generation depends on the order of types. * * @param args - Arguments for signing the action. * @returns The signature components r, s, and v. * @example * ```ts * import { signUserSignedAction } from "@nktkas/hyperliquid/signing"; * * const privateKey = "0x..."; // or `viem`, `ethers` * * const action = { * type: "approveAgent", * hyperliquidChain: "Testnet", // "Mainnet" or "Testnet" * signatureChainId: "0x66eee", * nonce: Date.now(), * agentAddress: "0x...", // Change to your agent address * agentName: "Agent", * }; * * const signature = await signUserSignedAction({ * wallet: privateKey, * action, * types: { * "HyperliquidTransaction:ApproveAgent": [ * { name: "hyperliquidChain", type: "string" }, * { name: "agentAddress", type: "address" }, * { name: "agentName", type: "string" }, * { name: "nonce", type: "uint64" }, * ], * }, * chainId: parseInt(action.signatureChainId, 16), * }); * * const response = await fetch("https://api.hyperliquid-testnet.xyz/exchange", { * method: "POST", * headers: { "Content-Type": "application/json" }, * body: JSON.stringify({ action, signature, nonce: action.nonce }), * }); * const body = await response.json(); * ``` */ export declare function signUserSignedAction(args: { /** Wallet to sign the action. */ wallet: AbstractWallet; /** The action to be signed. */ action: Record<string, unknown>; /** The types of the action. */ types: { [key: string]: { name: string; type: string; }[]; }; /** The chain ID. */ chainId: number; }): Promise<Signature>; /** * Sign a multi-signature action. * * Note: Signature generation depends on the order of the action keys. * * @param args - Arguments for signing the action. * @returns The signature components r, s, and v. * @example * ```ts * import { signL1Action, signMultiSigAction } from "@nktkas/hyperliquid/signing"; * import { privateKeyToAccount } from "viem/accounts"; * * const wallet = privateKeyToAccount("0x..."); * const multiSigUser = "0x..."; // Multi-sig user address * * const nonce = Date.now(); * const action = { // Example action * type: "scheduleCancel", * time: Date.now() + 10000 * }; * * // First, create signature from one of the authorized signers * const signature = await signL1Action({ * wallet, * action: [multiSigUser.toLowerCase(), wallet.address.toLowerCase(), action], * nonce, * isTestnet: true, * }); * * // Then use it in the multi-sig action * const multiSigSignature = await signMultiSigAction({ * wallet, * action: { * type: "multiSig", * signatureChainId: "0x66eee", * signatures: [signature], * payload: { * multiSigUser, * outerSigner: wallet.address, * action, * } * }, * nonce, * hyperliquidChain: "Testnet", * signatureChainId: "0x66eee", * }); * ``` */ export declare function signMultiSigAction(args: { /** Wallet to sign the action. */ wallet: AbstractWallet; /** The action to be signed. */ action: ValueMap; /** Unique request identifier (recommended current timestamp in ms). */ nonce: number; /** Optional vault address used in the action. */ vaultAddress?: Hex; /** Optional expiration time of the action in milliseconds since the epoch. */ expiresAfter?: number; /** HyperLiquid network ("Mainnet" or "Testnet"). */ hyperliquidChain: "Mainnet" | "Testnet"; /** Chain ID used for signing. */ signatureChainId: Hex; }): Promise<Signature>; //# sourceMappingURL=mod.d.ts.map