Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
28a20da
update to handle subscription responses
Feb 23, 2026
3ce8ace
small fix to remove string view
Feb 23, 2026
5a2aee2
refactor naming and approach
Mar 9, 2026
8d001cb
add support for fetching all spot/perp metadata async/sync
Mar 9, 2026
5bd21ca
build symbol to hyperliquid security id map
Mar 9, 2026
392de4d
add sign l1 request and place order implementation
Mar 10, 2026
609dae3
implement rest place and cancel orders
Mar 14, 2026
1fcf33f
resolve build issues
Mar 14, 2026
7fc4b21
Allow websocket to submit post requests
Mar 14, 2026
5b526d8
small fixes and test fill scenario
Mar 15, 2026
f77c76e
dont leak the test targets
Mar 15, 2026
ae308ff
track if the message is a snapshot for fills and order updates
Mar 15, 2026
44c40cb
fix ping pong
Mar 15, 2026
a79bc0e
add debug output logging
Mar 15, 2026
ee938b8
cleanup a few small nits
Mar 18, 2026
6744b82
update l2 book updates to be snapshots
Apr 26, 2026
a4d3ee6
remove old incremental approach to l2book
Apr 26, 2026
89eb441
initial support for trading outcomes
May 2, 2026
f83cb0d
parse the dates properly
May 2, 2026
237b8b7
add async outcome info endpoint
May 2, 2026
ec4a8b7
refactor to allow direct asset id
May 3, 2026
1a5de89
fix a restart loop bug
May 8, 2026
94bb8af
add optional correlation id for consumers to track requests
May 9, 2026
f625b1e
support an optional vault address for subaccounts
May 10, 2026
34d59ce
example of amending to crossing order
May 11, 2026
8433837
update amend order
May 13, 2026
672416c
support more reject types
May 23, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
*.dll
*.so.*


# Fortran module files
*.mod
*.smod
Expand Down Expand Up @@ -66,4 +65,10 @@ vcpkg_installed/

# test output & cache
Testing/
.cache/
.cache/

# IDE
.idea/

