The quickest way to start building on Hyperliquid with Quicknode is to create an endpoint, copy its provider URL, and send your first request to HyperCore or HyperEVM.
Get Your Hyperliquid Endpoint
Create a Quicknode account
Sign up here if you haven't already.
Go to your dashboard
Go to your Quicknode dashboard, then select Endpoints from the left sidebar.
Your Hyperliquid endpoint
Checking your account for a Hyperliquid endpoint…
Choose an example to run
Continue to Send Your First Request and choose a use case and language. The setup step shows exactly which endpoint details to copy from your dashboard.
For a detailed walkthrough of the Quicknode dashboard, check out our guide
Send Your First Request
Your endpoint is ready. Choose a practical workflow below, then switch among cURL, JavaScript, Python, Ruby, and Go examples. The examples use Quicknode's HTTP, WebSocket, and gRPC interfaces, including the latest HyperCore mempool, L4 order book, and priority fee feeds.
Explore Markets (/info) and Build on HyperEVM (/evm) are available
on all plans. Trade & Manage Orders uses the REST Exchange API; free trial
users receive a shared URL, while Build plans
and higher can use their Quicknode endpoint. Query History and Monitor
Live Data use HyperCore JSON-RPC, WebSocket, or gRPC services and require a
Build plan or higher. See Hyperliquid plan
access for details.
- Explore Markets
- Trade & Manage Orders
- Monitor Live Data
- Build on HyperEVM
- Query History
Build a live market snapshot
Get a quick view of the market by retrieving current prices and the BTC order book. You can then add candlestick data, market details, and account positions to build dashboards, trading bots, or pre-trade checks.
- cURL
- JavaScript
Python
- Ruby
- Go
Copy the EVM provider URL and set up cURL
In the Quicknode dashboard, open Endpoints and select your Hyperliquid endpoint. Under API access URL, select RPC and copy the complete EVM HTTPS URL into EVM_PROVIDER_URL, including its /evm ending. The setup removes that ending and stores the reusable base URL in QUICKNODE_ENDPOINT.
export EVM_PROVIDER_URL="PASTE_THE_EVM_HTTPS_URL_HERE"
export QUICKNODE_ENDPOINT="$(printf '%s' "$EVM_PROVIDER_URL" | sed 's#/evm/*$##')"
export HYPERLIQUID_ADDRESS="0xADDRESS_TO_INSPECT"
Get mids in under 30 seconds
Use this read-only request to verify the endpoint and retrieve the current mid price for every listed market.
curl "$QUICKNODE_ENDPOINT/info" \
-H "Content-Type: application/json" \
-d '{"type":"allMids"}'
Build the complete market snapshot
Add the BTC order book, the latest one-minute candles, and the account’s open positions to the current prices.
END_TIME=$(($(date +%s) * 1000))
START_TIME=$((END_TIME - 3600000))
curl "$QUICKNODE_ENDPOINT/info" \
-H "Content-Type: application/json" \
-d '{"type":"l2Book","coin":"BTC"}'
curl "$QUICKNODE_ENDPOINT/info" \
-H "Content-Type: application/json" \
-d '{"type":"candleSnapshot","req":{"coin":"BTC","interval":"1m","startTime":'"$START_TIME"',"endTime":'"$END_TIME"'}}'
curl "$QUICKNODE_ENDPOINT/info" \
-H "Content-Type: application/json" \
-d '{"type":"clearinghouseState","user":"'"$HYPERLIQUID_ADDRESS"'"}'
Copy the EVM provider URL and set up JavaScript
In the Quicknode dashboard, open Endpoints and select your Hyperliquid endpoint. Under API access URL, select RPC and copy the complete EVM HTTPS URL into EVM_PROVIDER_URL, including its /evm ending. The setup removes that ending and stores the reusable base URL in QUICKNODE_ENDPOINT.
mkdir hyperliquid-quickstart && cd hyperliquid-quickstart
npm init -y
export EVM_PROVIDER_URL="PASTE_THE_EVM_HTTPS_URL_HERE"
export QUICKNODE_ENDPOINT="$(printf '%s' "$EVM_PROVIDER_URL" | sed 's#/evm/*$##')"
export HYPERLIQUID_ADDRESS="0xADDRESS_TO_INSPECT"
Create the JavaScript example
Create example.js. Fetch current prices, BTC L2 depth, recent candles, and an account’s open positions, then print a compact market snapshot.
const endpoint = process.env.QUICKNODE_ENDPOINT.replace(/\/$/, '');
async function info(type, params = {}) {
const response = await fetch(endpoint + '/info', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ type, ...params }),
});
if (!response.ok) throw new Error(await response.text());
return response.json();
}
async function main() {
const endTime = Date.now();
const [mids, book, candles, account] = await Promise.all([
info('allMids'),
info('l2Book', { coin: 'BTC' }),
info('candleSnapshot', {
req: { coin: 'BTC', interval: '1m', startTime: endTime - 3_600_000, endTime },
}),
info('clearinghouseState', { user: process.env.HYPERLIQUID_ADDRESS }),
]);
const bid = Number(book.levels[0][0].px);
const ask = Number(book.levels[1][0].px);
console.log({
btcMid: mids.BTC, bid, ask, spread: ask - bid,
latestCandle: candles.at(-1),
accountValue: account.marginSummary.accountValue,
openPositions: account.assetPositions.length,
});
}
main().catch(error => {
console.error(error);
process.exitCode = 1;
});
Run the example
node example.js
Copy the EVM provider URL and set up Python
In the Quicknode dashboard, open Endpoints and select your Hyperliquid endpoint. Under API access URL, select RPC and copy the complete EVM HTTPS URL into EVM_PROVIDER_URL, including its /evm ending. The setup removes that ending and stores the reusable base URL in QUICKNODE_ENDPOINT.
mkdir hyperliquid-quickstart && cd hyperliquid-quickstart
python3 -m venv .venv
source .venv/bin/activate
pip install requests
export EVM_PROVIDER_URL="PASTE_THE_EVM_HTTPS_URL_HERE"
export QUICKNODE_ENDPOINT="$(printf '%s' "$EVM_PROVIDER_URL" | sed 's#/evm/*$##')"
export HYPERLIQUID_ADDRESS="0xADDRESS_TO_INSPECT"
Create the Python example
Create example.py. Fetch current prices, BTC L2 depth, recent candles, and an account’s open positions, then print a compact market snapshot.
import os
import time
from concurrent.futures import ThreadPoolExecutor
import requests
url = os.environ["QUICKNODE_ENDPOINT"].rstrip("/") + "/info"
def info(payload):
response = requests.post(url, json=payload, timeout=30)
response.raise_for_status()
return response.json()
end_time = int(time.time() * 1000)
with ThreadPoolExecutor(max_workers=4) as pool:
mids_future = pool.submit(info, {"type": "allMids"})
book_future = pool.submit(info, {"type": "l2Book", "coin": "BTC"})
candles_future = pool.submit(info, {"type": "candleSnapshot", "req": {
"coin": "BTC", "interval": "1m",
"startTime": end_time - 3_600_000, "endTime": end_time,
}})
account_future = pool.submit(info, {
"type": "clearinghouseState", "user": os.environ["HYPERLIQUID_ADDRESS"]
})
mids, book = mids_future.result(), book_future.result()
candles, account = candles_future.result(), account_future.result()
bid = float(book["levels"][0][0]["px"])
ask = float(book["levels"][1][0]["px"])
print({
"btc_mid": mids["BTC"], "bid": bid, "ask": ask, "spread": ask - bid,
"latest_candle": candles[-1] if candles else None,
"account_value": account["marginSummary"]["accountValue"],
"open_positions": len(account["assetPositions"]),
})
Run the example
python example.py
Copy the EVM provider URL and set up Ruby
In the Quicknode dashboard, open Endpoints and select your Hyperliquid endpoint. Under API access URL, select RPC and copy the complete EVM HTTPS URL into EVM_PROVIDER_URL, including its /evm ending. The setup removes that ending and stores the reusable base URL in QUICKNODE_ENDPOINT.
mkdir hyperliquid-quickstart && cd hyperliquid-quickstart
export EVM_PROVIDER_URL="PASTE_THE_EVM_HTTPS_URL_HERE"
export QUICKNODE_ENDPOINT="$(printf '%s' "$EVM_PROVIDER_URL" | sed 's#/evm/*$##')"
export HYPERLIQUID_ADDRESS="0xADDRESS_TO_INSPECT"
Create the Ruby example
Create example.rb. Fetch current prices, BTC L2 depth, recent candles, and an account’s open positions, then print a compact market snapshot.
require "json"
require "net/http"
uri = URI(ENV.fetch("QUICKNODE_ENDPOINT").sub(%r{/$}, "") + "/info")
def info(uri, payload)
response = Net::HTTP.post(uri, JSON.dump(payload), "Content-Type" => "application/json")
raise response.body unless response.is_a?(Net::HTTPSuccess)
JSON.parse(response.body)
end
mids = info(uri, { type: "allMids" })
book = info(uri, { type: "l2Book", coin: "BTC" })
end_time = (Time.now.to_f * 1000).to_i
candles = info(uri, { type: "candleSnapshot", req: {
coin: "BTC", interval: "1m", startTime: end_time - 3_600_000, endTime: end_time
} })
account = info(uri, { type: "clearinghouseState", user: ENV.fetch("HYPERLIQUID_ADDRESS") })
bid = book["levels"][0][0]["px"].to_f
ask = book["levels"][1][0]["px"].to_f
puts({
btc_mid: mids["BTC"], bid: bid, ask: ask, spread: ask - bid,
latest_candle: candles.last,
account_value: account.dig("marginSummary", "accountValue"),
open_positions: account.fetch("assetPositions").length
}.to_json)
Run the example
ruby example.rb
Copy the EVM provider URL and set up Go
In the Quicknode dashboard, open Endpoints and select your Hyperliquid endpoint. Under API access URL, select RPC and copy the complete EVM HTTPS URL into EVM_PROVIDER_URL, including its /evm ending. The setup removes that ending and stores the reusable base URL in QUICKNODE_ENDPOINT.
mkdir hyperliquid-quickstart && cd hyperliquid-quickstart
go mod init hyperliquid-quickstart
export EVM_PROVIDER_URL="PASTE_THE_EVM_HTTPS_URL_HERE"
export QUICKNODE_ENDPOINT="$(printf '%s' "$EVM_PROVIDER_URL" | sed 's#/evm/*$##')"
export HYPERLIQUID_ADDRESS="0xADDRESS_TO_INSPECT"
Create the Go example
Create main.go. Fetch current prices, BTC L2 depth, recent candles, and an account’s open positions, then print a compact market snapshot.
package main
import ("bytes"; "encoding/json"; "fmt"; "net/http"; "os"; "strconv"; "strings"; "time")
func post(url string, payload any, result any) error {
body, _ := json.Marshal(payload)
response, err := http.Post(url, "application/json", bytes.NewReader(body)); if err != nil { return err }
defer response.Body.Close(); return json.NewDecoder(response.Body).Decode(result)
}
func main() {
url := strings.TrimRight(os.Getenv("QUICKNODE_ENDPOINT"), "/") + "/info"
var mids map[string]string; var book map[string]any; var candles []map[string]any; var account map[string]any
if err := post(url, map[string]any{"type":"allMids"}, &mids); err != nil { panic(err) }
if err := post(url, map[string]any{"type":"l2Book", "coin":"BTC"}, &book); err != nil { panic(err) }
endTime := time.Now().UnixMilli()
if err := post(url, map[string]any{"type":"candleSnapshot", "req":map[string]any{
"coin":"BTC", "interval":"1m", "startTime":endTime-3_600_000, "endTime":endTime,
}}, &candles); err != nil { panic(err) }
if err := post(url, map[string]any{"type":"clearinghouseState", "user":os.Getenv("HYPERLIQUID_ADDRESS")}, &account); err != nil { panic(err) }
levels := book["levels"].([]any)
bidText := levels[0].([]any)[0].(map[string]any)["px"].(string)
askText := levels[1].([]any)[0].(map[string]any)["px"].(string)
bid, _ := strconv.ParseFloat(bidText, 64); ask, _ := strconv.ParseFloat(askText, 64)
positions, _ := account["assetPositions"].([]any)
var latestCandle map[string]any; if len(candles) > 0 { latestCandle = candles[len(candles)-1] }
fmt.Println("BTC mid:", mids["BTC"], "bid:", bid, "ask:", ask, "spread:", ask-bid)
fmt.Println("latest candle:", latestCandle, "open positions:", len(positions))
}
Run the example
go run .
Automate an order workflow
Build and review a limit order, take-profit and stop-loss orders, a cancellation, a TWAP order, and a leverage update without changing the account. The JavaScript example also signs the limit order locally, but does not send it unless you explicitly enable submission.
- cURL
- JavaScript
Python
- Ruby
- Go
Copy the EVM provider URL and set up cURL
In the Quicknode dashboard, open Endpoints and select your Hyperliquid endpoint. Under API access URL, select RPC and copy the complete EVM HTTPS URL into EVM_PROVIDER_URL, including its /evm ending. The setup removes that ending and stores the reusable base URL in QUICKNODE_ENDPOINT.
export EVM_PROVIDER_URL="PASTE_THE_EVM_HTTPS_URL_HERE"
export QUICKNODE_ENDPOINT="$(printf '%s' "$EVM_PROVIDER_URL" | sed 's#/evm/*$##')"
export ORDER_ID_TO_CANCEL="123456789" # Replace with an open order ID
Build common trading actions
Build a limit order, take-profit and stop-loss orders, a cancellation, a TWAP order, and a leverage update. These calls only return actions and hashes to review and sign; they do not change the account.
build() {
curl -s "$QUICKNODE_ENDPOINT/hypercore/exchange" \
-H "Content-Type: application/json" \
-d "$(jq -cn --argjson action "$1" '{action: $action}')" |
jq '{hash, nonce, action}'
}
# Limit order
build '{"type":"order","orders":[{"asset":"BTC","side":"buy","price":"60000","size":"0.001","tif":"gtc"}]}'
# Position stop loss
build '{"type":"order","orders":[{"a":"BTC","b":false,"p":"50000","s":"0.001","r":true,"t":{"trigger":{"isMarket":true,"triggerPx":"55000","tpsl":"sl"}}}],"grouping":"positionTpsl"}'
# Position take profit
build '{"type":"order","orders":[{"a":"BTC","b":false,"p":"90000","s":"0.001","r":true,"t":{"trigger":{"isMarket":true,"triggerPx":"90000","tpsl":"tp"}}}],"grouping":"positionTpsl"}'
# Cancel an existing order
build '{"type":"cancel","cancels":[{"a":"BTC","o":'"$ORDER_ID_TO_CANCEL"'}]}'
# Execute 0.01 BTC over 30 minutes in randomized slices
build '{"type":"twapOrder","twap":{"a":"BTC","b":true,"s":"0.01","r":false,"m":30,"t":true}}'
# Set 3x cross leverage for BTC
build '{"type":"updateLeverage","asset":"BTC","isCross":true,"leverage":3}'
Copy the EVM provider URL and set up JavaScript
In the Quicknode dashboard, open Endpoints and select your Hyperliquid endpoint. Under API access URL, select RPC and copy the complete EVM HTTPS URL into EVM_PROVIDER_URL, including its /evm ending. The setup removes that ending and stores the reusable base URL in QUICKNODE_ENDPOINT.
mkdir hyperliquid-quickstart && cd hyperliquid-quickstart
npm init -y
export EVM_PROVIDER_URL="PASTE_THE_EVM_HTTPS_URL_HERE"
export QUICKNODE_ENDPOINT="$(printf '%s' "$EVM_PROVIDER_URL" | sed 's#/evm/*$##')"
export ORDER_ID_TO_CANCEL="123456789" # Replace with an open order ID
npm install ethers
export HYPERLIQUID_PRIVATE_KEY="0xYOUR_API_WALLET_PRIVATE_KEY"
Create the JavaScript example
Create example.js. Build six common trading actions, then sign and prepare the limit-order payload locally. Submission remains disabled unless SEND_ORDER=true.
const endpoint = process.env.QUICKNODE_ENDPOINT.replace(/\/$/, '');
const { Wallet } = require('ethers');
const privateKey = process.env.HYPERLIQUID_PRIVATE_KEY;
if (!privateKey) throw new Error('Set HYPERLIQUID_PRIVATE_KEY to a dedicated API wallet key');
const wallet = new Wallet(privateKey);
async function exchange(body) {
const response = await fetch(endpoint + '/hypercore/exchange', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(body),
});
if (!response.ok) throw new Error(await response.text());
return response.json();
}
async function main() {
const actions = [
['limit order', { type: 'order', orders: [
{ asset: 'BTC', side: 'buy', price: '60000', size: '0.001', tif: 'gtc' },
] }],
['position stop loss', { type: 'order', orders: [{
a: 'BTC', b: false, p: '50000', s: '0.001', r: true,
t: { trigger: { isMarket: true, triggerPx: '55000', tpsl: 'sl' } },
}], grouping: 'positionTpsl' }],
['position take profit', { type: 'order', orders: [{
a: 'BTC', b: false, p: '90000', s: '0.001', r: true,
t: { trigger: { isMarket: true, triggerPx: '90000', tpsl: 'tp' } },
}], grouping: 'positionTpsl' }],
['cancel', { type: 'cancel', cancels: [
{ a: 'BTC', o: Number(process.env.ORDER_ID_TO_CANCEL) },
] }],
['TWAP', { type: 'twapOrder', twap: {
a: 'BTC', b: true, s: '0.01', r: false, m: 30, t: true,
} }],
['leverage update', {
type: 'updateLeverage', asset: 'BTC', isCross: true, leverage: 3,
}],
];
const builtActions = [];
for (const [name, action] of actions) {
const built = await exchange({ action });
builtActions.push(built);
console.log(name, { hash: built.hash, nonce: built.nonce, action: built.action });
}
const built = builtActions[0];
const signed = wallet.signingKey.sign(built.hash);
const request = {
action: built.action,
nonce: built.nonce,
signature: { r: signed.r, s: signed.s, v: signed.v },
};
console.log('Signer:', wallet.address);
console.log('Signed limit-order action:', JSON.stringify(request.action, null, 2));
if (process.env.SEND_ORDER !== 'true') {
console.log('Dry run complete. Set SEND_ORDER=true only after reviewing every value.');
return;
}
console.log(await exchange(request));
}
main().catch(error => {
console.error(error);
process.exitCode = 1;
});
Run the example
node example.js
Copy the EVM provider URL and set up Python
In the Quicknode dashboard, open Endpoints and select your Hyperliquid endpoint. Under API access URL, select RPC and copy the complete EVM HTTPS URL into EVM_PROVIDER_URL, including its /evm ending. The setup removes that ending and stores the reusable base URL in QUICKNODE_ENDPOINT.
mkdir hyperliquid-quickstart && cd hyperliquid-quickstart
python3 -m venv .venv
source .venv/bin/activate
pip install requests
export EVM_PROVIDER_URL="PASTE_THE_EVM_HTTPS_URL_HERE"
export QUICKNODE_ENDPOINT="$(printf '%s' "$EVM_PROVIDER_URL" | sed 's#/evm/*$##')"
export ORDER_ID_TO_CANCEL="123456789" # Replace with an open order ID
Create the Python example
Create example.py. Build six common trading actions and print each wire-format action, nonce, and hash without signing or submitting anything.
import os
import requests
url = os.environ["QUICKNODE_ENDPOINT"].rstrip("/") + "/hypercore/exchange"
actions = [
("limit order", {"type": "order", "orders": [{
"asset": "BTC", "side": "buy", "price": "60000", "size": "0.001", "tif": "gtc"
}]}),
("position stop loss", {"type": "order", "orders": [{
"a": "BTC", "b": False, "p": "50000", "s": "0.001", "r": True,
"t": {"trigger": {"isMarket": True, "triggerPx": "55000", "tpsl": "sl"}},
}], "grouping": "positionTpsl"}),
("position take profit", {"type": "order", "orders": [{
"a": "BTC", "b": False, "p": "90000", "s": "0.001", "r": True,
"t": {"trigger": {"isMarket": True, "triggerPx": "90000", "tpsl": "tp"}},
}], "grouping": "positionTpsl"}),
("cancel", {"type": "cancel", "cancels": [{
"a": "BTC", "o": int(os.environ["ORDER_ID_TO_CANCEL"])
}]}),
("TWAP", {"type": "twapOrder", "twap": {
"a": "BTC", "b": True, "s": "0.01", "r": False, "m": 30, "t": True
}}),
("leverage update", {
"type": "updateLeverage", "asset": "BTC", "isCross": True, "leverage": 3
}),
]
for name, action in actions:
response = requests.post(url, json={"action": action}, timeout=30)
response.raise_for_status()
built = response.json()
print(name, {"hash": built["hash"], "nonce": built["nonce"], "action": built["action"]})
Run the example
python example.py
Copy the EVM provider URL and set up Ruby
In the Quicknode dashboard, open Endpoints and select your Hyperliquid endpoint. Under API access URL, select RPC and copy the complete EVM HTTPS URL into EVM_PROVIDER_URL, including its /evm ending. The setup removes that ending and stores the reusable base URL in QUICKNODE_ENDPOINT.
mkdir hyperliquid-quickstart && cd hyperliquid-quickstart
export EVM_PROVIDER_URL="PASTE_THE_EVM_HTTPS_URL_HERE"
export QUICKNODE_ENDPOINT="$(printf '%s' "$EVM_PROVIDER_URL" | sed 's#/evm/*$##')"
export ORDER_ID_TO_CANCEL="123456789" # Replace with an open order ID
Create the Ruby example
Create example.rb. Build six common trading actions and print each wire-format action, nonce, and hash without signing or submitting anything.
require "json"
require "net/http"
uri = URI(ENV.fetch("QUICKNODE_ENDPOINT").sub(%r{/$}, "") + "/hypercore/exchange")
actions = {
"limit order" => { type: "order", orders: [{
asset: "BTC", side: "buy", price: "60000", size: "0.001", tif: "gtc"
}] },
"position stop loss" => { type: "order", orders: [{
a: "BTC", b: false, p: "50000", s: "0.001", r: true,
t: { trigger: { isMarket: true, triggerPx: "55000", tpsl: "sl" } }
}], grouping: "positionTpsl" },
"position take profit" => { type: "order", orders: [{
a: "BTC", b: false, p: "90000", s: "0.001", r: true,
t: { trigger: { isMarket: true, triggerPx: "90000", tpsl: "tp" } }
}], grouping: "positionTpsl" },
"cancel" => { type: "cancel", cancels: [{
a: "BTC", o: Integer(ENV.fetch("ORDER_ID_TO_CANCEL"))
}] },
"TWAP" => { type: "twapOrder", twap: {
a: "BTC", b: true, s: "0.01", r: false, m: 30, t: true
} },
"leverage update" => {
type: "updateLeverage", asset: "BTC", isCross: true, leverage: 3
}
}
actions.each do |name, action|
response = Net::HTTP.post(uri, JSON.dump(action: action), "Content-Type" => "application/json")
raise response.body unless response.is_a?(Net::HTTPSuccess)
built = JSON.parse(response.body)
puts({ name: name, hash: built["hash"], nonce: built["nonce"], action: built["action"] }.to_json)
end
Run the example
ruby example.rb
Copy the EVM provider URL and set up Go
In the Quicknode dashboard, open Endpoints and select your Hyperliquid endpoint. Under API access URL, select RPC and copy the complete EVM HTTPS URL into EVM_PROVIDER_URL, including its /evm ending. The setup removes that ending and stores the reusable base URL in QUICKNODE_ENDPOINT.
mkdir hyperliquid-quickstart && cd hyperliquid-quickstart
go mod init hyperliquid-quickstart
export EVM_PROVIDER_URL="PASTE_THE_EVM_HTTPS_URL_HERE"
export QUICKNODE_ENDPOINT="$(printf '%s' "$EVM_PROVIDER_URL" | sed 's#/evm/*$##')"
export ORDER_ID_TO_CANCEL="123456789" # Replace with an open order ID
Create the Go example
Create main.go. Build six common trading actions and print each wire-format action, nonce, and hash without signing or submitting anything.
package main
import ("bytes"; "encoding/json"; "fmt"; "net/http"; "os"; "strconv"; "strings")
func build(url string, action map[string]any) {
body, _ := json.Marshal(map[string]any{"action": action})
response, err := http.Post(url, "application/json", bytes.NewReader(body)); if err != nil { panic(err) }
defer response.Body.Close()
var built map[string]any; if err := json.NewDecoder(response.Body).Decode(&built); err != nil { panic(err) }
fmt.Println("hash:", built["hash"], "nonce:", built["nonce"], "action:", built["action"])
}
func main() {
url := strings.TrimRight(os.Getenv("QUICKNODE_ENDPOINT"), "/") + "/hypercore/exchange"
orderID, err := strconv.ParseInt(os.Getenv("ORDER_ID_TO_CANCEL"), 10, 64); if err != nil { panic(err) }
actions := []map[string]any{
{"type":"order", "orders":[]any{map[string]any{"asset":"BTC", "side":"buy", "price":"60000", "size":"0.001", "tif":"gtc"}}},
{"type":"order", "orders":[]any{map[string]any{
"a":"BTC", "b":false, "p":"50000", "s":"0.001", "r":true,
"t":map[string]any{"trigger":map[string]any{"isMarket":true, "triggerPx":"55000", "tpsl":"sl"}},
}}, "grouping":"positionTpsl"},
{"type":"order", "orders":[]any{map[string]any{
"a":"BTC", "b":false, "p":"90000", "s":"0.001", "r":true,
"t":map[string]any{"trigger":map[string]any{"isMarket":true, "triggerPx":"90000", "tpsl":"tp"}},
}}, "grouping":"positionTpsl"},
{"type":"cancel", "cancels":[]any{map[string]any{"a":"BTC", "o":orderID}}},
{"type":"twapOrder", "twap":map[string]any{"a":"BTC", "b":true, "s":"0.01", "r":false, "m":30, "t":true}},
{"type":"updateLeverage", "asset":"BTC", "isCross":true, "leverage":3},
}
for _, action := range actions { build(url, action) }
}
Run the example
go run .
Monitor market and order flow in real time
Watch trades, orders, and order-book changes as they happen. JavaScript shows WebSocket and gRPC together; cURL and Python focus on gRPC L2 and L4 data, while Ruby and Go focus on WebSocket updates. The cURL example also uses ORDER_PRIORITY to track pending and confirmed priority-fee actions.
- cURL
- JavaScript
Python
- Ruby
- Go
Copy the gRPC provider details and set up cURL
In the Quicknode dashboard, open Endpoints and select your Hyperliquid endpoint. Under API access URL, select GRPC. Copy the Hypercore value into GRPC_ENDPOINT and the Auth Token value into AUTH_TOKEN. The downloaded schemas define the L2, L4, and priority streams used below.
brew install grpcurl jq
mkdir hypercore-grpc && cd hypercore-grpc
curl -O https://raw.githubusercontent.com/quiknode-labs/hypercore-grpc-examples/main/proto/hyperliquid.proto
curl -O https://raw.githubusercontent.com/quiknode-labs/hypercore-grpc-examples/main/proto/orderbook.proto
export GRPC_ENDPOINT="your-endpoint.hype-mainnet.quiknode.pro:10000"
export AUTH_TOKEN="YOUR_QUICKNODE_TOKEN"
Stream aggregated L2 depth
StreamL2Book returns the current aggregated bid and ask levels. This command prints a compact top-of-book snapshot.
grpcurl -proto orderbook.proto \
-H "x-token: $AUTH_TOKEN" \
-d '{"coin":"BTC","nLevels":20}' \
"$GRPC_ENDPOINT" hyperliquid.OrderBookStreaming/StreamL2Book | \
jq -c --unbuffered '{coin, blockNumber, bestBid: .bids[0], bestAsk: .asks[0]}' | \
head -n 1
Watch typed L4 order changes
The first message is a reset snapshot. Later NEW, UPDATE, and REMOVE diffs include the actual order ID and owner address. This command prints three representative orders from the first update.
grpcurl -proto orderbook.proto \
-max-msg-sz 104857600 \
-H "x-token: $AUTH_TOKEN" \
-d '{"coins":["BTC"]}' \
"$GRPC_ENDPOINT" hyperliquid.OrderBookStreaming/StreamL4BookUpdates | \
jq -c --unbuffered '{height, snapshot, diffs: (.diffs[:3] | map({diffType, coin, oid, user, side, px, sz}))}' | \
head -n 1
Inspect mempool priority fees
ORDER_PRIORITY is an additional StreamData feed that normalizes priority-fee actions from mempool_txs and confirmed replica_cmds. Treat mempool events as pre-consensus observations, not finalized transactions.
{ printf '%s
' '{"subscribe":{"streamType":"ORDER_PRIORITY","filters":{"coin":{"values":["BTC"]}}}}'; sleep 10; } | \
grpcurl -proto hyperliquid.proto \
-H "x-token: $AUTH_TOKEN" \
-d @ "$GRPC_ENDPOINT" hyperliquid.Streaming/StreamData | \
jq -c --unbuffered 'select(.data.data) | (.data.data | fromjson) | {source, coin, side, p, outcome}' | \
head -n 1
Copy the WebSocket and gRPC provider details
In the Quicknode dashboard, open Endpoints and select your Hyperliquid endpoint. Under API access URL, select WSS and copy the Hypercore URL into WSS_PROVIDER_URL. Then select GRPC, copy the Hypercore value into GRPC_ENDPOINT, and copy Auth Token into AUTH_TOKEN.
mkdir hyperliquid-quickstart && cd hyperliquid-quickstart
npm init -y
npm install ws @grpc/grpc-js @grpc/proto-loader
curl -O https://raw.githubusercontent.com/quiknode-labs/hypercore-grpc-examples/main/proto/orderbook.proto
export WSS_PROVIDER_URL="PASTE_THE_HYPERCORE_WSS_URL_HERE"
export GRPC_ENDPOINT="your-endpoint.hype-mainnet.quiknode.pro:10000"
export AUTH_TOKEN="YOUR_QUICKNODE_TOKEN"
Create the JavaScript example
Create example.js. Subscribe to BTC trades, orders, and book updates over WebSocket while concurrently monitoring L2 depth and typed L4 changes over gRPC.
const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');
const WebSocket = require('ws');
const socket = new WebSocket(process.env.WSS_PROVIDER_URL);
const websocketStreams = ['trades', 'orders', 'book_updates'];
const lastWebSocketPrint = new Map();
socket.on('open', () => {
websocketStreams.forEach((streamType, index) => {
socket.send(JSON.stringify({
jsonrpc: '2.0', id: index + 1, method: 'hl_subscribe',
params: { streamType, filters: { coin: ['BTC'] } },
}));
});
});
socket.on('message', message => {
const payload = JSON.parse(message.toString());
const event = payload.params?.result ?? payload;
if (!event.stream || Date.now() - (lastWebSocketPrint.get(event.stream) ?? 0) < 1000) return;
lastWebSocketPrint.set(event.stream, Date.now());
console.log({
transport: 'WebSocket', stream: event.stream,
block: event.block?.block_number, events: event.block?.events?.length ?? 0,
});
});
const definition = protoLoader.loadSync('orderbook.proto', {
keepCase: false, longs: String, enums: String, defaults: true, oneofs: true,
});
const proto = grpc.loadPackageDefinition(definition).hyperliquid;
const client = new proto.OrderBookStreaming(
process.env.GRPC_ENDPOINT,
grpc.credentials.createSsl(),
{ 'grpc.max_receive_message_length': 100 * 1024 * 1024 },
);
const metadata = new grpc.Metadata();
metadata.add('x-token', process.env.AUTH_TOKEN);
const l2 = client.StreamL2Book({ coin: 'BTC', nLevels: 20 }, metadata);
const l4 = client.StreamL4BookUpdates({ coins: ['BTC'] }, metadata);
let lastL2Print = 0;
let lastL4Print = 0;
l2.on('data', update => {
if (Date.now() - lastL2Print < 1000) return;
lastL2Print = Date.now();
console.log({
transport: 'gRPC', stream: 'L2', block: update.blockNumber,
bestBid: update.bids[0], bestAsk: update.asks[0],
});
});
l4.on('data', update => {
if (Date.now() - lastL4Print < 1000) return;
lastL4Print = Date.now();
console.log({
transport: 'gRPC', stream: 'L4', height: update.height,
snapshot: update.snapshot, changes: update.diffs.length,
orderIds: update.diffs.slice(0, 3).map(diff => diff.oid),
});
});
for (const stream of [l2, l4]) {
stream.on('error', error => {
if (error.code !== grpc.status.CANCELLED) console.error(error);
});
}
process.on('SIGINT', () => {
socket.close();
l2.cancel();
l4.cancel();
client.close();
});
Run the example
node example.js
Copy the gRPC provider details and set up Python
In the Quicknode dashboard, open Endpoints and select your Hyperliquid endpoint. Under API access URL, select GRPC. Copy the Hypercore value into GRPC_ENDPOINT and the Auth Token value into AUTH_TOKEN. This Python example uses gRPC only.
mkdir hyperliquid-quickstart && cd hyperliquid-quickstart
python3 -m venv .venv
source .venv/bin/activate
pip install requests
pip install grpcio grpcio-tools
curl -O https://raw.githubusercontent.com/quiknode-labs/hypercore-grpc-examples/main/proto/orderbook.proto
python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. orderbook.proto
export GRPC_ENDPOINT="your-endpoint.hype-mainnet.quiknode.pro:10000"
export AUTH_TOKEN="YOUR_QUICKNODE_TOKEN"
Create the Python example
Create example.py. Monitor StreamL2Book and StreamL4BookUpdates concurrently, including L4 snapshot resets and real order IDs.
import os
import signal
import threading
import time
import grpc
import orderbook_pb2
import orderbook_pb2_grpc
channel = grpc.secure_channel(
os.environ["GRPC_ENDPOINT"],
grpc.ssl_channel_credentials(),
options=[("grpc.max_receive_message_length", 100 * 1024 * 1024)],
)
stub = orderbook_pb2_grpc.OrderBookStreamingStub(channel)
metadata = [("x-token", os.environ["AUTH_TOKEN"])]
stop = threading.Event()
calls = []
def stream_l2():
call = stub.StreamL2Book(
orderbook_pb2.L2BookRequest(coin="BTC", n_levels=20), metadata=metadata
)
calls.append(call)
last_printed = 0
try:
for update in call:
if stop.is_set():
break
if time.time() - last_printed < 1:
continue
last_printed = time.time()
print({
"stream": "L2", "block": update.block_number,
"best_bid": update.bids[0].px if update.bids else None,
"best_ask": update.asks[0].px if update.asks else None,
})
except grpc.RpcError:
if not stop.is_set():
raise
def stream_l4():
call = stub.StreamL4BookUpdates(
orderbook_pb2.L4BookUpdatesRequest(coins=["BTC"]), metadata=metadata
)
calls.append(call)
last_printed = 0
try:
for update in call:
if stop.is_set():
break
if time.time() - last_printed < 1:
continue
last_printed = time.time()
print({
"stream": "L4", "height": update.height,
"snapshot": update.snapshot, "changes": len(update.diffs),
"order_ids": [diff.oid for diff in update.diffs[:3]],
})
except grpc.RpcError:
if not stop.is_set():
raise
threads = [threading.Thread(target=stream_l2), threading.Thread(target=stream_l4)]
for thread in threads:
thread.start()
try:
while any(thread.is_alive() for thread in threads):
time.sleep(0.2)
except KeyboardInterrupt:
signal.signal(signal.SIGINT, signal.SIG_IGN)
finally:
stop.set()
for call in calls:
call.cancel()
for thread in threads:
thread.join()
channel.close()
Run the example
python example.py
Copy the Hypercore WSS URL and set up Ruby
In the Quicknode dashboard, open Endpoints and select your Hyperliquid endpoint. Under API access URL, select WSS and copy the complete Hypercore URL into WSS_PROVIDER_URL. This Ruby example uses WebSocket only.
mkdir hyperliquid-quickstart && cd hyperliquid-quickstart
gem install websocket-client-simple
export WSS_PROVIDER_URL="PASTE_THE_HYPERCORE_WSS_URL_HERE"
Create the Ruby example
Create example.rb. Subscribe to BTC trades, orders, and book updates over WebSocket and print one concise summary per stream each second.
require "json"
require "websocket-client-simple"
ws = WebSocket::Client::Simple.connect(ENV.fetch("WSS_PROVIDER_URL"))
subscriptions = %w[trades orders book_updates]
last_printed = {}
ws.on :open do
subscriptions.each_with_index do |stream, index|
ws.send(JSON.dump(jsonrpc: "2.0", id: index + 1, method: "hl_subscribe",
params: { streamType: stream, filters: { coin: ["BTC"] } }))
end
end
ws.on :message do |message|
data = JSON.parse(message.data)
event = data.dig("params", "result") || data
stream = event["stream"]
next unless stream && Time.now.to_i > (last_printed[stream] || 0)
last_printed[stream] = Time.now.to_i
block = event["block"] || {}
puts({ stream: stream, block: block["block_number"], events: (block["events"] || []).length }.to_json)
end
trap("INT") { ws.close; exit }
sleep
Run the example
ruby example.rb
Copy the Hypercore WSS URL and set up Go
In the Quicknode dashboard, open Endpoints and select your Hyperliquid endpoint. Under API access URL, select WSS and copy the complete Hypercore URL into WSS_PROVIDER_URL. This Go example uses WebSocket only.
mkdir hyperliquid-quickstart && cd hyperliquid-quickstart
go mod init hyperliquid-quickstart
go get nhooyr.io/websocket
export WSS_PROVIDER_URL="PASTE_THE_HYPERCORE_WSS_URL_HERE"
Create the Go example
Create main.go. Subscribe to BTC trades, orders, and book updates over WebSocket and print one concise summary per stream each second.
package main
import ("context"; "encoding/json"; "fmt"; "os"; "os/signal"; "time"; "nhooyr.io/websocket")
type rpcMessage struct {
Result json.RawMessage `json:"result"`
Params struct { Result json.RawMessage `json:"result"` } `json:"params"`
Error *struct { Code int `json:"code"`; Message string `json:"message"` } `json:"error"`
}
type streamEvent struct {
Stream string `json:"stream"`
Block struct { Number uint64 `json:"block_number"`; Events []json.RawMessage `json:"events"` } `json:"block"`
}
func main() {
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt); defer stop()
url := os.Getenv("WSS_PROVIDER_URL")
conn, _, err := websocket.Dial(ctx, url, nil); if err != nil { panic(err) }
conn.SetReadLimit(100 << 20)
defer conn.Close(websocket.StatusNormalClosure, "done")
for id, stream := range []string{"trades", "orders", "book_updates"} {
request := map[string]any{"jsonrpc":"2.0", "id":id+1, "method":"hl_subscribe", "params":map[string]any{"streamType":stream, "filters":map[string]any{"coin":[]string{"BTC"}}}}
data, _ := json.Marshal(request); if err := conn.Write(ctx, websocket.MessageText, data); err != nil { panic(err) }
}
last := map[string]time.Time{}
for {
_, data, err := conn.Read(ctx); if err != nil { if ctx.Err() != nil { return }; panic(err) }
var message rpcMessage; if err := json.Unmarshal(data, &message); err != nil { panic(err) }
if message.Error != nil { panic(fmt.Sprintf("WebSocket error %d: %s", message.Error.Code, message.Error.Message)) }
payload := data
if len(message.Params.Result) > 0 { payload = message.Params.Result }
var event streamEvent; if err := json.Unmarshal(payload, &event); err != nil { panic(err) }
if event.Stream == "" || time.Since(last[event.Stream]) < time.Second { continue }
last[event.Stream] = time.Now()
summary, _ := json.Marshal(map[string]any{"stream":event.Stream, "block":event.Block.Number, "events":len(event.Block.Events)})
fmt.Println(string(summary))
}
}
Run the example
go run .
Read HyperEVM with Ethereum JSON-RPC
Use the same JSON-RPC methods as Ethereum to read HyperEVM data. The examples check the network, retrieve the latest block number, and look up an account balance through the /evm endpoint.
- cURL
- JavaScript
Python
- Ruby
- Go
Copy the EVM provider URL and set up cURL
In the Quicknode dashboard, open Endpoints and select your Hyperliquid endpoint. Under API access URL, select RPC and copy the complete EVM HTTPS URL into EVM_PROVIDER_URL, including its /evm ending. The setup removes that ending and stores the reusable base URL in QUICKNODE_ENDPOINT.
export EVM_PROVIDER_URL="PASTE_THE_EVM_HTTPS_URL_HERE"
export QUICKNODE_ENDPOINT="$(printf '%s' "$EVM_PROVIDER_URL" | sed 's#/evm/*$##')"
export HYPEREVM_ADDRESS="0xADDRESS_TO_INSPECT"
Read HyperEVM state
These standard Ethereum JSON-RPC calls verify the chain, return the latest block, and inspect a native HYPE balance.
curl "$QUICKNODE_ENDPOINT/evm" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_chainId","params":[]}'
curl "$QUICKNODE_ENDPOINT/evm" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":2,"method":"eth_blockNumber","params":[]}'
curl "$QUICKNODE_ENDPOINT/evm" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":3,"method":"eth_getBalance","params":["'"$HYPEREVM_ADDRESS"'","latest"]}'
Copy the EVM provider URL and set up JavaScript
In the Quicknode dashboard, open Endpoints and select your Hyperliquid endpoint. Under API access URL, select RPC and copy the complete EVM HTTPS URL into EVM_PROVIDER_URL, including its /evm ending. The setup removes that ending and stores the reusable base URL in QUICKNODE_ENDPOINT.
mkdir hyperliquid-quickstart && cd hyperliquid-quickstart
npm init -y
export EVM_PROVIDER_URL="PASTE_THE_EVM_HTTPS_URL_HERE"
export QUICKNODE_ENDPOINT="$(printf '%s' "$EVM_PROVIDER_URL" | sed 's#/evm/*$##')"
export HYPEREVM_ADDRESS="0xADDRESS_TO_INSPECT"
Create the JavaScript example
Create example.js. Call standard Ethereum JSON-RPC methods through the HyperEVM /evm path.
const endpoint = process.env.QUICKNODE_ENDPOINT.replace(/\/$/, '') + '/evm';
const address = process.env.HYPEREVM_ADDRESS;
let id = 0;
async function rpc(method, params = []) {
const response = await fetch(endpoint, {
method: 'POST', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ jsonrpc: '2.0', id: ++id, method, params }),
});
const payload = await response.json();
if (payload.error) throw new Error(payload.error.message);
return payload.result;
}
async function main() {
const [chain, block, balance] = await Promise.all([
rpc('eth_chainId'), rpc('eth_blockNumber'), rpc('eth_getBalance', [address, 'latest']),
]);
console.log({ chainId: parseInt(chain, 16), block: parseInt(block, 16), balanceWei: BigInt(balance).toString() });
}
main().catch(error => {
console.error(error);
process.exitCode = 1;
});
Run the example
node example.js
Copy the EVM provider URL and set up Python
In the Quicknode dashboard, open Endpoints and select your Hyperliquid endpoint. Under API access URL, select RPC and copy the complete EVM HTTPS URL into EVM_PROVIDER_URL, including its /evm ending. The setup removes that ending and stores the reusable base URL in QUICKNODE_ENDPOINT.
mkdir hyperliquid-quickstart && cd hyperliquid-quickstart
python3 -m venv .venv
source .venv/bin/activate
pip install requests
export EVM_PROVIDER_URL="PASTE_THE_EVM_HTTPS_URL_HERE"
export QUICKNODE_ENDPOINT="$(printf '%s' "$EVM_PROVIDER_URL" | sed 's#/evm/*$##')"
export HYPEREVM_ADDRESS="0xADDRESS_TO_INSPECT"
Create the Python example
Create example.py. Call standard Ethereum JSON-RPC methods through the HyperEVM /evm path.
import os
from concurrent.futures import ThreadPoolExecutor
import requests
url = os.environ["QUICKNODE_ENDPOINT"].rstrip("/") + "/evm"
address = os.environ["HYPEREVM_ADDRESS"]
def rpc(method, params=None):
response = requests.post(url, json={"jsonrpc": "2.0", "id": 1, "method": method, "params": params or []}, timeout=30)
response.raise_for_status()
return response.json()["result"]
with ThreadPoolExecutor(max_workers=3) as pool:
chain = pool.submit(rpc, "eth_chainId")
block = pool.submit(rpc, "eth_blockNumber")
balance = pool.submit(rpc, "eth_getBalance", [address, "latest"])
print({"chain_id": int(chain.result(), 16), "block": int(block.result(), 16), "balance_wei": int(balance.result(), 16)})
Run the example
python example.py
Copy the EVM provider URL and set up Ruby
In the Quicknode dashboard, open Endpoints and select your Hyperliquid endpoint. Under API access URL, select RPC and copy the complete EVM HTTPS URL into EVM_PROVIDER_URL, including its /evm ending. The setup removes that ending and stores the reusable base URL in QUICKNODE_ENDPOINT.
mkdir hyperliquid-quickstart && cd hyperliquid-quickstart
export EVM_PROVIDER_URL="PASTE_THE_EVM_HTTPS_URL_HERE"
export QUICKNODE_ENDPOINT="$(printf '%s' "$EVM_PROVIDER_URL" | sed 's#/evm/*$##')"
export HYPEREVM_ADDRESS="0xADDRESS_TO_INSPECT"
Create the Ruby example
Create example.rb. Call standard Ethereum JSON-RPC methods through the HyperEVM /evm path.
require "json"
require "net/http"
uri = URI(ENV.fetch("QUICKNODE_ENDPOINT").sub(%r{/$}, "") + "/evm")
def rpc(uri, method, params = [])
payload = { jsonrpc: "2.0", id: 1, method: method, params: params }
response = Net::HTTP.post(uri, JSON.dump(payload), "Content-Type" => "application/json")
raise response.body unless response.is_a?(Net::HTTPSuccess)
JSON.parse(response.body)["result"]
end
chain = rpc(uri, "eth_chainId")
block = rpc(uri, "eth_blockNumber")
balance = rpc(uri, "eth_getBalance", [ENV.fetch("HYPEREVM_ADDRESS"), "latest"])
puts({ chain_id: chain.to_i(16), block: block.to_i(16), balance_wei: balance.to_i(16) }.to_json)
Run the example
ruby example.rb
Copy the EVM provider URL and set up Go
In the Quicknode dashboard, open Endpoints and select your Hyperliquid endpoint. Under API access URL, select RPC and copy the complete EVM HTTPS URL into EVM_PROVIDER_URL, including its /evm ending. The setup removes that ending and stores the reusable base URL in QUICKNODE_ENDPOINT.
mkdir hyperliquid-quickstart && cd hyperliquid-quickstart
go mod init hyperliquid-quickstart
export EVM_PROVIDER_URL="PASTE_THE_EVM_HTTPS_URL_HERE"
export QUICKNODE_ENDPOINT="$(printf '%s' "$EVM_PROVIDER_URL" | sed 's#/evm/*$##')"
export HYPEREVM_ADDRESS="0xADDRESS_TO_INSPECT"
Create the Go example
Create main.go. Call standard Ethereum JSON-RPC methods through the HyperEVM /evm path.
package main
import ("bytes"; "encoding/json"; "fmt"; "math/big"; "net/http"; "os"; "strings")
func rpc(url, method string, params []any) string {
body, _ := json.Marshal(map[string]any{"jsonrpc":"2.0", "id":1, "method":method, "params":params})
response, err := http.Post(url, "application/json", bytes.NewReader(body)); if err != nil { panic(err) }; defer response.Body.Close()
var payload struct{ Result string `json:"result"` }; if err := json.NewDecoder(response.Body).Decode(&payload); err != nil { panic(err) }; return payload.Result
}
func hexInt(value string) *big.Int { result := new(big.Int); result.SetString(strings.TrimPrefix(value, "0x"), 16); return result }
func main() {
url := strings.TrimRight(os.Getenv("QUICKNODE_ENDPOINT"), "/") + "/evm"
fmt.Println("chain ID:", hexInt(rpc(url, "eth_chainId", nil)))
fmt.Println("block:", hexInt(rpc(url, "eth_blockNumber", nil)))
fmt.Println("balance (wei):", hexInt(rpc(url, "eth_getBalance", []any{os.Getenv("HYPEREVM_ADDRESS"), "latest"})))
}
Run the example
go run .
Query blocks or analyze long-term history
Find the latest completed HyperCore trades block and filter its trades to BTC. You can use the same methods for orders, events, order-book updates, or TWAP activity; for analysis across longer time ranges, query indexed Hyperliquid data with SQL Explorer.
- cURL
- JavaScript
Python
- Ruby
- Go
Copy the EVM provider URL and set up cURL
In the Quicknode dashboard, open Endpoints and select your Hyperliquid endpoint. Under API access URL, select RPC and copy the complete EVM HTTPS URL into EVM_PROVIDER_URL, including its /evm ending. The setup removes that ending and stores the reusable base URL in QUICKNODE_ENDPOINT.
export EVM_PROVIDER_URL="PASTE_THE_EVM_HTTPS_URL_HERE"
export QUICKNODE_ENDPOINT="$(printf '%s' "$EVM_PROVIDER_URL" | sed 's#/evm/*$##')"
Fetch the latest completed trade block
Resolve the current trade-stream height, fetch the preceding completed block, and filter its events to BTC trades. Change trades to orders, events, book, twap, or writer_actions for another dataset.
LATEST=$(curl -sS "$QUICKNODE_ENDPOINT/hypercore" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"hl_getLatestBlockNumber","params":["trades"]}' \
| jq -r '.result - 1') && \
curl -sS "$QUICKNODE_ENDPOINT/hypercore" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":2,"method":"hl_getBlock","params":["trades",'"$LATEST"']}' \
| jq '.result.events |= map(select(.[1].coin == "BTC"))'
Copy the EVM provider URL and set up JavaScript
In the Quicknode dashboard, open Endpoints and select your Hyperliquid endpoint. Under API access URL, select RPC and copy the complete EVM HTTPS URL into EVM_PROVIDER_URL, including its /evm ending. The setup removes that ending and stores the reusable base URL in QUICKNODE_ENDPOINT.
mkdir hyperliquid-quickstart && cd hyperliquid-quickstart
npm init -y
export EVM_PROVIDER_URL="PASTE_THE_EVM_HTTPS_URL_HERE"
export QUICKNODE_ENDPOINT="$(printf '%s' "$EVM_PROVIDER_URL" | sed 's#/evm/*$##')"
Create the JavaScript example
Create example.js. Resolve the latest trade-stream height, fetch the preceding completed HyperCore block, and print only its BTC trades.
const endpoint = process.env.QUICKNODE_ENDPOINT.replace(/\/$/, '') + '/hypercore';
let id = 0;
async function rpc(method, params) {
const response = await fetch(endpoint, {
method: 'POST', headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ jsonrpc: '2.0', id: ++id, method, params }),
});
const payload = await response.json();
if (payload.error) throw new Error(payload.error.message);
return payload.result;
}
async function main() {
const latest = (await rpc('hl_getLatestBlockNumber', ['trades'])) - 1;
const block = await rpc('hl_getBlock', ['trades', latest]);
const btc = (block.events || []).map(event => event[1]).filter(event => event?.coin === 'BTC');
console.log({ block: latest, btcTrades: btc.length });
console.table(btc.slice(0, 10));
}
main().catch(error => {
console.error(error);
process.exitCode = 1;
});
Run the example
node example.js
Copy the EVM provider URL and set up Python
In the Quicknode dashboard, open Endpoints and select your Hyperliquid endpoint. Under API access URL, select RPC and copy the complete EVM HTTPS URL into EVM_PROVIDER_URL, including its /evm ending. The setup removes that ending and stores the reusable base URL in QUICKNODE_ENDPOINT.
mkdir hyperliquid-quickstart && cd hyperliquid-quickstart
python3 -m venv .venv
source .venv/bin/activate
pip install requests
export EVM_PROVIDER_URL="PASTE_THE_EVM_HTTPS_URL_HERE"
export QUICKNODE_ENDPOINT="$(printf '%s' "$EVM_PROVIDER_URL" | sed 's#/evm/*$##')"
Create the Python example
Create example.py. Resolve the latest trade-stream height, fetch the preceding completed HyperCore block, and print only its BTC trades.
import os
import requests
url = os.environ["QUICKNODE_ENDPOINT"].rstrip("/") + "/hypercore"
def rpc(method, params):
response = requests.post(url, json={"jsonrpc": "2.0", "id": 1, "method": method, "params": params}, timeout=30)
response.raise_for_status()
return response.json()["result"]
latest = rpc("hl_getLatestBlockNumber", ["trades"]) - 1
block = rpc("hl_getBlock", ["trades", latest])
btc = [event[1] for event in block.get("events", []) if len(event) > 1 and event[1].get("coin") == "BTC"]
print({"block": latest, "btc_trades": len(btc)})
print(btc[:10])
Run the example
python example.py
Copy the EVM provider URL and set up Ruby
In the Quicknode dashboard, open Endpoints and select your Hyperliquid endpoint. Under API access URL, select RPC and copy the complete EVM HTTPS URL into EVM_PROVIDER_URL, including its /evm ending. The setup removes that ending and stores the reusable base URL in QUICKNODE_ENDPOINT.
mkdir hyperliquid-quickstart && cd hyperliquid-quickstart
export EVM_PROVIDER_URL="PASTE_THE_EVM_HTTPS_URL_HERE"
export QUICKNODE_ENDPOINT="$(printf '%s' "$EVM_PROVIDER_URL" | sed 's#/evm/*$##')"
Create the Ruby example
Create example.rb. Resolve the latest trade-stream height, fetch the preceding completed HyperCore block, and print only its BTC trades.
require "json"
require "net/http"
uri = URI(ENV.fetch("QUICKNODE_ENDPOINT").sub(%r{/$}, "") + "/hypercore")
def rpc(uri, method, params)
payload = { jsonrpc: "2.0", id: 1, method: method, params: params }
response = Net::HTTP.post(uri, JSON.dump(payload), "Content-Type" => "application/json")
raise response.body unless response.is_a?(Net::HTTPSuccess)
JSON.parse(response.body)["result"]
end
latest = rpc(uri, "hl_getLatestBlockNumber", ["trades"]) - 1
block = rpc(uri, "hl_getBlock", ["trades", latest])
btc = (block["events"] || []).map { |event| event[1] }.select { |event| event["coin"] == "BTC" }
puts({ block: latest, btc_trades: btc.length }.to_json)
puts JSON.pretty_generate(btc.first(10))
Run the example
ruby example.rb
Copy the EVM provider URL and set up Go
In the Quicknode dashboard, open Endpoints and select your Hyperliquid endpoint. Under API access URL, select RPC and copy the complete EVM HTTPS URL into EVM_PROVIDER_URL, including its /evm ending. The setup removes that ending and stores the reusable base URL in QUICKNODE_ENDPOINT.
mkdir hyperliquid-quickstart && cd hyperliquid-quickstart
go mod init hyperliquid-quickstart
export EVM_PROVIDER_URL="PASTE_THE_EVM_HTTPS_URL_HERE"
export QUICKNODE_ENDPOINT="$(printf '%s' "$EVM_PROVIDER_URL" | sed 's#/evm/*$##')"
Create the Go example
Create main.go. Resolve the latest trade-stream height, fetch the preceding completed HyperCore block, and print only its BTC trades.
package main
import ("bytes"; "encoding/json"; "fmt"; "net/http"; "os"; "strings")
func rpc(url, method string, params []any, result any) {
body, _ := json.Marshal(map[string]any{"jsonrpc":"2.0", "id":1, "method":method, "params":params})
response, err := http.Post(url, "application/json", bytes.NewReader(body)); if err != nil { panic(err) }; defer response.Body.Close()
var payload struct{ Result json.RawMessage `json:"result"` }; if err := json.NewDecoder(response.Body).Decode(&payload); err != nil { panic(err) }
if err := json.Unmarshal(payload.Result, result); err != nil { panic(err) }
}
func main() {
url := strings.TrimRight(os.Getenv("QUICKNODE_ENDPOINT"), "/") + "/hypercore"
var latest int64; rpc(url, "hl_getLatestBlockNumber", []any{"trades"}, &latest); latest--
var block map[string]any; rpc(url, "hl_getBlock", []any{"trades", latest}, &block)
events, _ := block["events"].([]any)
btcTrades := 0
for _, raw := range events {
event, ok := raw.([]any); if !ok || len(event) < 2 { continue }
trade, ok := event[1].(map[string]any); if ok && trade["coin"] == "BTC" { btcTrades++ }
}
fmt.Println("block:", latest, "BTC trades:", btcTrades)
}
Run the example
go run .
Continue with the HyperCore overview or HyperEVM overview for endpoint URLs, authentication, and protocol details. For client libraries, see Hyperliquid SDKs.
If you want to continue learning about making API requests, check out our Hyperliquid guides and sample apps.