Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -198,13 +198,14 @@ Legend: ✅ implemented — ⬜ not yet implemented.
| `userDexAbstraction` (deprecated, use `userSetAbstraction`) | ✅ | `RestApi::userDexAbstraction` |
| `borrowLend` | ✅ | `RestApi::borrowLend` |
| `perpDeploy` (`registerAsset2` only - see note below) | ✅ | `RestApi::perpDeployRegisterAsset2` |
| `setReferrer` | ✅ | `RestApi::setReferrer` |
| `activateOutcomeDeployer` | ⬜ | |
| `agentEnableDexAbstraction` (deprecated, use `agentSetAbstraction`) | ⬜ | |
| `authorizeAqav2Role` | ⬜ | |
| `claimRewards` | ⬜ | |
| `convertToMultiSigUser` | ⬜ | |
| `createSubAccount` | ✅ | `RestApi::createSubAccount` |
| `createVault` | ⬜ | |
| `createVault` | ✅ | `RestApi::createVault` |
| `cSignerAction` | ⬜ | |
| `cValidatorAction` | ⬜ | |
| `evmUserModify` | ⬜ | |
Expand All @@ -213,7 +214,6 @@ Legend: ✅ implemented — ⬜ not yet implemented.
| `linkStakingUser` | ⬜ | |
| `registerReferrer` | ⬜ | |
| `setDisplayName` | ⬜ | |
| `setReferrer` | ⬜ | |
| `spotDeploy` (`registerToken2`) | ✅ | `RestApi::spotDeployRegisterToken2` |
| `spotDeploy` (`userGenesis`) | ✅ | `RestApi::spotDeployUserGenesis` |
| `spotDeploy` (`genesis`) | ✅ | `RestApi::spotDeployGenesis` |
Expand All @@ -236,7 +236,7 @@ Legend: ✅ implemented — ⬜ not yet implemented.
| `vaultDistribute` | ⬜ | |
| `vaultModify` | ⬜ | |

39 of 68 documented exchange actions implemented on REST (`RestApi`). `WebsocketApi` covers a smaller subset — `placeOrder`, `cancelOrder`, `cancelOrderByCloid`, `scheduleCancel`, `modifyOrder`, `batchModifyOrder` — plus posting `meta`/`spotMeta`/`outcomeMeta`/`perpDexs` info reads over the socket; the newer transfer/staking/TWAP actions are REST-only so far.
41 of 68 documented exchange actions implemented on REST (`RestApi`). `WebsocketApi` covers a smaller subset — `placeOrder`, `cancelOrder`, `cancelOrderByCloid`, `scheduleCancel`, `modifyOrder`, `batchModifyOrder` — plus posting `meta`/`spotMeta`/`outcomeMeta`/`perpDexs` info reads over the socket; the newer transfer/staking/TWAP actions are REST-only so far.

`perpDeploy` is a large multi-variant action (16 sub-actions sharing `"type": "perpDeploy"`); only `registerAsset2` (deploying a new HIP-3 perp asset, optionally creating a new dex) is implemented. The other 15 variants (`registerAsset`, `setOracle`, `setFundingMultipliers`, `setFundingInterestRates`, `haltTrading`, `setMarginTableIds`, `insertMarginTable`, `setFeeRecipient`, `setOpenInterestCaps`, `setSubDeployers`, `setMarginModes`, `setFeeScale`, `setGrowthModes`, `setPerpAnnotation`, `disableDex`) are post-deployment admin/config actions for an already-deployed dex and are not yet implemented.

Expand Down
31 changes: 31 additions & 0 deletions examples/rest_create_vault.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include "test_config.h"

#include <hyperliquid/rest/RestApi.h>
#include <hyperliquid/config/Config.h>
#include <spdlog/spdlog.h>

