diff --git a/packages/js/src/plugins/psyoptionsAmericanInstrumentModule/helpers.ts b/packages/js/src/plugins/psyoptionsAmericanInstrumentModule/helpers.ts index f70c5c2f5..f216f356c 100644 --- a/packages/js/src/plugins/psyoptionsAmericanInstrumentModule/helpers.ts +++ b/packages/js/src/plugins/psyoptionsAmericanInstrumentModule/helpers.ts @@ -32,7 +32,7 @@ export const prepareAmericanOptions = async ( const callerSide = caller.equals(rfq.taker) ? 'taker' : 'maker'; - const { legs } = convergence.rfqs().getSettlementResult({ + const { legs: legExchangeResult } = convergence.rfqs().getSettlementResult({ response, rfq, }); @@ -40,7 +40,7 @@ export const prepareAmericanOptions = async ( const ataTxBuilderArray: TransactionBuilder[] = []; const mintTxBuilderArray: TransactionBuilder[] = []; for (const [index, leg] of rfq.legs.entries()) { - const { receiver, amount } = legs[index]; + const { receiver, amount } = legExchangeResult[index]; if ( !(leg instanceof PsyoptionsAmericanInstrument) || receiver === callerSide @@ -83,14 +83,14 @@ export const prepareAmericanOptions = async ( }); const tokensToMint = amount - tokenBalance; - if (tokensToMint! <= 0) continue; + if (tokensToMint <= 0) continue; const ixWithSigners = - await psyoptionsAmerican.instructions.mintOptionInstruction( + await psyoptionsAmerican.instructions.mintOptionV2Instruction( americanProgram, optionToken.ataPubKey, writerToken.ataPubKey, underlyingToken.ataPubKey, - new BN(tokensToMint!), + new BN(tokensToMint), optionMarket as psyoptionsAmerican.OptionMarketWithKey ); ixWithSigners.ix.keys[0] = { diff --git a/packages/js/src/plugins/psyoptionsAmericanInstrumentModule/instrument.ts b/packages/js/src/plugins/psyoptionsAmericanInstrumentModule/instrument.ts index c458b57b2..47b5ab463 100644 --- a/packages/js/src/plugins/psyoptionsAmericanInstrumentModule/instrument.ts +++ b/packages/js/src/plugins/psyoptionsAmericanInstrumentModule/instrument.ts @@ -90,7 +90,8 @@ export class PsyoptionsAmericanInstrument implements LegInstrument { this.stableAssetMint, this.strikePriceDecimals, this.strikePrice, - this.expirationTimestamp + this.expirationTimestamp, + this.optionType ); return optionMarketIxs; } @@ -126,9 +127,9 @@ export class PsyoptionsAmericanInstrument implements LegInstrument { stableMint, expirationTimestamp, strike, - underlyingAmountPerContract + underlyingAmountPerContract, + optionType ); - return new PsyoptionsAmericanInstrument( convergence, optionType, @@ -303,7 +304,8 @@ export const getPsyAmericanMarketIxs = async ( stableMint: PublicKey, stableMintDecimals: number, strike: number, - expirationTimestamp: number + expirationTimestamp: number, + optionType: OptionType ): Promise => { const cvgWallet = new CvgWallet(cvg); const americanProgram = createAmericanProgram(cvg, cvgWallet); @@ -317,19 +319,35 @@ export const getPsyAmericanMarketIxs = async ( ); let optionMarket: psyoptionsAmerican.OptionMarketWithKey | null = null; - const [optionMarketKey] = await psyoptionsAmerican.deriveOptionKeyFromParams({ - expirationUnixTimestamp: expirationTimestampBN, - programId: americanProgram.programId, - quoteAmountPerContract: quoteAmountPerContractBN, - quoteMint: stableMint, - underlyingAmountPerContract: underlyingAmountPerContractBN, - underlyingMint, - }); - optionMarket = await psyoptionsAmerican.getOptionByKey( - americanProgram, - optionMarketKey - ); - + if (optionType === OptionType.CALL) { + const [optionMarketKey] = + await psyoptionsAmerican.deriveOptionKeyFromParams({ + expirationUnixTimestamp: expirationTimestampBN, + programId: americanProgram.programId, + quoteAmountPerContract: quoteAmountPerContractBN, + quoteMint: stableMint, + underlyingAmountPerContract: underlyingAmountPerContractBN, + underlyingMint, + }); + optionMarket = await psyoptionsAmerican.getOptionByKey( + americanProgram, + optionMarketKey + ); + } else if (optionType === OptionType.PUT) { + const [optionMarketKey] = + await psyoptionsAmerican.deriveOptionKeyFromParams({ + expirationUnixTimestamp: expirationTimestampBN, + programId: americanProgram.programId, + quoteAmountPerContract: underlyingAmountPerContractBN, + quoteMint: underlyingMint, + underlyingAmountPerContract: quoteAmountPerContractBN, + underlyingMint: stableMint, + }); + optionMarket = await psyoptionsAmerican.getOptionByKey( + americanProgram, + optionMarketKey + ); + } if (optionMarket) { return []; } @@ -343,7 +361,8 @@ export const getPsyAmericanMarketIxs = async ( quoteAmountPerContractBN, stableMint, underlyingAmountPerContractBN, - underlyingMint + underlyingMint, + optionType ); if (mintFeeAccount.txBuilder) { optionMarketIxs.push(...mintFeeAccount.txBuilder.getInstructions()); @@ -354,7 +373,6 @@ export const getPsyAmericanMarketIxs = async ( } optionMarketIxs.push(optionMarketIx.tx); - return optionMarketIxs; }; @@ -368,7 +386,8 @@ export const getAmericanOptionkeys = async ( stableMint: Mint, expirationUnixTimestamp: number, strike: number, - underlyingAmountPerContract: number + underlyingAmountPerContract: number, + optionType: OptionType ): Promise => { const quoteAmountPerContractBN = new BN( addDecimals(strike, stableMint.decimals) @@ -377,21 +396,38 @@ export const getAmericanOptionkeys = async ( addDecimals(underlyingAmountPerContract, underlyingMint.decimals) ); + if (optionType === OptionType.CALL) { + const [metaKey] = await psyoptionsAmerican.deriveOptionKeyFromParams({ + expirationUnixTimestamp: new BN(expirationUnixTimestamp), + programId: americanProgram.programId, + quoteAmountPerContract: quoteAmountPerContractBN, + quoteMint: stableMint.address, + underlyingAmountPerContract: underlyingAmountPerContractBN, + underlyingMint: underlyingMint.address, + }); + + const [callOptionMint] = PublicKey.findProgramAddressSync( + [metaKey.toBuffer(), Buffer.from('optionToken')], + americanProgram.programId + ); + + return { optionMint: callOptionMint, metaKey }; + } const [metaKey] = await psyoptionsAmerican.deriveOptionKeyFromParams({ expirationUnixTimestamp: new BN(expirationUnixTimestamp), programId: americanProgram.programId, - quoteAmountPerContract: quoteAmountPerContractBN, - quoteMint: stableMint.address, - underlyingAmountPerContract: underlyingAmountPerContractBN, - underlyingMint: underlyingMint.address, + quoteAmountPerContract: underlyingAmountPerContractBN, + quoteMint: underlyingMint.address, + underlyingAmountPerContract: quoteAmountPerContractBN, + underlyingMint: stableMint.address, }); - const [optionMint] = PublicKey.findProgramAddressSync( + const [putOptionMint] = PublicKey.findProgramAddressSync( [metaKey.toBuffer(), Buffer.from('optionToken')], americanProgram.programId ); - return { optionMint, metaKey }; + return { optionMint: putOptionMint, metaKey }; }; export type GetPsyAmericanOptionMarketAccounts = { @@ -414,30 +450,63 @@ const getPsyAmericanOptionMarketAccounts = async ( quoteAmountPerContract: BN, stableMint: PublicKey, underlyingAmountPerContract: BN, - underlyingMint: PublicKey + underlyingMint: PublicKey, + optionType: OptionType ): Promise => { + if (optionType === OptionType.CALL) { + const optionMarketIx = + await psyoptionsAmerican.instructions.initializeOptionInstruction( + americanProgram, + { + /** The option market expiration timestamp in seconds */ + expirationUnixTimestamp, + quoteAmountPerContract, + quoteMint: stableMint, + underlyingAmountPerContract, + underlyingMint, + } + ); + const feeOwner = psyoptionsAmerican.FEE_OWNER_KEY; + const mintFeeAccount = await getOrCreateATAtxBuilder( + cvg, + underlyingMint, + feeOwner + ); + + const exerciseFeeAccount = await getOrCreateATAtxBuilder( + cvg, + stableMint, + feeOwner + ); + + return { + optionMarketIx, + mintFeeAccount, + exerciseFeeAccount, + }; + } const optionMarketIx = await psyoptionsAmerican.instructions.initializeOptionInstruction( americanProgram, { /** The option market expiration timestamp in seconds */ expirationUnixTimestamp, - quoteAmountPerContract, - quoteMint: stableMint, - underlyingAmountPerContract, - underlyingMint, + quoteAmountPerContract: underlyingAmountPerContract, + quoteMint: underlyingMint, + underlyingAmountPerContract: quoteAmountPerContract, + underlyingMint: stableMint, } ); const feeOwner = psyoptionsAmerican.FEE_OWNER_KEY; const mintFeeAccount = await getOrCreateATAtxBuilder( cvg, - underlyingMint, + stableMint, feeOwner ); const exerciseFeeAccount = await getOrCreateATAtxBuilder( cvg, - stableMint, + underlyingMint, feeOwner ); diff --git a/packages/js/src/plugins/psyoptionsEuropeanInstrumentModule/helpers.ts b/packages/js/src/plugins/psyoptionsEuropeanInstrumentModule/helpers.ts index 97158ec4d..6d14ea69d 100644 --- a/packages/js/src/plugins/psyoptionsEuropeanInstrumentModule/helpers.ts +++ b/packages/js/src/plugins/psyoptionsEuropeanInstrumentModule/helpers.ts @@ -31,14 +31,14 @@ export const prepareEuropeanOptions = async ( const callerSide = caller.equals(rfq.taker) ? 'taker' : 'maker'; - const { legs } = convergence.rfqs().getSettlementResult({ + const { legs: legExchangeResult } = convergence.rfqs().getSettlementResult({ response, rfq, }); const mintTxBuilderArray: TransactionBuilder[] = []; const ataTxBuilderArray: TransactionBuilder[] = []; for (const [index, leg] of rfq.legs.entries()) { - const { receiver, amount } = legs[index]; + const { receiver, amount } = legExchangeResult[index]; if ( !(leg instanceof PsyoptionsEuropeanInstrument) || receiver === callerSide @@ -63,7 +63,7 @@ export const prepareEuropeanOptions = async ( ? stableMintToken : underlyingMintToken; - const optionDestination = await getOrCreateATAtxBuilder( + const optionToken = await getOrCreateATAtxBuilder( convergence, leg.optionType == psyoptionsEuropean.OptionType.PUT ? euroMeta.putOptionMint @@ -71,24 +71,18 @@ export const prepareEuropeanOptions = async ( caller ); - if ( - optionDestination.txBuilder && - ixTracker.checkedAdd(optionDestination.txBuilder) - ) { - ataTxBuilderArray.push(optionDestination.txBuilder); + if (optionToken.txBuilder && ixTracker.checkedAdd(optionToken.txBuilder)) { + ataTxBuilderArray.push(optionToken.txBuilder); } - const writerDestination = await getOrCreateATAtxBuilder( + const writerToken = await getOrCreateATAtxBuilder( convergence, leg.optionType == psyoptionsEuropean.OptionType.PUT ? euroMeta.putWriterMint : euroMeta.callWriterMint, caller ); - if ( - writerDestination.txBuilder && - ixTracker.checkedAdd(writerDestination.txBuilder) - ) { - ataTxBuilderArray.push(writerDestination.txBuilder); + if (writerToken.txBuilder && ixTracker.checkedAdd(writerToken.txBuilder)) { + ataTxBuilderArray.push(writerToken.txBuilder); } const { tokenBalance } = await convergence.tokens().getTokenBalance({ @@ -107,8 +101,8 @@ export const prepareEuropeanOptions = async ( leg.optionMetaPubKey, euroMeta as psyoptionsEuropean.EuroMeta, minterCollateralKey, - optionDestination.ataPubKey, - writerDestination.ataPubKey, + optionToken.ataPubKey, + writerToken.ataPubKey, addDecimals(tokensToMint, PsyoptionsEuropeanInstrument.decimals), leg.optionType ); diff --git a/packages/js/tests/helpers.ts b/packages/js/tests/helpers.ts index d5e0b1c89..aa52d4ade 100644 --- a/packages/js/tests/helpers.ts +++ b/packages/js/tests/helpers.ts @@ -237,11 +237,11 @@ export const createAmericanFixedBaseStraddle = async ( cvg, baseMint, quoteMint, - OptionType.CALL, + OptionType.PUT, 1, 'long', 1, - 29_000, + 27_000, expirationTimestamp ), ], diff --git a/packages/validator/fixtures/programs/psyoptions_american_instrument.so b/packages/validator/fixtures/programs/psyoptions_american_instrument.so index 1af845b28..8438fa296 100755 Binary files a/packages/validator/fixtures/programs/psyoptions_american_instrument.so and b/packages/validator/fixtures/programs/psyoptions_american_instrument.so differ diff --git a/packages/validator/fixtures/programs/psyoptions_european_instrument.so b/packages/validator/fixtures/programs/psyoptions_european_instrument.so index 13dc09288..a97b3252d 100755 Binary files a/packages/validator/fixtures/programs/psyoptions_european_instrument.so and b/packages/validator/fixtures/programs/psyoptions_european_instrument.so differ