Skip to content

Commit

Permalink
add updated psyoptions american instrument program binaries and imple…
Browse files Browse the repository at this point in the history
…ment PUT option logic
  • Loading branch information
Nagaprasadvr committed Oct 4, 2023
1 parent b1dc1e2 commit d5c6597
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,15 @@ 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,
});

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
Expand Down Expand Up @@ -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] = {
Expand Down
135 changes: 102 additions & 33 deletions packages/js/src/plugins/psyoptionsAmericanInstrumentModule/instrument.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,8 @@ export class PsyoptionsAmericanInstrument implements LegInstrument {
this.stableAssetMint,
this.strikePriceDecimals,
this.strikePrice,
this.expirationTimestamp
this.expirationTimestamp,
this.optionType
);
return optionMarketIxs;
}
Expand Down Expand Up @@ -126,9 +127,9 @@ export class PsyoptionsAmericanInstrument implements LegInstrument {
stableMint,
expirationTimestamp,
strike,
underlyingAmountPerContract
underlyingAmountPerContract,
optionType
);

return new PsyoptionsAmericanInstrument(
convergence,
optionType,
Expand Down Expand Up @@ -303,7 +304,8 @@ export const getPsyAmericanMarketIxs = async (
stableMint: PublicKey,
stableMintDecimals: number,
strike: number,
expirationTimestamp: number
expirationTimestamp: number,
optionType: OptionType
): Promise<CreateOptionInstrumentsResult> => {
const cvgWallet = new CvgWallet(cvg);
const americanProgram = createAmericanProgram(cvg, cvgWallet);
Expand All @@ -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 [];
}
Expand All @@ -343,7 +361,8 @@ export const getPsyAmericanMarketIxs = async (
quoteAmountPerContractBN,
stableMint,
underlyingAmountPerContractBN,
underlyingMint
underlyingMint,
optionType
);
if (mintFeeAccount.txBuilder) {
optionMarketIxs.push(...mintFeeAccount.txBuilder.getInstructions());
Expand All @@ -354,7 +373,6 @@ export const getPsyAmericanMarketIxs = async (
}

optionMarketIxs.push(optionMarketIx.tx);

return optionMarketIxs;
};

Expand All @@ -368,7 +386,8 @@ export const getAmericanOptionkeys = async (
stableMint: Mint,
expirationUnixTimestamp: number,
strike: number,
underlyingAmountPerContract: number
underlyingAmountPerContract: number,
optionType: OptionType
): Promise<GetAmericanOptionMetaResult> => {
const quoteAmountPerContractBN = new BN(
addDecimals(strike, stableMint.decimals)
Expand All @@ -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 = {
Expand All @@ -414,30 +450,63 @@ const getPsyAmericanOptionMarketAccounts = async (
quoteAmountPerContract: BN,
stableMint: PublicKey,
underlyingAmountPerContract: BN,
underlyingMint: PublicKey
underlyingMint: PublicKey,
optionType: OptionType
): Promise<GetPsyAmericanOptionMarketAccounts> => {
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
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -63,32 +63,26 @@ export const prepareEuropeanOptions = async (
? stableMintToken
: underlyingMintToken;

const optionDestination = await getOrCreateATAtxBuilder(
const optionToken = await getOrCreateATAtxBuilder(
convergence,
leg.optionType == psyoptionsEuropean.OptionType.PUT
? euroMeta.putOptionMint
: euroMeta.callOptionMint,
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({
Expand All @@ -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
);
Expand Down
4 changes: 2 additions & 2 deletions packages/js/tests/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -237,11 +237,11 @@ export const createAmericanFixedBaseStraddle = async (
cvg,
baseMint,
quoteMint,
OptionType.CALL,
OptionType.PUT,
1,
'long',
1,
29_000,
27_000,
expirationTimestamp
),
],
Expand Down
Binary file not shown.
Binary file not shown.

0 comments on commit d5c6597

Please sign in to comment.