View Source Hyperliquid.Api.Exchange.KeyUtils (hyperliquid v0.4.1)

Shared utilities for resolving private keys and validating addresses in exchange modules.

Private Key Resolution

All exchange modules accept an optional :private_key in their opts keyword list. When not provided, the key is resolved from Hyperliquid.Config.secret(). If neither is available, a clear error is raised.

Address Validation (Sensitive Actions)

Transfer and withdrawal actions (UsdSend, Withdraw3, SpotSend, SendAsset, ApproveAgent, ApproveBuilderFee) accept an optional :expected_address in opts. When provided, Signer.derive_address/1 is used to verify the private key matches the expected address, preventing accidental use of an agent sub-key for actions that require the real private key.

Breaking Change (v0.2.0)

private_key was previously the first positional argument in all exchange module functions. It is now an option in the opts keyword list (:private_key).

Summary

Functions

Resolves private key and validates expected address for sensitive actions.

Resolves the private key from opts or application config.

Signs EIP-712 typed data and returns the signature components.

Validates that the private key derives to the expected address.

Functions

Link to this function

resolve_and_validate!(opts)

View Source
@spec resolve_and_validate!(keyword()) :: String.t()

Resolves private key and validates expected address for sensitive actions.

Combines resolve_private_key!/1 and validate_expected_address!/2. Use this for transfer/withdrawal modules (UsdSend, Withdraw3, SpotSend, SendAsset, ApproveAgent, ApproveBuilderFee).

Link to this function

resolve_private_key!(opts)

View Source
@spec resolve_private_key!(keyword()) :: String.t()

Resolves the private key from opts or application config.

Options

  • :private_key - Explicit private key (hex string). Falls back to Config.secret().

Raises ArgumentError if no key is available.

Link to this function

sign_typed_data(private_key, domain_json, types_json, message_json, primary_type)

View Source
@spec sign_typed_data(String.t(), String.t(), String.t(), String.t(), String.t()) ::
  {:ok, map()} | {:error, {:signing_error, term()}}

Signs EIP-712 typed data and returns the signature components.

Wraps Signer.sign_typed_data/5 with proper error handling, matching the pattern used by L1 action modules.

Returns

  • {:ok, %{r: r, s: s, v: v}} on success
  • {:error, {:signing_error, term()}} on failure
Link to this function

validate_expected_address!(private_key, opts)

View Source
@spec validate_expected_address!(
  String.t(),
  keyword()
) :: :ok

Validates that the private key derives to the expected address.

Only performs validation when :expected_address is present in opts. Raises ArgumentError on mismatch.

Options

  • :expected_address - Expected checksummed Ethereum address (0x-prefixed)