UNPKG

@nktkas/hyperliquid

Version:

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

121 lines (120 loc) 3.91 kB
/** * User-signed ([EIP-712](https://eips.ethereum.org/EIPS/eip-712)) signing for fund and account actions. * @module */ import { signTypedData } from "./_abstractWallet.js"; import { trimSignature } from "./_multiSig.js"; /** * Signs a user-signed action. * * @param args The wallet, action, and EIP-712 types. * @return The ECDSA signature. * * @throws {AbstractWalletError} If signing fails. * * @example * ```ts * import { signUserSignedAction } from "@nktkas/hyperliquid/signing"; * import { ApproveAgentTypes } from "@nktkas/hyperliquid/api/exchange"; * import { privateKeyToAccount } from "npm:viem/accounts"; * * const wallet = privateKeyToAccount("0x..."); // `viem` or `ethers` or any `AbstractWallet` * * const types = ApproveAgentTypes; // or custom EIP-712 types matching the action * const action = { * type: "approveAgent", * signatureChainId: "0x66eee" as const, * hyperliquidChain: "Mainnet", * agentAddress: "0x...", * agentName: "Agent", * nonce: Date.now(), * }; * * const signature = await signUserSignedAction({ wallet, action, types }); * ``` * * @example * \- Full cycle of signing and sending a user-signed action to the Hyperliquid API * ```ts * import { signUserSignedAction } from "@nktkas/hyperliquid/signing"; * import { ApproveAgentTypes } from "@nktkas/hyperliquid/api/exchange"; * import { privateKeyToAccount } from "npm:viem/accounts"; * * const wallet = privateKeyToAccount("0x..."); // `viem` or `ethers` or any `AbstractWallet` * * const types = ApproveAgentTypes; // or custom EIP-712 types matching the action * const action = { * type: "approveAgent", * signatureChainId: "0x66eee" as const, * hyperliquidChain: "Mainnet", * agentAddress: "0x...", * agentName: "Agent", * nonce: Date.now(), * }; * * const signature = await signUserSignedAction({ wallet, action, types }); * * // 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: action.nonce }), * }); * const body = await response.json(); * ``` */ export async function signUserSignedAction(args) { const { wallet, action, types } = args; return await signTypedData({ wallet, domain: { name: "HyperliquidSignTransaction", version: "1", chainId: parseInt(action.signatureChainId), verifyingContract: "0x0000000000000000000000000000000000000000" }, types, primaryType: Object.keys(types)[0], message: action }); } /** * Signs an inner per-signer contribution to a multi-sig user-signed action. * * Signs the action with `payloadMultiSigUser` and `outerSigner` fields injected * (using a type extended after its first field); the returned signature is * trimmed for inclusion in the multi-sig wrapper. * * @param args The signer, action, types, and signing parameters. * @return The trimmed ECDSA signature. * * @throws {AbstractWalletError} If signing fails. */ export async function signUserSignedInner(args) { // Inject fields for multi-sig const primaryType = Object.keys(args.types)[0]; const primaryTypeFields = args.types[primaryType]; const extendedTypes = { ...args.types, [primaryType]: [ primaryTypeFields[0], { name: "payloadMultiSigUser", type: "address" }, { name: "outerSigner", type: "address" }, ...primaryTypeFields.slice(1) ] }; const signature = await signUserSignedAction({ wallet: args.signer, action: { payloadMultiSigUser: args.multiSigUser.toLowerCase(), outerSigner: args.outerSigner.toLowerCase(), ...args.action }, types: extendedTypes }); return trimSignature(signature); } //# sourceMappingURL=_userSigned.js.map