LI.FI Perps SDK is a TypeScript SDK for trading perpetuals across multiple DEXes through one unified interface. This repository is the pnpm + Changesets monorepo that builds and publishes it.
Using the SDK? Start with the @lifi/perps-sdk package README for installation, quick start, and the realtime API, or read the full documentation. The rest of this page is for working on the repository.
Published packages live under packages/. @lifi/perps-types sits at the base with zero dependencies; the core @lifi/perps-sdk depends on it; each provider plugin depends on the types directly and takes the core SDK as a peer dependency.
| Package | Install for | Description |
|---|---|---|
@lifi/perps-sdk |
every project | Core SDK — PerpsClient, service functions, realtime client |
@lifi/perps-sdk-provider-hyperliquid |
Hyperliquid | Hyperliquid provider plugin |
@lifi/perps-sdk-provider-lighter |
Lighter | Lighter provider plugin |
@lifi/perps-types |
(transitive) | Shared types; re-exported from @lifi/perps-sdk |
pnpm workspace — Node >=24. From the repository root:
| Command | Does |
|---|---|
pnpm install |
Install workspace dependencies |
pnpm build |
Build every package (CJS + ESM + types) |
pnpm test |
Run all package tests (vitest) |
pnpm test:unit |
Unit tests only |
pnpm test:cov |
Tests with coverage |
pnpm check |
Biome lint/format check |
pnpm check:write |
Biome auto-fix |
pnpm check:types |
TypeScript type checking across packages |
pnpm check:circular-deps |
madge circular-dependency check |
pnpm knip:check |
Report unused files, deps, and exports |
Releases are automated with Changesets. You never edit versions or run npm publish by hand — you describe each change in a changeset, and CI (.github/workflows/publish.yaml) versions and publishes from main.
After a change that affects a published package, add a changeset:
pnpm changesetIt asks which packages changed and the bump level for each, then writes a markdown file under .changeset/. Commit that file with your PR. A changeset records exactly two things:
| Field | Controls |
|---|---|
package + patch / minor / major |
the semver bump magnitude |
| summary | the changelog entry |
Choose the bump by consumer impact: patch for fixes, minor for backward-compatible additions, major for breaking changes.
A PR that touches no published code (CI, examples/, root config) needs no release — record that explicitly with an empty changeset so the intent is visible:
pnpm changeset --empty- Merge your PR (with its changeset) to
main. - CI opens or refreshes a
chore: version packagesPR that consumes all pending changesets, bumps versions, and updates changelogs. - Merge that PR → CI publishes the bumped packages to npm (OIDC trusted publishing) and creates GitHub releases.
The bump level never selects a channel — the channel is whole-repo state, not a per-changeset field.
| Channel | npm dist-tag | How |
|---|---|---|
| Stable | latest |
default; merge changesets as above |
| Preview | preview |
label a PR release-preview → publishes a throwaway 0.0.0-preview-<sha> |
| Alpha / Beta | alpha / beta |
enter pre-release mode (below) |
For a sustained pre-release line, enter pre mode on main:
pnpm changeset pre enter beta # commit the generated .changeset/pre.json
# every release from main is now X.Y.Z-beta.N on the `beta` dist-tag
pnpm changeset pre exit # commit the deletion to return to stableWhile in pre mode, authors still write ordinary changesets — pre mode applies the -beta.N suffix to all of them. Consumers opt in with npm i @lifi/perps-sdk@beta.
Runnable scripts in examples/:
| Script | What it shows |
|---|---|
market-data.ts |
Fetching markets, assets, prices, orderbook, OHLCV |
account-data.ts |
Account state, positions, orders, fills |
agent-trading.ts |
Full setup flow + placing and cancelling orders |
error-handling.ts |
Handling PerpsError codes and retries |
custom-storage.ts |
Plugging in a custom credential store |
websocket-subscriptions.ts |
Realtime prices, orderbook, multi-listener dedup, status |