int main()
{
auto wallet = loadWalletFromConfig();
hyperliquid::setLogLevel(hyperliquid::LogLevel::Debug);

hyperliquid::ApiConfig config;
config.env = hyperliquid::Environment::Testnet;
config.wallet = wallet;

hyperliquid::RestApi api(config);

hyperliquid::CreateVaultRequest req;
req.name = "SDK Test Vault";
req.description = "Vault created by hyperliquid-sdk-cpp's rest_create_vault example.";
req.initialUsd = 100.0; // Hyperliquid requires at least 100 USD to create a vault.

auto resp = api.createVault(req);
spdlog::info("createVault: status={} type={}", resp.status, resp.type);
if (resp.vaultAddress)
spdlog::info(" New vault address: {}", *resp.vaultAddress);
if (resp.error)
spdlog::info(" Error: {}", *resp.error);

return 0;
}
27 changes: 27 additions & 0 deletions examples/rest_set_referrer.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#include "test_config.h"

#include <hyperliquid/rest/RestApi.h>
#include <hyperliquid/config/Config.h>
#include <spdlog/spdlog.h>

int main()
{
auto wallet = loadWalletFromConfig();
hyperliquid::setLogLevel(hyperliquid::LogLevel::Debug);

hyperliquid::ApiConfig config;
config.env = hyperliquid::Environment::Testnet;
config.wallet = wallet;

hyperliquid::RestApi api(config);

hyperliquid::SetReferrerRequest req;
req.code = "SDKTEST"; // Replace with a real testnet referral code before running.

auto resp = api.setReferrer(req);
spdlog::info("setReferrer: status={} type={}", resp.status, resp.type);
if (resp.error)
spdlog::info(" Error: {}", *resp.error);

return 0;
}
10 changes: 7 additions & 3 deletions include/hyperliquid/rest/RestApi.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,16 +146,17 @@ class RestApi {
const std::optional<std::string>& vaultAddress = std::nullopt);
TwapCancelResponse twapCancel(const TwapCancelRequest& request,
const std::optional<std::string>& vaultAddress = std::nullopt);
// vaultTransfer/hip3LiquidatorTransfer/createSubAccount/subAccountTransfer/borrowLend/
// usdClassTransfer/sendAsset/usdSend/spotSend/withdraw3/approveBuilderFee move funds (or
// manage sub-accounts) against the calling wallet directly (their target
// vaultTransfer/hip3LiquidatorTransfer/createSubAccount/subAccountTransfer/createVault/
// borrowLend/usdClassTransfer/sendAsset/usdSend/spotSend/withdraw3/approveBuilderFee move
// funds (or manage sub-accounts/vaults) against the calling wallet directly (their target
// vault/dex/destination/sub-account/etc. is a field of the request itself, or there is no
// vault-like target at all), so unlike the other exchange methods they do not take a
// vaultAddress parameter.
SimpleResponse vaultTransfer(const VaultTransferRequest& request);
SimpleResponse hip3LiquidatorTransfer(const Hip3LiquidatorTransferRequest& request);
CreateSubAccountResponse createSubAccount(const CreateSubAccountRequest& request);
SimpleResponse subAccountTransfer(const SubAccountTransferRequest& request);
CreateVaultResponse createVault(const CreateVaultRequest& request);
SimpleResponse borrowLend(const BorrowLendRequest& request);
SimpleResponse spotDeployRegisterToken2(const SpotDeployRegisterToken2Request& request);
SimpleResponse spotDeployUserGenesis(const SpotDeployUserGenesisRequest& request);
Expand All @@ -170,6 +171,7 @@ class RestApi {
SimpleResponse withdraw3(const Withdraw3Request& request);
SimpleResponse approveBuilderFee(const ApproveBuilderFeeRequest& request);
SimpleResponse userSetAbstraction(const UserSetAbstractionRequest& request);
SimpleResponse setReferrer(const SetReferrerRequest& request);
SimpleResponse cDeposit(uint64_t wei);
SimpleResponse cWithdraw(uint64_t wei);
SimpleResponse tokenDelegate(const TokenDelegateRequest& request);
Expand Down Expand Up @@ -297,6 +299,7 @@ class RestApi {
void hip3LiquidatorTransferAsync(const Hip3LiquidatorTransferRequest& request);
void createSubAccountAsync(const CreateSubAccountRequest& request);
void subAccountTransferAsync(const SubAccountTransferRequest& request);
void createVaultAsync(const CreateVaultRequest& request);
void borrowLendAsync(const BorrowLendRequest& request);
void spotDeployRegisterToken2Async(const SpotDeployRegisterToken2Request& request);
void spotDeployUserGenesisAsync(const SpotDeployUserGenesisRequest& request);
Expand All @@ -311,6 +314,7 @@ class RestApi {
void withdraw3Async(const Withdraw3Request& request);
void approveBuilderFeeAsync(const ApproveBuilderFeeRequest& request);
void userSetAbstractionAsync(const UserSetAbstractionRequest& request);
void setReferrerAsync(const SetReferrerRequest& request);
void cDepositAsync(uint64_t wei);
void cWithdrawAsync(uint64_t wei);
void tokenDelegateAsync(const TokenDelegateRequest& request);
Expand Down
1 change: 1 addition & 0 deletions include/hyperliquid/rest/RestApiMessageParser.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ namespace hyperliquid
TwapOrderResponse parseTwapOrder(const std::string& message);
TwapCancelResponse parseTwapCancel(const std::string& message);
CreateSubAccountResponse parseCreateSubAccount(const std::string& message);
CreateVaultResponse parseCreateVault(const std::string& message);
DelegationsResponse parseDelegations(const std::string& message);
DelegatorSummaryResponse parseDelegatorSummary(const std::string& message);
DelegatorHistoryResponse parseDelegatorHistory(const std::string& message);
Expand Down
1 change: 1 addition & 0 deletions include/hyperliquid/rest/RestEndpointListener.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ class RestEndpointListener {
virtual void onTwapOrder(const TwapOrderResponse&, std::optional<uint64_t> = std::nullopt) {}
virtual void onTwapCancel(const TwapCancelResponse&, std::optional<uint64_t> = std::nullopt) {}
virtual void onCreateSubAccount(const CreateSubAccountResponse&, std::optional<uint64_t> = std::nullopt) {}
virtual void onCreateVault(const CreateVaultResponse&, std::optional<uint64_t> = std::nullopt) {}
virtual void onDelegations(const DelegationsResponse&, std::optional<uint64_t> = std::nullopt) {}
virtual void onDelegatorSummary(const DelegatorSummaryResponse&, std::optional<uint64_t> = std::nullopt) {}
virtual void onDelegatorHistory(const DelegatorHistoryResponse&, std::optional<uint64_t> = std::nullopt) {}
Expand Down
20 changes: 20 additions & 0 deletions include/hyperliquid/types/RequestTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ namespace hyperliquid
Hip3LiquidatorTransfer,
CreateSubAccount,
SubAccountTransfer,
CreateVault,
BorrowLend,
SpotDeployRegisterToken2,
SpotDeployUserGenesis,
Expand All @@ -243,6 +244,7 @@ namespace hyperliquid
Withdraw3,
ApproveBuilderFee,
UserSetAbstraction,
SetReferrer,

// Exchange endpoints (signed, user-signed action)
CDeposit,
Expand Down Expand Up @@ -340,6 +342,7 @@ namespace hyperliquid
case RestEndpointType::Hip3LiquidatorTransfer: return "hip3LiquidatorTransfer";
case RestEndpointType::CreateSubAccount: return "createSubAccount";
case RestEndpointType::SubAccountTransfer: return "subAccountTransfer";
case RestEndpointType::CreateVault: return "createVault";
case RestEndpointType::BorrowLend: return "borrowLend";
case RestEndpointType::SpotDeployRegisterToken2: return "spotDeploy";
case RestEndpointType::SpotDeployUserGenesis: return "spotDeploy";
Expand All @@ -354,6 +357,7 @@ namespace hyperliquid
case RestEndpointType::Withdraw3: return "withdraw3";
case RestEndpointType::ApproveBuilderFee: return "approveBuilderFee";
case RestEndpointType::UserSetAbstraction: return "userSetAbstraction";
case RestEndpointType::SetReferrer: return "setReferrer";

case RestEndpointType::CDeposit: return "cDeposit";
case RestEndpointType::CWithdraw: return "cWithdraw";
Expand Down Expand Up @@ -452,6 +456,7 @@ namespace hyperliquid
case RestEndpointType::Hip3LiquidatorTransfer: return true;
case RestEndpointType::CreateSubAccount: return true;
case RestEndpointType::SubAccountTransfer: return true;
case RestEndpointType::CreateVault: return true;
case RestEndpointType::BorrowLend: return true;
case RestEndpointType::SpotDeployRegisterToken2: return true;
case RestEndpointType::SpotDeployUserGenesis: return true;
Expand All @@ -466,6 +471,7 @@ namespace hyperliquid
case RestEndpointType::Withdraw3: return true;
case RestEndpointType::ApproveBuilderFee: return true;
case RestEndpointType::UserSetAbstraction: return true;
case RestEndpointType::SetReferrer: return true;

case RestEndpointType::CDeposit: return true;
case RestEndpointType::CWithdraw: return true;
Expand Down Expand Up @@ -941,6 +947,20 @@ namespace hyperliquid
std::optional<std::string> destination;
};

struct CreateVaultRequest
{
std::string name;
std::string description;
// USD, converted to raw 1e6 units on the wire (see ExchangeRequestBuilder::createVault).
// Hyperliquid requires at least 100 USD to create a vault; not enforced client-side.
double initialUsd;
};

struct SetReferrerRequest
{
std::string code;
};

inline int outcomeEncoding(int outcomeIndex, int side)
{
return 10 * outcomeIndex + side;
Expand Down
8 changes: 8 additions & 0 deletions include/hyperliquid/types/ResponseTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -1539,6 +1539,14 @@ namespace hyperliquid
std::optional<std::string> error;
};

struct CreateVaultResponse
{
std::string status;
std::string type;
std::optional<std::string> vaultAddress;
std::optional<std::string> error;
};

struct TwapCancelResponse
{
std::string status;
Expand Down
6 changes: 6 additions & 0 deletions include/hyperliquid/websocket/WebsocketApi.h
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,9 @@ namespace hyperliquid
void subAccountTransfer(const SubAccountTransferRequest& request,
std::optional<uint64_t> correlationId = std::nullopt);

void createVault(const CreateVaultRequest& request,
std::optional<uint64_t> correlationId = std::nullopt);

void usdClassTransfer(const UsdClassTransferRequest& request,
std::optional<uint64_t> correlationId = std::nullopt);
void sendAsset(const SendAssetRequest& request,
Expand All @@ -226,6 +229,9 @@ namespace hyperliquid
void userSetAbstraction(const UserSetAbstractionRequest& request,
std::optional<uint64_t> correlationId = std::nullopt);

void setReferrer(const SetReferrerRequest& request,
std::optional<uint64_t> correlationId = std::nullopt);

void cDeposit(uint64_t wei,
std::optional<uint64_t> correlationId = std::nullopt);
void cWithdraw(uint64_t wei,
Expand Down
25 changes: 25 additions & 0 deletions src/messages/ExchangeRequestBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,20 @@ namespace hyperliquid
return body;
}

nlohmann::ordered_json ExchangeRequestBuilder::createVault(const CreateVaultRequest& request) const
{
nlohmann::ordered_json action;
action["type"] = "createVault";
action["name"] = request.name;
action["description"] = request.description;
// Same raw-1e6-unit USDC representation as vaultTransfer's "usd" field above.
action["initialUsd"] = static_cast<uint64_t>(std::llround(request.initialUsd * 1e6));

nlohmann::ordered_json body;
body["action"] = action;
return body;
}

nlohmann::ordered_json ExchangeRequestBuilder::borrowLend(const BorrowLendRequest& request) const
{
nlohmann::ordered_json action;
Expand Down Expand Up @@ -693,6 +707,17 @@ namespace hyperliquid
return body;
}

nlohmann::ordered_json ExchangeRequestBuilder::setReferrer(const SetReferrerRequest& request) const
{
nlohmann::ordered_json action;
action["type"] = "setReferrer";
action["code"] = request.code;

nlohmann::ordered_json body;
body["action"] = action;
return body;
}

nlohmann::ordered_json ExchangeRequestBuilder::tokenDelegate(const TokenDelegateRequest& request) const
{
nlohmann::ordered_json action;
Expand Down
4 changes: 4 additions & 0 deletions src/messages/ExchangeRequestBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ class ExchangeRequestBuilder {

nlohmann::ordered_json subAccountTransfer(const SubAccountTransferRequest& request) const;

nlohmann::ordered_json createVault(const CreateVaultRequest& request) const;

nlohmann::ordered_json borrowLend(const BorrowLendRequest& request) const;

nlohmann::ordered_json spotDeployRegisterToken2(const SpotDeployRegisterToken2Request& request) const;
Expand Down Expand Up @@ -79,6 +81,8 @@ class ExchangeRequestBuilder {

nlohmann::ordered_json userSetAbstraction(const UserSetAbstractionRequest& request) const;

nlohmann::ordered_json setReferrer(const SetReferrerRequest& request) const;

nlohmann::ordered_json cDeposit(uint64_t wei) const;

nlohmann::ordered_json cWithdraw(uint64_t wei) const;
Expand Down
26 changes: 26 additions & 0 deletions src/rest/RestApi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -652,6 +652,13 @@ SimpleResponse RestApi::subAccountTransfer(const SubAccountTransferRequest& requ
impl_->exchangeRequestBuilder.subAccountTransfer(request)));
}

CreateVaultResponse RestApi::createVault(const CreateVaultRequest& request)
{
return RestApiMessageParser().parseCreateVault(
impl_->signAndSendSync(RestEndpointType::CreateVault,
impl_->exchangeRequestBuilder.createVault(request)));
}

SimpleResponse RestApi::borrowLend(const BorrowLendRequest& request)
{
return RestApiMessageParser().parseSimpleResponse(
Expand Down Expand Up @@ -750,6 +757,13 @@ SimpleResponse RestApi::userSetAbstraction(const UserSetAbstractionRequest& requ
impl_->exchangeRequestBuilder.userSetAbstraction(request)));
}

SimpleResponse RestApi::setReferrer(const SetReferrerRequest& request)
{
return RestApiMessageParser().parseSimpleResponse(
impl_->signAndSendSync(RestEndpointType::SetReferrer,
impl_->exchangeRequestBuilder.setReferrer(request)));
}

SimpleResponse RestApi::cDeposit(uint64_t wei)
{
return RestApiMessageParser().parseSimpleResponse(
Expand Down Expand Up @@ -1262,6 +1276,12 @@ void RestApi::subAccountTransferAsync(const SubAccountTransferRequest& request)
impl_->exchangeRequestBuilder.subAccountTransfer(request));
}

void RestApi::createVaultAsync(const CreateVaultRequest& request)
{
impl_->signAndSend(RestEndpointType::CreateVault,
impl_->exchangeRequestBuilder.createVault(request));
}

void RestApi::borrowLendAsync(const BorrowLendRequest& request)
{
impl_->signAndSend(RestEndpointType::BorrowLend,
Expand Down Expand Up @@ -1346,6 +1366,12 @@ void RestApi::userSetAbstractionAsync(const UserSetAbstractionRequest& request)
impl_->exchangeRequestBuilder.userSetAbstraction(request));
}

void RestApi::setReferrerAsync(const SetReferrerRequest& request)
{
impl_->signAndSend(RestEndpointType::SetReferrer,
impl_->exchangeRequestBuilder.setReferrer(request));
}

void RestApi::cDepositAsync(uint64_t wei)
{
impl_->signAndSend(RestEndpointType::CDeposit, impl_->exchangeRequestBuilder.cDeposit(wei));
Expand Down
Loading
Loading