---
title: Prepare perps actions
description: Prepare, authorize, simulate, and execute physical-long and offset-short transactions.
---

> **For AI agents:** the complete documentation index is at [llms.txt](/llms.txt). Append `.md` to any page URL for its markdown version.

High-level preparation methods derive calldata from a USDC contribution and leverage selection. They return the same frozen `PreparedAction` used by every other SDK write, so consumers use one authorization and execution lifecycle.

## Increase a physical long

```ts
const prepared = await sv3.position.prepareIncreaseLongByLeverage({
  market,
  userContributionRaw: parseUsdc("100"),
  leverageBps: 20_000n,
  slippageBps: 100n,
  deadlineSeconds: 300,
});
```

This prepares `expandWithExactReserveIn`. The SDK derives gross debt, quotes the fee-aware curve buy, verifies post-buy floor capacity and current cap headroom, and encodes a minimum AVM output. A 1× request records zero new debt.

To add collateral without increasing long size:

```ts
const prepared = await sv3.position.prepareAddLongCollateral({
  market,
  amountRaw: parseUsdc("25"),
});
```

This is a product-language alias for repaying debt. It does not buy or sell AVM.

## Open an offset short

```ts
const prepared = await sv3.perp.prepareOpenShortByLeverage({
  market,
  marginRaw: parseUsdc("100"),
  leverageBps: 20_000n,
  slippageBps: 100n,
  deadlineSeconds: 300,
});

const quote = prepared.quoteContext;
if (quote === undefined || !("kind" in quote) || quote.kind !== "shortByLeverage") {
  throw new Error("missing short quote");
}
```

The SDK discovers the attached `OffsetPerpMarket`; callers do not supply or trust a second address. It derives exact AVM size inside the full live safety envelope and encodes `minReleasedPremiumRaw` from the explicit slippage value.

## Add short margin

```ts
const prepared = await sv3.perp.prepareAddMarginForMarket({
  market,
  positionId,
  amountRaw: parseUsdc("25"),
});
```

This resolves the attached perp from FloorMarket and targets one exact lot. Adding margin does not increase its size.

Low-level `prepareOpenShortExactSize`, `prepareAddMargin`, and `prepareCloseShortFull` remain available when an integration intentionally manages the attached perp address and exact settlement constraints itself. Prefer the `ForMarket` or `ByLeverage` methods for application code.

## Reduce, flag, and liquidate

The safe application namespace also covers every public risk-reducing or permissionless lifecycle action:

```ts
await sv3.perp.prepareRemoveMargin({ market, positionId, amountRaw });
await sv3.perp.prepareCloseShortExactSize({
  market,
  positionId,
  sizeAvm,
  maxRestoreCostRaw,
  minPayoutRaw,
});
await sv3.perp.prepareCloseShortFullForMarket({
  market,
  positionId,
  maxRestoreCostRaw,
  minPayoutRaw,
});
await sv3.perp.prepareFlag({ market, positionId });
await sv3.perp.prepareLiquidate({
  market,
  positionId,
  maxRestoreCostRaw,
  minRestoredAvm,
});
```

Obtain restoration, payout, health, and maturity inputs from `sv3.perp.quoteClose` and `quoteHealth`. Never invent a liquidation price or omit `maxRestoreCostRaw` / `minRestoredAvm`; surrender during liquidation honors both limits.

Perp pause/cap administration and protocol revenue claims are privileged and intentionally excluded from the safe application namespace.

## Authorization

Prepared actions never send an approval automatically. Load the exact requirement:

```ts
const context = prepared.quoteContext;
const shortDebit =
  context !== undefined && "kind" in context && context.kind === "shortByLeverage"
    ? context.totalWalletDebitRaw
    : parseUsdc("100");

const requirements = await sv3.authorization.loadRequirements(prepared, {
  token: reserveToken,
  spender: prepared.to,
  amount: shortDebit,
  mode: "auto",
});
```

Both `openShortExactSize` and `addMargin` support their EIP-2612 permit variants. Contract wallets automatically use the allowance path.

## Simulate and send

```ts
const simulation = await sv3.transactions.simulatePrepared(prepared);
const pending = await sv3.transactions.executePrepared(prepared, { permit });
const confirmed = await pending.wait();
```

Offset-perp prepared actions carry the FloorMarket as their state target even though calldata is sent to `OffsetPerpMarket`. `executePrepared` therefore checks the correct pinned curve state and then simulates the actual perp call as the connected wallet before sending.

Never silently rebuild and send a changed position after `StaleStateError`. Show the new quote and ask the user to confirm it.
