> ## Documentation Index
> Fetch the complete documentation index at: https://docs.li.fi/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> Install the SDK, create a client, read market data, and place your first order.

This gets you from an empty project to a placed order. It uses Hyperliquid throughout; swapping the venue means swapping the provider plugin and the `provider` argument, and nothing else in the shape of the code.

<Note>
  Perps runs on a gated endpoint rather than the public API host, so the calls below need access granted for your integrator before they return anything. See [Access](/perps/overview#access).
</Note>

## 1. Install

Install the core SDK plus the plugin for each venue you target.

```bash theme={"system"}
npm install @lifi/perps-sdk @lifi/perps-sdk-provider-hyperliquid
```

## 2. Create a client

```typescript theme={"system"}
import { createPerpsClient } from '@lifi/perps-sdk'
import { hyperliquidProvider } from '@lifi/perps-sdk-provider-hyperliquid'

const client = createPerpsClient({
  integrator: 'my-app',
  apiKey: process.env.LIFI_API_KEY!,
  providers: [hyperliquidProvider()],
})
```

`integrator` identifies your application and `apiKey` comes from the [Partner Portal](https://portal.li.fi/). Registering a provider binds that venue's read surface to the client, and you look it up later by key.

One option is worth knowing before you need it: `retry` controls HTTP retry behaviour and accepts either one policy for everything or a policy per venue.

This `client` is the read surface market data and account queries run against. Setup and trading go through `PerpsClient` instead, a separate class built on top of it — see step 4. There, the user's wallet is supplied via `setUserWallet` rather than as a constructor option, since it can be set or swapped after the client already exists.

## 3. Read market data

Market data needs no user and no setup, which makes it the fastest way to confirm your client is configured correctly.

```typescript theme={"system"}
import { getMarkets } from '@lifi/perps-sdk'

const { markets } = await getMarkets(client, { provider: 'hyperliquid' })
console.log(markets.slice(0, 5))
```

If this returns markets, your key, integrator, and access are all working. If it does not, fix that before going near a wallet.

## 4. Set the account up

Trading needs a one-time setup per user, per venue. What it does differs by venue, and the SDK coordinates it for you rather than asking you to script each scheme.

Give `PerpsClient` the user's wallet before calling it, since setup is where the user's signature is first captured.

```typescript theme={"system"}
import { PerpsClient } from '@lifi/perps-sdk'
import { hyperliquidProvider } from '@lifi/perps-sdk-provider-hyperliquid'

const perps = new PerpsClient({
  integrator: 'my-app',
  apiKey: process.env.LIFI_API_KEY!,
  providers: [hyperliquidProvider()],
})
perps.setUserWallet(userWallet)

const setup = await perps.checkSetup({ provider: 'hyperliquid', address: userAddress })

for (const step of setup.setup) {
  await perps.executeProviderSetupAction({
    provider: 'hyperliquid',
    address: userAddress,
    step,
  })
}
```

`checkSetup` returns whatever is still pending for this account; once it comes back empty, `isReady` is `true` and there is nothing left to sign. On Hyperliquid this approves an agent wallet. On Lighter it registers a signing key on-chain. On Ondo it establishes a session. The user signs once here, which is what buys you a trading flow with no wallet popup on every order.

## 5. Place an order

```typescript theme={"system"}
import { OrderSide, OrderType, getMarketsContext } from '@lifi/perps-sdk'

const [market] = markets // from step 3

const { prices } = await getMarketsContext(client, {
  provider: 'hyperliquid',
  marketIds: [market.id],
})

const result = await perps.placeOrder({
  provider: 'hyperliquid',
  address: userAddress,
  market: { marketId: market.id, categoryId: market.categoryId },
  side: OrderSide.BUY,
  type: OrderType.MARKET,
  size: '0.1',
  price: prices[0].midPrice, // required on every order, including market orders
})
```

A successful result carries the venue's order identifier, and where the action touched a chain, a transaction hash and an explorer link. A failure carries an error and often a structured error code, which is the one to branch on rather than the message text.

The other trading methods follow the same shape: `placeTriggerOrder` for standalone take-profit and stop-loss orders, `placeTwapOrder` and `cancelTwapOrder` for time-weighted orders, `cancelOrders`, and `modifyOrders` for editing an order in place instead of cancelling and re-placing it.

<Note>
  Take-profit and stop-loss attached to an entry are part of the order itself, not a separate call. Reach for the standalone trigger method only when there is no order to attach to.
</Note>

## 6. Stream

Polling for fills works and wastes both your rate limit and your users' patience. The WebSocket client subscribes per channel and returns the function that unsubscribes.

```typescript theme={"system"}
import { PerpsWsClient } from '@lifi/perps-sdk'
import { hyperliquidWsProvider } from '@lifi/perps-sdk-provider-hyperliquid'

const ws = new PerpsWsClient(client, {
  wsProviders: { hyperliquid: hyperliquidWsProvider() },
})

const unsubscribe = await ws.subscribe(
  { channel: 'orderbook', dex: 'hyperliquid', marketId: 'ETH' },
  (event) => console.log(event.data),
)
```

Several listeners on the same channel share a single connection to the venue, so subscribing per component is not the mistake it would otherwise be.

## Next steps

<CardGroup cols={2}>
  <Card title="Concepts" icon="diagram-project" href="/perps/concepts" horizontal>
    What happens inside a trading call, and where credentials are kept.
  </Card>

  <Card title="Venues" icon="building-columns" href="/perps/venues" horizontal>
    Per-venue setup, deposits, and withdrawals.
  </Card>

  <Card title="Runnable examples" icon="code" href="https://github.com/lifinance/perps-sdk/tree/main/examples" horizontal>
    Market data, account data, agent trading, error handling, and streaming.
  </Card>

  <Card title="Method reference" icon="book" href="https://public-perps-docs.mintlify.app/" horizontal>
    Every method, parameter, and error code.
  </Card>
</CardGroup>
