Hyperliquid is a high-performance blockchain designed specifically for decentralized derivatives trading. It offers incredibly fast transaction processing, low fees, and a fully onchain open financial system.
This guide will walk you through setting up trading on Hyperliquid using Privy’s EVM wallets, focusing on how to securely authenticate and interact with the Hyperliquid API without ever exposing private keys.
The Privy SDKs are designed to be fully compatible with the Hyperliquid API, allowing you to build secure trading applications with ease.
Resources
Integrating with Hyperliquid
Setting up Hyperliquid with Privy in NodeJS
We’ll be using the Hyperliquid SDK with Privy’s ethers.js integration to interact with the Hyperliquid API.
1. Installation
First, install the necessary dependencies:
npm install @nktkas/hyperliquid @privy-io/server-auth ethers@latest
2. Initialize Privy Server SDK
Set up Privy’s server SDK to interact with your managed wallets:
import { PrivyClient } from '@privy-io/server-auth';
// Initialize Privy client with your API key
const privyClient = new PrivyClient('insert-your-app-id', 'insert-your-app-secret', {
walletApi: {
authorizationPrivateKey: 'insert-your-authorization-private-key' // Optional
}
});
3. Create Ethers Compatible Signer
Use Privy’s createEthersSigner
utility to create an ethers-compatible signer:
import { ethers } from 'ethers';
import { createEthersSigner } from '@privy-io/server-auth/ethers';
// Initialize your ethers provider
const provider = new ethers.JsonRpcProvider('https://base.llamarpc.com');
// Get your wallet from Privy
const walletId = 'insert-wallet-id';
const wallet = await privyClient.walletApi.getWallet({id: walletId});
const address = wallet.address;
// Create an ethers signer
const signer = createEthersSigner({
walletId,
address,
provider,
privyClient,
});
4. Initialize Hyperliquid SDK
Use the ethers signer to initialize the Hyperliquid client:
import * as hl from '@nktkas/hyperliquid';
// Create Hyperliquid transport and client
const transport = new hl.HttpTransport();
const client = new hl.ExchangeClient({
transport,
wallet: signer
});
const infoClient = new hl.InfoClient({ transport })
5. Check if Wallet has Account
Before trading, ensure the wallet has an account on Hyperliquid:
// Check if Hyperliquid account is active
const preTransferCheck = await infoClient.preTransferCheck({
user: wallet.address,
source: "<address-used-to-credit-account>",
});
if (!preTransferCheck.userExists) {
throw new Error("Hyperliquid account does not exist for this wallet.");
}
6. Getting Tradable Assets and Contexts
Before trading assets their metadata and contexts need to be fetched first:
// Get available assets
const metaAndCtx = await infoClient.metaAndAssetCtxs();
const meta = metaAndCtx[0];
const ctx = metaAndCtx[1];
// Find the asset index for BTC
const btcIndex = meta.universe.findIndex((asset) => asset.name === "BTC");
const universe = meta.universe[btcIndex];
const btcContext = ctx[btcIndex];
const price = formatPrice(
new BigNumber(btcContext.markPx).times(1.01),
universe.szDecimals,
);
const triggerPrice = formatPrice(
new BigNumber(btcContext.markPx).times(0.99),
universe.szDecimals,
);
const size = formatSize(
new BigNumber(15).div(btcContext.markPx),
universe.szDecimals,
);
7. Making Trades
Now you can use the client to place orders and interact with the Hyperliquid API:
// Place a market order
const orderResponse = await client.order({
orders: [
{
a: btcIndex, // Asset index
b: true, // Buy order
s: sz, // Size
r: false, // Not reduce-only
p: pxUp, // Price (0 for market order)
t: { trigger: { isMarket: true, tpsl: "tp", triggerPx: pxDown } }, // Market order
},
],
grouping: "na", // No grouping
});
console.log("Order placed:", orderResponse);
// Check open positions
const userState = await infoClient.clearinghouseState({ user: address });
console.log("Account state:", userState);
This approach keeps your wallet’s private keys secure by delegating all signing operations
to Privy’s secure API, while providing full compatibility with Hyperliquid’s trading features.
Setting up Hyperliquid with Privy in NodeJS
We’ll be using the Hyperliquid SDK with Privy’s ethers.js integration to interact with the Hyperliquid API.
1. Installation
First, install the necessary dependencies:
npm install @nktkas/hyperliquid @privy-io/server-auth ethers@latest
2. Initialize Privy Server SDK
Set up Privy’s server SDK to interact with your managed wallets:
import { PrivyClient } from '@privy-io/server-auth';
// Initialize Privy client with your API key
const privyClient = new PrivyClient('insert-your-app-id', 'insert-your-app-secret', {
walletApi: {
authorizationPrivateKey: 'insert-your-authorization-private-key' // Optional
}
});
3. Create Ethers Compatible Signer
Use Privy’s createEthersSigner
utility to create an ethers-compatible signer:
import { ethers } from 'ethers';
import { createEthersSigner } from '@privy-io/server-auth/ethers';
// Initialize your ethers provider
const provider = new ethers.JsonRpcProvider('https://base.llamarpc.com');
// Get your wallet from Privy
const walletId = 'insert-wallet-id';
const wallet = await privyClient.walletApi.getWallet({id: walletId});
const address = wallet.address;
// Create an ethers signer
const signer = createEthersSigner({
walletId,
address,
provider,
privyClient,
});
4. Initialize Hyperliquid SDK
Use the ethers signer to initialize the Hyperliquid client:
import * as hl from '@nktkas/hyperliquid';
// Create Hyperliquid transport and client
const transport = new hl.HttpTransport();
const client = new hl.ExchangeClient({
transport,
wallet: signer
});
const infoClient = new hl.InfoClient({ transport })
5. Check if Wallet has Account
Before trading, ensure the wallet has an account on Hyperliquid:
// Check if Hyperliquid account is active
const preTransferCheck = await infoClient.preTransferCheck({
user: wallet.address,
source: "<address-used-to-credit-account>",
});
if (!preTransferCheck.userExists) {
throw new Error("Hyperliquid account does not exist for this wallet.");
}
6. Getting Tradable Assets and Contexts
Before trading assets their metadata and contexts need to be fetched first:
// Get available assets
const metaAndCtx = await infoClient.metaAndAssetCtxs();
const meta = metaAndCtx[0];
const ctx = metaAndCtx[1];
// Find the asset index for BTC
const btcIndex = meta.universe.findIndex((asset) => asset.name === "BTC");
const universe = meta.universe[btcIndex];
const btcContext = ctx[btcIndex];
const price = formatPrice(
new BigNumber(btcContext.markPx).times(1.01),
universe.szDecimals,
);
const triggerPrice = formatPrice(
new BigNumber(btcContext.markPx).times(0.99),
universe.szDecimals,
);
const size = formatSize(
new BigNumber(15).div(btcContext.markPx),
universe.szDecimals,
);
7. Making Trades
Now you can use the client to place orders and interact with the Hyperliquid API:
// Place a market order
const orderResponse = await client.order({
orders: [
{
a: btcIndex, // Asset index
b: true, // Buy order
s: sz, // Size
r: false, // Not reduce-only
p: pxUp, // Price (0 for market order)
t: { trigger: { isMarket: true, tpsl: "tp", triggerPx: pxDown } }, // Market order
},
],
grouping: "na", // No grouping
});
console.log("Order placed:", orderResponse);
// Check open positions
const userState = await infoClient.clearinghouseState({ user: address });
console.log("Account state:", userState);
This approach keeps your wallet’s private keys secure by delegating all signing operations
to Privy’s secure API, while providing full compatibility with Hyperliquid’s trading features.
Setting up Hyperliquid with Privy in Python
The Python integration allows you to use Privy’s server-side wallet management with Hyperliquid’s Python SDK to build secure trading applications.
Installation
First, install the required dependencies:
pip install hyperliquid-python-sdk>=0.14.1 privy-eth-account
Make sure to use at least version 0.14.1 of the hyperliquid-python-sdk, as earlier versions use deprecated RPC methods that may not work correctly.
Initialize Privy
Set up the Privy client to interact with your managed wallets:
from privy_eth_account import PrivyHTTPClient
# Initialize your Privy client
client = PrivyHTTPClient(
app_id="YOUR_APP_ID",
app_secret="YOUR_APP_SECRET",
authorization_key="YOUR_AUTHORIZATION_KEY"
)
Create a Signer
Privy EVM wallets natively integrate with the Python eth-account library, so you can use it to create a signer that interacts with the Hyperliquid API.
from privy_eth_account import create_eth_account
# Create an account instance for a wallet
wallet_id = "insert-wallet-id"
wallet_address = "insert-wallet-address"
account = create_eth_account(client, wallet_address, wallet_id)
Set up the Hyperliquid Exchange Client
Now that you have a signer, you can set up the Hyperliquid exchange client:
from hyperliquid.exchange import Exchange
exchange = Exchange(account, base_url, account_address=wallet_address, perp_dexs=perp_dexs)
Making Trades
You can now use the exchange client to place orders and interact with the Hyperliquid API:
order_result = exchange.order("ETH", True, 0.2, 1100, {"limit": {"tif": "Gtc"}})
We’ll be using Ferrofluid with Privy’s native integration to interact with
the Hyperliquid API.
1. Installation
First, add the necessary dependencies:
[dependencies]
ferrofluid = "0.1.1"
tokio = { version = "1", features = ["full"] }
alloy = "0.1"
2. Initialize Privy Signer
Set up Privy’s signer to interact with your managed wallets:
use ferrofluid::{
signers::PrivySigner,
errors::HyperliquidError,
};
use alloy::primitives::address;
type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
// Initialize crypto provider (required)
rustls::crypto::aws_lc_rs::default_provider()
.install_default()
.expect("Failed to install crypto provider");
// Set environment variables:
// export PRIVY_APP_ID=your_app_id
// export PRIVY_SECRET=your_secret
let wallet_id = "your-privy-wallet-id".to_string();
let address = address!("your-wallet-address");
let signer = PrivySigner::new(wallet_id, address)?;
// Alternative: provide credentials explicitly
// let signer = PrivySigner::with_credentials(
// wallet_id,
// address,
// app_id.to_string(),
// app_secret.to_string(),
// )?;
3. Initialize Hyperliquid SDK
Use the Privy signer to initialize the Hyperliquid client:
use ferrofluid::providers::ExchangeProvider;
let exchange = ExchangeProvider::mainnet(signer);
4. Making Trades
You can now use the exchange client to place orders:
use ferrofluid::types::requests::{OrderRequest, OrderType, Limit};
let order = OrderRequest {
asset: 0, // 0 = BTC, 1 = ETH
is_buy: true,
limit_px: "65000.0".to_string(),
sz: "0.001".to_string(),
reduce_only: false,
order_type: OrderType::Limit(Limit { tif: "Gtc".to_string() }),
cloid: None,
};
let result = exchange.place_order(&order).await?;
println!("Order result: {:?}", result);
5. Common Operations
Here are some common operations you might need:
use ferrofluid::providers::InfoProvider;
// Check account balance and positions
let info = InfoProvider::mainnet();
let user_state = info.user_state(address).await?;
println!("Withdrawable balance: ${}", user_state.withdrawable);
println!("Account value: ${}", user_state.margin_summary.account_value);
// Transfer USDC
let recipient = address!("recipient-address");
let transfer_result = exchange.usd_transfer(recipient, "100.0").await?;
// Check open positions
for position in &user_state.asset_positions {
if position.position.szi != "0" {
println!("{}: {} @ ${}",
position.position.coin,
position.position.szi,
position.position.entry_px.as_ref().unwrap_or(&"N/A".to_string())
);
}
}
Complete Example
use ferrofluid::{
providers::{ExchangeProvider, InfoProvider},
signers::PrivySigner,
types::requests::{OrderRequest, OrderType, Limit},
};
use alloy::primitives::address;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Initialize crypto provider
rustls::crypto::aws_lc_rs::default_provider()
.install_default()
.expect("Failed to install crypto provider");
// Set up Privy signer
let wallet_id = "your-privy-wallet-id".to_string();
let wallet_address = address!("your-wallet-address");
let signer = PrivySigner::new(wallet_id, wallet_address)?;
// Create clients
let exchange = ExchangeProvider::mainnet(signer);
let info = InfoProvider::mainnet();
// Check balance
let state = info.user_state(wallet_address).await?;
println!("Balance: ${}", state.withdrawable);
// Place a limit order for BTC
let order = OrderRequest {
asset: 0, // BTC
is_buy: true,
limit_px: "65000.0".to_string(),
sz: "0.001".to_string(),
reduce_only: false,
order_type: OrderType::Limit(Limit { tif: "Gtc".to_string() }),
cloid: None,
};
let result = exchange.place_order(&order).await?;
println!("Order placed: {:?}", result);
Ok(())
}
Conclusion
By combining Privy’s secure wallet infrastructure with Hyperliquid’s high-performance trading platform, you can build powerful trading applications without compromising on security. The custom signer approach allows you to leverage Privy’s key management while still benefiting from all the features of Hyperliquid’s API.
For more advanced features like subscription to real-time order book data or implementing complex trading strategies, refer to the Hyperliquid documentation.
Your application can now securely trade on Hyperliquid using Privy’s managed wallets!
Responses are generated using AI and may contain mistakes.