PerpsClient trading and setup methods. Authorization follows each provider’s ProviderAction.signer and signingMethod: order-management methods normally use the plugin’s SDK-managed credential, while user-authorized operations such as Hyperliquid sendAsset can invoke the wallet.
Every provider action (setup, trading, withdrawals) fails with
401 / 2012 (TermsNotAccepted) until the address has accepted the current terms version. See Error Handling.setUserWallet
Set or update the end-user wallet. Call this when the user connects their wallet (for example, from wagmi’suseWalletClient()); pass undefined to clear it when the wallet disconnects.
The SDK bundles its own
viem range. If your app uses a different viem version, cast the wallet once (walletClient as Parameters<PerpsClient['setUserWallet']>[0]). A viem wallet client stays on the chain it was created on: call setUserWallet again when the wallet’s chain changes, or configure setSwitchChain so the SDK switches before EIP-712 and EVM legs.
The wallet is used for provider-declared USER authorization, including setup signatures, SIWE, EVM deposit transactions, Lighter’s REGISTER_API_KEY countersignature, and user-signed transfers or withdrawals. Order-management actions use each plugin’s SDK-managed credential and do not reach this wallet.
setSwitchChain
Set or replace the chain-switching hook. The hook is invoked before aUSER-signed EIP-712 action (including meta actions) whose domain chainId differs from the wallet’s. It receives the target chainId and must return a wallet client on that chain. Returning undefined, or a wallet on the wrong chain, throws a PerpsError (SDKError). The hook can also be provided once at construction via the switchChain option on PerpsClientOptions.
getMarketSettings
Read the current venue-side margin mode and leverage that the next order on a market will use.
Returns:
MarketSettings — { marginMode, leverage }. The read resolves the venue value or throws.
Throws: PerpsError with ValidationError for a spot market. On Hyperliquid, it throws AccountNotFound when the wallet has no venue account. On Ondo, it throws SetupRequired when no session is stored and Unauthorized when Ondo rejects the session. On Lighter, it needs no token and returns the venue default for a wallet with no Lighter account. See Account access.
After a write (placeOrder with leverage, updatePositionMargin, sendAsset), the venue’s settings, account, orders and fills reads can return pre-write data for a couple of seconds. Update your UI optimistically and re-read once after a short delay.
placeOrder
Place an order. Builds the action, auto-signs through the provider plugin, and submits in one call.
Returns:
ExecuteActionResponse with results[] array, one entry per action (including a prepended updateLeverage).
cancelOrders
Cancel one or more orders. Auto-signs through the provider plugin.
Returns:
ExecuteActionResponse with results[] array.
To cancel every open order in one action, use execute with ActionType.CANCEL_ALL_ORDERS (see Cancelling Orders).
modifyOrders
Modify orders in place. Auto-signs through the provider plugin.
Returns:
ExecuteActionResponse with results[] array.
placeTriggerOrder
Place standalone trigger orders (TP/SL on existing positions). Auto-signs with the provider’s SDK-managed credential.
Returns:
ExecuteActionResponse with results[] array.
placeTwapOrder
Place a TWAP parent order that executes over a fixed duration. Auto-signs with the provider’s SDK-managed credential.
Returns:
ExecuteActionResponse with results[] array. A Submitted or Accepted result carries twapId — the provider-native identifier for the placed TWAP parent.
A provider only honours the extras it declares via its
placeTwapOrder action’s params descriptors (GET /providers); other providers ignore them. See each provider’s trading page — Hyperliquid, Lighter, Ondo — for its extras and duration bounds.cancelTwapOrder
Cancel a running TWAP parent order. Auto-signs with the provider’s SDK-managed credential.
Returns:
ExecuteActionResponse with results[] array.
updatePositionMargin
Adjust position margin. Auto-signs with the provider’s SDK-managed credential.
Returns:
ExecuteActionResponse with results[] array. See Position Margin for what each market allows and how much can be removed.
sendAsset
Move collateral between a provider’s categories (e.g. between perps and spot). This is a convenience wrapper overexecute(SEND_ASSET) and follows the provider descriptor’s signer; Hyperliquid uses the user’s wallet.
USER-signed, so the wallet must be on the typed-data domain chain (see setSwitchChain).
Returns:
ExecuteActionResponse with results[] array. A venue rejection does not throw. The venue’s balances can lag the transfer for a couple of seconds; re-read once after a short delay.
Generic action helper
The high-level methods above (placeOrder, cancelOrders, modifyOrders, placeTriggerOrder, placeTwapOrder, cancelTwapOrder, 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. MirrorsplaceOrder/modifyOrders/etc. but generic over ActionType. Internally builds the action, picks the signing pipeline from the descriptor’s signingMethod, signs, and submits in a single create → authorize → execute pass.
Returns:
ExecuteActionResponse with results[] array. execute does not throw on a venue refusal; check results[i].status.
SignActionProgress is { index, total, action, functionName, chainId, status, txHash }, where status is 'submitted' (wallet broadcast, hash known) then 'confirmed' (receipt mined) — emitted twice per on-chain leg, so a consumer can render a live per-transaction stepper.Use
execute for action types without dedicated wrappers — for example UPDATE_LEVERAGE, CANCEL_ALL_ORDERS or setup-choice 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 thecreateAction 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.
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 steps (e.g.APPROVE_AGENT, APPROVE_BUILDER_FEE on Hyperliquid; REGISTER_API_KEY on Lighter) and user choices (Hyperliquid ACCOUNT_MODE, Lighter ACCOUNT_TYPE) 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.
The SDK is the supported integration path for setup. It reads the account, decides which steps are satisfied, runs the steps in sequence order, and makes the client-side venue calls. For callers that use the API directly, see Integrating without the SDK.
checkSetup
Return the unsatisfiedProvider.setup steps for this account as a flat list, together with the checklist a UI renders. Each ActionStep is self-describing — its action keys back to the provider’s setup step, which declares the signer, relay, and signing scheme — so no signer-role partition is exposed here.
Returns:
ProviderSetup — { accountExists: boolean; setup: ActionStep[]; isReady: boolean; checklist: SetupChecklistItem[] }.
accountExistsreports whether the address already has account state with the provider.setupholds the staged steps. Only aUSER-signed step that is not a choice is staged.isReadyistrueonly when nothing is staged and every choice onchecklistis satisfied.checklistis the renderable onboarding list. Each item is{ descriptor: SetupAction; satisfied: boolean; selected: SetupOption | null; currentValue: string | null }. Not-yet-applicable conditional steps (e.g. Hyperliquid’srevokeAgent, see Providers / Hyperliquid — Setup) are omitted rather than shown unsatisfied.
How checkSetup() treats each step
A choice is never executed by the SDK on its own. The option with
default: true is only the recommended option, which a UI can pre-select. An unsatisfied choice keeps isReady false, and nothing changes until you pass an option to executeProviderOption. currentValue holds the raw venue value as the venue names it, for example plus or premium for the Lighter account tier.
Read the result in three states:
isReady can stay false with an empty setup while an SDK-signed step is still pending; call checkSetup again.
buildProviderSetup
Build the unsigned setupActionSteps still outstanding for an account, ordered by descriptor sequence, without signing or submitting. The backend filters out already-satisfied setup — same filtering as checkSetup().setup — but the response carries only { actions }, without checkSetup’s surrounding accountExists, isReady, and checklist metadata. Like checkSetup().setup, it stages only USER-signed steps that are not choices.
Returns:
CreateActionResponse — { actions: ActionStep[] }.
executeProviderSetupAction
Sign and submit one pre-staged setupActionStep end-to-end. The caller obtains the step and the checklist from the same checkSetup call, without a refetch. The checklist is a snapshot: it does not change when a step runs. Call checkSetup again after each step, and handle the first unsatisfied item of the checklist each time. A choice step blocks the steps after it, so the loop executes a choice through executeProviderOption when it reaches one:
Returns:
Promise<ExecuteActionResponse>. A Failed or Indeterminate step is a result in the report, not an exception.
Throws: PerpsError (SDKError) when the step’s action is not in the provider’s setup, when a step with a lower sequence on checklist is still unsatisfied, or when signing or submission fails before any result is known. PerpsExecutionError carries the known results when a later stage fails. A choice counts as such a step. Satisfy the choice first, with executeProviderOption.
Requires the user wallet, set with
perps.setUserWallet(walletClient), 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).executeProviderOption
Execute the option the user chose for a choice step (for example HyperliquidaccountMode or Lighter accountType) end-to-end. The option is a SetupOption: it carries its own bound type and params. Dispatches through the same pipeline as execute, but an option change is a single mandatory action. A Failed or Indeterminate result is returned in the report and does not throw. Read the status before you treat the option as applied.
Returns:
Promise<ExecuteActionResponse>. Read results[i].status: a refusal is a Failed result, not an exception.
executeProviderRevoke
Undo a satisfied setup step by executing itsrevoke action. The SDK creates, signs, and submits the action, and signs it with the descriptor of that action from Provider.actions. The step is unsatisfied afterwards, so it stages again on the next checkSetup().
Returns:
Promise<ExecuteActionResponse>.
Throws: PerpsError (SDKError) when step.revoke is null, or when createAction stages nothing to revoke. A refused or Indeterminate revoke is a result in the report. Otherwise it throws the errors that executeProviderOption throws.
Order and position reads
ThesePerpsClient methods read directly from the venue through the registered provider plugin. They take the same parameters as the getOrders and getOrder services.
getOrders returns { orders: Order[] } (Order = RegularOrder | TriggerOrder | TwapOrder, discriminated on type). getOrder returns one Order.
getPositionRemovableMargin
Return the margin you can remove from an already-fetchedPosition, as a decimal string; undefined when the position has no individual margin adjustment and '0' when nothing is removable. See Position Margin.
client
perps.client is the underlying PerpsSDKClient. Pass it to service functions such as getMarkets, getPositions and getTermsAcceptance, and to PerpsWsClient.
App-level meta actions
These three methods dispatch provider-independent app-level actions — LI.FI terms acceptance and the internal referral code — using theMETA_PROVIDER sentinel instead of a real provider key. They are always signed as EIP-712 typed data with the configured user wallet. See SDK / Actions — App-level onboarding for the full dispatch model.
submitOnboarding
Accept the current terms and, when a code is supplied and the backend accepts it, attach that internal referral code — in one signature.
Returns:
ExecuteActionResponse — resolves to { results: [] } when the backend requires no consent from this address.
createReferralCode
Reserve the shareable internal referral codeaddress owns.
The address must have reached the backend’s executed-notional threshold before it can create a code, and an address owns exactly one permanent code.
Returns:
ExecuteActionResponse.
executeMetaAction
Low-level entry point bothsubmitOnboarding and createReferralCode call. Use it directly for META_ACCEPT_TERMS or any future meta action without a dedicated wrapper.
Returns:
ExecuteActionResponse. Throws PerpsError when no user wallet is configured, when the backend returns more than one step or a non-EIP-712 step, or when the submitted step reports a failed result. A wallet signature refusal propagates as the wallet’s own error.
API Reference: POST /createAction · /executeAction