UNPKG

@nktkas/hyperliquid

Version:

Hyperliquid API SDK for all major JS runtimes, written in TypeScript.

41 lines (40 loc) 1.86 kB
/** * Common execution shell shared by L1 and user-signed Exchange API actions. * @module */ import { getWalletAddress } from "../../../../signing/mod.js"; import { assertSuccessResponse } from "./errors.js"; import { globalNonceManager } from "./_nonce.js"; import { withLock } from "./_semaphore.js"; /** * Common shell for executing an Exchange API request: * acquires per-`(walletAddress × isTestnet)` lock, generates nonce, calls `build` to construct * the signed payload, sends to the Exchange endpoint, and validates the response. * * @param config Exchange API configuration. * @param build Callback that, given the nonce, returns the action, signature, and any extras. * @param signal Optional {@link AbortSignal} to cancel the request. * @return The validated API response. * * @throws {ApiRequestError} If the API returns an error response. */ export async function executeWithShell(config, build, signal) { const leader = "wallet" in config ? config.wallet : config.signers[0]; const walletAddress = await getWalletAddress(leader); // Lock per (wallet × testnet) ensures requests arrive at the server in nonce order. const key = `${walletAddress}:${config.transport.isTestnet}`; return await withLock(key, async ()=>{ // --- Generate nonce -------------------------------------- const nonce = await (config.nonceManager?.(walletAddress) ?? globalNonceManager.getNonce(key)); // --- Build signed payload -------------------------------- const { action, signature, extras } = await build(nonce); // --- Send and validate ----------------------------------- const response = await config.transport.request("exchange", { action, signature, nonce, ...extras }, signal); assertSuccessResponse(response); return response; }); } //# sourceMappingURL=_shell.js.map