Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
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