@nktkas/hyperliquid
Version:
Hyperliquid API SDK for all major JS runtimes, written in TypeScript.
134 lines (133 loc) • 4.65 kB
TypeScript
/**
* L1 (phantom-agent) signing for trading actions.
* @module
*/
/// <amd-module name="file:///home/runner/work/hyperliquid/hyperliquid/src/signing/_l1.ts" />
import { type AbstractWallet, type Signature } from "./_abstractWallet.js";
/**
* Creates a hash of the L1 action.
*
* @param args The action and metadata to hash.
* @return The keccak256 hash as a hex string.
*
* @example
* ```ts
* import { createL1ActionHash } from "@nktkas/hyperliquid/signing";
*
* const action = { type: "cancel", cancels: [{ a: 0, o: 12345 }] };
* const nonce = Date.now();
*
* const actionHash = createL1ActionHash({ action, nonce });
* ```
*/
export declare function createL1ActionHash(args: {
/** The action to be hashed (hash depends on key order). */
action: Record<string, unknown> | unknown[];
/** The current timestamp in ms. */
nonce: number;
/** Optional vault address used in the action. */
vaultAddress?: `0x${string}`;
/** Optional expiration time of the action in ms since the epoch. */
expiresAfter?: number;
}): `0x${string}`;
/**
* Signs an L1 action.
*
* @param args The wallet, action, and signing parameters.
* @return The ECDSA signature.
*
* @throws {AbstractWalletError} If signing fails.
*
* @example
* ```ts
* import { signL1Action } from "@nktkas/hyperliquid/signing";
* import { privateKeyToAccount } from "npm:viem/accounts";
*
* const wallet = privateKeyToAccount("0x..."); // `viem` or `ethers` or any `AbstractWallet`
*
* const action = { type: "cancel", cancels: [{ a: 0, o: 12345 }] };
* const nonce = Date.now();
*
* const signature = await signL1Action({ wallet, action, nonce });
* ```
*
* @example
* \- Full cycle of signing and sending an L1 action to the Hyperliquid API
* ```ts
* import { canonicalize, signL1Action } from "@nktkas/hyperliquid/signing";
* import { CancelRequest } from "@nktkas/hyperliquid/api/exchange";
* import { privateKeyToAccount } from "npm:viem/accounts";
*
* const wallet = privateKeyToAccount("0x..."); // `viem` or `ethers` or any `AbstractWallet`
*
* // For correct hashing, keys in the L1 action must be in
* // the same order as in the schema definition
* // ⌄⌄⌄⌄⌄⌄⌄⌄⌄
* const action = canonicalize(CancelRequest.entries.action, {
* type: "cancel",
* cancels: [{ a: 0, o: 12345 }],
* });
* const nonce = Date.now();
*
* const signature = await signL1Action({ wallet, action, nonce });
*
* // Send the signed action to the Hyperliquid API
* const response = await fetch("https://api.hyperliquid.xyz/exchange", {
* method: "POST",
* headers: { "Content-Type": "application/json" },
* body: JSON.stringify({ action, signature, nonce }),
* });
* const body = await response.json();
* ```
*/
export declare function signL1Action<TAction extends Record<string, unknown> | unknown[]>(args: {
/** Wallet to sign the action. */
wallet: AbstractWallet;
/** The action to be signed (hash depends on key order). */
action: TAction;
/** The current timestamp in ms. */
nonce: number;
/**
* Indicates if the action is for the testnet.
*
* Default: `false`
*/
isTestnet?: boolean;
/** Optional vault address used in the action. */
vaultAddress?: `0x${string}`;
/** Optional expiration time of the action in ms since the epoch. */
expiresAfter?: number;
}): Promise<Signature>;
/**
* Signs an inner per-signer contribution to a multi-sig L1 action.
*
* Signs `[multiSigUser, outerSigner, action]` with both addresses lowercased;
* the returned signature is trimmed for inclusion in the multi-sig wrapper.
*
* @param args The signer, action, and signing parameters.
* @return The trimmed ECDSA signature.
*
* @throws {AbstractWalletError} If signing fails.
*/
export declare function signL1Inner(args: {
/** Inner signer (one of the multi-sig authorized users). */
signer: AbstractWallet;
/** The action to be authorized. */
action: Record<string, unknown> | unknown[];
/** The multi-sig account address. */
multiSigUser: `0x${string}`;
/** The leader address (address of the wallet that signs the outer wrapper). */
outerSigner: `0x${string}`;
/** The current timestamp in ms. */
nonce: number;
/**
* Indicates if the action is for the testnet.
*
* Default: `false`
*/
isTestnet?: boolean;
/** Optional vault address used in the action. */
vaultAddress?: `0x${string}`;
/** Optional expiration time of the action in ms since the epoch. */
expiresAfter?: number;
}): Promise<Signature>;