@epicentral/sos-sdk 0.15.1-beta → 0.16.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.
@@ -0,0 +1,67 @@
1
+ /**
2
+ * This code was AUTOGENERATED using the Codama library.
3
+ * Please DO NOT EDIT THIS FILE, instead use visitors
4
+ * to add features, then rerun Codama to update it.
5
+ *
6
+ * @see https://github.com/codama-idl/codama
7
+ */
8
+
9
+ import {
10
+ combineCodec,
11
+ getF64Decoder,
12
+ getF64Encoder,
13
+ getStructDecoder,
14
+ getStructEncoder,
15
+ getU64Decoder,
16
+ getU64Encoder,
17
+ type FixedSizeCodec,
18
+ type FixedSizeDecoder,
19
+ type FixedSizeEncoder,
20
+ } from "@solana/kit";
21
+
22
+ /**
23
+ * One leg of a multi-strike mint. All amounts in base units
24
+ * (1 contract = 1_000_000; collateral in collateral-mint base units).
25
+ */
26
+ export type MintLegArgs = {
27
+ strikePrice: number;
28
+ quantity: bigint;
29
+ makerCollateralAmount: bigint;
30
+ borrowedAmount: bigint;
31
+ maxRequiredCollateralAmount: bigint;
32
+ };
33
+
34
+ export type MintLegArgsArgs = {
35
+ strikePrice: number;
36
+ quantity: number | bigint;
37
+ makerCollateralAmount: number | bigint;
38
+ borrowedAmount: number | bigint;
39
+ maxRequiredCollateralAmount: number | bigint;
40
+ };
41
+
42
+ export function getMintLegArgsEncoder(): FixedSizeEncoder<MintLegArgsArgs> {
43
+ return getStructEncoder([
44
+ ["strikePrice", getF64Encoder()],
45
+ ["quantity", getU64Encoder()],
46
+ ["makerCollateralAmount", getU64Encoder()],
47
+ ["borrowedAmount", getU64Encoder()],
48
+ ["maxRequiredCollateralAmount", getU64Encoder()],
49
+ ]);
50
+ }
51
+
52
+ export function getMintLegArgsDecoder(): FixedSizeDecoder<MintLegArgs> {
53
+ return getStructDecoder([
54
+ ["strikePrice", getF64Decoder()],
55
+ ["quantity", getU64Decoder()],
56
+ ["makerCollateralAmount", getU64Decoder()],
57
+ ["borrowedAmount", getU64Decoder()],
58
+ ["maxRequiredCollateralAmount", getU64Decoder()],
59
+ ]);
60
+ }
61
+
62
+ export function getMintLegArgsCodec(): FixedSizeCodec<
63
+ MintLegArgsArgs,
64
+ MintLegArgs
65
+ > {
66
+ return combineCodec(getMintLegArgsEncoder(), getMintLegArgsDecoder());
67
+ }
package/index.ts CHANGED
@@ -12,7 +12,25 @@ export {
12
12
  export { parseOptionProgramInstruction } from "./shared/option-program-parser";
13
13
 
14
14
  export * from "./accounts/pdas";
15
- export * from "./accounts/fetchers";
15
+ export {
16
+ accountExists,
17
+ decodeCollateralVaultFromCollateralPoolRawData,
18
+ decodeOptionPoolTradePubkeysFromRawData,
19
+ fetchAccountData,
20
+ fetchBuyerPosition,
21
+ fetchBuyerSettlementClaim,
22
+ fetchCollateralPool,
23
+ fetchLenderPosition,
24
+ fetchMakerSettlementClaim,
25
+ fetchManyAccounts,
26
+ fetchMarketDataAccount,
27
+ fetchOptionAccount,
28
+ fetchOptionAccounts,
29
+ fetchOptionPool,
30
+ fetchPoolLoan,
31
+ fetchVault,
32
+ fetchWriterPosition,
33
+ } from "./accounts/fetchers";
16
34
  export * from "./accounts/list";
17
35
  export * from "./accounts/resolve-option";
18
36
 
@@ -33,6 +51,7 @@ export {
33
51
 
34
52
  export * from "./short/builders";
35
53
  export * from "./short/close-option";
54
+ export * from "./short/multi-mint";
36
55
  export * from "./short/pool";
37
56
  export * from "./short/preflight";
38
57
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@epicentral/sos-sdk",
3
- "version": "0.15.1-beta",
3
+ "version": "0.16.0-beta",
4
4
  "private": false,
5
5
  "description": "Solana Option Standard SDK. The frontend-first SDK for Native Options Trading on Solana. Created by Epicentral Labs.",
6
6
  "type": "module",
@@ -23,6 +23,7 @@ import {
23
23
  parseInitConfigInstruction,
24
24
  parseInitializeMarketDataInstruction,
25
25
  parseInitOptionPoolInstruction,
26
+ parseInitOptionSeriesInstruction,
26
27
  parseLiquidateWriterPositionInstruction,
27
28
  parseLiquidateWriterPositionRescueInstruction,
28
29
  parseMigrateCollateralPoolV1ToV2Instruction,
@@ -38,6 +39,7 @@ import {
38
39
  parseOmlpUpdateSupplyLimitInstruction,
39
40
  parseOptionExerciseInstruction,
40
41
  parseOptionMintInstruction,
42
+ parseOptionMintMultiInstruction,
41
43
  parseOptionValidateInstruction,
42
44
  parsePrepareBuyerSettlementInstruction,
43
45
  parsePrepareMakerSettlementInstruction,
@@ -162,6 +164,11 @@ export function parseOptionProgramInstruction<
162
164
  parseInitConfigInstruction(instruction),
163
165
  instructionType,
164
166
  );
167
+ case OptionProgramInstruction.InitOptionSeries:
168
+ return withInstructionType(
169
+ parseInitOptionSeriesInstruction(instruction),
170
+ instructionType,
171
+ );
165
172
  case OptionProgramInstruction.InitOptionPool:
166
173
  return withInstructionType(
167
174
  parseInitOptionPoolInstruction(instruction),
@@ -247,6 +254,11 @@ export function parseOptionProgramInstruction<
247
254
  parseOptionMintInstruction(instruction),
248
255
  instructionType,
249
256
  );
257
+ case OptionProgramInstruction.OptionMintMulti:
258
+ return withInstructionType(
259
+ parseOptionMintMultiInstruction(instruction),
260
+ instructionType,
261
+ );
250
262
  case OptionProgramInstruction.OptionValidate:
251
263
  return withInstructionType(
252
264
  parseOptionValidateInstruction(instruction),
@@ -0,0 +1,403 @@
1
+ /**
2
+ * Multi-strike minting builders (Phase 2).
3
+ *
4
+ * Flow:
5
+ * 1. `deriveOptionSeriesLegAddresses` per strike (pure derivation).
6
+ * 2. `findLegsNeedingSeriesInit` — checks which strikes still need
7
+ * `init_option_series` (missing option account OR missing writer position
8
+ * for this maker). Series init creates NO Metaplex metadata: the option's
9
+ * identity lives on the OptionAccount PDA and clients render names from
10
+ * chain state.
11
+ * 3. `buildInitOptionSeriesInstruction` per needed strike (chunk 2 per tx).
12
+ * 4. `buildOptionMintMultiTransactionWithDerivation` — chunks legs into
13
+ * transactions of ≤ MAX_MINT_LEGS, one Switchboard quote per chunk, and
14
+ * per-leg account bundles in remaining_accounts after the quote triple.
15
+ *
16
+ * Per-leg remaining_accounts stride (must match the program's
17
+ * `multi_mint::MINT_LEG_ACCOUNT_STRIDE`):
18
+ * [option_account, option_pool, collateral_pool, collateral_vault,
19
+ * long_mint, short_mint, escrow_long_account, maker_short_account,
20
+ * writer_position, (pool_loan when leg.borrowedAmount > 0)]
21
+ */
22
+
23
+ import type { Address, Instruction, TransactionSigner } from "@solana/kit";
24
+ import {
25
+ getInitOptionSeriesInstructionAsync,
26
+ getOptionMintMultiInstructionAsync,
27
+ type OptionType,
28
+ } from "../generated";
29
+ import { PROGRAM_ID, toAddress } from "../client/program";
30
+ import type { AddressLike, BuiltTransaction, KitRpc } from "../client/types";
31
+ import { fetchMarketDataAccount } from "../accounts/fetchers";
32
+ import {
33
+ deriveAssociatedTokenAddress,
34
+ deriveCollateralPoolPda,
35
+ deriveLongMintPda,
36
+ deriveMarketDataPda,
37
+ deriveOptionAccountPda,
38
+ deriveOptionPoolPda,
39
+ derivePoolLoanPdaFromWriterPosition,
40
+ deriveShortMintPda,
41
+ deriveWriterPositionPda,
42
+ } from "../accounts/pdas";
43
+ import { invariant } from "../shared/errors";
44
+ import {
45
+ appendRemainingAccounts,
46
+ type RemainingAccountInput,
47
+ } from "../shared/remaining-accounts";
48
+ import {
49
+ buildSwitchboardQuoteInstruction,
50
+ feedIdBytesToHex,
51
+ inferSwitchboardNetwork,
52
+ INSTRUCTIONS_SYSVAR_ADDRESS,
53
+ SLOT_HASHES_SYSVAR_ADDRESS,
54
+ SWITCHBOARD_DEFAULT_DEVNET_QUEUE,
55
+ } from "../oracle/switchboard";
56
+ import { deriveVolatilityQuoteAddressFromMarketData } from "../oracle/volatility-quote";
57
+
58
+ /**
59
+ * Effective legs per `option_mint_multi` transaction. The on-chain ceiling is
60
+ * 4 (`multi_mint::MAX_MINT_LEGS`); 3 keeps the quote + multi-mint transaction
61
+ * comfortably inside the 1232-byte wire limit with ALT compression and the
62
+ * ~1.4M CU budget.
63
+ */
64
+ export const MAX_MINT_LEGS = 3;
65
+
66
+ /** Series-init instructions that fit in one transaction (no oracle quote needed). */
67
+ export const MAX_SERIES_INITS_PER_TRANSACTION = 2;
68
+
69
+ export interface MultiMintLegInput {
70
+ strikePrice: number;
71
+ /** Contracts in base units (1 contract = 1_000_000). */
72
+ quantity: bigint;
73
+ /** Maker's own deposit for this leg (collateral base units). */
74
+ makerCollateralAmount: bigint;
75
+ /** Borrowed portion for this leg (collateral base units). */
76
+ borrowedAmount: bigint;
77
+ /** Slippage guard: max on-chain required collateral accepted (base units). */
78
+ maxRequiredCollateralAmount: bigint;
79
+ }
80
+
81
+ export interface OptionSeriesLegAddresses {
82
+ strikePrice: number;
83
+ optionAccount: Address;
84
+ longMint: Address;
85
+ shortMint: Address;
86
+ optionPool: Address;
87
+ collateralPool: Address;
88
+ collateralVault: Address;
89
+ escrowLongAccount: Address;
90
+ premiumVault: Address;
91
+ makerShortAccount: Address;
92
+ writerPosition: Address;
93
+ poolLoan: Address;
94
+ }
95
+
96
+ export async function deriveOptionSeriesLegAddresses(params: {
97
+ underlyingAsset: AddressLike;
98
+ optionType: OptionType;
99
+ strikePrice: number;
100
+ expirationDate: bigint | number;
101
+ collateralMint: AddressLike;
102
+ maker: AddressLike;
103
+ programId?: AddressLike;
104
+ }): Promise<OptionSeriesLegAddresses> {
105
+ const programId = params.programId ?? PROGRAM_ID;
106
+ const [optionAccount] = await deriveOptionAccountPda({
107
+ underlyingAsset: params.underlyingAsset,
108
+ optionType: params.optionType,
109
+ strikePrice: params.strikePrice,
110
+ expirationDate: params.expirationDate,
111
+ programId,
112
+ });
113
+ const [[longMint], [shortMint], [optionPool], [collateralPool]] = await Promise.all([
114
+ deriveLongMintPda(optionAccount, programId),
115
+ deriveShortMintPda(optionAccount, programId),
116
+ deriveOptionPoolPda(optionAccount, programId),
117
+ deriveCollateralPoolPda(optionAccount, programId),
118
+ ]);
119
+ const [[writerPosition], collateralVault, escrowLongAccount, premiumVault] =
120
+ await Promise.all([
121
+ deriveWriterPositionPda(optionPool, params.maker, programId),
122
+ deriveAssociatedTokenAddress(collateralPool, params.collateralMint, true),
123
+ deriveAssociatedTokenAddress(optionPool, longMint, true),
124
+ deriveAssociatedTokenAddress(optionPool, params.collateralMint, true),
125
+ ]);
126
+ const [makerShortAccount, [poolLoan]] = await Promise.all([
127
+ deriveAssociatedTokenAddress(params.maker, shortMint),
128
+ derivePoolLoanPdaFromWriterPosition(writerPosition, programId),
129
+ ]);
130
+
131
+ return {
132
+ strikePrice: params.strikePrice,
133
+ optionAccount,
134
+ longMint,
135
+ shortMint,
136
+ optionPool,
137
+ collateralPool,
138
+ collateralVault,
139
+ escrowLongAccount,
140
+ premiumVault,
141
+ makerShortAccount,
142
+ writerPosition,
143
+ poolLoan,
144
+ };
145
+ }
146
+
147
+ /**
148
+ * Strikes that still need `init_option_series` before `option_mint_multi`:
149
+ * the option account is missing OR the maker's writer position has not been
150
+ * allocated yet (both are created by series init).
151
+ */
152
+ export async function findLegsNeedingSeriesInit(
153
+ rpc: KitRpc,
154
+ legs: OptionSeriesLegAddresses[]
155
+ ): Promise<OptionSeriesLegAddresses[]> {
156
+ if (legs.length === 0) return [];
157
+ const addresses = legs.flatMap((leg) => [leg.optionAccount, leg.writerPosition]);
158
+ const response = await rpc
159
+ .getMultipleAccounts(addresses, { encoding: "base64" })
160
+ .send();
161
+ const needing: OptionSeriesLegAddresses[] = [];
162
+ legs.forEach((leg, i) => {
163
+ const optionInfo = response.value[i * 2];
164
+ const writerInfo = response.value[i * 2 + 1];
165
+ if (!optionInfo || !writerInfo) {
166
+ needing.push(leg);
167
+ }
168
+ });
169
+ return needing;
170
+ }
171
+
172
+ export interface BuildInitOptionSeriesParams {
173
+ underlyingAsset: AddressLike;
174
+ underlyingMint: AddressLike;
175
+ collateralMint: AddressLike;
176
+ optionType: OptionType;
177
+ strikePrice: number;
178
+ expirationDate: bigint | number;
179
+ maker: TransactionSigner<string>;
180
+ volatilityQuoteAccount: AddressLike;
181
+ programId?: AddressLike;
182
+ }
183
+
184
+ /** One `init_option_series` instruction (no oracle quote, no metadata CPIs). */
185
+ export async function buildInitOptionSeriesInstruction(
186
+ params: BuildInitOptionSeriesParams
187
+ ): Promise<Instruction<string>> {
188
+ return await getInitOptionSeriesInstructionAsync(
189
+ {
190
+ volatilityQuoteAccount: toAddress(params.volatilityQuoteAccount),
191
+ underlyingMint: toAddress(params.underlyingMint),
192
+ collateralMint: toAddress(params.collateralMint),
193
+ maker: params.maker,
194
+ optionType: params.optionType,
195
+ strikePrice: params.strikePrice,
196
+ expirationDate: params.expirationDate,
197
+ underlyingAsset: toAddress(params.underlyingAsset),
198
+ },
199
+ { programAddress: params.programId ? toAddress(params.programId) : PROGRAM_ID }
200
+ );
201
+ }
202
+
203
+ export interface BuildOptionMintMultiParams {
204
+ underlyingAsset: AddressLike;
205
+ underlyingMint: AddressLike;
206
+ /** Collateral mint shared by every leg (one collateral pool family). */
207
+ collateralMint: AddressLike;
208
+ optionType: OptionType;
209
+ expirationDate: bigint | number;
210
+ legs: MultiMintLegInput[];
211
+ maker: TransactionSigner<string>;
212
+ /** Maker's collateral ATA; derived when omitted. */
213
+ makerCollateralAccount?: AddressLike;
214
+ rpc: KitRpc;
215
+ rpcEndpoint: string;
216
+ programId?: AddressLike;
217
+ /** Required when any leg borrows. */
218
+ vault?: AddressLike;
219
+ escrowState?: AddressLike;
220
+ escrowAuthority?: AddressLike;
221
+ escrowTokenAccount?: AddressLike;
222
+ /** Legs per transaction (default {@link MAX_MINT_LEGS}, on-chain max 4). */
223
+ maxLegsPerTransaction?: number;
224
+ switchboardCrossbarUrl?: string;
225
+ switchboardNumSignatures?: number;
226
+ /**
227
+ * 0-based index of the Switchboard quote ix in the FINAL transaction after
228
+ * wallet-prepended compute-budget ixs (OPX standard layout: 2).
229
+ */
230
+ switchboardQuoteInstructionIndex?: number;
231
+ }
232
+
233
+ export interface BuiltOptionMintMultiChunk extends BuiltTransaction {
234
+ /** Legs included in this transaction (same order as the stride bundles). */
235
+ legs: MultiMintLegInput[];
236
+ legAddresses: OptionSeriesLegAddresses[];
237
+ }
238
+
239
+ export interface BuildOptionMintMultiResult {
240
+ /** One entry per transaction to send sequentially. */
241
+ chunks: BuiltOptionMintMultiChunk[];
242
+ /** Per-leg derived addresses (for ALT extension before sending). */
243
+ legAddresses: OptionSeriesLegAddresses[];
244
+ /**
245
+ * Every per-leg address referenced via remaining_accounts — extend the
246
+ * program lookup table with these before sending so each chunk compresses
247
+ * under the 1232-byte limit.
248
+ */
249
+ lookupAddresses: Address[];
250
+ }
251
+
252
+ /**
253
+ * Build `option_mint_multi` transactions for a strike ladder. Every leg's
254
+ * series must already exist (`init_option_series`); use
255
+ * {@link findLegsNeedingSeriesInit} + {@link buildInitOptionSeriesInstruction}
256
+ * first.
257
+ */
258
+ export async function buildOptionMintMultiTransactionWithDerivation(
259
+ params: BuildOptionMintMultiParams
260
+ ): Promise<BuildOptionMintMultiResult> {
261
+ invariant(params.legs.length > 0, "at least one leg is required");
262
+ const maxLegs = params.maxLegsPerTransaction ?? MAX_MINT_LEGS;
263
+ invariant(maxLegs >= 1 && maxLegs <= 4, "maxLegsPerTransaction must be 1-4");
264
+
265
+ const anyBorrow = params.legs.some((leg) => leg.borrowedAmount > 0n);
266
+ if (anyBorrow) {
267
+ invariant(!!params.vault, "vault is required when any leg borrows");
268
+ invariant(!!params.escrowState, "escrowState is required when any leg borrows");
269
+ invariant(
270
+ !!params.escrowAuthority,
271
+ "escrowAuthority is required when any leg borrows"
272
+ );
273
+ invariant(
274
+ !!params.escrowTokenAccount,
275
+ "escrowTokenAccount is required when any leg borrows"
276
+ );
277
+ }
278
+
279
+ const programId = params.programId ?? PROGRAM_ID;
280
+ const [marketData] = await deriveMarketDataPda(params.underlyingAsset, programId);
281
+ const marketDataAccount = await fetchMarketDataAccount(params.rpc, marketData);
282
+ invariant(!!marketDataAccount, "Market data account not found for underlying asset.");
283
+ const volatilityQuoteAccount =
284
+ deriveVolatilityQuoteAddressFromMarketData(marketDataAccount);
285
+ const switchboardFeedId = feedIdBytesToHex(
286
+ Uint8Array.from(marketDataAccount.switchboardFeedId as unknown as Uint8Array)
287
+ );
288
+
289
+ const makerAddress = toAddress(params.maker.address);
290
+ const makerCollateralAccount = params.makerCollateralAccount
291
+ ? toAddress(params.makerCollateralAccount)
292
+ : await deriveAssociatedTokenAddress(makerAddress, params.collateralMint);
293
+
294
+ const legAddresses = await Promise.all(
295
+ params.legs.map((leg) =>
296
+ deriveOptionSeriesLegAddresses({
297
+ underlyingAsset: params.underlyingAsset,
298
+ optionType: params.optionType,
299
+ strikePrice: leg.strikePrice,
300
+ expirationDate: params.expirationDate,
301
+ collateralMint: params.collateralMint,
302
+ maker: makerAddress,
303
+ programId,
304
+ })
305
+ )
306
+ );
307
+
308
+ const quoteNetwork = await inferSwitchboardNetwork(params.rpc);
309
+
310
+ const chunks: BuiltOptionMintMultiChunk[] = [];
311
+ for (let start = 0; start < params.legs.length; start += maxLegs) {
312
+ const chunkLegs = params.legs.slice(start, start + maxLegs);
313
+ const chunkAddresses = legAddresses.slice(start, start + maxLegs);
314
+
315
+ const multiIx = await getOptionMintMultiInstructionAsync(
316
+ {
317
+ volatilityQuoteAccount: toAddress(volatilityQuoteAccount),
318
+ underlyingMint: toAddress(params.underlyingMint),
319
+ collateralMint: toAddress(params.collateralMint),
320
+ makerCollateralAccount,
321
+ vault: params.vault ? toAddress(params.vault) : undefined,
322
+ escrowState: params.escrowState ? toAddress(params.escrowState) : undefined,
323
+ escrowAuthority: params.escrowAuthority
324
+ ? toAddress(params.escrowAuthority)
325
+ : undefined,
326
+ escrowTokenAccount: params.escrowTokenAccount
327
+ ? toAddress(params.escrowTokenAccount)
328
+ : undefined,
329
+ maker: params.maker,
330
+ optionType: params.optionType,
331
+ expirationDate: params.expirationDate,
332
+ underlyingAsset: toAddress(params.underlyingAsset),
333
+ legs: chunkLegs.map((leg) => ({
334
+ strikePrice: leg.strikePrice,
335
+ quantity: leg.quantity,
336
+ makerCollateralAmount: leg.makerCollateralAmount,
337
+ borrowedAmount: leg.borrowedAmount,
338
+ maxRequiredCollateralAmount: leg.maxRequiredCollateralAmount,
339
+ })),
340
+ },
341
+ { programAddress: toAddress(programId) }
342
+ );
343
+
344
+ const remaining: RemainingAccountInput[] = [
345
+ { address: SWITCHBOARD_DEFAULT_DEVNET_QUEUE, isWritable: false },
346
+ { address: SLOT_HASHES_SYSVAR_ADDRESS, isWritable: false },
347
+ { address: INSTRUCTIONS_SYSVAR_ADDRESS, isWritable: false },
348
+ ];
349
+ chunkLegs.forEach((leg, i) => {
350
+ const addrs = chunkAddresses[i];
351
+ remaining.push(
352
+ { address: addrs.optionAccount, isWritable: true },
353
+ { address: addrs.optionPool, isWritable: true },
354
+ { address: addrs.collateralPool, isWritable: true },
355
+ { address: addrs.collateralVault, isWritable: true },
356
+ { address: addrs.longMint, isWritable: true },
357
+ { address: addrs.shortMint, isWritable: true },
358
+ { address: addrs.escrowLongAccount, isWritable: true },
359
+ { address: addrs.makerShortAccount, isWritable: true },
360
+ { address: addrs.writerPosition, isWritable: true }
361
+ );
362
+ if (leg.borrowedAmount > 0n) {
363
+ remaining.push({ address: addrs.poolLoan, isWritable: true });
364
+ }
365
+ });
366
+
367
+ const fullIx = appendRemainingAccounts(multiIx, remaining);
368
+
369
+ const quote = await buildSwitchboardQuoteInstruction({
370
+ rpcEndpoint: params.rpcEndpoint,
371
+ feedIdHex: switchboardFeedId,
372
+ network: quoteNetwork,
373
+ crossbarUrl: params.switchboardCrossbarUrl,
374
+ numSignatures: params.switchboardNumSignatures,
375
+ instructionIdx: params.switchboardQuoteInstructionIndex ?? 1,
376
+ });
377
+
378
+ chunks.push({
379
+ instructions: [quote.instruction, fullIx],
380
+ legs: chunkLegs,
381
+ legAddresses: chunkAddresses,
382
+ });
383
+ }
384
+
385
+ const lookupAddresses = Array.from(
386
+ new Set(
387
+ legAddresses.flatMap((addrs) => [
388
+ addrs.optionAccount,
389
+ addrs.optionPool,
390
+ addrs.collateralPool,
391
+ addrs.collateralVault,
392
+ addrs.longMint,
393
+ addrs.shortMint,
394
+ addrs.escrowLongAccount,
395
+ addrs.makerShortAccount,
396
+ addrs.writerPosition,
397
+ addrs.poolLoan,
398
+ ])
399
+ )
400
+ );
401
+
402
+ return { chunks, legAddresses, lookupAddresses };
403
+ }