> 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

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: 97,
  rpcUrl: "https://bsc-testnet-rpc.publicnode.com",
  oracleUrl: "https://oracle-aggregator.testnet.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;
  wsRpcUrl?: 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 and Peach external swaps |

`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 { bscTestnet } from "viem/chains";

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

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

const sdk = new HertzFlowSDK({
  chainId: 97,
  account: "0xYourAccount",
  rpcUrl: "https://bsc-testnet-rpc.publicnode.com",
  oracleUrl: "https://oracle-aggregator.testnet.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.

### Events over WebSocket

Set `wsRpcUrl` to use a WebSocket client for event subscriptions. Without it, the SDK uses the public HTTP client. You can also force HTTP polling for an individual subscription with `{ usePolling: true }`.

```typescript
const sdk = new HertzFlowSDK({
  chainId: 97,
  rpcUrl: "https://bsc-testnet-rpc.publicnode.com",
  wsRpcUrl: "wss://bsc-testnet-rpc.publicnode.com",
  oracleUrl: "https://oracle-aggregator.testnet.htzfl.link/api",
  account: "0xYourAccount",
});
```

## 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.

### 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.

### Claims and referrals

| Method                                                          | Description                                             |
| --------------------------------------------------------------- | ------------------------------------------------------- |
| `sdk.claim.getClaimableFundingData(markets)`                    | Read claimable funding fees                             |
| `sdk.claim.claimFundingFees(pairs)`                             | Claim funding fees for market/token pairs               |
| `sdk.claim.claimPriceImpactRebates(items)`                      | Claim price-impact rebates                              |
| `sdk.claim.claimAllRebates(params)`                             | Claim funding fees and price-impact rebates together    |
| `sdk.referral.getCodeOwner(code)`                               | Read the owner of a referral code                       |
| `sdk.referral.getTraderReferralCode(account?)`                  | Read an account's active referral code                  |
| `sdk.referral.getTraderReferralSnapshot(account?)`              | Read an account's referral attachment and tier snapshot |
| `sdk.referral.getTierDetail(tierId?)`                           | Read referral tier details                              |
| `sdk.referral.getReferrerChain(account?)`                       | Read an account's first- and second-level referrers     |
| `sdk.referral.getUserReferralInfo()`                            | Read the current account's referral summary             |
| `sdk.referral.registerCode(code)`                               | Register a referral code                                |
| `sdk.referral.bindReferrer(code)`                               | Bind the current account to a referrer                  |
| `sdk.referral.transferCode(code, newOwner)`                     | Transfer ownership of a referral code                   |
| `sdk.referral.getAffiliateRewards(markets)`                     | Read affiliate rewards                                  |
| `sdk.referral.claimAffiliateRewards(markets, tokens, receiver)` | Claim affiliate rewards                                 |

### Credit

`CREDIT_TOKEN_DECIMALS` is exported by the package and is currently `18`.

| Method                                            | Description                                                   |
| ------------------------------------------------- | ------------------------------------------------------------- |
| `sdk.credit.getFeeClaimLimits(account?)`          | Read total and maximum claimable Credit                       |
| `sdk.credit.getFeeClaimPreview(amount, account?)` | Preview the tokens and amounts returned by a fee-rebate claim |
| `sdk.credit.getFeeClaimAllowance(account?)`       | Read Credit allowance for the claim vault                     |
| `sdk.credit.approveFeeClaim(amount)`              | Approve Credit for fee-rebate claims                          |
| `sdk.credit.claimFeeRebate(amount)`               | Claim the fee rebate represented by Credit                    |
| `sdk.credit.claimAirdrop()`                       | Claim a Credit distribution                                   |
| `sdk.credit.claimTokenAirdrop()`                  | Claim the token distribution exposed by the XP contract       |

### 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 |
| `sdk.allowance.subscribeApprovalEvents(tokens, callback)`       | Subscribe to approval events for the current account           |

### External swaps

The external swap module integrates Peach exact-input routing. Use an SDK instance configured for BNB Smart Chain mainnet (`56`) for quote discovery, transaction planning, and simulation. Router addresses returned by the API are checked against `externalSwap.trustedRouterAddresses`, which defaults to the SDK's known Peach router.

| Method                                             | Description                                              |
| -------------------------------------------------- | -------------------------------------------------------- |
| `sdk.externalSwap.getStatus()`                     | Read provider, chainflow, and router status              |
| `sdk.externalSwap.getQuote(request)`               | Get an exact-input quote and encoded swap transaction    |
| `sdk.externalSwap.getOrderQuote(request)`          | Get an exact-input quote for an order external handler   |
| `sdk.externalSwap.buildSwapPlan({ quote, owner })` | Build the approval, when required, and swap transactions |
| `sdk.externalSwap.simulateSwap({ quote, owner })`  | Simulate the quoted swap transaction                     |
| `sdk.externalSwap.approveSwap({ quote })`          | Approve the quoted ERC-20 input token                    |
| `sdk.externalSwap.executeSwap({ quote })`          | Execute the quoted swap                                  |

```typescript
const mainnetSwapSdk = new HertzFlowSDK({
  chainId: 56,
  rpcUrl: "https://bsc-rpc.publicnode.com",
  // oracleUrl is required by the SDK configuration but is not used by externalSwap.
  oracleUrl: "https://oracle-aggregator.mainnet.htzfl.link/api",
});

