# PartyA Open Facet

The **PartyA Open Facet** is how traders enter positions in the Options protocol. It handles the creation of open intents and manages their lifecycle until a PartyB picks them up or they're cancelled or expired.

> **Key Concepts:**
>
> * **Open Intent:** PartyA's on-chain expression of intent to open an options position. It sits `PENDING` until a PartyB locks it and opens the trade. No position exists until PartyB acts.
> * **TradeAgreements:** This defines the terms of the options contract — symbol, quantity, strike price, expiration, margin type, trade side, and exercise fee.&#x20;
> * **PartyB Whitelist:** An list of PartyB addresses that are permitted to act on the intent.&#x20;
> * **Strike Price:** The price at which the option can be exercised. Distinct from `price`, which is the premium PartyA is willing to pay to open the position.
> * **Expiration Timestamp:** When the options contract expires. After this point the option can be settled or exercised based on the protocol's settlement logic.
> * **ExerciseFee:** A fee structure applied when the option is exercised — defined by a rate and a cap.
> * **Solver Fee:** The fee PartyA pays to PartyB for taking the other side of the trade, split into `openFee` and `closeFee`.
> * **Maintenance Margin (mm):** An amount PartyA would pay to PartyB if the position gets liquidated. Only relevant on the SELL side.
> * **OpenIntentStatus:** Tracks the intent's lifecycle — `PENDING`, `LOCKED` (PartyB is processing it), `CANCELED`, `CANCEL_PENDING`, or `EXPIRED`.
> * **Instant Mode:** Blocks the standard open and cancel paths when active — instant mode uses its own separate flow.

***

#### Overview

Opening a position in the Options protocol is a two-step process:

1. PartyA submits an open intent via `sendOpenIntent()`, specifying all the terms of the options contract they want to enter, a price ceiling, and a deadline
2. A PartyB sees the intent, locks it, and opens the trade — at which point the intent transitions out of `PENDING` and a live `Trade` is created

The facet also handles the cleanup side of the open intent lifecycle:

3. If no PartyB fills the intent before the deadline, anyone can call `expireOpenIntent()` to formally mark it `EXPIRED` and unlock any reserved collateral
4. If PartyA changes their mind before fill, they call `cancelOpenIntent()` — which either cancels immediately (if the intent isn't locked) or enters `CANCEL_PENDING` (if a PartyB is currently processing it)

***

#### sendOpenIntent()

Creates a new open intent and submits it to the protocol. This is the entry point for all new options positions. The intent is immediately set to `PENDING` and becomes visible to eligible PartyBs.

**Function Signature:**

```solidity
function sendOpenIntent(
    address[] calldata partyBsWhiteList,
    uint256 symbolId,
    uint256 price,
    uint256 quantity,
    uint256 strikePrice,
    uint256 expirationTimestamp,
    uint256 mm,
    TradeSide tradeSide,
    MarginType marginType,
    ExerciseFee calldata exerciseFee,
    Fee calldata solverFee,
    uint256 deadline,
    address feeToken,
    address affiliate,
    bytes calldata userData
) external whenPartyNotPaused(msg.sender) whenInstantModeIsNotActive(msg.sender) returns (uint256 intentId);
```

**Parameters:**

* **partyBsWhiteList:** An array of PartyB addresses allowed to fill this intent.&#x20;
* **symbolId:** The ID of the options symbol to trade (e.g. the ETH call at a given strike)
* **price:** The maximum premium PartyA is willing to pay to open the position. PartyB must open at or below this price.
* **quantity:** The size of the position in base units.
* **strikePrice:** The strike price of the options contract — the price at which the holder can exercise the option.
* **expirationTimestamp:** The Unix timestamp at which the options contract expires.
* **mm:** The maintenance margin amount. If the position gets liquidated, this is paid from PartyA to PartyB. Only relevant for SELL side trades.&#x20;
* **tradeSide:** A `TradeSide` enum value — `BUY` (long the option) or `SELL` (short the option / write the option).
* **marginType:** A `MarginType` enum value — `ISOLATED` (this position has its own dedicated collateral) or `CROSS` (shared across multiple positions with a given counterparty).
* **exerciseFee:** An `ExerciseFee` struct containing a `rate` (percentage of notional) and a `cap` (maximum fee amount) applied at exercise time.
* **solverFee:** A `Fee` struct containing `openFee` and `closeFee` — the compensation PartyA pays to the PartyB solver for providing liquidity.
* **deadline:** A Unix timestamp. If no PartyB fills the intent by this time, it can be expired.
* **feeToken:** The ERC-20 token used to pay fees on this trade.
* **affiliate:** The affiliate address to attribute this trade to for fee routing purposes. Pass the zero address if no affiliate applies.
* **userData:** Arbitrary bytes that are stored alongside the intent and can be used by frontends or PartyBs for custom routing or metadata.

***

#### expireOpenIntent()

Transitions a batch of open intents to `EXPIRED` once their deadlines have passed. Callable by anyone — no ownership required.&#x20;

**Function Signature:**

```solidity
function expireOpenIntent(uint256[] calldata expiredIntentIds) external whenPartyNotPaused(msg.sender);
```

**Parameters:**

* **expiredIntentIds:** An array of open intent IDs to expire. The deadline of each must have already passed or the library call will revert.

***

#### cancelOpenIntent()

Requests cancellation of one or more open intents. The outcome depends on the current state of each intent at the time of the call:

* If the intent is **unlocked** (no PartyB has locked it yet) → immediately moves to `CANCELED`
* If the intent is **locked** (a PartyB is processing it) → moves to `CANCEL_PENDING`, awaiting PartyB's decision
* If the deadline has **already passed** → treated as expiry, moves to `EXPIRED`
* If the intent has **already been opened** into a live trade → cancellation is not possible and the call reverts for that intent

**Function Signature:**

```solidity
function cancelOpenIntent(uint256[] calldata intentIds) external whenPartyNotPaused(msg.sender) whenInstantModeIsNotActive(msg.sender);
```

**Parameters:**

* **intentIds:** An array of open intent IDs to cancel. The caller must be the PartyA of each intent.
