@epicentral/sos-sdk 0.9.1-beta → 0.10.0-beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -63,7 +63,8 @@ Additional modules:
63
63
  | `buildUnwindWriterUnsoldTransactionWithDerivation` | Builds unwind unsold transaction. |
64
64
  | `buildUnwindWriterUnsoldWithLoanRepayment` | **Unwind + repay pool loans in one tx.** Use when closing unsold shorts that borrowed from OMLP. |
65
65
  | `buildSyncWriterPositionTransaction` | Syncs writer position with pool accumulators. |
66
- | `buildSettleMakerCollateralTransaction` | Settles maker collateral after buyer closes (repays principal + accrued interest to OMLP from collateral vault first, then returns remainder to maker). |
66
+ | `buildSettleMakerCollateralTransaction` | Expiry Phase A: repays one active loan's principal + accrued interest to OMLP from collateral vault. Writers with multiple loans for the expired option call it once per loan; maker residual is claimed separately. |
67
+ | `getClaimMakerRemainingInstructionAsync` | Expiry Phase C generated instruction: returns remaining maker collateral after Phase B buyer payouts complete. |
67
68
  | `buildCloseOptionTransaction` | Closes option token account. |
68
69
  | `buildClaimThetaTransaction` | Claims theta (time-decay share) for writer. |
69
70
  | `buildRepayPoolLoanFromCollateralInstruction` | Repays pool loan from collateral (short/pool). |
@@ -77,8 +78,19 @@ Additional modules:
77
78
  - On-chain transfers for lender repayment and collateral return are authorized by program PDAs (`collateral_pool` / `option_pool`) where applicable.
78
79
  - `buildSettleMakerCollateralTransaction`
79
80
  - No maker transaction signer is required by this instruction format.
80
- - On-chain repayment (`collateral_vault` -> `omlp_vault`) and maker return are signed by the `collateral_pool` PDA.
81
+ - On-chain repayment (`collateral_vault` -> `omlp_vault`) is signed by the `collateral_pool` PDA.
81
82
  - Lender repayment is sourced from collateral vault funds, not maker wallet funds.
83
+ - Expiry residual maker collateral is returned later by `claim_maker_remaining` after buyer payout Phase B.
84
+
85
+ ### Expiry Settlement
86
+
87
+ Expiry settlement is lender-first and split across three instructions:
88
+
89
+ 1. `settle_maker_collateral` (Phase A) for every non-liquidated maker. Lender repayment is paid to the loan vault's ATA for the pool collateral mint, so devnet fake SOL/USDC pools and mainnet WSOL pools use the same mint-safe path. If a writer has multiple active `PoolLoan` accounts for that expired option, keepers submit one Phase A transaction per loan; the maker share is not marked Phase A settled until all are repaid.
90
+ 2. `auto_exercise_expired` / `auto_exercise_all_expired` (Phase B) for buyers, capped by `eligible_maker_pot`; options with zero buyer positions are considered buyer-settled so maker claims do not stall. The single and batch paths take the collateral/settlement mint so cash-settled payouts use the correct token decimals; batch remaining accounts must pair each position with that buyer's token account for the same mint.
91
+ 3. `claim_maker_remaining` (Phase C) for makers after `phase_b_complete`, returning residual collateral in the pool collateral mint.
92
+
93
+ New program errors exposed in the IDL: `LenderRepaymentNotComplete`, `BuyerPayoutNotComplete`, and `MakerLiquidated`.
82
94
 
83
95
  ### OMLP (Lending)
84
96
 