const quote = await mainnetSwapSdk.externalSwap.getQuote({
  tokenIn: "0xTokenIn",
  tokenOut: "0xTokenOut",
  amountIn: 1_000_000n,
  slippageBps: 50,
});

const plan = await mainnetSwapSdk.externalSwap.buildSwapPlan({
  quote,
  owner: "0xYourAccount",
});

// Submit plan.approval first when it is defined, then submit plan.swap.
```

Quotes are time-sensitive. Build or simulate the transaction before `quote.deadline`; otherwise the SDK throws `ExternalSwapError` with code `QUOTE_EXPIRED`.

### Gas and low-level helpers

| 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                              |
| `sdk.executeMulticall(request)`                                                           | Execute an SDK multicall request                               |
| `sdk.callContract(address, abi, method, params, options?)`                                | Simulate and submit a contract call                            |
| `sdk.sendTransaction(transaction, options?)`                                              | Send pre-encoded calldata through the configured wallet client |

The package also provides typed subpath exports for `abis/*`, `configs/*`, `types/*`, and `utils/*` for advanced integrations.

## Event Subscriptions

Subscriptions are account-scoped. Each subscription returns an unsubscribe function.

```typescript
const unsubscribe = sdk.events.subscribeOrderExecuted(
  (logs) => {
    for (const log of logs) {
      console.log(log.parsedData);
    }
  },
  { usePolling: false }
);

// Later:
unsubscribe();
```

Available typed subscriptions include:

* Positions: `subscribePositionIncrease`, `subscribePositionDecrease`
* Orders: `subscribeOrderCreated`, `subscribeOrderUpdated`, `subscribeOrderExecuted`, `subscribeOrderCancelled`
* HzLP: `subscribeDepositCreated`, `subscribeDepositExecuted`, `subscribeDepositCancelled`, `subscribeWithdrawalCreated`, `subscribeWithdrawalExecuted`, `subscribeWithdrawalCancelled`
* HzV: `subscribeHlvDepositCreated`, `subscribeHlvDepositExecuted`, `subscribeHlvDepositCancelled`, `subscribeHlvWithdrawalCreated`, `subscribeHlvWithdrawalExecuted`, `subscribeHlvWithdrawalCancelled`
* Shifts: `subscribeShiftCreated`, `subscribeShiftExecuted`, `subscribeShiftCancelled`
* Multichain: `subscribeMultichainTransferOut`, `subscribeMultichainTransferIn`

Use `subscribeEventLog1()` or `subscribeEventLog2()` when you need the lower-level event streams.

## Runtime Management

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

`setAccount()` restarts account-scoped event and allowance subscriptions for the new account. Call `destroy()` when the SDK instance is no longer needed:

```typescript
sdk.destroy();
```

This stops active event and allowance subscriptions.


---

# 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 dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

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

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
