Complete reference for all PerpsClient trading methods. Every trading method below auto-signs with the SDK-managed agent — the user’s wallet is not prompted. The user’s wallet is only invoked for the one-time setup actions covered under Setup and setUserWallet.
setUserWallet
Set or update the end-user wallet. Call this when the user connects their wallet (for example, from wagmi’s useWalletClient()); pass undefined to clear it when the wallet disconnects.
import type { WalletClient } from 'viem';
perps.setUserWallet(walletClient);
// Later, on wallet disconnect:
perps.setUserWallet(undefined);
| Field | Type | Required | Description |
|---|
userWallet | WalletClient | undefined | Yes | viem-compatible wallet client; pass undefined to clear |
The user wallet is used only for one-time setup actions, not for trades. Specifically: APPROVE_AGENT, APPROVE_BUILDER_FEE, the L1 EIP-191 countersignature on Lighter’s REGISTER_API_KEY, and DEPOSIT (an EVM transaction). Trade actions (placeOrder, cancelOrders, modifyOrders, placeTriggerOrder, updatePositionMargin) are signed by the SDK-managed agent and never reach this wallet.
placeOrder
Place an order. Builds the action, auto-signs with the agent, and submits in one call.
const result = await perps.placeOrder(params);
| Field | Type | Required | Description |
|---|
address | string | Yes | User’s wallet address |
provider | string | Yes | Provider identifier |
market | MarketRef | Yes | Target market ({ marketId, categoryId }) |
side | 'BUY' | 'SELL' | Yes | Order direction |
type | 'MARKET' | 'LIMIT' | 'TRIGGER_ONLY' | Yes | Order type |
size | string | Yes | Order size |
price | string | Yes | Limit price or slippage limit |
leverage | number | No | Leverage to set (generates an updateLeverage step if it differs from the current setting) |
reduceOnly | boolean | No | Only reduce position |
timeInForce | string | No | GTC, IOC, POST_ONLY, GTT |
expiresAt | string | No | Unix ms timestamp expiry for GTT (must be in the future) |
takeProfit | TriggerOrderInput | No | Take profit trigger |
stopLoss | TriggerOrderInput | No | Stop loss trigger |
Returns: ExecuteActionResponse with results[] array.
cancelOrders
Cancel one or more orders. Auto-signs with the agent.
const result = await perps.cancelOrders(params);
| Field | Type | Required | Description |
|---|
address | string | Yes | User’s wallet address |
provider | string | Yes | Provider identifier |
ids | string[] | Yes | Order IDs to cancel |
Returns: ExecuteActionResponse with results[] array.
modifyOrders
Modify orders in place. Auto-signs with the agent.
const result = await perps.modifyOrders({
provider: 'hyperliquid',
address: userAddress,
modifications: [{ id: '12345678', price: '94500.00' }],
});
| Field | Type | Required | Description |
|---|
provider | string | Yes | Provider identifier |
address | string | Yes | User’s wallet address |
modifications | ModifyOrderInput[] | Yes | Modifications to apply |
Returns: ExecuteActionResponse with results[] array.
placeTriggerOrder
Place standalone trigger orders (TP/SL on existing positions). Auto-signs with the agent.
const result = await perps.placeTriggerOrder({
provider: 'hyperliquid',
address: userAddress,
market: { marketId: 'BTC', categoryId: 'hyperliquid' },
side: 'SELL',
takeProfit: { triggerPrice: '100000.00' },
stopLoss: { triggerPrice: '90000.00' },
});
| Field | Type | Required | Description |
|---|
provider | string | Yes | Provider identifier |
address | string | Yes | User’s wallet address |
market | MarketRef | Yes | Target market ({ marketId, categoryId }) |
side | 'BUY' | 'SELL' | Yes | Order side |
takeProfit | TriggerOrderInput | No | Take profit trigger |
stopLoss | TriggerOrderInput | No | Stop loss trigger |
Returns: ExecuteActionResponse with results[] array.
updatePositionMargin
Adjust position margin. Auto-signs with the agent.
const result = await perps.updatePositionMargin({
provider: 'hyperliquid',
address: userAddress,
market: { marketId: 'BTC', categoryId: 'hyperliquid' },
action: 'add',
amount: '500.00',
});
| Field | Type | Required | Description |
|---|
provider | string | Yes | Provider identifier |
address | string | Yes | User’s wallet address |
market | MarketRef | Yes | Target market ({ marketId, categoryId }) |
action | 'add' | 'remove' | Yes | Add or remove margin |
amount | string | Yes | Margin amount |
Returns: ExecuteActionResponse with results[] array.
Generic action helper
The high-level methods above (placeOrder, cancelOrders, modifyOrders, placeTriggerOrder, updatePositionMargin) are convenience wrappers around a single generic helper. Use it directly when an action does not have a dedicated wrapper.
execute
Auto-sign-and-submit for any action type. Mirrors placeOrder/modifyOrders/etc. but generic over ActionType. Internally builds the action, picks the correct signing pipeline (EIP-712, WASM blob, or EVM tx) from the provider’s descriptor, signs, and submits in a single create→sign→submit pass.
import { ActionType } from '@lifi/perps-types';
const result = await perps.execute({
provider: 'hyperliquid',
address: userAddress,
action: ActionType.UPDATE_LEVERAGE,
params: {
market: { marketId: 'BTC', categoryId: 'hyperliquid' },
leverage: 10,
},
});
| Field | Type | Required | Description |
|---|
provider | string | Yes | Provider identifier |
address | string | Yes | User’s wallet address |
action | ActionType | Yes | Action type to execute |
params | ActionParamsMap[T] | Yes | Action-specific params |
Returns: ExecuteActionResponse with results[] array.
Use execute for action types without dedicated wrappers — for example UPDATE_LEVERAGE or provider-specific account-configuration actions. For trading actions with wrappers (placeOrder, cancelOrders, …), prefer the wrappers; they expose richer typed parameters.
buildAction
Build the action payloads for an action without signing or submitting. Typed wrapper around the createAction service (see Actions / createAction) and the natural counterpart to execute — use it when you need to inspect the steps, sign them in a custom flow, or hand them off across a process boundary before calling executeAction yourself.
import { ActionType } from '@lifi/perps-types';
const { actions } = await perps.buildAction(ActionType.UPDATE_LEVERAGE, {
provider: 'hyperliquid',
address: userAddress,
params: {
market: { marketId: 'BTC', categoryId: 'hyperliquid' },
leverage: 10,
},
});
| Field | Type | Required | Description |
|---|
action | ActionType | Yes | Action type to build (first positional argument) |
provider | string | Yes | Provider identifier |
address | string | Yes | User’s wallet address |
params | ActionParamsMap[T] | Yes | Action-specific params |
Returns: CreateActionResponse — { actions: ActionStep[] }. The SDK resolves the correct signer address (agent or user) for the given action type before delegating to createAction.
Setup
Account-setup actions (e.g. APPROVE_AGENT, APPROVE_BUILDER_FEE on Hyperliquid; REGISTER_API_KEY on Lighter) are coordinated through the setup helpers. The high-level flow is described in Concepts / Action Pattern; the methods below are the lower-level building blocks.
checkSetup
Return the unsatisfied entries on the provider’s setup descriptors for this account as a flat list. Each ActionStep is self-describing — its action keys back to the provider’s setup descriptor, which declares the step’s signer and signing scheme — so no signer-role partition is exposed here.
const required = await perps.checkSetup({
provider: 'hyperliquid',
address: userAddress,
});
if (!required.isReady) {
// required.setup: ActionStep[] — outstanding steps, ordered by descriptor sequence
}
| Field | Type | Required | Description |
|---|
provider | string | Yes | Provider identifier |
address | string | Yes | User’s wallet address |
Returns: ProviderSetup — { setup: ActionStep[]; isReady: boolean }.
Provider.options descriptors are never returned here — options are post-setup tunables and never gate trading. Option state is surfaced separately via getAccount().settings.
signProviderSetupAction
Sign a single setup step using whichever signing path matches the step’s shape — EIP-712 typed data (approveAgent, approveBuilderFee, accountMode, …), WASM blob (Lighter’s REGISTER_API_KEY hybrid flow), or EVM transaction. Lets consumers collect signed steps without embedding per-method signing logic.
const required = await perps.checkSetup({
provider: 'hyperliquid',
address: userAddress,
});
const signedActions = await Promise.all(
required.setup.map((step) =>
perps.signProviderSetupAction('hyperliquid', userAddress, step),
),
);
| Field | Type | Required | Description |
|---|
provider | string | Yes | Provider identifier (first positional argument) |
address | string | Yes | User’s wallet address (second positional argument) |
step | ActionStep | Yes | A single step from checkSetup().setup (third positional argument) |
Returns: SignedActionStep.
Requires the user wallet to be set via setUserWallet (or passed at construction) for any step that requires the user’s L1 wallet — that includes EIP-712, EVM-tx, and Lighter’s REGISTER_API_KEY (which signs the EIP-191 message embedded in the WASM blob).
executeProviderSetup
Submit the signed setup steps returned by checkSetup. Pass the setup steps and their signed counterparts (in the same order); the SDK dispatches them to the provider.
const signedActions = await Promise.all(
required.setup.map((step) =>
perps.signProviderSetupAction('hyperliquid', userAddress, step),
),
);
const result = await perps.executeProviderSetup({
provider: 'hyperliquid',
address: userAddress,
setup: required.setup,
signedActions,
});
| Field | Type | Required | Description |
|---|
provider | string | Yes | Provider identifier |
address | string | Yes | User’s wallet address |
setup | ActionStep[] | Yes | The unsatisfied setup steps from checkSetup() |
signedActions | SignedActionStep[] | Yes | Signed counterparts of setup, in the same order |
Returns: ExecuteProviderSetupResult — { results: ExecuteActionResponse }.
executeProviderSetupAction
Sign and submit one pre-staged setup ActionStep end-to-end. The caller is expected to have already obtained the step from a prior checkSetup call (no refetch).
await perps.executeProviderSetupAction({
provider: 'lighter',
address: userAddress,
step: required.setup[0],
});
| Field | Type | Required | Description |
|---|
provider | string | Yes | Provider identifier |
address | string | Yes | User’s wallet address |
step | ActionStep | Yes | A single step from checkSetup().setup |
Returns: Promise<void>.
API Reference: POST /createAction · /executeAction