Skip to main content
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[]
  1. Create — call createAction() with the action type and params. Returns one or more ActionStep payloads containing EIP-712 typedData.
  2. Sign — sign each typedData with the appropriate wallet (user wallet in USER mode, agent in USER_AGENT mode).
  3. 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

ParameterTypeRequiredDescription
clientPerpsSDKClientYesSDK client
params.providerstringYesProvider identifier
params.addressstringYesUser’s wallet address (account owner)
params.signerAddressstringNoAddress that will sign. Required for USER_AGENT mode (set to agent address). Defaults to address.
params.actionActionTypeYesAction type (see Action Types)
params.paramsobjectYesAction-specific parameters (see Actions API)
optionsSDKRequestOptionsNoRequest options

Returns

CreateActionResponse{ actions: ActionStep[] }: Each ActionStep:
FieldTypeDescription
actionActionTypeAction type
typedDataPerpsTypedDataEIP-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

ParameterTypeRequiredDescription
clientPerpsSDKClientYesSDK client
params.providerstringYesProvider identifier
params.addressstringYesUser’s wallet address (account owner)
params.signerAddressstringNoAddress that signed. Required for USER_AGENT mode. Defaults to address.
params.actionActionTypeYesAction type from the create request
params.actionsSignedActionStep[]YesSigned payloads from createAction
optionsSDKRequestOptionsNoRequest options
Each SignedActionStep:
FieldTypeDescription
actionActionTypeAction type from the create response
typedDataPerpsTypedDataOriginal typedData from createAction
signatureHexSigner’s signature of the typedData

Returns

ExecuteActionResponse{ results: ActionResult[] }: Each ActionResult:
FieldTypeDescription
actionActionTypeAction type
successbooleanWhether the action was accepted
orderIdstring?Order ID (for placeOrder and placeTriggerOrder)
errorstring?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:
ActionCategoryDescription
approveAgentSetupAuthorize an agent wallet
approveBuilderFeeSetupApprove builder fee
userSetAbstractionSetupEnable account abstraction (user-signed)
agentSetAbstractionSetupEnable account abstraction (agent-signed)
placeOrderTradingPlace a new order
placeTriggerOrderTradingPlace standalone TP/SL
cancelOrderTradingCancel orders by ID
modifyOrderTradingModify existing orders
updateLeverageTradingChange leverage for an asset
updatePositionMarginTradingAdd/remove margin on a position
withdrawalTransferWithdraw funds to L1
sendAssetTransferMove collateral between sub-exchanges
For parameter schemas per action type, see Actions API. API Reference: POST /createAction, POST /executeAction