# example config with secrets
test.json
64 changes: 52 additions & 12 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.16)
project(hyperliquid-sdk-cpp VERSION 0.1.0 LANGUAGES CXX)
project(hyperliquid-sdk-cpp VERSION 0.1.0 LANGUAGES C CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
Expand All @@ -8,13 +8,39 @@ find_package(OpenSSL REQUIRED)
find_package(Boost REQUIRED COMPONENTS system)
find_package(simdjson CONFIG REQUIRED)
find_package(nlohmann_json CONFIG REQUIRED)
find_package(spdlog CONFIG REQUIRED)

include(FetchContent)
FetchContent_Declare(
secp256k1
GIT_REPOSITORY https://github.com/bitcoin-core/secp256k1.git
GIT_TAG v0.7.1
)
set(SECP256K1_ENABLE_MODULE_RECOVERY ON CACHE BOOL "" FORCE)
set(SECP256K1_BUILD_TESTS OFF CACHE BOOL "" FORCE)
set(SECP256K1_BUILD_EXHAUSTIVE_TESTS OFF CACHE BOOL "" FORCE)
set(SECP256K1_BUILD_BENCHMARK OFF CACHE BOOL "" FORCE)
set(SECP256K1_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
set(SECP256K1_BUILD_CTIME_TESTS OFF CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(secp256k1)

set(SDK_SOURCES
src/websocket/WSRunner.cpp
src/websocket/MarketData.cpp
src/websocket/WSMessageParser.cpp
src/rest/RestMessageParser.cpp
src/rest/InfoApi.cpp
src/rest/RestApiMessageParser.cpp
src/rest/RestApi.cpp
src/rest/HttpSession.cpp
src/messages/InfoRequestBuilder.cpp
src/messages/ExchangeRequestBuilder.cpp
src/rest/SymbolMap.cpp
src/config/Config.cpp

src/websocket/WebsocketRunner.cpp
src/websocket/WebsocketApi.cpp
src/websocket/WebsocketMessageParser.cpp

src/signing/Signing.cpp
src/signing/SigningHelpers.cpp
src/signing/sha3.c

include/hyperliquid/types/RequestTypes.h
)

Expand All @@ -25,7 +51,6 @@ target_include_directories(hyperliquid-sdk
${CMAKE_CURRENT_SOURCE_DIR}/include
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src
${CMAKE_CURRENT_SOURCE_DIR}/src/websocket
)

target_link_libraries(hyperliquid-sdk
Expand All @@ -35,6 +60,8 @@ target_link_libraries(hyperliquid-sdk
OpenSSL::Crypto
nlohmann_json::nlohmann_json
simdjson::simdjson
secp256k1
spdlog::spdlog
)

if(NOT MSVC)
Expand All @@ -48,11 +75,24 @@ set_target_properties(hyperliquid-sdk PROPERTIES
)

option(HYPERLIQUID_BUILD_EXAMPLES "Build example programs" OFF)
option(HYPERLIQUID_BUILD_TESTS "Build tests" OFF)

if(HYPERLIQUID_BUILD_EXAMPLES)
add_executable(print_book examples/print_book.cpp)
target_link_libraries(print_book PRIVATE hyperliquid-sdk)
if(HYPERLIQUID_BUILD_TESTS)
enable_testing()
find_package(GTest CONFIG REQUIRED)

add_executable(signing_test tests/signing_test.cpp)
target_link_libraries(signing_test PRIVATE hyperliquid-sdk GTest::gtest GTest::gtest_main nlohmann_json::nlohmann_json)
target_include_directories(signing_test PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src)
add_test(NAME signing_test COMMAND signing_test)
endif()

add_executable(fetch_meta examples/fetch_meta.cpp)
target_link_libraries(fetch_meta PRIVATE hyperliquid-sdk)
if(HYPERLIQUID_BUILD_EXAMPLES)
file(GLOB EXAMPLE_SOURCES examples/*.cpp)
foreach(EXAMPLE_SOURCE ${EXAMPLE_SOURCES})
get_filename_component(EXAMPLE_NAME ${EXAMPLE_SOURCE} NAME_WE)
add_executable(${EXAMPLE_NAME} ${EXAMPLE_SOURCE})
target_link_libraries(${EXAMPLE_NAME} PRIVATE hyperliquid-sdk nlohmann_json::nlohmann_json spdlog::spdlog)
target_compile_definitions(${EXAMPLE_NAME} PRIVATE EXAMPLES_DIR="${CMAKE_CURRENT_SOURCE_DIR}/examples/")
endforeach()
endif()
5 changes: 3 additions & 2 deletions CMakePresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
"name": "default",
"binaryDir": "${sourceDir}/build",
"cacheVariables": {
"CMAKE_TOOLCHAIN_FILE": "$env{HOME}/.vcpkg-clion/vcpkg/scripts/buildsystems/vcpkg.cmake",
"HYPERLIQUID_BUILD_EXAMPLES": "ON"
"CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake",
"HYPERLIQUID_BUILD_EXAMPLES": "ON",
"HYPERLIQUID_BUILD_TESTS": "ON"
}
}
]
Expand Down
5 changes: 5 additions & 0 deletions examples/example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"wallet": "0xYOUR_WALLET_ADDRESS",
"privateKey": "YOUR_PRIVATE_KEY",
"subaccount": "0xYOUR_SUBACCOUNT_ADDRESS_OR_NULL"
}
48 changes: 0 additions & 48 deletions examples/fetch_meta.cpp

This file was deleted.

67 changes: 0 additions & 67 deletions examples/print_book.cpp

This file was deleted.

64 changes: 64 additions & 0 deletions examples/rest_meta.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#include <hyperliquid/rest/RestApi.h>
#include <hyperliquid/rest/RestApiMessageParser.h>
#include <../include/hyperliquid/config/Config.h>
#include <spdlog/spdlog.h>

int main() {
hyperliquid::setLogLevel(hyperliquid::LogLevel::Debug);

hyperliquid::ApiConfig config;
config.env = hyperliquid::Environment::Mainnet;

hyperliquid::RestApi api(config);
hyperliquid::RestApiMessageParser parser;

spdlog::info("=== Spot ===");
auto spotMeta = parser.parseSpotMeta(api.spotMeta());

spdlog::info("{} assets:", spotMeta.tokens.size());
for (const auto& asset : spotMeta.tokens) {
spdlog::info(" {} szDecimals={}", asset.name, asset.szDecimals);
}

auto dexes = parser.parsePerpDexs(api.perpDexs());

spdlog::info("=== Outcomes ===");
auto rawOutcome = api.outcomeMeta();
spdlog::info(rawOutcome);
auto outcomeMeta = parser.parseOutcomeMeta(rawOutcome);
spdlog::info("{} outcomes:", outcomeMeta.outcomes.size());
for (const auto& outcome : outcomeMeta.outcomes) {
const auto& d = outcome.description;
spdlog::info(" [{}] {} class={} underlying={} expiry={} targetPrice={} period={}",
outcome.outcome, outcome.name, d.outcomeClass, d.underlying,
std::chrono::system_clock::to_time_t(d.expiry), d.targetPrice, d.period);
for (const auto& side : outcome.sideSpecs) {
spdlog::info(" side: {}", side.name);
}
}

spdlog::info("=== Perps ===");
auto defaultMeta = parser.parseMeta(api.meta());

spdlog::info("{} assets:", defaultMeta.universe.size());
for (const auto& asset : defaultMeta.universe) {
spdlog::info(" {} szDecimals={} maxLeverage={}", asset.name, asset.szDecimals, asset.maxLeverage);
}

spdlog::info("Found {} HIP-3 perp dexes:", dexes.dexes.size());
for (const auto& dex : dexes.dexes) {
spdlog::info(" {} ({}) deployer={}", dex.name, dex.fullName, dex.deployer);
}

for (const auto& dex : dexes.dexes) {
spdlog::info("=== {} ===", dex.name);
auto meta = parser.parseMeta(api.meta(dex.name));

spdlog::info("{} assets:", meta.universe.size());
for (const auto& asset : meta.universe) {
spdlog::info(" {} szDecimals={} maxLeverage={}", asset.name, asset.szDecimals, asset.maxLeverage);
}
}

return 0;
}
Loading