All mutating operations — trading, withdrawals, leverage changes, position margin, account setup — go through the same two service functions: createAction and executeAction.
The Trading pages document the convenience wrappers (placeOrder, cancelOrders, etc.) that handle signing automatically in USER_AGENT mode. This page covers the generic action functions used in USER mode or when you need full control.
Pattern
createAction → actions[] → sign each typedData → executeAction → results[]
- Create — call
createAction() with the action type and params. Returns one or more ActionStep payloads containing EIP-712 typedData.
- Sign — sign each
typedData with the appropriate wallet (user wallet in USER mode, agent in USER_AGENT mode).
- Execute — call
executeAction() with the signed payloads. Returns success/failure for each action.
createAction
Build action payloads for signing.
import { createAction } from '@lifi/perps-sdk';
const { actions } = await createAction(client, {
provider: 'hyperliquid',
address: userAddress,
action: 'placeOrder',
params: {
asset: { assetId: 'BTC', market: 'hyperliquid' },
side: 'BUY',
type: 'LIMIT',
size: '0.1',
price: '94000.00',
timeInForce: 'GTC',
},
});
// actions: ActionStep[] — one or more payloads to sign
Parameters
| Parameter | Type | Required | Description |
|---|
client | PerpsSDKClient | Yes | SDK client |
params.provider | string | Yes | Provider identifier |
params.address | string | Yes | User’s wallet address (account owner) |
params.signerAddress | string | No | Address that will sign. Required for USER_AGENT mode (set to agent address). Defaults to address. |
params.action | ActionType | Yes | Action type (see Action Types) |
params.params | object | Yes | Action-specific parameters (see Actions API) |
options | SDKRequestOptions | No | Request options |
Returns
CreateActionResponse — { actions: ActionStep[] }:
Each ActionStep:
| Field | Type | Description |
|---|
action | ActionType | Action type |
typedData | PerpsTypedData | EIP-712 typed data to sign |
A single createAction call may return multiple actions. For example, placeOrder with a leverage param different from the current setting returns both an updateLeverage and a placeOrder step.
executeAction
Submit signed action payloads.
import { executeAction } from '@lifi/perps-sdk';
const result = await executeAction(client, {
provider: 'hyperliquid',
address: userAddress,
action: 'placeOrder',
actions: signedActions,
});
for (const r of result.results) {
console.log(r.action, r.success, r.orderId);
}
Parameters
| Parameter | Type | Required | Description |
|---|
client | PerpsSDKClient | Yes | SDK client |
params.provider | string | Yes | Provider identifier |
params.address | string | Yes | User’s wallet address (account owner) |
params.signerAddress | string | No | Address that signed. Required for USER_AGENT mode. Defaults to address. |
params.action | ActionType | Yes | Action type from the create request |
params.actions | SignedActionStep[] | Yes | Signed payloads from createAction |
options | SDKRequestOptions | No | Request options |
Each SignedActionStep:
| Field | Type | Description |
|---|
action | ActionType | Action type from the create response |
typedData | PerpsTypedData | Original typedData from createAction |
signature | Hex | Signer’s signature of the typedData |
Returns
ExecuteActionResponse — { results: ActionResult[] }:
Each ActionResult:
| Field | Type | Description |
|---|
action | ActionType | Action type |
success | boolean | Whether the action was accepted |
orderId | string? | Order ID (for placeOrder and placeTriggerOrder) |
error | string? | Error message if failed |
Full Example
A complete create -> sign -> execute flow for placing a limit order in USER mode:
import { createAction, executeAction } from '@lifi/perps-sdk';
// 1. Create
const { actions } = await createAction(client, {
provider: 'hyperliquid',
address: userAddress,
action: 'placeOrder',
params: {
asset: { assetId: 'BTC', market: 'hyperliquid' },
side: 'BUY',
type: 'LIMIT',
size: '0.1',
price: '94000.00',
timeInForce: 'GTC',
},
});
// 2. Sign each action with the user's wallet
const signedActions = await Promise.all(
actions.map(async (a) => ({
action: a.action,
typedData: a.typedData,
signature: await walletClient.signTypedData({ ...a.typedData }),
}))
);
// 3. Execute
const result = await executeAction(client, {
provider: 'hyperliquid',
address: userAddress,
action: 'placeOrder',
actions: signedActions,
});
console.log(result.results);
// [{ action: 'placeOrder', success: true, orderId: '12345678' }]
Action Types
All action types from the provider’s prepareAccountActions and actions arrays can be used with createAction/executeAction:
| Action | Category | Description |
|---|
approveAgent | Setup | Authorize an agent wallet |
approveBuilderFee | Setup | Approve builder fee |
userSetAbstraction | Setup | Enable account abstraction (user-signed) |
agentSetAbstraction | Setup | Enable account abstraction (agent-signed) |
placeOrder | Trading | Place a new order |
placeTriggerOrder | Trading | Place standalone TP/SL |
cancelOrder | Trading | Cancel orders by ID |
modifyOrder | Trading | Modify existing orders |
updateLeverage | Trading | Change leverage for an asset |
updatePositionMargin | Trading | Add/remove margin on a position |
withdrawal | Transfer | Withdraw funds to L1 |
sendAsset | Transfer | Move collateral between sub-exchanges |
For parameter schemas per action type, see Actions API.
API Reference: POST /createAction, POST /executeAction