Hyperliquid SDK

repository·main·Indexed 43 days ago

https://github.com/quiknode-labs/hyperliquid-sdk

A collection of community-maintained SDKs by QuickNode for trading on the Hyperliquid protocol. It provides high-level abstractions for order placement, position management, and prediction market trading across Python, TypeScript, Rust, and Go, including support for Info, HyperCore, and EVM interfaces.

Tokens
71.2K
Snippets
208
Records
282
Agent score
50%

What's inside Hyperliquid SDK

  1. Core SDK Features

    main

    The Hyperliquid SDKs provide the following capabilities across all supported languages:

    • One-line orders: Simplified order placement without manual build-sign-send steps.
    • Flexible Sizing: Specify order size in asset units or USD (notional).
    • Order Priority: Set Hyperliquid priorityFee (requires funding via cDeposit).
    • HIP-4 & HIP-3 Support: Discovery-based trading for prediction markets and standard API support for HIP-3 markets.
    • Order & Position Management: Modify, cancel, and track orders, or close positions with a single call.
    • Error Handling: Actionable error messages with guidance.
  2. Use external signing (KMS/HSM/remote signer)

    main

    For enhanced security, you can keep the private key outside the SDK process by providing a signing callback via hyperliquid.WithSigner. This allows you to sign the build hash using a KMS, HSM, or remote signer.

    When using a signer, builder-fee auto-approval is skipped; you must call sdk.ApproveBuilderFee("1%") once per agent. If signing fails, the error can be detected using hyperliquid.IsSignerError(err).

    sdk, _ := hyperliquid.New(endpoint,
    	hyperliquid.WithSigner(func(ctx context.Context, hashHex string) (*hyperliquid.Signature, error) {
    		// sign hashHex with your KMS/HSM/remote signer, return r, s, v (v in {27, 28}).
    		// ctx is bounded by the SDK Timeout; honour it for cancellation.
    	}),
    	hyperliquid.WithSignerAddress("0xYOUR_AGENT_ADDRESS"), // acting agent address
    )
    
    // Required if using a signer
    sdk.ApproveBuilderFee("1%")
  3. Configure endpoint flexibility in the Rust SDK

    main

    The SDK is designed to automatically extract the token and route requests correctly regardless of the endpoint format provided. Supported formats include base URLs, URLs with trailing slashes, or URLs specifying specific sub-paths like /info, /hypercore, or /evm.

    // All of these work - the SDK extracts the token and routes correctly
    let endpoint = "https://x.quiknode.pro/TOKEN";
    let endpoint = "https://x.quiknode.pro/TOKEN/";
    let endpoint = "https://x.quiknode.pro/TOKEN/info";
    let endpoint = "https://x.quiknode.pro/TOKEN/hypercore";
    let endpoint = "https://x.quiknode.pro/TOKEN/evm";
  4. Execute Vault and Deadline-constrained actions

    main

    You can perform actions on behalf of a vault or subaccount by providing a vaultAddress. Additionally, you can set an expiresAfter millisecond timestamp to ensure an action is rejected if not processed within a certain window. These fields are signed into the action hash.

    Use hyperliquid.WithVaultAddress(vault) and hyperliquid.WithExpiresAfter(deadline) for one-line orders, or the corresponding methods on the OrderBuilder.

    vault := "0xVault..."
    deadline := time.Now().Add(30 * time.Second).UnixMilli()
    
    // One-line order with vault and deadline
    sdk.Buy("BTC", hyperliquid.WithSize(0.001), hyperliquid.WithPrice(65000),
        hyperliquid.WithVaultAddress(vault), hyperliquid.WithExpiresAfter(deadline))
    
    // Using fluent builder
    order := hyperliquid.Order().Buy("BTC").Size(0.001).Price(65000).GTC().
        VaultAddress(vault).ExpiresAfter(deadline)
    sdk.PlaceOrder(order)
    
    // Cancels and modifies for vaults
    sdk.Cancel(oid, "BTC", hyperliquid.CancelWithVaultAddress(vault), hyperliquid.CancelWithExpiresAfter(deadline))
    sdk.Modify(oid, "BTC", "buy", "61000", "0.001", hyperliquid.ModifyWithVaultAddress(vault))
    sdk.ClosePosition("BTC", hyperliquid.CloseWithVaultAddress(vault))
    
    // Trigger orders for vaults
    sdk.StopLoss("BTC", 0.001, 60000, hyperliquid.TriggerWithVaultAddress(vault))
  5. Handle Packed Streams (L2 and BBO)

    main
    The SDK provides "packed" streams (l2_book_packed, bbo_book_packed) for a fast-path data route. In these streams, prices (px) and sizes (sz) are provided as u64 fixed-point integers scaled by 1e8. To get the actual decimal value, you must divide the value by 1e8.
  6. Use Vaults and Action TTL

    main

    When performing actions, you can specify optional fields that are signed into the action.

    Vault Trading: To trade on behalf of a vault or subaccount, provide the vault_address in order and cancel methods. Action TTL (Time To Live): To ensure an action is rejected if not executed by a specific time, use the expires_after parameter (timestamp in milliseconds).

    # Trade on behalf of a vault
    sdk.buy("BTC", size=0.001, price=65000, vault_address="0xVault...")
    sdk.cancel(oid, "BTC", vault_address="0xVault...")
    sdk.close_position("BTC", vault_address="0xVault...")
    
    # Action TTL
    import time
    sdk.buy("BTC", size=0.001, price=65000,
            expires_after=int(time.time() * 1000) + 60_000)
  7. Use external signing with KMS/HSM

    main

    For enhanced security, you can keep your private key outside the SDK process by providing a signer callback. The callback must accept a hash_hex string and return a dictionary containing r, s, and v (where v is 27 or 28).

    from hyperliquid_sdk import HyperliquidSDK
    
    def signer(hash_hex: str) -> dict:
        # sign hash_hex with your KMS/HSM/remote signer
        # return {'r': ..., 's': ..., 'v': 27 or 28}
        ...
    
    sdk = HyperliquidSDK(
        endpoint,
        signer=signer,
        signer_address="0xYOUR_AGENT_ADDRESS",  # acting agent address
    )
    
    # Note: Builder-fee auto-approval is skipped with a signer.
    # Call this once per agent if needed:
    sdk.approve_builder_fee("1%")
  8. Compare L2 vs L4 Order Books

    main

    Choosing between L2 and L4 depends on your latency requirements and the level of detail needed for your strategy.

    FeatureL2 BookL4 Book
    AggregationBy price levelIndividual orders
    Order IDsNoYes
    Queue PositionUnknownVisible
    BandwidthLowerHigher
    ProtocolWebSocket or gRPCgRPC only
    Use CasePrice monitoringMarket making, HFT
  9. Understand L4 Order Books for Market Making and HFT

    main

    The L4 order book is a gRPC-only stream that provides every individual order including its unique order_id. This is critical for high-frequency trading (HFT) and market making because it allows you to track your exact queue position and perform order flow analysis (e.g., detecting icebergs).

    Important Implementation Note: The server may send an unsolicited full snapshot at any time after you subscribe. When a snapshot is received, you MUST discard your local book state and replace it entirely with the snapshot data.

    Data Structure:

    {
        "coin": "BTC",
        "bids": [[price, size, order_id], ...],
        "asks": [[price, size, order_id], ...]
    }
    use hyperliquid_sdk::GRPCStream;
    
    fn on_l4_book(data: serde_json::Value) {
        // L4 book data structure:
        // {
        //     "coin": "BTC",
        //     "bids": [[price, size, order_id], ...],
        //     "asks": [[price, size, order_id], ...]
        // }
        if let Some(bids) = data.get("bids").and_then(|b| b.as_array()) {
            for bid in bids.iter().take(3) {
                let px = bid.get(0).and_then(|v| v.as_f64()).unwrap_or(0.0);
                let sz = bid.get(1).and_then(|v| v.as_f64()).unwrap_or(0.0);
                let oid = bid.get(2).and_then(|v| v.as_i64()).unwrap_or(0);
                println!("Bid: ${:.2} x {} (order: {})", px, sz, oid);
            }
        }
    }
    
    let mut stream = GRPCStream::new(endpoint)?;
    stream.l4_book("BTC", on_l4_book);
    stream.run()?;
  10. Advanced: Use external signing (KMS/HSM/remote signer)

    main

    For security, you can keep your private key outside the SDK process by providing a signer callback. This is useful for using KMS, HSM, or remote signers. When using a custom signer, builder-fee auto-approval is skipped, so you must call sdk.approveBuilderFee("1%") once per agent.

    If the callback fails, the SDK throws a SignerError with the code SIGNER_FAILED.

    import { HyperliquidSDK, Signer } from '@quicknode/hyperliquid-sdk';
    
    const signer: Signer = async (hashHex, { signal } = {}) => {
      // sign hashHex with your KMS/HSM/remote signer; honour `signal` for timeouts
      return { r: "0x...", s: "0x...", v: 27 };
    };
    
    const sdk = new HyperliquidSDK(endpoint, {
      signer,
      signerAddress: "0xYOUR_AGENT_ADDRESS",  // acting agent address
    });
  11. Understand L4 Order Books for Market Making

    main

    The L4 order book is a high-performance gRPC stream that provides visibility into every individual order including its order_id. This is critical for high-frequency trading (HFT) and market making because it allows you to track your exact queue position and detect order flow patterns like icebergs.

    L4 Data Structure:

    {
      "coin": "BTC",
      "bids": [[price, size, order_id], ...],
      "asks": [[price, size, order_id], ...]
    }

    Important: L4 Snapshot Contract When subscribing to L4 streams (l4Book, l4BookBytes, or l4BookUpdates), the server may send an unsolicited full snapshot at any time. Clients MUST discard local book state and replace it with any snapshot received mid-stream.

    const sdk = new HyperliquidSDK(endpoint);
    
    sdk.grpc.l4Book("BTC", (data) => {
      // L4 book data structure:
      // {
      //   "coin": "BTC",
      //   "bids": [[price, size, order_id], ...],
      //   "asks": [[price, size, order_id], ...]
      // }
      const bids = data.bids || [];
      for (const bid of bids.slice(0, 3)) {
        const [px, sz, oid] = bid;
        console.log(`Bid: $${Number(px).toLocaleString()} x ${sz} (order: ${oid})`);
      }
    });
    
    await sdk.grpc.start();
  12. Trade for Vaults and Subaccounts

    main

    To trade on behalf of a vault or subaccount, you must provide the vault_address in the order or exchange options. This address is included in the signed action hash.

    • Order level: Use .vault_address("0x...") on the Order builder.
    • Options level: Use ExchangeOptions with a vault_address for methods like modify_with_options or close_position_with_options.
    • Fast Cancels: Use CancelOptions { fast: true, ..Default::default() } with cancel_with_options to emit the "f": true flag for faster execution.
    use hyperliquid_sdk::{CancelOptions, ExchangeOptions, Order};
    
    // Trade on behalf of a vault
    sdk.order(
        Order::buy("BTC")
            .size(0.001)
            .price(65000.0)
            .gtc()
            .vault_address("0x1719884eb866cb12b2287399b15f7db5e7d775ea")
    ).await?;
    
    // Fast cancel
    let fast = CancelOptions { fast: true, ..Default::default() };
    sdk.cancel_with_options(oid, "BTC", &fast).await?;