> For the complete documentation index, see [llms.txt](https://hertzflow.gitbook.io/hertzflow-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://hertzflow.gitbook.io/hertzflow-docs/tech-docs/hertzflow-sdk.md).

# HertzFlow SDK

TypeScript SDK for integrating with the HertzFlow protocol.

The HertzFlow SDK is a TypeScript SDK for reading HertzFlow markets, positions, and orders and submitting transactions from `viem`-based applications.

## Requirements

* Node.js 18 or later
* A BNB Smart Chain RPC endpoint
* A HertzFlow oracle URL
* A `viem` wallet client for write transactions

## Installation

Install the SDK and `viem` in your application:

```bash
npm install @hertzflow/sdk-v2 viem
```

```bash
yarn add @hertzflow/sdk-v2 viem
```

```bash
pnpm add @hertzflow/sdk-v2 viem
```

## Quick Start

```typescript
import { HertzFlowSDK } from "@hertzflow/sdk-v2";

const sdk = new HertzFlowSDK({
  chainId: 56,
  rpcUrl: "https://bsc-rpc.publicnode.com",
  oracleUrl: "https://oracle-aggregator.mainnet.htzfl.link/api",
});

const markets = await sdk.markets.getMarkets();
const { tokensData } = await sdk.tokens.getTokensData();
const { pricesData } = await sdk.tokens.getTokenRecentPrices();
const marketsData = Object.fromEntries(
  markets.map((market) => [market.marketTokenAddress, market])
);

sdk.setAccount("0xYourAccount");

const { positionsData } = await sdk.positions.getPositions({
  prices: pricesData ?? {},
  marketsData,
  tokensData: tokensData ?? {},
});
```

Read methods use the SDK's public client. To submit a transaction, also provide a wallet client in the constructor or call `sdk.setWalletClient()`.

## Configuration

```typescript
interface HertzFlowSdkConfig {
  chainId: 56 | 97;
  account?: Address;
  oracleUrl: string;
  rpcUrl: string;
  publicClient?: PublicClient;
  walletClient?: WalletClient;
  tokens?: Record<string, Partial<Token>> | (() => Promise<TokensData>);
  markets?: Record<string, Partial<MarketSdkConfig>>;
  externalSwap?: {
    apiBaseUrl?: string;
    requestTimeoutMs?: number;
    trustedRouterAddresses?: Address[];
  };
  settings?: {
    uiFeeReceiverAccount?: string;
    ignoreTimeoutError?: boolean;
    debugMode?: boolean;
  };
}
```

| Network                 | Chain ID | Notes                      |
| ----------------------- | -------: | -------------------------- |
| BNB Smart Chain Testnet |     `97` | HertzFlow protocol modules |
| BNB Smart Chain         |     `56` | HertzFlow protocol modules |

`debugMode` defaults to enabled. Set it to `false` to disable internal SDK console logging.

### Custom viem clients

```typescript
import { HertzFlowSDK } from "@hertzflow/sdk-v2";
import { createPublicClient, createWalletClient, http } from "viem";
import { bsc } from "viem/chains";

const publicClient = createPublicClient({
  chain: bsc,
  transport: http("https://bsc-rpc.publicnode.com"),
});

const walletClient = createWalletClient({
  chain: bsc,
  transport: http("https://bsc-rpc.publicnode.com"),
  account: "0xYourAccount",
});

const sdk = new HertzFlowSDK({
  chainId: 56,
  account: "0xYourAccount",
  rpcUrl: "https://bsc-rpc.publicnode.com",
  oracleUrl: "https://oracle-aggregator.mainnet.htzfl.link/api",
  publicClient,
  walletClient,
});
```

Keep `account` in the SDK configuration in sync with the wallet client. Supplying a wallet client does not set the SDK account automatically.

## API Reference

### Markets

| Method                                    | Description                                                            |
| ----------------------------------------- | ---------------------------------------------------------------------- |
| `sdk.markets.getMarkets(offset?, limit?)` | Read the market list from the contracts                                |
| `sdk.markets.getMarketsConfigs(markets)`  | Read market configuration values                                       |
| `sdk.markets.getMarketsValues(params)`    | Read current pool, open interest, funding, and borrowing values        |
| `sdk.markets.mergeMarketsInfo(params)`    | Combine markets, tokens, configs, and values into enriched market data |

### Tokens and prices

| Method                                                | Description                                                                                                  |
| ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| `sdk.tokens.getTokensData()`                          | Load built-in token metadata and merge configured static overrides or async metadata for newly listed tokens |
| `sdk.tokens.getTokenRecentPrices()`                   | Fetch the latest oracle prices                                                                               |
| `sdk.tokens.getTokensBalances(account?, tokensList?)` | Read native and ERC-20 balances                                                                              |
| `sdk.tokens.getTokenMetadata(tokenAddresses)`         | Read ERC-20 name, symbol, and decimals on-chain                                                              |
| `sdk.tokens.getNativeToken()`                         | Return the configured native token                                                                           |
| `sdk.oracle.getLatestPrices()`                        | Fetch raw latest-price records                                                                               |

### Positions and orders

| Method                                          | Description                                                            |
| ----------------------------------------------- | ---------------------------------------------------------------------- |
| `sdk.positions.getPositions(params)`            | Read an account's open positions                                       |
| `sdk.positions.getPositionsConstants()`         | Read position and collateral limits                                    |
| `sdk.orders.getOrders(params)`                  | Read and filter an account's orders                                    |
| `sdk.orders.createIncreaseOrder(params)`        | Create a market or limit increase order, optionally with SL/TP changes |
| `sdk.orders.createDecreaseOrder(params[])`      | Create one or more decrease orders                                     |
| `sdk.orders.updateOrder(params)`                | Update an existing order                                               |
| `sdk.orders.cancelOrders(orderKeys)`            | Cancel one or more orders                                              |
| `sdk.orders.depositPositionCollateral(params)`  | Add collateral to a position                                           |
| `sdk.orders.withdrawPositionCollateral(params)` | Remove collateral from a position                                      |

Amounts are integer `bigint` values in their documented token or USD precision. Slippage arguments differ by method: `createIncreaseOrder()` and `createDecreaseOrder()` receive basis points, while the collateral deposit and withdrawal helpers receive a decimal ratio and convert it internally.

### Swap + increase orders

For an internal USD collateral order such as HFUSD, the SDK can swap the user's payment token through Peach and use the output to mint the internal USD token before creating the increase order. This integration is available on BNB Smart Chain mainnet (`56`) only. Complete a small-value mainnet validation in the application before enabling it in production.

The full flow runs in one `ExchangeRouter.multicall`:

```
ExchangeRouter.multicall
  ├─ sendWnt(executionFee) -> OrderVault
  ├─ sendTokens / sendWnt(payment token) -> ExternalHandler
  ├─ makeExternalCalls #1
  │    ├─ approve payment token + Peach ERC20 swap
  │    └─ refund the underlying token -> HFBank
  ├─ makeExternalCalls #2
  │    └─ HFBank.mint(OrderVault)
  └─ createOrder
       initialCollateralToken       = internalUsd.wrappedTokenAddress
       initialCollateralDeltaAmount = 0
       swapPath                     = []
```

`internalUsd` must identify the HFBank, wrapped token (for example HFUSD), and its underlying token (for example USDT). Get an order-specific quote and pass it to `createIncreaseOrder()`:

```typescript
const peachQuote = await sdk.externalSwap.getOrderQuote({
  tokenIn: payToken.address,
  tokenOut: internalUsd.underlyingTokenAddress!,
  amountIn: payAmount,
  slippageBps: 50,
});

await sdk.orders.createIncreaseOrder({
  // Include the remaining normal increase-order parameters.
  fromTokenAddress: payToken.address,
  collateralTokenAddress: internalUsd.wrappedTokenAddress,
  receiveTokenAddress: internalUsd.wrappedTokenAddress,
  increaseAmounts: {
    initialCollateralAmount: payAmount,
    sizeDeltaUsd,
    acceptablePrice,
  },
  internalUsd,
  externalSwapQuote: peachQuote,
});
```

`getOrderQuote()` returns an ERC-20-compatible quote for the order handler. If the user pays with native BNB, it re-quotes the input as WBNB so the order can send WBNB to `ExternalHandler`; do not pass a standalone native `swapETH` quote to an order. The swap, mint, and order are atomic: if any step reverts, the entire multicall reverts.

For limit increase orders, the Peach swap and internal USD mint happen when the order is submitted; they are not deferred until the limit price is triggered.

Before submission, request a fresh quote and ensure its input token and amount match the order, its output token matches `internalUsd.underlyingTokenAddress`, its router is trusted, its transaction value is `0`, and its deadline has not expired. The user approves the HertzFlow Synthetics Router; the Peach approval is executed inside the order's external call.

### Liquidity

| Method                                                         | Description                                                                                     |
| -------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
| `sdk.liquidity.getOrders(params?)`                             | Read pending HzLP and HzV deposit and withdrawal orders                                         |
| `sdk.liquidity.cancelOrder(order)`                             | Cancel one pending liquidity order                                                              |
| `sdk.liquidity.cancelOrders(orders)`                           | Cancel multiple pending liquidity orders in one router call; all orders must use the same scope |
| `sdk.liquidity.createDeposit(params)`                          | Deposit long and short tokens into an HzLP market                                               |
| `sdk.liquidity.createWithdrawal(params)`                       | Redeem HzLP market tokens                                                                       |
| `sdk.liquidity.createHlvDeposit(params)`                       | Deposit into an HzV vault, with optional per-market allocations                                 |
| `sdk.liquidity.createHlvWithdrawal(params)`                    | Withdraw from an HzV vault, with optional per-market allocations                                |
| `sdk.allowance.approveTokenForLiquidityRouter(token, amount?)` | Compatibility alias that approves the Synthetics Router                                         |

The liquidity order reader can filter by account, market address, scope (`market` or `hlv`), and limit. The liquidity transaction helpers return a transaction hash. The SDK can retry a deposit or withdrawal with the execution fee required by the contract simulation when the supplied fee is too low.

### Allowances

| Method                                                          | Description                                                    |
| --------------------------------------------------------------- | -------------------------------------------------------------- |
| `sdk.allowance.getTokenAllowance(token, spender)`               | Read an ERC-20 allowance                                       |
| `sdk.allowance.approveToken(token, spender, amount?)`           | Approve an ERC-20 spender; the default amount is `maxUint256`  |
| `sdk.allowance.getTokenAllowanceForSyntheticsRouter(token)`     | Read allowance for the Synthetics Router                       |
| `sdk.allowance.approveTokenForSyntheticsRouter(token, amount?)` | Approve the Synthetics Router                                  |
| `sdk.allowance.getTokenAllowanceForLiquidityRouter(token)`      | Compatibility alias that reads the Synthetics Router allowance |

### Gas and execution fees

| Method                                                                                    | Description                           |
| ----------------------------------------------------------------------------------------- | ------------------------------------- |
| `sdk.utils.getGasLimits()`                                                                | Read protocol gas-limit configuration |
| `sdk.utils.getGasPrice()`                                                                 | Read and buffer the current gas price |
| `sdk.utils.getEstimatedGasFee(type, params, gasLimits?)`                                  | Estimate gas for a protocol action    |
| `sdk.utils.getExecutionFee(type, tokensData, nativePrice, params, gasLimits?, gasPrice?)` | Calculate the execution fee           |
| `sdk.utils.getUiFeeFactor()`                                                              | Read the configured UI fee factor     |

## Runtime Management

```typescript
sdk.setAccount("0xNewAccount");
sdk.setWalletClient(walletClient);
sdk.setPublicClient(publicClient);
```

Use `setAccount()` when the active wallet changes. Use `setWalletClient()` or `setPublicClient()` to replace the clients at runtime.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://hertzflow.gitbook.io/hertzflow-docs/tech-docs/hertzflow-sdk.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
