Skip to main content

SDK (@harbor/sdk)

Thin TypeScript client over the same on-chain surface as these integrator guides. No Harbor REST/WebSocket API — quotes are dry-runs; prices and market state are view calls; txs are ABI-encoded calldata.

Package@harbor/sdk (0.2.0)
Repobaofinance/harbor-sdk
Peerviem ^2
ChainEthereum mainnet (chainId 1) only
npmPending — install from GitHub until @harbor publish runs

Addresses and ABIs match the docs-hosted package: Addresses and ABIs.

Install

npm install github:baofinance/harbor-sdk#f7dcd51853bf1efa083d3149b3b90dc710525f1a viem

After npm publish:

npm install @harbor/sdk viem

Quick start

import { createPublicClient, http } from "viem";
import { mainnet } from "viem/chains";
import { createHarborClient } from "@harbor/sdk";

const publicClient = createPublicClient({
chain: mainnet,
transport: http(),
});

const harbor = createHarborClient({ publicClient, chainId: 1 });

const quote = await harbor.quoteMint("eth-fxusd", {
side: "pegged",
wrappedCollateralIn: 10n ** 18n,
});
if (!quote.allowed) throw new Error("mint disallowed at current CR");

const approve = harbor.encodeTx.approveWrappedCollateral({
marketId: "eth-fxusd",
amount: quote.wrappedCollateralIn,
});
const mint = harbor.encodeTx.mintPeggedToken({
marketId: "eth-fxusd",
wrappedCollateralIn: quote.wrappedCollateralIn,
// Placeholder checksum address — replace with the real receiver
receiver: "0x0000000000000000000000000000000000000001",
minPeggedOut: quote.minOut,
});

API surface

MethodOn-chain source
getAddresses / getMarket / listMarketsmainnet-v1.json
getPrice(marketId)Minter peggedTokenPrice / leveragedTokenPrice; aggregator latestAnswer
getMarketState(marketId)collateralRatio, leverageRatio, config()
quoteMint / quoteRedeem*DryRun (allowed is false when incentive ratio is 1e18)
encodeTx.*mint* / redeem* + ERC-20 approve
encodeZap.*Genesis / minter zap calldata (market must list zap addresses)
swap.getRoute / encodeSwap / encodeRouteSwapHarbor Swap: lookup route; encode a supplied executor; or resolve-then-encode — pass swapper into createHarborClient

Default minOut uses 50 bps slippage off the dry-run out amount; override per call.

Zaps

const zapCollateralIn = 1_000_000n; // e.g. 1 USDC (6 decimals) on a USDC rail
// Prefer a zap-specific preview when available. Otherwise:
// - wrap leg: set a conservative minWrappedCollateralOut
// - minter leg: quoteMint / *DryRun for the same market+side after converting to wrapped units
const mintQuote = await harbor.quoteMint("eth-fxusd", {
side: "pegged",
wrappedCollateralIn: /* wrapped amount expected from the wrap leg */ 10n ** 18n,
});
harbor.encodeZap.minterCollateralToToken({
marketId: "eth-fxusd",
side: "pegged",
receiver: "0x0000000000000000000000000000000000000001",
collateralAmount: zapCollateralIn,
minWrappedCollateralOut: 0n, // replace with wrap-leg floor
minTokenOut: mintQuote.minOut, // minter-leg floor from that quote, not an unrelated mint
});

Also: genesisNativeAsset, genesisCollateral, minterNativeToToken (ETH rail), minterBaseAssetToToken (USDC rail). Prefer direct minter when you already hold wrapped collateral. Cookbook: Zaps.

Harbor Swap (Yield / keepers)

import type { HexAddress } from "@harbor/sdk";

const harbor = createHarborClient({
publicClient,
swapper: "0x0000000000000000000000000000000000000001", // Swapper_v1 once published
});
const from = "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48" as HexAddress; // USDC
const to = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2" as HexAddress; // WETH
const amountIn = 1_000_000n; // 1 USDC (6 decimals)
const route = await harbor.swap!.getRoute(from, to);
// Derive a nonzero rate floor from an off-chain quote + slippage (illustrative 50 bps):
// minAmountOutPerUnitIn ≈ expectedOut * 1e18 / amountIn * 9950 / 10000
const minAmountOutPerUnitIn = 995_000_000_000_000_000n; // replace with quote-derived floor
const tx = await harbor.swap!.encodeRouteSwap({
fromToken: from,
toToken: to,
amountIn,
minAmountOutPerUnitIn,
});

Not for mint/redeem. See Harbor Swap.

Not shipped: Chainlink-shaped oracle adapters.

Market ids

Use the address-book keys (examples): eth-fxusd, btc-fxusd, btc-steth, steth-eur, fxusd-eur. Filter with listMarkets("live"). Check market.status before production use.

Alias: the app marketId for haUSD/stETH is steth-usd. The integrator address book uses usd-steth for the same market. Treat them as the same stack; prefer the key your SoT publishes (getMarket("usd-steth") in @harbor/sdk, steth-usd in harbor-app).

Key-order follow-up: some keys are <index>-<collateral> and others <collateral>-<index>. harbor-app should normalize to one order (prefer index-collateral) and keep aliases for former keys — see Addresses and ABIs.