@@ -70,6 +70,13 @@ export type CollateralPool = {
70
70
  makerCount: number;
71
71
  isExercised: boolean;
72
72
  isFullySettled: boolean;
73
+ phaseAComplete: boolean;
74
+ phaseBComplete: boolean;
75
+ eligibleMakerPot: bigint;
76
+ remainingMakerPostDebtCollateral: bigint;
77
+ eligibleMakerCount: number;
78
+ makersPhaseASettled: number;
79
+ totalBuyerIntrinsicOwedSnapshot: bigint;
73
80
  createdAt: bigint;
74
81
  lastUpdated: bigint;
75
82
  bump: number;
@@ -89,6 +96,13 @@ export type CollateralPoolArgs = {
89
96
  makerCount: number;
90
97
  isExercised: boolean;
91
98
  isFullySettled: boolean;
99
+ phaseAComplete: boolean;
100
+ phaseBComplete: boolean;
101
+ eligibleMakerPot: number | bigint;
102
+ remainingMakerPostDebtCollateral: number | bigint;
103
+ eligibleMakerCount: number;
104
+ makersPhaseASettled: number;
105
+ totalBuyerIntrinsicOwedSnapshot: number | bigint;
92
106
  createdAt: number | bigint;
93
107
  lastUpdated: number | bigint;
94
108
  bump: number;
@@ -112,6 +126,13 @@ export function getCollateralPoolEncoder(): FixedSizeEncoder<CollateralPoolArgs>
112
126
  ["makerCount", getU32Encoder()],
113
127
  ["isExercised", getBooleanEncoder()],
114
128
  ["isFullySettled", getBooleanEncoder()],
129
+ ["phaseAComplete", getBooleanEncoder()],
130
+ ["phaseBComplete", getBooleanEncoder()],
131
+ ["eligibleMakerPot", getU64Encoder()],
132
+ ["remainingMakerPostDebtCollateral", getU64Encoder()],
133
+ ["eligibleMakerCount", getU32Encoder()],
134
+ ["makersPhaseASettled", getU32Encoder()],
135
+ ["totalBuyerIntrinsicOwedSnapshot", getU64Encoder()],
115
136
  ["createdAt", getI64Encoder()],
116
137
  ["lastUpdated", getI64Encoder()],
117
138
  ["bump", getU8Encoder()],
@@ -137,6 +158,13 @@ export function getCollateralPoolDecoder(): FixedSizeDecoder<CollateralPool> {
137
158
  ["makerCount", getU32Decoder()],
138
159
  ["isExercised", getBooleanDecoder()],
139
160
  ["isFullySettled", getBooleanDecoder()],
161
+ ["phaseAComplete", getBooleanDecoder()],
162
+ ["phaseBComplete", getBooleanDecoder()],
163
+ ["eligibleMakerPot", getU64Decoder()],
164
+ ["remainingMakerPostDebtCollateral", getU64Decoder()],
165
+ ["eligibleMakerCount", getU32Decoder()],
166
+ ["makersPhaseASettled", getU32Decoder()],
167
+ ["totalBuyerIntrinsicOwedSnapshot", getU64Decoder()],
140
168
  ["createdAt", getI64Decoder()],
141
169
  ["lastUpdated", getI64Decoder()],
142
170
  ["bump", getU8Decoder()],
@@ -213,5 +241,5 @@ export async function fetchAllMaybeCollateralPool(
213
241
  }
214
242
 
215
243
  export function getCollateralPoolSize(): number {
216
- return 183;
244
+ return 217;
217
245
  }
@@ -65,7 +65,9 @@ export type MakerCollateralShare = {
65
65
  premiumCollected: bigint;
66
66
  exercisePayout: bigint;
67
67
  lenderRepayment: bigint;
68
+ postDebtCollateral: bigint;
68
69
  makerReturn: bigint;
70
+ phaseASettled: boolean;
69
71
  isSettled: boolean;
70
72
  realizedPnl: bigint;
71
73
  createdAt: bigint;
@@ -84,7 +86,9 @@ export type MakerCollateralShareArgs = {
84
86
  premiumCollected: number | bigint;
85
87
  exercisePayout: number | bigint;
86
88
  lenderRepayment: number | bigint;
89
+ postDebtCollateral: number | bigint;
87
90
  makerReturn: number | bigint;
91
+ phaseASettled: boolean;
88
92
  isSettled: boolean;
89
93
  realizedPnl: number | bigint;
90
94
  createdAt: number | bigint;
@@ -107,7 +111,9 @@ export function getMakerCollateralShareEncoder(): FixedSizeEncoder<MakerCollater
107
111
  ["premiumCollected", getU64Encoder()],
108
112
  ["exercisePayout", getU64Encoder()],
109
113
  ["lenderRepayment", getU64Encoder()],
114
+ ["postDebtCollateral", getU64Encoder()],
110
115
  ["makerReturn", getU64Encoder()],
116
+ ["phaseASettled", getBooleanEncoder()],
111
117
  ["isSettled", getBooleanEncoder()],
112
118
  ["realizedPnl", getI64Encoder()],
113
119
  ["createdAt", getI64Encoder()],
@@ -135,7 +141,9 @@ export function getMakerCollateralShareDecoder(): FixedSizeDecoder<MakerCollater
135
141
  ["premiumCollected", getU64Decoder()],
136
142
  ["exercisePayout", getU64Decoder()],
137
143
  ["lenderRepayment", getU64Decoder()],
144
+ ["postDebtCollateral", getU64Decoder()],
138
145
  ["makerReturn", getU64Decoder()],
146
+ ["phaseASettled", getBooleanDecoder()],
139
147
  ["isSettled", getBooleanDecoder()],
140
148
  ["realizedPnl", getI64Decoder()],
141
149
  ["createdAt", getI64Decoder()],
@@ -225,5 +233,5 @@ export async function fetchAllMaybeMakerCollateralShare(
225
233
  }
226
234
 
227
235
  export function getMakerCollateralShareSize(): number {
228
- return 194;
236
+ return 203;
229
237
  }
@@ -154,78 +154,84 @@ export const OPTION_PROGRAM_ERROR__COLLATERAL_POOL_NOT_FOUND = 0x17b3; // 6067
154
154
  export const OPTION_PROGRAM_ERROR__NO_COLLATERAL_TO_WITHDRAW = 0x17b4; // 6068
155
155
  /** OptionNotExpired: Option has not expired yet - cannot settle */
156
156
  export const OPTION_PROGRAM_ERROR__OPTION_NOT_EXPIRED = 0x17b5; // 6069
157
+ /** LenderRepaymentNotComplete: Lender repayment phase is not complete */
158
+ export const OPTION_PROGRAM_ERROR__LENDER_REPAYMENT_NOT_COMPLETE = 0x17b6; // 6070
159
+ /** BuyerPayoutNotComplete: Buyer payout phase is not complete */
160
+ export const OPTION_PROGRAM_ERROR__BUYER_PAYOUT_NOT_COMPLETE = 0x17b7; // 6071
161
+ /** MakerLiquidated: Maker was liquidated and is excluded from expiry settlement */
162
+ export const OPTION_PROGRAM_ERROR__MAKER_LIQUIDATED = 0x17b8; // 6072
157
163
  /** SupplyLimitExceeded: Deposit would exceed vault supply limit */
158
- export const OPTION_PROGRAM_ERROR__SUPPLY_LIMIT_EXCEEDED = 0x17b6; // 6070
164
+ export const OPTION_PROGRAM_ERROR__SUPPLY_LIMIT_EXCEEDED = 0x17b9; // 6073
159
165
  /** InvalidFeeWallet: Invalid fee wallet - must match protocol constant */
160
- export const OPTION_PROGRAM_ERROR__INVALID_FEE_WALLET = 0x17b7; // 6071
166
+ export const OPTION_PROGRAM_ERROR__INVALID_FEE_WALLET = 0x17ba; // 6074
161
167
  /** InvalidProtocolFee: Invalid protocol fee rate */
162
- export const OPTION_PROGRAM_ERROR__INVALID_PROTOCOL_FEE = 0x17b8; // 6072
168
+ export const OPTION_PROGRAM_ERROR__INVALID_PROTOCOL_FEE = 0x17bb; // 6075
163
169
  /** UnderlyingAssetMismatch: Underlying asset mismatch - market data or mint does not match option */
164
- export const OPTION_PROGRAM_ERROR__UNDERLYING_ASSET_MISMATCH = 0x17b9; // 6073
170
+ export const OPTION_PROGRAM_ERROR__UNDERLYING_ASSET_MISMATCH = 0x17bc; // 6076
165
171
  /** InvalidMint: Invalid token mint - does not match expected underlying asset */
166
- export const OPTION_PROGRAM_ERROR__INVALID_MINT = 0x17ba; // 6074
172
+ export const OPTION_PROGRAM_ERROR__INVALID_MINT = 0x17bd; // 6077
167
173
  /** BatchSizeExceeded: Batch size exceeds maximum allowed (10 positions) */
168
- export const OPTION_PROGRAM_ERROR__BATCH_SIZE_EXCEEDED = 0x17bb; // 6075
174
+ export const OPTION_PROGRAM_ERROR__BATCH_SIZE_EXCEEDED = 0x17be; // 6078
169
175
  /** NoPositionsProvided: No positions provided in batch */
170
- export const OPTION_PROGRAM_ERROR__NO_POSITIONS_PROVIDED = 0x17bc; // 6076
176
+ export const OPTION_PROGRAM_ERROR__NO_POSITIONS_PROVIDED = 0x17bf; // 6079
171
177
  /** PositionOptionMismatch: Position account does not belong to this option */
172
- export const OPTION_PROGRAM_ERROR__POSITION_OPTION_MISMATCH = 0x17bd; // 6077
178
+ export const OPTION_PROGRAM_ERROR__POSITION_OPTION_MISMATCH = 0x17c0; // 6080
173
179
  /** OptionPoolMismatch: Option account does not match the option pool's option account */
174
- export const OPTION_PROGRAM_ERROR__OPTION_POOL_MISMATCH = 0x17be; // 6078
180
+ export const OPTION_PROGRAM_ERROR__OPTION_POOL_MISMATCH = 0x17c1; // 6081
175
181
  /** InvalidSeed: Invalid seed - must be exactly 32 bytes */
176
- export const OPTION_PROGRAM_ERROR__INVALID_SEED = 0x17bf; // 6079
182
+ export const OPTION_PROGRAM_ERROR__INVALID_SEED = 0x17c2; // 6082
177
183
  /** InvalidAuthority: Invalid authority - does not match escrow authority */
178
- export const OPTION_PROGRAM_ERROR__INVALID_AUTHORITY = 0x17c0; // 6080
184
+ export const OPTION_PROGRAM_ERROR__INVALID_AUTHORITY = 0x17c3; // 6083
179
185
  /** EscrowAccountRequired: Escrow accounts required when borrowed_amount > 0 */
180
- export const OPTION_PROGRAM_ERROR__ESCROW_ACCOUNT_REQUIRED = 0x17c1; // 6081
186
+ export const OPTION_PROGRAM_ERROR__ESCROW_ACCOUNT_REQUIRED = 0x17c4; // 6084
181
187
  /** InvalidEscrowMaker: Escrow state maker does not match instruction maker */
182
- export const OPTION_PROGRAM_ERROR__INVALID_ESCROW_MAKER = 0x17c2; // 6082
188
+ export const OPTION_PROGRAM_ERROR__INVALID_ESCROW_MAKER = 0x17c5; // 6085
183
189
  /** EscrowMintMismatch: Escrow collateral mint does not match collateral pool mint */
184
- export const OPTION_PROGRAM_ERROR__ESCROW_MINT_MISMATCH = 0x17c3; // 6083
190
+ export const OPTION_PROGRAM_ERROR__ESCROW_MINT_MISMATCH = 0x17c6; // 6086
185
191
  /** InsufficientEscrowBalance: Insufficient balance in escrow token account */
186
- export const OPTION_PROGRAM_ERROR__INSUFFICIENT_ESCROW_BALANCE = 0x17c4; // 6084
192
+ export const OPTION_PROGRAM_ERROR__INSUFFICIENT_ESCROW_BALANCE = 0x17c7; // 6087
187
193
  /** InvalidEscrowOwner: Escrow token account owner mismatch */
188
- export const OPTION_PROGRAM_ERROR__INVALID_ESCROW_OWNER = 0x17c5; // 6085
194
+ export const OPTION_PROGRAM_ERROR__INVALID_ESCROW_OWNER = 0x17c8; // 6088
189
195
  /** InvalidEscrowMint: Escrow token account mint mismatch */
190
- export const OPTION_PROGRAM_ERROR__INVALID_ESCROW_MINT = 0x17c6; // 6086
196
+ export const OPTION_PROGRAM_ERROR__INVALID_ESCROW_MINT = 0x17c9; // 6089
191
197
  /** AccountFrozen: Token account is frozen and cannot be burned */
192
- export const OPTION_PROGRAM_ERROR__ACCOUNT_FROZEN = 0x17c7; // 6087
198
+ export const OPTION_PROGRAM_ERROR__ACCOUNT_FROZEN = 0x17ca; // 6090
193
199
  /** InvalidAccount: Invalid account - does not match expected account */
194
- export const OPTION_PROGRAM_ERROR__INVALID_ACCOUNT = 0x17c8; // 6088
200
+ export const OPTION_PROGRAM_ERROR__INVALID_ACCOUNT = 0x17cb; // 6091
195
201
  /** UnwindRepayAccountsMissing: Unwind repayment accounts are required when active pool loans exist */
196
- export const OPTION_PROGRAM_ERROR__UNWIND_REPAY_ACCOUNTS_MISSING = 0x17c9; // 6089
202
+ export const OPTION_PROGRAM_ERROR__UNWIND_REPAY_ACCOUNTS_MISSING = 0x17cc; // 6092
197
203
  /** InsufficientCollateralVault: Collateral vault has insufficient funds for unwind collateral return */
198
- export const OPTION_PROGRAM_ERROR__INSUFFICIENT_COLLATERAL_VAULT = 0x17ca; // 6090
204
+ export const OPTION_PROGRAM_ERROR__INSUFFICIENT_COLLATERAL_VAULT = 0x17cd; // 6093
199
205
  /** InvalidVaultMint: Invalid vault mint - does not match expected collateral mint */
200
- export const OPTION_PROGRAM_ERROR__INVALID_VAULT_MINT = 0x17cb; // 6091
206
+ export const OPTION_PROGRAM_ERROR__INVALID_VAULT_MINT = 0x17ce; // 6094
201
207
  /** InvalidCollateralMint: Invalid collateral mint - not supported or no vault exists */
202
- export const OPTION_PROGRAM_ERROR__INVALID_COLLATERAL_MINT = 0x17cc; // 6092
208
+ export const OPTION_PROGRAM_ERROR__INVALID_COLLATERAL_MINT = 0x17cf; // 6095
203
209
  /** CollateralMismatch: Collateral mint mismatch - position uses different collateral type */
204
- export const OPTION_PROGRAM_ERROR__COLLATERAL_MISMATCH = 0x17cd; // 6093
210
+ export const OPTION_PROGRAM_ERROR__COLLATERAL_MISMATCH = 0x17d0; // 6096
205
211
  /** BuyRemainingAccountsUnsorted: buy_from_pool remaining_accounts are not sorted by (created_at asc, pubkey asc) */
206
- export const OPTION_PROGRAM_ERROR__BUY_REMAINING_ACCOUNTS_UNSORTED = 0x17ce; // 6094
212
+ export const OPTION_PROGRAM_ERROR__BUY_REMAINING_ACCOUNTS_UNSORTED = 0x17d1; // 6097
207
213
  /** CloseLongWritersIncomplete: close_long_to_pool requires a complete set of active WriterPositions: sum(sold_qty) must equal pool.total_sold_qty */
208
- export const OPTION_PROGRAM_ERROR__CLOSE_LONG_WRITERS_INCOMPLETE = 0x17cf; // 6095
214
+ export const OPTION_PROGRAM_ERROR__CLOSE_LONG_WRITERS_INCOMPLETE = 0x17d2; // 6098
209
215
  /** CloseLongNoSoldInventory: close_long_to_pool cannot run because no writer has sold inventory for this pool */
210
- export const OPTION_PROGRAM_ERROR__CLOSE_LONG_NO_SOLD_INVENTORY = 0x17d0; // 6096
216
+ export const OPTION_PROGRAM_ERROR__CLOSE_LONG_NO_SOLD_INVENTORY = 0x17d3; // 6099
211
217
  /** CloseLongDuplicateWriter: close_long_to_pool remaining_accounts contain duplicate WriterPosition entries */
212
- export const OPTION_PROGRAM_ERROR__CLOSE_LONG_DUPLICATE_WRITER = 0x17d1; // 6097
218
+ export const OPTION_PROGRAM_ERROR__CLOSE_LONG_DUPLICATE_WRITER = 0x17d4; // 6100
213
219
  /** MaintenanceBufferBreached: Writer position breaches maintenance buffer: free_collateral + claimable_theta < accrued_interest + fees + buffer */
214
- export const OPTION_PROGRAM_ERROR__MAINTENANCE_BUFFER_BREACHED = 0x17d2; // 6098
220
+ export const OPTION_PROGRAM_ERROR__MAINTENANCE_BUFFER_BREACHED = 0x17d5; // 6101
215
221
  /** LiquidationInsufficientCollateralForDebt: Liquidation cannot cover full debt (principal + interest + fees) from writer's collateral + theta; call rescue path instead */
216
- export const OPTION_PROGRAM_ERROR__LIQUIDATION_INSUFFICIENT_COLLATERAL_FOR_DEBT = 0x17d3; // 6099
222
+ export const OPTION_PROGRAM_ERROR__LIQUIDATION_INSUFFICIENT_COLLATERAL_FOR_DEBT = 0x17d6; // 6102
217
223
  /** ThetaClaimDisabled: claim_theta instruction has been removed; theta is now auto-realized on unwind or forfeited on liquidation */
218
- export const OPTION_PROGRAM_ERROR__THETA_CLAIM_DISABLED = 0x17d4; // 6100
224
+ export const OPTION_PROGRAM_ERROR__THETA_CLAIM_DISABLED = 0x17d7; // 6103
219
225
  /** PoolLoanWriterMismatch: PoolLoan.writer_position does not match the WriterPosition in this instruction */
220
- export const OPTION_PROGRAM_ERROR__POOL_LOAN_WRITER_MISMATCH = 0x17d5; // 6101
226
+ export const OPTION_PROGRAM_ERROR__POOL_LOAN_WRITER_MISMATCH = 0x17d8; // 6104
221
227
  /** MaintenanceLoansIncomplete: Maintenance debt sync remaining_accounts must contain every active PoolLoan for this writer */
222
- export const OPTION_PROGRAM_ERROR__MAINTENANCE_LOANS_INCOMPLETE = 0x17d6; // 6102
228
+ export const OPTION_PROGRAM_ERROR__MAINTENANCE_LOANS_INCOMPLETE = 0x17d9; // 6105
223
229
  /** RescueUnauthorized: Rescue liquidation is gated to the vault keeper */
224
- export const OPTION_PROGRAM_ERROR__RESCUE_UNAUTHORIZED = 0x17d7; // 6103
230
+ export const OPTION_PROGRAM_ERROR__RESCUE_UNAUTHORIZED = 0x17da; // 6106
225
231
  /** InvalidLoanRepayment: Loan repayment amount exceeds synced balances (principal/interest/fees) */
226
- export const OPTION_PROGRAM_ERROR__INVALID_LOAN_REPAYMENT = 0x17d8; // 6104
232
+ export const OPTION_PROGRAM_ERROR__INVALID_LOAN_REPAYMENT = 0x17db; // 6107
227
233
  /** RescuePreconditionsNotMet: Rescue preconditions not met: collateral_vault must be short of the remaining debt after theta forfeiture */
228
- export const OPTION_PROGRAM_ERROR__RESCUE_PRECONDITIONS_NOT_MET = 0x17d9; // 6105
234
+ export const OPTION_PROGRAM_ERROR__RESCUE_PRECONDITIONS_NOT_MET = 0x17dc; // 6108
229
235
 
230
236
  export type OptionProgramError =
231
237
  | typeof OPTION_PROGRAM_ERROR__ACCOUNT_FROZEN
@@ -233,6 +239,7 @@ export type OptionProgramError =
233
239
  | typeof OPTION_PROGRAM_ERROR__ARITHMETIC_OVERFLOW
234
240
  | typeof OPTION_PROGRAM_ERROR__ARITHMETIC_UNDERFLOW
235
241
  | typeof OPTION_PROGRAM_ERROR__BATCH_SIZE_EXCEEDED
242
+ | typeof OPTION_PROGRAM_ERROR__BUYER_PAYOUT_NOT_COMPLETE
236
243
  | typeof OPTION_PROGRAM_ERROR__BUY_REMAINING_ACCOUNTS_UNSORTED
237
244
  | typeof OPTION_PROGRAM_ERROR__CLOSE_LONG_DUPLICATE_WRITER
238
245
  | typeof OPTION_PROGRAM_ERROR__CLOSE_LONG_NO_SOLD_INVENTORY
@@ -289,10 +296,12 @@ export type OptionProgramError =
289
296
  | typeof OPTION_PROGRAM_ERROR__INVALID_UNDERLYING_PRICE
290
297
  | typeof OPTION_PROGRAM_ERROR__INVALID_VAULT_MINT
291
298
  | typeof OPTION_PROGRAM_ERROR__INVALID_VOLATILITY
299
+ | typeof OPTION_PROGRAM_ERROR__LENDER_REPAYMENT_NOT_COMPLETE
292
300
  | typeof OPTION_PROGRAM_ERROR__LIQUIDATION_INSUFFICIENT_COLLATERAL_FOR_DEBT
293
301
  | typeof OPTION_PROGRAM_ERROR__LOW_ORACLE_PRICE_CONFIDENCE
294
302
  | typeof OPTION_PROGRAM_ERROR__MAINTENANCE_BUFFER_BREACHED
295
303
  | typeof OPTION_PROGRAM_ERROR__MAINTENANCE_LOANS_INCOMPLETE
304
+ | typeof OPTION_PROGRAM_ERROR__MAKER_LIQUIDATED
296
305
  | typeof OPTION_PROGRAM_ERROR__MARKET_CLOSED
297
306
  | typeof OPTION_PROGRAM_ERROR__MAXIMUM_POSITION_SIZE_EXCEEDED
298
307
  | typeof OPTION_PROGRAM_ERROR__MAX_POSITIONS_REACHED
@@ -343,6 +352,7 @@ if (process.env.NODE_ENV !== "production") {
343
352
  [OPTION_PROGRAM_ERROR__ARITHMETIC_OVERFLOW]: `Arithmetic overflow occurred`,
344
353
  [OPTION_PROGRAM_ERROR__ARITHMETIC_UNDERFLOW]: `Arithmetic underflow occurred`,
345
354
  [OPTION_PROGRAM_ERROR__BATCH_SIZE_EXCEEDED]: `Batch size exceeds maximum allowed (10 positions)`,
355
+ [OPTION_PROGRAM_ERROR__BUYER_PAYOUT_NOT_COMPLETE]: `Buyer payout phase is not complete`,
346
356
  [OPTION_PROGRAM_ERROR__BUY_REMAINING_ACCOUNTS_UNSORTED]: `buy_from_pool remaining_accounts are not sorted by (created_at asc, pubkey asc)`,
347
357
  [OPTION_PROGRAM_ERROR__CLOSE_LONG_DUPLICATE_WRITER]: `close_long_to_pool remaining_accounts contain duplicate WriterPosition entries`,
348
358
  [OPTION_PROGRAM_ERROR__CLOSE_LONG_NO_SOLD_INVENTORY]: `close_long_to_pool cannot run because no writer has sold inventory for this pool`,
@@ -399,10 +409,12 @@ if (process.env.NODE_ENV !== "production") {
399
409
  [OPTION_PROGRAM_ERROR__INVALID_UNDERLYING_PRICE]: `Underlying price is invalid`,
400
410
  [OPTION_PROGRAM_ERROR__INVALID_VAULT_MINT]: `Invalid vault mint - does not match expected collateral mint`,
401
411
  [OPTION_PROGRAM_ERROR__INVALID_VOLATILITY]: `Volatility must be greater than zero`,
412
+ [OPTION_PROGRAM_ERROR__LENDER_REPAYMENT_NOT_COMPLETE]: `Lender repayment phase is not complete`,
402
413
  [OPTION_PROGRAM_ERROR__LIQUIDATION_INSUFFICIENT_COLLATERAL_FOR_DEBT]: `Liquidation cannot cover full debt (principal + interest + fees) from writer's collateral + theta; call rescue path instead`,
403
414
  [OPTION_PROGRAM_ERROR__LOW_ORACLE_PRICE_CONFIDENCE]: `Oracle price confidence is too low`,
404
415
  [OPTION_PROGRAM_ERROR__MAINTENANCE_BUFFER_BREACHED]: `Writer position breaches maintenance buffer: free_collateral + claimable_theta < accrued_interest + fees + buffer`,
405
416
  [OPTION_PROGRAM_ERROR__MAINTENANCE_LOANS_INCOMPLETE]: `Maintenance debt sync remaining_accounts must contain every active PoolLoan for this writer`,
417
+ [OPTION_PROGRAM_ERROR__MAKER_LIQUIDATED]: `Maker was liquidated and is excluded from expiry settlement`,
406
418
  [OPTION_PROGRAM_ERROR__MARKET_CLOSED]: `Market is closed`,
407
419
  [OPTION_PROGRAM_ERROR__MAXIMUM_POSITION_SIZE_EXCEEDED]: `Maximum position size exceeded`,
408
420
  [OPTION_PROGRAM_ERROR__MAX_POSITIONS_REACHED]: `Maximum positions limit reached`,
@@ -57,9 +57,8 @@ export type AutoExerciseAllExpiredInstruction<
57
57
  TAccountOptionPool extends string | AccountMeta<string> = string,
58
58
  TAccountOptionAccount extends string | AccountMeta<string> = string,
59
59
  TAccountUnderlyingMint extends string | AccountMeta<string> = string,
60
+ TAccountCollateralMint extends string | AccountMeta<string> = string,
60
61
  TAccountCollateralVault extends string | AccountMeta<string> = string,
61
- TAccountOmlpVault extends string | AccountMeta<string> = string,
62
- TAccountOmlpVaultState extends string | AccountMeta<string> = string,
63
62
  TAccountOptionMint extends string | AccountMeta<string> = string,
64
63
  TAccountSwitchboardQueue extends string | AccountMeta<string> = string,
65
64
  TAccountSlotHashesSysvar extends string | AccountMeta<string> =
@@ -89,15 +88,12 @@ export type AutoExerciseAllExpiredInstruction<
89
88
  TAccountUnderlyingMint extends string
90
89
  ? ReadonlyAccount<TAccountUnderlyingMint>
91
90
  : TAccountUnderlyingMint,
91
+ TAccountCollateralMint extends string
92
+ ? ReadonlyAccount<TAccountCollateralMint>
93
+ : TAccountCollateralMint,
92
94
  TAccountCollateralVault extends string
93
95
  ? WritableAccount<TAccountCollateralVault>
94
96
  : TAccountCollateralVault,
95
- TAccountOmlpVault extends string
96
- ? WritableAccount<TAccountOmlpVault>
97
- : TAccountOmlpVault,
98
- TAccountOmlpVaultState extends string
99
- ? WritableAccount<TAccountOmlpVaultState>
100
- : TAccountOmlpVaultState,
101
97
  TAccountOptionMint extends string
102
98
  ? WritableAccount<TAccountOptionMint>
103
99
  : TAccountOptionMint,
@@ -171,9 +167,8 @@ export type AutoExerciseAllExpiredAsyncInput<
171
167
  TAccountOptionPool extends string = string,
172
168
  TAccountOptionAccount extends string = string,
173
169
  TAccountUnderlyingMint extends string = string,
170
+ TAccountCollateralMint extends string = string,
174
171
  TAccountCollateralVault extends string = string,
175
- TAccountOmlpVault extends string = string,
176
- TAccountOmlpVaultState extends string = string,
177
172
  TAccountOptionMint extends string = string,
178
173
  TAccountSwitchboardQueue extends string = string,
179
174
  TAccountSlotHashesSysvar extends string = string,
@@ -191,17 +186,9 @@ export type AutoExerciseAllExpiredAsyncInput<
191
186
  * state PDA and to keep vault aggregates consistent across batches.
192
187
  */
193
188
  underlyingMint: Address<TAccountUnderlyingMint>;
189
+ collateralMint: Address<TAccountCollateralMint>;
194
190
  /** Pool's collateral vault (source of payout) */
195
191
  collateralVault: Address<TAccountCollateralVault>;
196
- /** OMLP Vault token account to receive repayments */
197
- omlpVault: Address<TAccountOmlpVault>;
198
- /**
199
- * OMLP Vault state PDA (mut: `total_loans`, `total_liquidity`,
200
- * `acc_interest_per_share_fp`). One vault state is used for the whole
201
- * batch — batch auto-exercise only repays lenders in the underlying
202
- * mint of the option.
203
- */
204
- omlpVaultState?: Address<TAccountOmlpVaultState>;
205
192
  /** Option mint (for burning) */
206
193
  optionMint: Address<TAccountOptionMint>;
207
194
  switchboardQueue: Address<TAccountSwitchboardQueue>;
@@ -221,9 +208,8 @@ export async function getAutoExerciseAllExpiredInstructionAsync<
221
208
  TAccountOptionPool extends string,
222
209
  TAccountOptionAccount extends string,
223
210
  TAccountUnderlyingMint extends string,
211
+ TAccountCollateralMint extends string,
224
212
  TAccountCollateralVault extends string,
225
- TAccountOmlpVault extends string,
226
- TAccountOmlpVaultState extends string,
227
213
  TAccountOptionMint extends string,
228
214
  TAccountSwitchboardQueue extends string,
229
215
  TAccountSlotHashesSysvar extends string,
@@ -239,9 +225,8 @@ export async function getAutoExerciseAllExpiredInstructionAsync<
239
225
  TAccountOptionPool,
240
226
  TAccountOptionAccount,
241
227
  TAccountUnderlyingMint,
228
+ TAccountCollateralMint,
242
229
  TAccountCollateralVault,
243
- TAccountOmlpVault,
244
- TAccountOmlpVaultState,
245
230
  TAccountOptionMint,
246
231
  TAccountSwitchboardQueue,
247
232
  TAccountSlotHashesSysvar,
@@ -259,9 +244,8 @@ export async function getAutoExerciseAllExpiredInstructionAsync<
259
244
  TAccountOptionPool,
260
245
  TAccountOptionAccount,
261
246
  TAccountUnderlyingMint,
247
+ TAccountCollateralMint,
262
248
  TAccountCollateralVault,
263
- TAccountOmlpVault,
264
- TAccountOmlpVaultState,
265
249
  TAccountOptionMint,
266
250
  TAccountSwitchboardQueue,
267
251
  TAccountSlotHashesSysvar,
@@ -282,9 +266,8 @@ export async function getAutoExerciseAllExpiredInstructionAsync<
282
266
  optionPool: { value: input.optionPool ?? null, isWritable: true },
283
267
  optionAccount: { value: input.optionAccount ?? null, isWritable: true },
284
268
  underlyingMint: { value: input.underlyingMint ?? null, isWritable: false },
269
+ collateralMint: { value: input.collateralMint ?? null, isWritable: false },
285
270
  collateralVault: { value: input.collateralVault ?? null, isWritable: true },
286
- omlpVault: { value: input.omlpVault ?? null, isWritable: true },
287
- omlpVaultState: { value: input.omlpVaultState ?? null, isWritable: true },
288
271
  optionMint: { value: input.optionMint ?? null, isWritable: true },
289
272
  switchboardQueue: {
290
273
  value: input.switchboardQueue ?? null,
@@ -326,17 +309,6 @@ export async function getAutoExerciseAllExpiredInstructionAsync<
326
309
  ],
327
310
  });
328
311
  }
329
- if (!accounts.omlpVaultState.value) {
330
- accounts.omlpVaultState.value = await getProgramDerivedAddress({
331
- programAddress,
332
- seeds: [
333
- getBytesEncoder().encode(new Uint8Array([118, 97, 117, 108, 116])),
334
- getAddressEncoder().encode(
335
- expectAddress(accounts.underlyingMint.value),
336
- ),
337
- ],
338
- });
339
- }
340
312
  if (!accounts.slotHashesSysvar.value) {
341
313
  accounts.slotHashesSysvar.value =
342
314
  "SysvarS1otHashes111111111111111111111111111" as Address<"SysvarS1otHashes111111111111111111111111111">;
@@ -361,9 +333,8 @@ export async function getAutoExerciseAllExpiredInstructionAsync<
361
333
  getAccountMeta(accounts.optionPool),
362
334
  getAccountMeta(accounts.optionAccount),
363
335
  getAccountMeta(accounts.underlyingMint),
336
+ getAccountMeta(accounts.collateralMint),
364
337
  getAccountMeta(accounts.collateralVault),
365
- getAccountMeta(accounts.omlpVault),
366
- getAccountMeta(accounts.omlpVaultState),
367
338
  getAccountMeta(accounts.optionMint),
368
339
  getAccountMeta(accounts.switchboardQueue),
369
340
  getAccountMeta(accounts.slotHashesSysvar),
@@ -383,9 +354,8 @@ export async function getAutoExerciseAllExpiredInstructionAsync<
383
354
  TAccountOptionPool,
384
355
  TAccountOptionAccount,
385
356
  TAccountUnderlyingMint,
357
+ TAccountCollateralMint,
386
358
  TAccountCollateralVault,
387
- TAccountOmlpVault,
388
- TAccountOmlpVaultState,
389
359
  TAccountOptionMint,
390
360
  TAccountSwitchboardQueue,
391
361
  TAccountSlotHashesSysvar,
@@ -402,9 +372,8 @@ export type AutoExerciseAllExpiredInput<
402
372
  TAccountOptionPool extends string = string,
403
373
  TAccountOptionAccount extends string = string,
404
374
  TAccountUnderlyingMint extends string = string,
375
+ TAccountCollateralMint extends string = string,
405
376
  TAccountCollateralVault extends string = string,
406
- TAccountOmlpVault extends string = string,
407
- TAccountOmlpVaultState extends string = string,
408
377
  TAccountOptionMint extends string = string,
409
378
  TAccountSwitchboardQueue extends string = string,
410
379
  TAccountSlotHashesSysvar extends string = string,
@@ -422,17 +391,9 @@ export type AutoExerciseAllExpiredInput<
422
391
  * state PDA and to keep vault aggregates consistent across batches.
423
392
  */
424
393
  underlyingMint: Address<TAccountUnderlyingMint>;
394
+ collateralMint: Address<TAccountCollateralMint>;
425
395
  /** Pool's collateral vault (source of payout) */
426
396
  collateralVault: Address<TAccountCollateralVault>;
427
- /** OMLP Vault token account to receive repayments */
428
- omlpVault: Address<TAccountOmlpVault>;
429
- /**
430
- * OMLP Vault state PDA (mut: `total_loans`, `total_liquidity`,
431
- * `acc_interest_per_share_fp`). One vault state is used for the whole
432
- * batch — batch auto-exercise only repays lenders in the underlying
433
- * mint of the option.
434
- */
435
- omlpVaultState: Address<TAccountOmlpVaultState>;
436
397
  /** Option mint (for burning) */
437
398
  optionMint: Address<TAccountOptionMint>;
438
399
  switchboardQueue: Address<TAccountSwitchboardQueue>;
@@ -452,9 +413,8 @@ export function getAutoExerciseAllExpiredInstruction<
452
413
  TAccountOptionPool extends string,
453
414
  TAccountOptionAccount extends string,
454
415
  TAccountUnderlyingMint extends string,
416
+ TAccountCollateralMint extends string,
455
417
  TAccountCollateralVault extends string,
456
- TAccountOmlpVault extends string,
457
- TAccountOmlpVaultState extends string,
458
418
  TAccountOptionMint extends string,
459
419
  TAccountSwitchboardQueue extends string,
460
420
  TAccountSlotHashesSysvar extends string,
@@ -470,9 +430,8 @@ export function getAutoExerciseAllExpiredInstruction<
470
430
  TAccountOptionPool,
471
431
  TAccountOptionAccount,
472
432
  TAccountUnderlyingMint,
433
+ TAccountCollateralMint,
473
434
  TAccountCollateralVault,
474
- TAccountOmlpVault,
475
- TAccountOmlpVaultState,
476
435
  TAccountOptionMint,
477
436
  TAccountSwitchboardQueue,
478
437
  TAccountSlotHashesSysvar,
@@ -489,9 +448,8 @@ export function getAutoExerciseAllExpiredInstruction<
489
448
  TAccountOptionPool,
490
449
  TAccountOptionAccount,
491
450
  TAccountUnderlyingMint,
451
+ TAccountCollateralMint,
492
452
  TAccountCollateralVault,
493
- TAccountOmlpVault,
494
- TAccountOmlpVaultState,
495
453
  TAccountOptionMint,
496
454
  TAccountSwitchboardQueue,
497
455
  TAccountSlotHashesSysvar,
@@ -511,9 +469,8 @@ export function getAutoExerciseAllExpiredInstruction<
511
469
  optionPool: { value: input.optionPool ?? null, isWritable: true },
512
470
  optionAccount: { value: input.optionAccount ?? null, isWritable: true },
513
471
  underlyingMint: { value: input.underlyingMint ?? null, isWritable: false },
472
+ collateralMint: { value: input.collateralMint ?? null, isWritable: false },
514
473
  collateralVault: { value: input.collateralVault ?? null, isWritable: true },
515
- omlpVault: { value: input.omlpVault ?? null, isWritable: true },
516
- omlpVaultState: { value: input.omlpVaultState ?? null, isWritable: true },
517
474
  optionMint: { value: input.optionMint ?? null, isWritable: true },
518
475
  switchboardQueue: {
519
476
  value: input.switchboardQueue ?? null,
@@ -565,9 +522,8 @@ export function getAutoExerciseAllExpiredInstruction<
565
522
  getAccountMeta(accounts.optionPool),
566
523
  getAccountMeta(accounts.optionAccount),
567
524
  getAccountMeta(accounts.underlyingMint),
525
+ getAccountMeta(accounts.collateralMint),
568
526
  getAccountMeta(accounts.collateralVault),
569
- getAccountMeta(accounts.omlpVault),
570
- getAccountMeta(accounts.omlpVaultState),
571
527
  getAccountMeta(accounts.optionMint),
572
528
  getAccountMeta(accounts.switchboardQueue),
573
529
  getAccountMeta(accounts.slotHashesSysvar),
@@ -587,9 +543,8 @@ export function getAutoExerciseAllExpiredInstruction<
587
543
  TAccountOptionPool,
588
544
  TAccountOptionAccount,
589
545
  TAccountUnderlyingMint,
546
+ TAccountCollateralMint,
590
547
  TAccountCollateralVault,
591
- TAccountOmlpVault,
592
- TAccountOmlpVaultState,
593
548
  TAccountOptionMint,
594
549
  TAccountSwitchboardQueue,
595
550
  TAccountSlotHashesSysvar,
@@ -615,28 +570,20 @@ export type ParsedAutoExerciseAllExpiredInstruction<
615
570
  * state PDA and to keep vault aggregates consistent across batches.
616
571
  */
617
572
  underlyingMint: TAccountMetas[3];
573
+ collateralMint: TAccountMetas[4];
618
574
  /** Pool's collateral vault (source of payout) */
619
- collateralVault: TAccountMetas[4];
620
- /** OMLP Vault token account to receive repayments */
621
- omlpVault: TAccountMetas[5];
622
- /**
623
- * OMLP Vault state PDA (mut: `total_loans`, `total_liquidity`,
624
- * `acc_interest_per_share_fp`). One vault state is used for the whole
625
- * batch — batch auto-exercise only repays lenders in the underlying
626
- * mint of the option.
627
- */
628
- omlpVaultState: TAccountMetas[6];
575
+ collateralVault: TAccountMetas[5];
629
576
  /** Option mint (for burning) */
630
- optionMint: TAccountMetas[7];
631
- switchboardQueue: TAccountMetas[8];
632
- slotHashesSysvar: TAccountMetas[9];
633
- instructionsSysvar: TAccountMetas[10];
577
+ optionMint: TAccountMetas[6];
578
+ switchboardQueue: TAccountMetas[7];
579
+ slotHashesSysvar: TAccountMetas[8];
580
+ instructionsSysvar: TAccountMetas[9];
634
581
  /** Market data for this underlying asset (contains switchboard_feed_id) */
635
- marketData: TAccountMetas[11];
582
+ marketData: TAccountMetas[10];
636
583
  /** Keeper who pays for gas - anyone can call this after expiration */
637
- keeper: TAccountMetas[12];
638
- tokenProgram: TAccountMetas[13];
639
- systemProgram: TAccountMetas[14];
584
+ keeper: TAccountMetas[11];
585
+ tokenProgram: TAccountMetas[12];
586
+ systemProgram: TAccountMetas[13];
640
587
  };
641
588
  data: AutoExerciseAllExpiredInstructionData;
642
589
  };
@@ -649,7 +596,7 @@ export function parseAutoExerciseAllExpiredInstruction<
649
596
  InstructionWithAccounts<TAccountMetas> &
650
597
  InstructionWithData<ReadonlyUint8Array>,
651
598
  ): ParsedAutoExerciseAllExpiredInstruction<TProgram, TAccountMetas> {
652
- if (instruction.accounts.length < 15) {
599
+ if (instruction.accounts.length < 14) {
653
600
  // TODO: Coded error.
654
601
  throw new Error("Not enough accounts");
655
602
  }
@@ -666,9 +613,8 @@ export function parseAutoExerciseAllExpiredInstruction<
666
613
  optionPool: getNextAccount(),
667
614
  optionAccount: getNextAccount(),
668
615
  underlyingMint: getNextAccount(),
616
+ collateralMint: getNextAccount(),
669
617
  collateralVault: getNextAccount(),
670
- omlpVault: getNextAccount(),
671
- omlpVaultState: getNextAccount(),
672
618
  optionMint: getNextAccount(),
673
619
  switchboardQueue: getNextAccount(),
674
620
  slotHashesSysvar: getNextAccount(),