From ac27352cfcadad650e42620517a569aebec90d51 Mon Sep 17 00:00:00 2001 From: Nagaprasadvr Date: Wed, 20 Sep 2023 12:43:17 +0530 Subject: [PATCH 01/13] add few methods to LegInstruments interface --- .../js/src/plugins/instrumentModule/types.ts | 3 ++ .../instrument.ts | 39 +++++++++++++++++- .../spotInstrumentModule/instruments.ts | 40 ++++++++++++++++++- 3 files changed, 80 insertions(+), 2 deletions(-) diff --git a/packages/js/src/plugins/instrumentModule/types.ts b/packages/js/src/plugins/instrumentModule/types.ts index 600ec3a28..0313376d6 100644 --- a/packages/js/src/plugins/instrumentModule/types.ts +++ b/packages/js/src/plugins/instrumentModule/types.ts @@ -17,6 +17,9 @@ export interface LegInstrument { getSide: () => LegSide; serializeInstrumentData: () => Buffer; getValidationAccounts(): Promise; + getBaseAssetMint(): Promise; + getBaseAssetAccount(): Promise; + getOracleAccount(baseAssetIndex: number): Promise; } // TODO add registration of quote instruments diff --git a/packages/js/src/plugins/psyoptionsAmericanInstrumentModule/instrument.ts b/packages/js/src/plugins/psyoptionsAmericanInstrumentModule/instrument.ts index ad226fc03..9e3f8120f 100644 --- a/packages/js/src/plugins/psyoptionsAmericanInstrumentModule/instrument.ts +++ b/packages/js/src/plugins/psyoptionsAmericanInstrumentModule/instrument.ts @@ -1,4 +1,4 @@ -import { Keypair, PublicKey } from '@solana/web3.js'; +import { AccountMeta, Keypair, PublicKey } from '@solana/web3.js'; import { Leg, BaseAssetIndex } from '@convergence-rfq/rfq'; import { OptionMarketWithKey } from '@mithraic-labs/psy-american'; import { OptionType } from '@mithraic-labs/tokenized-euros'; @@ -66,7 +66,44 @@ export class PsyoptionsAmericanInstrument implements LegInstrument { getAmount = () => this.amount; getDecimals = () => PsyoptionsAmericanInstrument.decimals; getSide = () => this.side; + async getBaseAssetAccount(): Promise { + const baseAsset = this.convergence + .protocol() + .pdas() + .baseAsset({ index: this.baseAssetIndex.value }); + + const baseAssetAccount: AccountMeta = { + pubkey: baseAsset, + isSigner: false, + isWritable: false, + }; + return baseAssetAccount; + } + async getBaseAssetMint(): Promise { + return this.un; + } + + async getOracleAccount(baseAssetIndex: number): Promise { + const baseAsset = this.convergence + .protocol() + .pdas() + .baseAsset({ index: baseAssetIndex }); + + const baseAssetModel = await this.convergence + .protocol() + .findBaseAssetByAddress({ address: baseAsset }); + + if (!baseAssetModel.priceOracle.address) { + throw Error('Base asset does not have a price oracle!'); + } + const oracleAccount = { + pubkey: baseAssetModel.priceOracle.address, + isSigner: false, + isWritable: false, + }; + return oracleAccount; + } static async create( convergence: Convergence, underlyingMint: Mint, diff --git a/packages/js/src/plugins/spotInstrumentModule/instruments.ts b/packages/js/src/plugins/spotInstrumentModule/instruments.ts index b4f0070ad..6ff60f7e2 100644 --- a/packages/js/src/plugins/spotInstrumentModule/instruments.ts +++ b/packages/js/src/plugins/spotInstrumentModule/instruments.ts @@ -1,4 +1,4 @@ -import { PublicKey } from '@solana/web3.js'; +import { AccountMeta, PublicKey } from '@solana/web3.js'; import { Leg, BaseAssetIndex, QuoteAsset } from '@convergence-rfq/rfq'; import { FixableBeetArgsStruct } from '@convergence-rfq/beet'; import { publicKey } from '@convergence-rfq/beet-solana'; @@ -42,6 +42,44 @@ export class SpotLegInstrument implements LegInstrument { getDecimals = () => this.decimals; getAmount = () => this.amount; getBaseAssetIndex = () => this.baseAssetIndex; + async getBaseAssetAccount(): Promise { + const baseAsset = this.convergence + .protocol() + .pdas() + .baseAsset({ index: this.baseAssetIndex.value }); + + const baseAssetAccount: AccountMeta = { + pubkey: baseAsset, + isSigner: false, + isWritable: false, + }; + + return baseAssetAccount; + } + async getBaseAssetMint(): Promise { + return this.mintAddress; + } + + async getOracleAccount(baseAssetIndex: number): Promise { + const baseAsset = this.convergence + .protocol() + .pdas() + .baseAsset({ index: baseAssetIndex }); + + const baseAssetModel = await this.convergence + .protocol() + .findBaseAssetByAddress({ address: baseAsset }); + + if (!baseAssetModel.priceOracle.address) { + throw Error('Base asset does not have a price oracle!'); + } + const oracleAccount = { + pubkey: baseAssetModel.priceOracle.address, + isSigner: false, + isWritable: false, + }; + return oracleAccount; + } static async create( convergence: Convergence, From 96a5c5e0d80dfe75d682cf2d74788b7689b8d347 Mon Sep 17 00:00:00 2001 From: Nagaprasadvr Date: Wed, 20 Sep 2023 14:26:09 +0530 Subject: [PATCH 02/13] new changes --- .../js/src/plugins/instrumentModule/types.ts | 6 +-- .../instrument.ts | 8 ++-- .../instrument.ts | 8 ++-- packages/js/src/plugins/rfqModule/helpers.ts | 40 ++++++++--------- .../rfqModule/operations/addLegsToRfq.ts | 2 +- .../rfqModule/operations/confirmResponse.ts | 36 +++++----------- .../plugins/rfqModule/operations/createRfq.ts | 6 ++- .../operations/finalizeRfqConstruction.ts | 39 ++++------------- .../rfqModule/operations/respondToRfq.ts | 43 ++++++------------- .../spotInstrumentModule/instruments.ts | 8 ++-- 10 files changed, 72 insertions(+), 124 deletions(-) diff --git a/packages/js/src/plugins/instrumentModule/types.ts b/packages/js/src/plugins/instrumentModule/types.ts index 369d37a78..057c97a5c 100644 --- a/packages/js/src/plugins/instrumentModule/types.ts +++ b/packages/js/src/plugins/instrumentModule/types.ts @@ -18,9 +18,9 @@ export interface LegInstrument { getDecimals: () => number; getSide: () => LegSide; serializeInstrumentData: () => Buffer; - getBaseAssetMint(): Promise; - getBaseAssetAccount(): Promise; - getOracleAccount(baseAssetIndex: number): Promise; + getBaseAssetMint(): PublicKey; + getBaseAssetAccount(): AccountMeta; + getOracleAccount(): Promise; getValidationAccounts(): AccountMeta[]; getPreparationsBeforeRfqCreation(): Promise; } diff --git a/packages/js/src/plugins/psyoptionsAmericanInstrumentModule/instrument.ts b/packages/js/src/plugins/psyoptionsAmericanInstrumentModule/instrument.ts index fda74f375..7b105520e 100644 --- a/packages/js/src/plugins/psyoptionsAmericanInstrumentModule/instrument.ts +++ b/packages/js/src/plugins/psyoptionsAmericanInstrumentModule/instrument.ts @@ -99,7 +99,7 @@ export class PsyoptionsAmericanInstrument implements LegInstrument { ); return optionMarketIxs; } - async getBaseAssetAccount(): Promise { + getBaseAssetAccount(): AccountMeta { const baseAsset = this.convergence .protocol() .pdas() @@ -113,18 +113,18 @@ export class PsyoptionsAmericanInstrument implements LegInstrument { return baseAssetAccount; } - async getBaseAssetMint(): Promise { + getBaseAssetMint(): PublicKey { if (!this.underlyingAssetMint) { throw new Error('Missing underlying asset mint'); } return this.underlyingAssetMint; } - async getOracleAccount(baseAssetIndex: number): Promise { + async getOracleAccount(): Promise { const baseAsset = this.convergence .protocol() .pdas() - .baseAsset({ index: baseAssetIndex }); + .baseAsset({ index: this.baseAssetIndex.value }); const baseAssetModel = await this.convergence .protocol() diff --git a/packages/js/src/plugins/psyoptionsEuropeanInstrumentModule/instrument.ts b/packages/js/src/plugins/psyoptionsEuropeanInstrumentModule/instrument.ts index 135dd2f5e..73076d67f 100644 --- a/packages/js/src/plugins/psyoptionsEuropeanInstrumentModule/instrument.ts +++ b/packages/js/src/plugins/psyoptionsEuropeanInstrumentModule/instrument.ts @@ -152,7 +152,7 @@ export class PsyoptionsEuropeanInstrument implements LegInstrument { return optionMarketIxs; } - async getBaseAssetAccount(): Promise { + getBaseAssetAccount(): AccountMeta { const baseAsset = this.convergence .protocol() .pdas() @@ -166,18 +166,18 @@ export class PsyoptionsEuropeanInstrument implements LegInstrument { return baseAssetAccount; } - async getBaseAssetMint(): Promise { + getBaseAssetMint(): PublicKey { if (!this.underlyingAssetMint) { throw new Error('Missing underlying asset mint'); } return this.underlyingAssetMint; } - async getOracleAccount(baseAssetIndex: number): Promise { + async getOracleAccount(): Promise { const baseAsset = this.convergence .protocol() .pdas() - .baseAsset({ index: baseAssetIndex }); + .baseAsset({ index: this.baseAssetIndex.value }); const baseAssetModel = await this.convergence .protocol() diff --git a/packages/js/src/plugins/rfqModule/helpers.ts b/packages/js/src/plugins/rfqModule/helpers.ts index 957ffd3d8..645e9fc17 100644 --- a/packages/js/src/plugins/rfqModule/helpers.ts +++ b/packages/js/src/plugins/rfqModule/helpers.ts @@ -9,7 +9,6 @@ import { isQuoteStandard, } from '../rfqModule/models'; import { UnparsedAccount } from '../../types'; -import { Convergence } from '../../Convergence'; import { LegInstrument, getSerializedLegLength, @@ -21,6 +20,7 @@ import { PsyoptionsAmericanInstrument } from '../psyoptionsAmericanInstrumentMod import { PsyoptionsEuropeanInstrument } from '../psyoptionsEuropeanInstrumentModule'; import { LEG_MULTIPLIER_DECIMALS } from './constants'; import { Rfq, Response, isFixedSizeOpen } from './models'; +import { Convergence } from '@/Convergence'; export function getPages( accounts: T[], @@ -109,26 +109,9 @@ export const instrumentsToLegsAndExpectedLegsHash = ( export const legsToBaseAssetAccounts = ( convergence: Convergence, - legs: Leg[] + legs: LegInstrument[] ): AccountMeta[] => { - const baseAssetAccounts: AccountMeta[] = []; - - for (const leg of legs) { - const baseAsset = convergence - .protocol() - .pdas() - .baseAsset({ index: leg.baseAssetIndex.value }); - - const baseAssetAccount: AccountMeta = { - pubkey: baseAsset, - isSigner: false, - isWritable: false, - }; - - baseAssetAccounts.push(baseAssetAccount); - } - - return baseAssetAccounts; + return legs.map((leg) => leg.getBaseAssetAccount()); }; // TODO remove async part after option instruments refactoring @@ -222,3 +205,20 @@ export const isOptionLegInstrument = (instrument: LegInstrument): boolean => { instrument instanceof PsyoptionsEuropeanInstrument ); }; + +export const removeDuplicateAccountMeta = ( + accountMeta: AccountMeta[] +): AccountMeta[] => { + const uniqueAccountMeta: AccountMeta[] = []; + for (let i = 0; i < accountMeta.length; i++) { + let unique = true; + for (let j = 0; j < accountMeta.length; j++) { + if (i !== j && accountMeta[i].pubkey.equals(accountMeta[j].pubkey)) { + unique = false; + break; + } + } + if (unique) uniqueAccountMeta.push(accountMeta[i]); + } + return uniqueAccountMeta; +}; diff --git a/packages/js/src/plugins/rfqModule/operations/addLegsToRfq.ts b/packages/js/src/plugins/rfqModule/operations/addLegsToRfq.ts index 0fcdb2863..208594186 100644 --- a/packages/js/src/plugins/rfqModule/operations/addLegsToRfq.ts +++ b/packages/js/src/plugins/rfqModule/operations/addLegsToRfq.ts @@ -1,5 +1,5 @@ import { createAddLegsToRfqInstruction } from '@convergence-rfq/rfq'; -import { PublicKey, AccountMeta } from '@solana/web3.js'; +import { PublicKey } from '@solana/web3.js'; import { SendAndConfirmTransactionResponse } from '../../rpcModule'; import { instrumentsToLegAccounts, instrumentsToLegs } from '../helpers'; diff --git a/packages/js/src/plugins/rfqModule/operations/confirmResponse.ts b/packages/js/src/plugins/rfqModule/operations/confirmResponse.ts index 81bb25098..6b54a48f8 100644 --- a/packages/js/src/plugins/rfqModule/operations/confirmResponse.ts +++ b/packages/js/src/plugins/rfqModule/operations/confirmResponse.ts @@ -1,5 +1,5 @@ import { createConfirmResponseInstruction } from '@convergence-rfq/rfq'; -import { PublicKey, AccountMeta, ComputeBudgetProgram } from '@solana/web3.js'; +import { PublicKey, ComputeBudgetProgram } from '@solana/web3.js'; import { SendAndConfirmTransactionResponse } from '../../rpcModule'; import { Convergence } from '../../../Convergence'; @@ -16,6 +16,7 @@ import { } from '../../../utils/TransactionBuilder'; import { ResponseSide, toSolitaQuoteSide } from '../models/ResponseSide'; import { toSolitaOverrideLegMultiplierBps } from '../models/Confirmation'; +import { removeDuplicateAccountMeta } from '../helpers'; const Key = 'ConfirmResponseOperation' as const; @@ -193,36 +194,19 @@ export const confirmResponseBuilder = async ( programs, }); - const baseAssetIndexValuesSet: Set = new Set(); const rfqModel = await convergence.rfqs().findRfqByAddress({ address: rfq }); - for (const leg of rfqModel.legs) { - baseAssetIndexValuesSet.add(leg.getBaseAssetIndex().value); - } - const baseAssetAccounts: AccountMeta[] = []; - const oracleAccounts: AccountMeta[] = []; - const baseAssetIndexValues = Array.from(baseAssetIndexValuesSet); - for (const index of baseAssetIndexValues) { - const baseAsset = convergence.protocol().pdas().baseAsset({ index }); - baseAssetAccounts.push({ - pubkey: baseAsset, - isSigner: false, - isWritable: false, - }); + const baseAssetAccounts = await Promise.all( + rfqModel.legs.map((leg) => leg.getBaseAssetAccount()) + ); - const baseAssetModel = await convergence - .protocol() - .findBaseAssetByAddress({ address: baseAsset }); + // baseAssetAccounts = removeDuplicateAccountMeta(baseAssetAccounts); - if (baseAssetModel.priceOracle.address) { - oracleAccounts.push({ - pubkey: baseAssetModel.priceOracle.address, - isSigner: false, - isWritable: false, - }); - } - } + const oracleAccounts = await Promise.all( + rfqModel.legs.map((leg) => leg.getOracleAccount()) + ); + // oracleAccounts = removeDuplicateAccountMeta(oracleAccounts); return TransactionBuilder.make() .setFeePayer(payer) .add( diff --git a/packages/js/src/plugins/rfqModule/operations/createRfq.ts b/packages/js/src/plugins/rfqModule/operations/createRfq.ts index 071ea149a..6c6ec2a77 100644 --- a/packages/js/src/plugins/rfqModule/operations/createRfq.ts +++ b/packages/js/src/plugins/rfqModule/operations/createRfq.ts @@ -12,7 +12,6 @@ import { getRfqLegstoAdd, instrumentsToLegs, calculateExpectedLegsSize, - // convertInstrumentsDataToInstrmentsWithTnx, } from '../helpers'; import { TransactionBuilder, @@ -363,7 +362,10 @@ export const createRfqBuilder = async ( }, ]; - const baseAssetAccounts = legsToBaseAssetAccounts(convergence, legs); + const baseAssetAccounts = legsToBaseAssetAccounts( + convergence, + instrumentsToAdd + ); const legAccounts = await instrumentsToLegAccounts(instrumentsToAdd); return TransactionBuilder.make() diff --git a/packages/js/src/plugins/rfqModule/operations/finalizeRfqConstruction.ts b/packages/js/src/plugins/rfqModule/operations/finalizeRfqConstruction.ts index 5e43011c0..e5dffedc5 100644 --- a/packages/js/src/plugins/rfqModule/operations/finalizeRfqConstruction.ts +++ b/packages/js/src/plugins/rfqModule/operations/finalizeRfqConstruction.ts @@ -16,6 +16,7 @@ import { Signer, } from '../../../types'; import { Convergence } from '../../../Convergence'; +import { removeDuplicateAccountMeta } from '../helpers'; import { LegInstrument } from '@/plugins/instrumentModule'; const Key = 'FinalizeRfqConstructionOperation' as const; @@ -211,39 +212,17 @@ export const finalizeRfqConstructionBuilder = async ( isWritable: false, }; - const oracleAccounts: AccountMeta[] = []; - - const baseAssetAccounts: AccountMeta[] = []; - const baseAssetIndexValuesSet: Set = new Set(); - - for (const leg of legs) { - baseAssetIndexValuesSet.add(leg.getBaseAssetIndex().value); - } - - const baseAssetIndexValues = Array.from(baseAssetIndexValuesSet); - - for (const index of baseAssetIndexValues) { - const baseAsset = convergence.protocol().pdas().baseAsset({ index }); - const baseAssetAccount: AccountMeta = { - pubkey: baseAsset, - isSigner: false, - isWritable: false, - }; + const baseAssetAccounts = await Promise.all( + legs.map((leg) => leg.getBaseAssetAccount()) + ); - baseAssetAccounts.push(baseAssetAccount); + // baseAssetAccounts = removeDuplicateAccountMeta(baseAssetAccounts); - const baseAssetModel = await convergence - .protocol() - .findBaseAssetByAddress({ address: baseAsset }); + const oracleAccounts = await Promise.all( + legs.map((leg) => leg.getOracleAccount()) + ); - if (baseAssetModel.priceOracle.address) { - oracleAccounts.push({ - pubkey: baseAssetModel.priceOracle.address, - isSigner: false, - isWritable: false, - }); - } - } + // oracleAccounts = removeDuplicateAccountMeta(oracleAccounts); anchorRemainingAccounts.push( configAccount, diff --git a/packages/js/src/plugins/rfqModule/operations/respondToRfq.ts b/packages/js/src/plugins/rfqModule/operations/respondToRfq.ts index 529505697..b5a564301 100644 --- a/packages/js/src/plugins/rfqModule/operations/respondToRfq.ts +++ b/packages/js/src/plugins/rfqModule/operations/respondToRfq.ts @@ -1,5 +1,5 @@ import { createRespondToRfqInstruction } from '@convergence-rfq/rfq'; -import { PublicKey, AccountMeta, ComputeBudgetProgram } from '@solana/web3.js'; +import { PublicKey, ComputeBudgetProgram } from '@solana/web3.js'; import { SendAndConfirmTransactionResponse } from '../../rpcModule'; import { assertResponse, Response } from '../models/Response'; @@ -17,6 +17,7 @@ import { } from '../../../utils/TransactionBuilder'; import { Quote, Rfq } from '../models'; import { toSolitaQuote } from '../models/Quote'; +import { removeDuplicateAccountMeta } from '../helpers'; const getNextResponsePdaAndDistinguisher = async ( cvg: Convergence, @@ -257,35 +258,17 @@ export const respondToRfqBuilder = async ( rfqModel ); - // TODO: DRY - const baseAssetIndexValuesSet: Set = new Set(); - for (const leg of rfqModel.legs) { - baseAssetIndexValuesSet.add(leg.getBaseAssetIndex().value); - } - const baseAssetAccounts: AccountMeta[] = []; - const baseAssetIndexValues = Array.from(baseAssetIndexValuesSet); - const oracleAccounts: AccountMeta[] = []; - for (const index of baseAssetIndexValues) { - const baseAsset = convergence.protocol().pdas().baseAsset({ index }); - const baseAssetAccount: AccountMeta = { - pubkey: baseAsset, - isSigner: false, - isWritable: false, - }; - - baseAssetAccounts.push(baseAssetAccount); - - const baseAssetModel = await convergence - .protocol() - .findBaseAssetByAddress({ address: baseAsset }); - if (baseAssetModel.priceOracle.address) { - oracleAccounts.push({ - pubkey: baseAssetModel.priceOracle.address, - isSigner: false, - isWritable: false, - }); - } - } + const baseAssetAccounts = await Promise.all( + rfqModel.legs.map((leg) => leg.getBaseAssetAccount()) + ); + + // baseAssetAccounts = removeDuplicateAccountMeta(baseAssetAccounts); + + const oracleAccounts = await Promise.all( + rfqModel.legs.map((leg) => leg.getOracleAccount()) + ); + + // oracleAccounts = removeDuplicateAccountMeta(oracleAccounts); return TransactionBuilder.make() .setFeePayer(maker) diff --git a/packages/js/src/plugins/spotInstrumentModule/instruments.ts b/packages/js/src/plugins/spotInstrumentModule/instruments.ts index ecdbc7d4e..8851afbf0 100644 --- a/packages/js/src/plugins/spotInstrumentModule/instruments.ts +++ b/packages/js/src/plugins/spotInstrumentModule/instruments.ts @@ -49,7 +49,7 @@ export class SpotLegInstrument implements LegInstrument { async getPreparationsBeforeRfqCreation(): Promise { return []; } - async getBaseAssetAccount(): Promise { + getBaseAssetAccount(): AccountMeta { const baseAsset = this.convergence .protocol() .pdas() @@ -63,15 +63,15 @@ export class SpotLegInstrument implements LegInstrument { return baseAssetAccount; } - async getBaseAssetMint(): Promise { + getBaseAssetMint(): PublicKey { return this.mintAddress; } - async getOracleAccount(baseAssetIndex: number): Promise { + async getOracleAccount(): Promise { const baseAsset = this.convergence .protocol() .pdas() - .baseAsset({ index: baseAssetIndex }); + .baseAsset({ index: this.baseAssetIndex.value }); const baseAssetModel = await this.convergence .protocol() From d369a61952395d619e5b0721e6ec01f673958e9d Mon Sep 17 00:00:00 2001 From: Nagaprasadvr Date: Fri, 22 Sep 2023 10:32:40 +0530 Subject: [PATCH 03/13] modify removeDuplicateAccountMetas --- packages/js/src/plugins/rfqModule/helpers.ts | 11 ++++------- .../rfqModule/operations/finalizeRfqConstruction.ts | 13 +++++++------ 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/packages/js/src/plugins/rfqModule/helpers.ts b/packages/js/src/plugins/rfqModule/helpers.ts index 645e9fc17..159e41fca 100644 --- a/packages/js/src/plugins/rfqModule/helpers.ts +++ b/packages/js/src/plugins/rfqModule/helpers.ts @@ -211,14 +211,11 @@ export const removeDuplicateAccountMeta = ( ): AccountMeta[] => { const uniqueAccountMeta: AccountMeta[] = []; for (let i = 0; i < accountMeta.length; i++) { - let unique = true; - for (let j = 0; j < accountMeta.length; j++) { - if (i !== j && accountMeta[i].pubkey.equals(accountMeta[j].pubkey)) { - unique = false; - break; - } + if ( + !uniqueAccountMeta.find((x) => x.pubkey.equals(accountMeta[i].pubkey)) + ) { + uniqueAccountMeta.push(accountMeta[i]); } - if (unique) uniqueAccountMeta.push(accountMeta[i]); } return uniqueAccountMeta; }; diff --git a/packages/js/src/plugins/rfqModule/operations/finalizeRfqConstruction.ts b/packages/js/src/plugins/rfqModule/operations/finalizeRfqConstruction.ts index e5dffedc5..9c91d8673 100644 --- a/packages/js/src/plugins/rfqModule/operations/finalizeRfqConstruction.ts +++ b/packages/js/src/plugins/rfqModule/operations/finalizeRfqConstruction.ts @@ -196,7 +196,7 @@ export const finalizeRfqConstructionBuilder = async ( collateralInfo = collateralInfo ?? collateralInfoPda; collateralToken = collateralToken ?? collateralTokenPda; - + console.log('legsLength', legs.length); const anchorRemainingAccounts: AccountMeta[] = []; const protocol = convergence.protocol().pdas().protocol(); @@ -212,17 +212,18 @@ export const finalizeRfqConstructionBuilder = async ( isWritable: false, }; - const baseAssetAccounts = await Promise.all( + let baseAssetAccounts = await Promise.all( legs.map((leg) => leg.getBaseAssetAccount()) ); - // baseAssetAccounts = removeDuplicateAccountMeta(baseAssetAccounts); - - const oracleAccounts = await Promise.all( + baseAssetAccounts = removeDuplicateAccountMeta(baseAssetAccounts); + console.log('baseAssetAccounts', baseAssetAccounts); + let oracleAccounts = await Promise.all( legs.map((leg) => leg.getOracleAccount()) ); - // oracleAccounts = removeDuplicateAccountMeta(oracleAccounts); + oracleAccounts = removeDuplicateAccountMeta(oracleAccounts); + console.log('oracleAccounts', oracleAccounts); anchorRemainingAccounts.push( configAccount, From 007cf2780f6a2f8bf8d6e8f722ea45ba4c4703e5 Mon Sep 17 00:00:00 2001 From: Nagaprasadvr Date: Fri, 22 Sep 2023 12:00:00 +0530 Subject: [PATCH 04/13] few refactoring --- .../src/plugins/instrumentModule/methods.ts | 40 ---------------- .../js/src/plugins/instrumentModule/types.ts | 1 + .../instrument.ts | 12 ++++- .../instrument.ts | 9 ++++ packages/js/src/plugins/rfqModule/helpers.ts | 46 ------------------- .../rfqModule/operations/addLegsToRfq.ts | 7 +-- .../rfqModule/operations/cleanUpResponse.ts | 5 +- .../operations/cleanUpResponseLegs.ts | 5 +- .../rfqModule/operations/confirmResponse.ts | 12 ++--- .../plugins/rfqModule/operations/createRfq.ts | 25 +++++----- .../operations/finalizeRfqConstruction.ts | 11 +---- .../operations/partiallySettleLegs.ts | 5 +- .../partlyRevertSettlementPreparation.ts | 5 +- .../operations/prepareMoreLegsSettlement.ts | 7 ++- .../rfqModule/operations/prepareSettlement.ts | 14 +++--- .../rfqModule/operations/respondToRfq.ts | 13 ++---- .../operations/revertSettlementPreparation.ts | 5 +- .../plugins/rfqModule/operations/settle.ts | 5 +- .../spotInstrumentModule/instruments.ts | 14 +++++- 19 files changed, 82 insertions(+), 159 deletions(-) diff --git a/packages/js/src/plugins/instrumentModule/methods.ts b/packages/js/src/plugins/instrumentModule/methods.ts index 7de7c2860..534e954d5 100644 --- a/packages/js/src/plugins/instrumentModule/methods.ts +++ b/packages/js/src/plugins/instrumentModule/methods.ts @@ -4,11 +4,7 @@ import { AccountMeta } from '@solana/web3.js'; import { createSerializerFromFixableBeetArgsStruct } from '../../types'; import { addDecimals } from '../../utils/conversions'; import { toSolitaLegSide } from '../rfqModule/models/LegSide'; -import { PsyoptionsEuropeanInstrument } from '../psyoptionsEuropeanInstrumentModule'; -import { PsyoptionsAmericanInstrument } from '../psyoptionsAmericanInstrumentModule'; -import { SpotLegInstrument } from '../spotInstrumentModule'; import { LegInstrument, QuoteInstrument } from './types'; -import { Convergence } from '@/Convergence'; export function toLeg(legInstrument: LegInstrument): Leg { return { @@ -41,14 +37,6 @@ export function getProgramAccount(legInstrument: LegInstrument): AccountMeta { }; } -export function getValidationAccounts( - legInstrument: LegInstrument -): AccountMeta[] { - return [getProgramAccount(legInstrument)].concat( - legInstrument.getValidationAccounts() - ); -} - export function toQuote(legInstrument: QuoteInstrument): QuoteAsset { return { instrumentProgram: legInstrument.getProgramId(), @@ -56,31 +44,3 @@ export function toQuote(legInstrument: QuoteInstrument): QuoteAsset { instrumentDecimals: legInstrument.getDecimals(), }; } - -//TODO: refactor this method to use instrument interface in the future -export const legToBaseAssetMint = async ( - convergence: Convergence, - leg: LegInstrument -) => { - if (leg instanceof PsyoptionsEuropeanInstrument) { - const euroMetaOptionMint = await convergence.tokens().findMintByAddress({ - address: leg.optionMint, - }); - - return euroMetaOptionMint; - } else if (leg instanceof PsyoptionsAmericanInstrument) { - const americanOptionMint = await convergence.tokens().findMintByAddress({ - address: leg.optionMint, - }); - - return americanOptionMint; - } else if (leg instanceof SpotLegInstrument) { - const mint = await convergence.tokens().findMintByAddress({ - address: leg.mintAddress, - }); - - return mint; - } - - throw Error('Unsupported instrument!'); -}; diff --git a/packages/js/src/plugins/instrumentModule/types.ts b/packages/js/src/plugins/instrumentModule/types.ts index 057c97a5c..2ab5156b8 100644 --- a/packages/js/src/plugins/instrumentModule/types.ts +++ b/packages/js/src/plugins/instrumentModule/types.ts @@ -23,6 +23,7 @@ export interface LegInstrument { getOracleAccount(): Promise; getValidationAccounts(): AccountMeta[]; getPreparationsBeforeRfqCreation(): Promise; + toLeg(): Leg; } // TODO add registration of quote instruments diff --git a/packages/js/src/plugins/psyoptionsAmericanInstrumentModule/instrument.ts b/packages/js/src/plugins/psyoptionsAmericanInstrumentModule/instrument.ts index c526dd383..1ebc587b5 100644 --- a/packages/js/src/plugins/psyoptionsAmericanInstrumentModule/instrument.ts +++ b/packages/js/src/plugins/psyoptionsAmericanInstrumentModule/instrument.ts @@ -16,6 +16,7 @@ import { Mint } from '../tokenModule'; import { CreateOptionInstrumentsResult, LegInstrument, + toLeg, } from '../instrumentModule'; import { addDecimals, removeDecimals } from '../../utils/conversions'; import { Convergence } from '../../Convergence'; @@ -75,10 +76,14 @@ export class PsyoptionsAmericanInstrument implements LegInstrument { readonly stableAssetMint?: PublicKey ) {} - getBaseAssetIndex = () => this.baseAssetIndex; getAmount = () => this.amount; + getBaseAssetIndex = () => this.baseAssetIndex; getDecimals = () => PsyoptionsAmericanInstrument.decimals; getSide = () => this.side; + toLeg(): Leg { + return toLeg(this); + } + async getPreparationsBeforeRfqCreation(): Promise { if (!this.underlyingAssetMint) { throw new Error('Missing underlying asset mint'); @@ -232,6 +237,11 @@ export class PsyoptionsAmericanInstrument implements LegInstrument { .pdas() .mintInfo({ mint: this.stableAssetMint }); return [ + { + pubkey: this.getProgramId(), + isSigner: false, + isWritable: false, + }, { pubkey: this.optionMetaPubKey, isSigner: false, isWritable: false }, { pubkey: mintInfoPda, diff --git a/packages/js/src/plugins/psyoptionsEuropeanInstrumentModule/instrument.ts b/packages/js/src/plugins/psyoptionsEuropeanInstrumentModule/instrument.ts index 4763e05c9..5bd25d3d9 100644 --- a/packages/js/src/plugins/psyoptionsEuropeanInstrumentModule/instrument.ts +++ b/packages/js/src/plugins/psyoptionsEuropeanInstrumentModule/instrument.ts @@ -22,6 +22,7 @@ import { Mint } from '../tokenModule'; import { CreateOptionInstrumentsResult, LegInstrument, + toLeg, } from '../instrumentModule'; import { addDecimals, removeDecimals } from '../../utils/conversions'; import { assert } from '../../utils/assert'; @@ -151,6 +152,9 @@ export class PsyoptionsEuropeanInstrument implements LegInstrument { return optionMarketIxs; } + toLeg(): Leg { + return toLeg(this); + } getBaseAssetAccount(): AccountMeta { const baseAsset = this.convergence @@ -263,6 +267,11 @@ export class PsyoptionsEuropeanInstrument implements LegInstrument { throw new Error('Missing underlying asset mint'); } return [ + { + pubkey: this.getProgramId(), + isSigner: false, + isWritable: false, + }, { pubkey: this.optionMetaPubKey, isSigner: false, isWritable: false }, { pubkey: this.convergence diff --git a/packages/js/src/plugins/rfqModule/helpers.ts b/packages/js/src/plugins/rfqModule/helpers.ts index 7ea9f26bb..5ac473552 100644 --- a/packages/js/src/plugins/rfqModule/helpers.ts +++ b/packages/js/src/plugins/rfqModule/helpers.ts @@ -1,6 +1,5 @@ import { AccountMeta } from '@solana/web3.js'; import { Sha256 } from '@aws-crypto/sha256-js'; -import { Leg } from '@convergence-rfq/rfq'; import { Confirmation, Quote, @@ -12,15 +11,12 @@ import { UnparsedAccount } from '../../types'; import { LegInstrument, getSerializedLegLength, - getValidationAccounts, serializeAsLeg, - toLeg, } from '../instrumentModule'; import { PsyoptionsAmericanInstrument } from '../psyoptionsAmericanInstrumentModule'; import { PsyoptionsEuropeanInstrument } from '../psyoptionsEuropeanInstrumentModule'; import { LEG_MULTIPLIER_DECIMALS } from './constants'; import { Rfq, Response, isFixedSizeOpen } from './models'; -import { Convergence } from '@/Convergence'; export function getPages( accounts: T[], @@ -83,48 +79,6 @@ export const calculateExpectedLegsSize = ( ); }; -// TODO remove -export const instrumentsToLegsAndLegsSize = ( - instruments: LegInstrument[] -): [Leg[], number] => { - return [ - instrumentsToLegs(instruments), - calculateExpectedLegsSize(instruments), - ]; -}; - -export const instrumentsToLegs = (instruments: LegInstrument[]): Leg[] => { - return instruments.map((i) => toLeg(i)); -}; - -// TODO remove -export const instrumentsToLegsAndExpectedLegsHash = ( - instruments: LegInstrument[] -): [Leg[], Uint8Array] => { - return [ - instrumentsToLegs(instruments), - calculateExpectedLegsHash(instruments), - ]; -}; - -export const legsToBaseAssetAccounts = ( - convergence: Convergence, - legs: LegInstrument[] -): AccountMeta[] => { - return legs.map((leg) => leg.getBaseAssetAccount()); -}; - -// TODO remove async part after option instruments refactoring -export const instrumentsToLegAccounts = async ( - instruments: LegInstrument[] -): Promise => { - const accounts = await Promise.all( - instruments.map((i) => getValidationAccounts(i)) - ); - - return accounts.flat(); -}; - export const sortByActiveAndExpiry = (rfqs: Rfq[]) => { return rfqs .sort((a, b) => { diff --git a/packages/js/src/plugins/rfqModule/operations/addLegsToRfq.ts b/packages/js/src/plugins/rfqModule/operations/addLegsToRfq.ts index 208594186..050a82c95 100644 --- a/packages/js/src/plugins/rfqModule/operations/addLegsToRfq.ts +++ b/packages/js/src/plugins/rfqModule/operations/addLegsToRfq.ts @@ -2,7 +2,6 @@ import { createAddLegsToRfqInstruction } from '@convergence-rfq/rfq'; import { PublicKey } from '@solana/web3.js'; import { SendAndConfirmTransactionResponse } from '../../rpcModule'; -import { instrumentsToLegAccounts, instrumentsToLegs } from '../helpers'; import { Convergence } from '../../../Convergence'; import { Operation, @@ -133,8 +132,10 @@ export const addLegsToRfqBuilder = async ( const protocol = protocolPdaClient.protocol(); const { taker = convergence.identity(), instruments, rfq } = params; - const legs = instrumentsToLegs(instruments); - const legAccounts = await instrumentsToLegAccounts(instruments); + const legs = instruments.map((ins) => ins.toLeg()); + const legAccounts = instruments + .map((ins) => ins.getValidationAccounts()) + .flat(); const baseAssetAccounts = await Promise.all( instruments.map((instrument) => instrument.getBaseAssetAccount()) diff --git a/packages/js/src/plugins/rfqModule/operations/cleanUpResponse.ts b/packages/js/src/plugins/rfqModule/operations/cleanUpResponse.ts index 37442530b..691ceeffb 100644 --- a/packages/js/src/plugins/rfqModule/operations/cleanUpResponse.ts +++ b/packages/js/src/plugins/rfqModule/operations/cleanUpResponse.ts @@ -11,7 +11,6 @@ import { } from '../../../types'; import { TransactionBuilder, TransactionBuilderOptions } from '../../../utils'; import { InstrumentPdasClient } from '../../instrumentModule/InstrumentPdasClient'; -import { legToBaseAssetMint } from '@/plugins/instrumentModule'; import { SendAndConfirmTransactionResponse } from '@/plugins'; const Key = 'cleanUpResponseOperation' as const; @@ -163,7 +162,7 @@ export const cleanUpResponseBuilder = async ( index: i, }); - const baseAssetMint = await legToBaseAssetMint(convergence, leg); + const baseAssetMint = leg.getBaseAssetMint(); const legAccounts: AccountMeta[] = [ { pubkey: firstToPrepare, @@ -177,7 +176,7 @@ export const cleanUpResponseBuilder = async ( }, { pubkey: convergence.tokens().pdas().associatedTokenAccount({ - mint: baseAssetMint!.address, + mint: baseAssetMint, owner: dao, programs, }), diff --git a/packages/js/src/plugins/rfqModule/operations/cleanUpResponseLegs.ts b/packages/js/src/plugins/rfqModule/operations/cleanUpResponseLegs.ts index d5c4bd846..e2f3fb2d8 100644 --- a/packages/js/src/plugins/rfqModule/operations/cleanUpResponseLegs.ts +++ b/packages/js/src/plugins/rfqModule/operations/cleanUpResponseLegs.ts @@ -17,7 +17,6 @@ import { import { getOrCreateATA } from '../../../utils/ata'; import { InstrumentPdasClient } from '../../instrumentModule/InstrumentPdasClient'; import { protocolCache } from '../../protocolModule/cache'; -import { legToBaseAssetMint } from '@/plugins/instrumentModule'; const Key = 'CleanUpResponseLegsOperation' as const; @@ -176,7 +175,7 @@ export const cleanUpResponseLegsBuilder = async ( }); const leg = rfqModel.legs[i]; - const baseAssetMint = await legToBaseAssetMint(convergence, leg); + const baseAssetMint = leg.getBaseAssetMint(); const legAccounts: AccountMeta[] = [ { @@ -192,7 +191,7 @@ export const cleanUpResponseLegsBuilder = async ( { pubkey: await getOrCreateATA( convergence, - baseAssetMint!.address, + baseAssetMint, protocol.authority ), isSigner: false, diff --git a/packages/js/src/plugins/rfqModule/operations/confirmResponse.ts b/packages/js/src/plugins/rfqModule/operations/confirmResponse.ts index 6b54a48f8..ab2cde5b9 100644 --- a/packages/js/src/plugins/rfqModule/operations/confirmResponse.ts +++ b/packages/js/src/plugins/rfqModule/operations/confirmResponse.ts @@ -196,17 +196,13 @@ export const confirmResponseBuilder = async ( const rfqModel = await convergence.rfqs().findRfqByAddress({ address: rfq }); - const baseAssetAccounts = await Promise.all( - rfqModel.legs.map((leg) => leg.getBaseAssetAccount()) - ); - - // baseAssetAccounts = removeDuplicateAccountMeta(baseAssetAccounts); - - const oracleAccounts = await Promise.all( + let baseAssetAccounts = rfqModel.legs.map((leg) => leg.getBaseAssetAccount()); + let oracleAccounts = await Promise.all( rfqModel.legs.map((leg) => leg.getOracleAccount()) ); + baseAssetAccounts = removeDuplicateAccountMeta(baseAssetAccounts); + oracleAccounts = removeDuplicateAccountMeta(oracleAccounts); - // oracleAccounts = removeDuplicateAccountMeta(oracleAccounts); return TransactionBuilder.make() .setFeePayer(payer) .add( diff --git a/packages/js/src/plugins/rfqModule/operations/createRfq.ts b/packages/js/src/plugins/rfqModule/operations/createRfq.ts index 3299092d3..129378884 100644 --- a/packages/js/src/plugins/rfqModule/operations/createRfq.ts +++ b/packages/js/src/plugins/rfqModule/operations/createRfq.ts @@ -7,9 +7,6 @@ import { SendAndConfirmTransactionResponse } from '../../rpcModule'; import { assertRfq, FixedSize, Rfq, toSolitaFixedSize } from '../models'; import { calculateExpectedLegsHash, - instrumentsToLegAccounts, - legsToBaseAssetAccounts, - instrumentsToLegs, calculateExpectedLegsSize, } from '../helpers'; import { @@ -311,8 +308,7 @@ export const createRfqBuilder = async ( } = params; let { expectedLegsSize } = params; - const legs = instrumentsToLegs(instruments); - + const legs = instruments.map((ins) => ins.toLeg()); const expectedLegsSizeValue = calculateExpectedLegsSize(instruments); expectedLegsSize = expectedLegsSize ?? expectedLegsSizeValue; @@ -338,11 +334,10 @@ export const createRfqBuilder = async ( }, ]; - const baseAssetAccounts = legsToBaseAssetAccounts( - convergence, - instrumentsToAdd - ); - const legAccounts = await instrumentsToLegAccounts(instrumentsToAdd); + let baseAssetAccounts = instruments.map((ins) => ins.getBaseAssetAccount()); + let legAccounts = instruments + .map((ins) => ins.getValidationAccounts()) + .flat(); let rfqBuilder = TransactionBuilder.make() .setFeePayer(payer) @@ -385,8 +380,10 @@ export const createRfqBuilder = async ( while (!rfqBuilder.checkTransactionFits()) { instrumentsToAdd = instrumentsToAdd.slice(0, instrumentsToAdd.length - 1); legsToAdd = legsToAdd.slice(0, instrumentsToAdd.length); - legAccounts = await instrumentsToLegAccounts(instrumentsToAdd); - baseAssetAccounts = legsToBaseAssetAccounts(convergence, legsToAdd); + legAccounts = instrumentsToAdd + .map((ins) => ins.getValidationAccounts()) + .flat(); + baseAssetAccounts = instrumentsToAdd.map((i) => i.getBaseAssetAccount()); rfqBuilder = TransactionBuilder.make() .setFeePayer(payer) .setContext({ @@ -423,8 +420,10 @@ export const createRfqBuilder = async ( }); } + console.log('baseAccoo', baseAssetAccounts.length); + console.log('len', legsToAdd.length); const remainingLegsToAdd = instruments.slice(legsToAdd.length, legs.length); - + console.log('remaining', remainingLegsToAdd.length); return { createRfqTxBuilder: rfqBuilder, remainingLegsToAdd, diff --git a/packages/js/src/plugins/rfqModule/operations/finalizeRfqConstruction.ts b/packages/js/src/plugins/rfqModule/operations/finalizeRfqConstruction.ts index 9c91d8673..15053e605 100644 --- a/packages/js/src/plugins/rfqModule/operations/finalizeRfqConstruction.ts +++ b/packages/js/src/plugins/rfqModule/operations/finalizeRfqConstruction.ts @@ -196,7 +196,6 @@ export const finalizeRfqConstructionBuilder = async ( collateralInfo = collateralInfo ?? collateralInfoPda; collateralToken = collateralToken ?? collateralTokenPda; - console.log('legsLength', legs.length); const anchorRemainingAccounts: AccountMeta[] = []; const protocol = convergence.protocol().pdas().protocol(); @@ -212,25 +211,19 @@ export const finalizeRfqConstructionBuilder = async ( isWritable: false, }; - let baseAssetAccounts = await Promise.all( - legs.map((leg) => leg.getBaseAssetAccount()) - ); - - baseAssetAccounts = removeDuplicateAccountMeta(baseAssetAccounts); - console.log('baseAssetAccounts', baseAssetAccounts); + let baseAssetAccounts = legs.map((leg) => leg.getBaseAssetAccount()); let oracleAccounts = await Promise.all( legs.map((leg) => leg.getOracleAccount()) ); + baseAssetAccounts = removeDuplicateAccountMeta(baseAssetAccounts); oracleAccounts = removeDuplicateAccountMeta(oracleAccounts); - console.log('oracleAccounts', oracleAccounts); anchorRemainingAccounts.push( configAccount, ...baseAssetAccounts, ...oracleAccounts ); - return TransactionBuilder.make() .setFeePayer(payer) .setContext({ diff --git a/packages/js/src/plugins/rfqModule/operations/partiallySettleLegs.ts b/packages/js/src/plugins/rfqModule/operations/partiallySettleLegs.ts index 3e8571e35..b2c3b670d 100644 --- a/packages/js/src/plugins/rfqModule/operations/partiallySettleLegs.ts +++ b/packages/js/src/plugins/rfqModule/operations/partiallySettleLegs.ts @@ -16,7 +16,6 @@ import { TransactionBuilderOptions, } from '../../../utils/TransactionBuilder'; import { InstrumentPdasClient } from '../../instrumentModule'; -import { legToBaseAssetMint } from '@/plugins/instrumentModule'; const Key = 'PartiallySettleLegsOperation' as const; @@ -178,7 +177,7 @@ export const partiallySettleLegsBuilder = async ( rfqModel, }); - const baseAssetMint = await legToBaseAssetMint(convergence, leg); + const baseAssetMint = leg.getBaseAssetMint(); const legAccounts: AccountMeta[] = [ //`escrow` @@ -193,7 +192,7 @@ export const partiallySettleLegsBuilder = async ( .tokens() .pdas() .associatedTokenAccount({ - mint: baseAssetMint!.address, + mint: baseAssetMint, owner: receiver === 'maker' ? maker : taker, programs, }), diff --git a/packages/js/src/plugins/rfqModule/operations/partlyRevertSettlementPreparation.ts b/packages/js/src/plugins/rfqModule/operations/partlyRevertSettlementPreparation.ts index 20eeaa70b..8af616f1f 100644 --- a/packages/js/src/plugins/rfqModule/operations/partlyRevertSettlementPreparation.ts +++ b/packages/js/src/plugins/rfqModule/operations/partlyRevertSettlementPreparation.ts @@ -17,7 +17,6 @@ import { } from '../../../utils/TransactionBuilder'; import { InstrumentPdasClient } from '../../instrumentModule'; import { AuthoritySide, toSolitaAuthoritySide } from '../models/AuthoritySide'; -import { legToBaseAssetMint } from '@/plugins/instrumentModule'; const Key = 'PartlyRevertSettlementPreparationOperation' as const; @@ -179,7 +178,7 @@ export const partlyRevertSettlementPreparationBuilder = async ( }; const leg = rfqModel.legs[i]; - const baseAssetMint = await legToBaseAssetMint(convergence, leg); + const baseAssetMint = leg.getBaseAssetMint(); const legAccounts: AccountMeta[] = [ //`escrow` @@ -194,7 +193,7 @@ export const partlyRevertSettlementPreparationBuilder = async ( .tokens() .pdas() .associatedTokenAccount({ - mint: baseAssetMint!.address, + mint: baseAssetMint, owner: side === 'maker' ? responseModel.maker : rfqModel.taker, programs, }), diff --git a/packages/js/src/plugins/rfqModule/operations/prepareMoreLegsSettlement.ts b/packages/js/src/plugins/rfqModule/operations/prepareMoreLegsSettlement.ts index 14287a14c..cc20f8983 100644 --- a/packages/js/src/plugins/rfqModule/operations/prepareMoreLegsSettlement.ts +++ b/packages/js/src/plugins/rfqModule/operations/prepareMoreLegsSettlement.ts @@ -26,7 +26,6 @@ import { } from '../../../utils/TransactionBuilder'; import { getOrCreateATA } from '../../../utils/ata'; import { InstrumentPdasClient } from '../../instrumentModule'; -import { legToBaseAssetMint } from '@/plugins/instrumentModule'; const Key = 'PrepareMoreLegsSettlementOperation' as const; @@ -208,7 +207,7 @@ export const prepareMoreLegsSettlementBuilder = async ( }); const leg = rfqModel.legs[i]; - const baseAssetMint = await legToBaseAssetMint(convergence, leg); + const baseAssetMint = leg.getBaseAssetMint(); const legAccounts: AccountMeta[] = [ // `caller @@ -226,7 +225,7 @@ export const prepareMoreLegsSettlementBuilder = async ( // }), pubkey: await getOrCreateATA( convergence, - baseAssetMint!.address, + baseAssetMint, caller.publicKey, programs ), @@ -235,7 +234,7 @@ export const prepareMoreLegsSettlementBuilder = async ( }, // `mint` { - pubkey: baseAssetMint!.address, + pubkey: baseAssetMint, isSigner: false, isWritable: false, }, diff --git a/packages/js/src/plugins/rfqModule/operations/prepareSettlement.ts b/packages/js/src/plugins/rfqModule/operations/prepareSettlement.ts index 03272f574..2c2bd8f55 100644 --- a/packages/js/src/plugins/rfqModule/operations/prepareSettlement.ts +++ b/packages/js/src/plugins/rfqModule/operations/prepareSettlement.ts @@ -26,9 +26,7 @@ import { } from '../../../utils/TransactionBuilder'; import { Rfq } from '../../rfqModule'; import { getOrCreateATAtxBuilder } from '../../../utils/ata'; -import { Mint } from '../../tokenModule'; import { InstrumentPdasClient } from '../../instrumentModule'; -import { legToBaseAssetMint } from '@/plugins/instrumentModule'; import { prepareAmericanOptions, psyoptionsAmericanInstrumentProgram, @@ -205,11 +203,15 @@ export const prepareSettlementBuilder = async ( const spotInstrumentProgram = convergence.programs().getSpotInstrument(); - const baseAssetMints: Mint[] = []; + const baseAssetMintPubkeys = rfqModel.legs.map((leg) => + leg.getBaseAssetMint() + ); - for (const leg of rfqModel.legs) { - baseAssetMints.push(await legToBaseAssetMint(convergence, leg)); - } + const baseAssetMints = await Promise.all( + baseAssetMintPubkeys.map((baseAssetMintPubkey) => + convergence.tokens().findMintByAddress({ address: baseAssetMintPubkey }) + ) + ); const anchorRemainingAccounts: AccountMeta[] = []; diff --git a/packages/js/src/plugins/rfqModule/operations/respondToRfq.ts b/packages/js/src/plugins/rfqModule/operations/respondToRfq.ts index b5a564301..ba849493c 100644 --- a/packages/js/src/plugins/rfqModule/operations/respondToRfq.ts +++ b/packages/js/src/plugins/rfqModule/operations/respondToRfq.ts @@ -258,17 +258,12 @@ export const respondToRfqBuilder = async ( rfqModel ); - const baseAssetAccounts = await Promise.all( - rfqModel.legs.map((leg) => leg.getBaseAssetAccount()) - ); - - // baseAssetAccounts = removeDuplicateAccountMeta(baseAssetAccounts); - - const oracleAccounts = await Promise.all( + let baseAssetAccounts = rfqModel.legs.map((leg) => leg.getBaseAssetAccount()); + let oracleAccounts = await Promise.all( rfqModel.legs.map((leg) => leg.getOracleAccount()) ); - - // oracleAccounts = removeDuplicateAccountMeta(oracleAccounts); + baseAssetAccounts = removeDuplicateAccountMeta(baseAssetAccounts); + oracleAccounts = removeDuplicateAccountMeta(oracleAccounts); return TransactionBuilder.make() .setFeePayer(maker) diff --git a/packages/js/src/plugins/rfqModule/operations/revertSettlementPreparation.ts b/packages/js/src/plugins/rfqModule/operations/revertSettlementPreparation.ts index 68e6e51d3..95098962a 100644 --- a/packages/js/src/plugins/rfqModule/operations/revertSettlementPreparation.ts +++ b/packages/js/src/plugins/rfqModule/operations/revertSettlementPreparation.ts @@ -17,7 +17,6 @@ import { } from '../../../utils/TransactionBuilder'; import { InstrumentPdasClient } from '../../instrumentModule'; import { AuthoritySide, toSolitaAuthoritySide } from '../models/AuthoritySide'; -import { legToBaseAssetMint } from '@/plugins/instrumentModule'; const Key = 'RevertSettlementPreparationOperation' as const; @@ -173,7 +172,7 @@ export const revertSettlementPreparationBuilder = async ( const leg = rfqModel.legs[i]; - const baseAssetMint = await legToBaseAssetMint(convergence, leg); + const baseAssetMint = leg.getBaseAssetMint(); const legAccounts: AccountMeta[] = [ //`escrow` @@ -188,7 +187,7 @@ export const revertSettlementPreparationBuilder = async ( .tokens() .pdas() .associatedTokenAccount({ - mint: baseAssetMint!.address, + mint: baseAssetMint, owner: side === 'maker' ? responseModel.maker : rfqModel.taker, programs, }), diff --git a/packages/js/src/plugins/rfqModule/operations/settle.ts b/packages/js/src/plugins/rfqModule/operations/settle.ts index 831947092..3ecd96020 100644 --- a/packages/js/src/plugins/rfqModule/operations/settle.ts +++ b/packages/js/src/plugins/rfqModule/operations/settle.ts @@ -16,7 +16,6 @@ import { TransactionBuilderOptions, } from '../../../utils/TransactionBuilder'; import { InstrumentPdasClient } from '../../instrumentModule'; -import { legToBaseAssetMint } from '@/plugins/instrumentModule'; const Key = 'SettleOperation' as const; @@ -162,7 +161,7 @@ export const settleBuilder = async ( const leg = rfqModel.legs[legIndex]; const { receiver } = legs[legIndex]; - const baseAssetMint = await legToBaseAssetMint(convergence, leg); + const baseAssetMint = leg.getBaseAssetMint(); const instrumentProgramAccount: AccountMeta = { pubkey: rfqModel.legs[legIndex].getProgramId(), @@ -191,7 +190,7 @@ export const settleBuilder = async ( .tokens() .pdas() .associatedTokenAccount({ - mint: baseAssetMint!.address, + mint: baseAssetMint, owner: receiver === 'maker' ? maker : taker, programs, }), diff --git a/packages/js/src/plugins/spotInstrumentModule/instruments.ts b/packages/js/src/plugins/spotInstrumentModule/instruments.ts index 8851afbf0..f5aa42728 100644 --- a/packages/js/src/plugins/spotInstrumentModule/instruments.ts +++ b/packages/js/src/plugins/spotInstrumentModule/instruments.ts @@ -8,6 +8,7 @@ import { CreateOptionInstrumentsResult, LegInstrument, QuoteInstrument, + toLeg, } from '../instrumentModule'; import { Convergence } from '../../Convergence'; import { createSerializerFromFixableBeetArgsStruct } from '../../types'; @@ -87,7 +88,9 @@ export class SpotLegInstrument implements LegInstrument { }; return oracleAccount; } - + toLeg(): Leg { + return toLeg(this); + } static async create( convergence: Convergence, mint: Mint, @@ -127,7 +130,14 @@ export class SpotLegInstrument implements LegInstrument { .rfqs() .pdas() .mintInfo({ mint: this.mintAddress }); - return [{ pubkey: mintInfo, isSigner: false, isWritable: false }]; + return [ + { + pubkey: this.getProgramId(), + isSigner: false, + isWritable: false, + }, + { pubkey: mintInfo, isSigner: false, isWritable: false }, + ]; } /** Helper method to serialize the instrument data for this instrument. */ From 3407b44e50b870d17be8c5663d001a9804ef1c21 Mon Sep 17 00:00:00 2001 From: Nagaprasadvr Date: Mon, 25 Sep 2023 08:48:17 +0530 Subject: [PATCH 05/13] tests passing --- .../js/src/plugins/instrumentModule/plugin.ts | 4 +-- .../js/src/plugins/instrumentModule/types.ts | 1 + .../instrument.ts | 24 +++++++++++------ .../instrument.ts | 27 ++++++++++++------- .../js/src/plugins/rfqModule/models/Rfq.ts | 11 +++++++- .../plugins/rfqModule/operations/createRfq.ts | 3 --- .../rfqModule/operations/prepareSettlement.ts | 19 ++++++------- .../spotInstrumentModule/instruments.ts | 4 +++ packages/js/tests/helpers.ts | 2 +- 9 files changed, 62 insertions(+), 33 deletions(-) diff --git a/packages/js/src/plugins/instrumentModule/plugin.ts b/packages/js/src/plugins/instrumentModule/plugin.ts index 23c3a7f6a..5445d85b0 100644 --- a/packages/js/src/plugins/instrumentModule/plugin.ts +++ b/packages/js/src/plugins/instrumentModule/plugin.ts @@ -26,7 +26,7 @@ export const instrumentModule = (): ConvergencePlugin => ({ legInstrumentParsers.push([programAddress, factory]); }; - convergence.parseLegInstrument = function (leg: SolitaLeg) { + convergence.parseLegInstrument = async function (leg: SolitaLeg) { const factory = legInstrumentParsers.find(([key]) => leg.instrumentProgram.equals(key) )?.[1]; @@ -48,7 +48,7 @@ declare module '../../Convergence' { programAddress: PublicKey, factory: LegInstrumentParser ): void; - parseLegInstrument(leg: SolitaLeg): LegInstrument; + parseLegInstrument(leg: SolitaLeg): Promise; } } diff --git a/packages/js/src/plugins/instrumentModule/types.ts b/packages/js/src/plugins/instrumentModule/types.ts index 2ab5156b8..4bab536e5 100644 --- a/packages/js/src/plugins/instrumentModule/types.ts +++ b/packages/js/src/plugins/instrumentModule/types.ts @@ -24,6 +24,7 @@ export interface LegInstrument { getValidationAccounts(): AccountMeta[]; getPreparationsBeforeRfqCreation(): Promise; toLeg(): Leg; + getUnderlyingBaseAssetMint(): PublicKey; } // TODO add registration of quote instruments diff --git a/packages/js/src/plugins/psyoptionsAmericanInstrumentModule/instrument.ts b/packages/js/src/plugins/psyoptionsAmericanInstrumentModule/instrument.ts index 1ebc587b5..76c267121 100644 --- a/packages/js/src/plugins/psyoptionsAmericanInstrumentModule/instrument.ts +++ b/packages/js/src/plugins/psyoptionsAmericanInstrumentModule/instrument.ts @@ -72,8 +72,8 @@ export class PsyoptionsAmericanInstrument implements LegInstrument { readonly baseAssetIndex: BaseAssetIndex, readonly amount: number, readonly side: LegSide, - readonly underlyingAssetMint?: PublicKey, - readonly stableAssetMint?: PublicKey + readonly underlyingAssetMint: PublicKey, + readonly stableAssetMint: PublicKey ) {} getAmount = () => this.amount; @@ -119,9 +119,10 @@ export class PsyoptionsAmericanInstrument implements LegInstrument { return baseAssetAccount; } getBaseAssetMint(): PublicKey { - if (!this.underlyingAssetMint) { - throw new Error('Missing underlying asset mint'); - } + return this.optionMint; + } + + getUnderlyingBaseAssetMint(): PublicKey { return this.underlyingAssetMint; } @@ -293,10 +294,10 @@ export class PsyoptionsAmericanInstrument implements LegInstrument { } export const psyoptionsAmericanInstrumentParser = { - parseFromLeg( + async parseFromLeg( convergence: Convergence, leg: Leg - ): PsyoptionsAmericanInstrument { + ): Promise { const { side, instrumentAmount, instrumentData, baseAssetIndex } = leg; const [ { @@ -313,6 +314,11 @@ export const psyoptionsAmericanInstrumentParser = { Buffer.from(instrumentData) ); + const optionMeta = await PsyoptionsAmericanInstrument.fetchMeta( + convergence, + metaKey + ); + return new PsyoptionsAmericanInstrument( convergence, optionType, @@ -328,7 +334,9 @@ export const psyoptionsAmericanInstrumentParser = { metaKey, baseAssetIndex, removeDecimals(instrumentAmount, PsyoptionsAmericanInstrument.decimals), - fromSolitaLegSide(side) + fromSolitaLegSide(side), + optionMeta.underlyingAssetMint, + optionMeta.quoteAssetMint ); }, }; diff --git a/packages/js/src/plugins/psyoptionsEuropeanInstrumentModule/instrument.ts b/packages/js/src/plugins/psyoptionsEuropeanInstrumentModule/instrument.ts index 5bd25d3d9..f8cc46bad 100644 --- a/packages/js/src/plugins/psyoptionsEuropeanInstrumentModule/instrument.ts +++ b/packages/js/src/plugins/psyoptionsEuropeanInstrumentModule/instrument.ts @@ -119,9 +119,9 @@ export class PsyoptionsEuropeanInstrument implements LegInstrument { readonly baseAssetIndex: BaseAssetIndex, readonly amount: number, readonly side: LegSide, - readonly underlyingAssetMint?: PublicKey, - readonly stableAssetMint?: PublicKey, - readonly oracleAddress?: PublicKey + readonly underlyingAssetMint: PublicKey, + readonly stableAssetMint: PublicKey, + readonly oracleAddress: PublicKey ) {} getBaseAssetIndex = () => this.baseAssetIndex; @@ -171,9 +171,10 @@ export class PsyoptionsEuropeanInstrument implements LegInstrument { return baseAssetAccount; } getBaseAssetMint(): PublicKey { - if (!this.underlyingAssetMint) { - throw new Error('Missing underlying asset mint'); - } + return this.optionMint; + } + + getUnderlyingBaseAssetMint(): PublicKey { return this.underlyingAssetMint; } @@ -329,10 +330,10 @@ export class PsyoptionsEuropeanInstrument implements LegInstrument { } export const psyoptionsEuropeanInstrumentParser = { - parseFromLeg( + async parseFromLeg( convergence: Convergence, leg: Leg - ): PsyoptionsEuropeanInstrument { + ): Promise { const { side, instrumentAmount, instrumentData, baseAssetIndex } = leg; const [ { @@ -349,6 +350,11 @@ export const psyoptionsEuropeanInstrumentParser = { Buffer.from(instrumentData) ); + const optionMeta = await PsyoptionsEuropeanInstrument.fetchMeta( + convergence, + metaKey + ); + return new PsyoptionsEuropeanInstrument( convergence, optionType, @@ -364,7 +370,10 @@ export const psyoptionsEuropeanInstrumentParser = { metaKey, baseAssetIndex, removeDecimals(instrumentAmount, PsyoptionsEuropeanInstrument.decimals), - fromSolitaLegSide(side) + fromSolitaLegSide(side), + optionMeta.underlyingMint, + optionMeta.stableMint, + optionMeta.oracle ); }, }; diff --git a/packages/js/src/plugins/rfqModule/models/Rfq.ts b/packages/js/src/plugins/rfqModule/models/Rfq.ts index d53e04e06..a720854b5 100644 --- a/packages/js/src/plugins/rfqModule/models/Rfq.ts +++ b/packages/js/src/plugins/rfqModule/models/Rfq.ts @@ -15,6 +15,7 @@ import { collateralMintCache } from '../../../plugins/collateralModule'; import { FixedSize, fromSolitaFixedSize } from './FixedSize'; import { OrderType, fromSolitaOrderType } from './OrderType'; import { StoredRfqState, fromSolitaStoredRfqState } from './StoredRfqState'; +import { psyoptionsAmericanInstrumentDataSerializer } from '@/plugins/psyoptionsAmericanInstrumentModule'; /** * This model captures all the relevant information about an RFQ @@ -104,6 +105,14 @@ export const toRfq = async ( ); const collateralMint = await collateralMintCache.get(convergence); const collateralDecimals = collateralMint.decimals; + + const legs: LegInstrument[] = []; + + for (const leg of account.data.legs) { + const legInstrument = await convergence.parseLegInstrument(leg); + legs.push(legInstrument); + } + return { model: 'rfq', address: account.publicKey, @@ -130,6 +139,6 @@ export const toRfq = async ( totalResponses: account.data.totalResponses, clearedResponses: account.data.clearedResponses, confirmedResponses: account.data.confirmedResponses, - legs: account.data.legs.map((leg) => convergence.parseLegInstrument(leg)), + legs, }; }; diff --git a/packages/js/src/plugins/rfqModule/operations/createRfq.ts b/packages/js/src/plugins/rfqModule/operations/createRfq.ts index 129378884..416e6da56 100644 --- a/packages/js/src/plugins/rfqModule/operations/createRfq.ts +++ b/packages/js/src/plugins/rfqModule/operations/createRfq.ts @@ -420,10 +420,7 @@ export const createRfqBuilder = async ( }); } - console.log('baseAccoo', baseAssetAccounts.length); - console.log('len', legsToAdd.length); const remainingLegsToAdd = instruments.slice(legsToAdd.length, legs.length); - console.log('remaining', remainingLegsToAdd.length); return { createRfqTxBuilder: rfqBuilder, remainingLegsToAdd, diff --git a/packages/js/src/plugins/rfqModule/operations/prepareSettlement.ts b/packages/js/src/plugins/rfqModule/operations/prepareSettlement.ts index 2c2bd8f55..760d9ef7c 100644 --- a/packages/js/src/plugins/rfqModule/operations/prepareSettlement.ts +++ b/packages/js/src/plugins/rfqModule/operations/prepareSettlement.ts @@ -29,12 +29,14 @@ import { getOrCreateATAtxBuilder } from '../../../utils/ata'; import { InstrumentPdasClient } from '../../instrumentModule'; import { prepareAmericanOptions, + psyoptionsAmericanInstrumentDataSerializer, psyoptionsAmericanInstrumentProgram, } from '@/plugins/psyoptionsAmericanInstrumentModule'; import { prepareEuropeanOptions, psyoptionsEuropeanInstrumentProgram, } from '@/plugins/psyoptionsEuropeanInstrumentModule'; +import { Mint } from '@/plugins/tokenModule/models'; const Key = 'PrepareSettlementOperation' as const; @@ -203,15 +205,14 @@ export const prepareSettlementBuilder = async ( const spotInstrumentProgram = convergence.programs().getSpotInstrument(); - const baseAssetMintPubkeys = rfqModel.legs.map((leg) => - leg.getBaseAssetMint() - ); - - const baseAssetMints = await Promise.all( - baseAssetMintPubkeys.map((baseAssetMintPubkey) => - convergence.tokens().findMintByAddress({ address: baseAssetMintPubkey }) - ) - ); + const baseAssetMints: Mint[] = []; + for (const leg of rfqModel.legs) { + const baseAssetMintPubkey = leg.getBaseAssetMint(); + const baseAssetMint = await convergence + .tokens() + .findMintByAddress({ address: baseAssetMintPubkey }); + baseAssetMints.push(baseAssetMint); + } const anchorRemainingAccounts: AccountMeta[] = []; diff --git a/packages/js/src/plugins/spotInstrumentModule/instruments.ts b/packages/js/src/plugins/spotInstrumentModule/instruments.ts index f5aa42728..066a854c4 100644 --- a/packages/js/src/plugins/spotInstrumentModule/instruments.ts +++ b/packages/js/src/plugins/spotInstrumentModule/instruments.ts @@ -68,6 +68,10 @@ export class SpotLegInstrument implements LegInstrument { return this.mintAddress; } + getUnderlyingBaseAssetMint(): PublicKey { + return this.mintAddress; + } + async getOracleAccount(): Promise { const baseAsset = this.convergence .protocol() diff --git a/packages/js/tests/helpers.ts b/packages/js/tests/helpers.ts index b41d2de09..ea830bacf 100644 --- a/packages/js/tests/helpers.ts +++ b/packages/js/tests/helpers.ts @@ -19,6 +19,7 @@ import { PsyoptionsAmericanInstrument, SpotLegInstrument, Mint, + psyoptionsAmericanInstrumentDataSerializer, } from '../src'; import { getUserKp, RPC_ENDPOINT } from '../../validator'; import { BASE_MINT_BTC_PK, QUOTE_MINT_PK } from './constants'; @@ -128,7 +129,6 @@ export const createAmericanCoveredCallRfq = async ( fixedSize: { type: 'fixed-base', amount: 1 }, quoteAsset: await SpotQuoteInstrument.create(cvg, quoteMint), }); - return { rfq, response }; }; From 9e75249b293d417fbf4cdbcc73c6a6718662dd58 Mon Sep 17 00:00:00 2001 From: Nagaprasadvr Date: Mon, 25 Sep 2023 09:12:15 +0530 Subject: [PATCH 06/13] cleanup --- .../src/plugins/instrumentModule/methods.ts | 20 ++----------------- .../js/src/plugins/instrumentModule/types.ts | 2 +- .../instrument.ts | 16 ++++++++++++--- .../instrument.ts | 16 ++++++++++++--- .../js/src/plugins/rfqModule/models/Rfq.ts | 1 - .../rfqModule/operations/prepareSettlement.ts | 1 - .../spotInstrumentModule/instruments.ts | 18 +++++++++++++---- packages/js/tests/helpers.ts | 1 - 8 files changed, 43 insertions(+), 32 deletions(-) diff --git a/packages/js/src/plugins/instrumentModule/methods.ts b/packages/js/src/plugins/instrumentModule/methods.ts index 534e954d5..04789603b 100644 --- a/packages/js/src/plugins/instrumentModule/methods.ts +++ b/packages/js/src/plugins/instrumentModule/methods.ts @@ -1,28 +1,12 @@ -import { Leg, QuoteAsset, legBeet } from '@convergence-rfq/rfq'; +import { QuoteAsset, legBeet } from '@convergence-rfq/rfq'; import { AccountMeta } from '@solana/web3.js'; import { createSerializerFromFixableBeetArgsStruct } from '../../types'; -import { addDecimals } from '../../utils/conversions'; -import { toSolitaLegSide } from '../rfqModule/models/LegSide'; import { LegInstrument, QuoteInstrument } from './types'; -export function toLeg(legInstrument: LegInstrument): Leg { - return { - instrumentProgram: legInstrument.getProgramId(), - baseAssetIndex: legInstrument.getBaseAssetIndex(), - instrumentData: legInstrument.serializeInstrumentData(), - instrumentAmount: addDecimals( - legInstrument.getAmount(), - legInstrument.getDecimals() - ), - instrumentDecimals: legInstrument.getDecimals(), - side: toSolitaLegSide(legInstrument.getSide()), - }; -} - export function serializeAsLeg(legInstrument: LegInstrument) { const legSerializer = createSerializerFromFixableBeetArgsStruct(legBeet); - return legSerializer.serialize(toLeg(legInstrument)); + return legSerializer.serialize(legInstrument.toLeg()); } export function getSerializedLegLength(legInstrument: LegInstrument) { diff --git a/packages/js/src/plugins/instrumentModule/types.ts b/packages/js/src/plugins/instrumentModule/types.ts index 4bab536e5..fa1f3059d 100644 --- a/packages/js/src/plugins/instrumentModule/types.ts +++ b/packages/js/src/plugins/instrumentModule/types.ts @@ -23,8 +23,8 @@ export interface LegInstrument { getOracleAccount(): Promise; getValidationAccounts(): AccountMeta[]; getPreparationsBeforeRfqCreation(): Promise; - toLeg(): Leg; getUnderlyingBaseAssetMint(): PublicKey; + toLeg(): Leg; } // TODO add registration of quote instruments diff --git a/packages/js/src/plugins/psyoptionsAmericanInstrumentModule/instrument.ts b/packages/js/src/plugins/psyoptionsAmericanInstrumentModule/instrument.ts index 76c267121..cd9b2920f 100644 --- a/packages/js/src/plugins/psyoptionsAmericanInstrumentModule/instrument.ts +++ b/packages/js/src/plugins/psyoptionsAmericanInstrumentModule/instrument.ts @@ -16,12 +16,15 @@ import { Mint } from '../tokenModule'; import { CreateOptionInstrumentsResult, LegInstrument, - toLeg, } from '../instrumentModule'; import { addDecimals, removeDecimals } from '../../utils/conversions'; import { Convergence } from '../../Convergence'; import { createSerializerFromFixableBeetArgsStruct } from '../../types'; -import { LegSide, fromSolitaLegSide } from '../rfqModule/models/LegSide'; +import { + LegSide, + fromSolitaLegSide, + toSolitaLegSide, +} from '../rfqModule/models/LegSide'; import { CvgWallet, NoopWallet } from '../../utils/Wallets'; import { GetOrCreateATAtxBuilderReturnType, @@ -81,7 +84,14 @@ export class PsyoptionsAmericanInstrument implements LegInstrument { getDecimals = () => PsyoptionsAmericanInstrument.decimals; getSide = () => this.side; toLeg(): Leg { - return toLeg(this); + return { + instrumentProgram: this.getProgramId(), + baseAssetIndex: this.getBaseAssetIndex(), + instrumentData: this.serializeInstrumentData(), + instrumentAmount: addDecimals(this.getAmount(), this.getDecimals()), + instrumentDecimals: this.getDecimals(), + side: toSolitaLegSide(this.getSide()), + }; } async getPreparationsBeforeRfqCreation(): Promise { diff --git a/packages/js/src/plugins/psyoptionsEuropeanInstrumentModule/instrument.ts b/packages/js/src/plugins/psyoptionsEuropeanInstrumentModule/instrument.ts index f8cc46bad..6c772bb2e 100644 --- a/packages/js/src/plugins/psyoptionsEuropeanInstrumentModule/instrument.ts +++ b/packages/js/src/plugins/psyoptionsEuropeanInstrumentModule/instrument.ts @@ -22,13 +22,16 @@ import { Mint } from '../tokenModule'; import { CreateOptionInstrumentsResult, LegInstrument, - toLeg, } from '../instrumentModule'; import { addDecimals, removeDecimals } from '../../utils/conversions'; import { assert } from '../../utils/assert'; import { Convergence } from '../../Convergence'; import { createSerializerFromFixableBeetArgsStruct } from '../../types'; -import { LegSide, fromSolitaLegSide } from '../rfqModule/models/LegSide'; +import { + LegSide, + fromSolitaLegSide, + toSolitaLegSide, +} from '../rfqModule/models/LegSide'; import { CvgWallet } from '@/utils'; export const createEuropeanProgram = async (convergence: Convergence) => { @@ -153,7 +156,14 @@ export class PsyoptionsEuropeanInstrument implements LegInstrument { return optionMarketIxs; } toLeg(): Leg { - return toLeg(this); + return { + instrumentProgram: this.getProgramId(), + baseAssetIndex: this.getBaseAssetIndex(), + instrumentData: this.serializeInstrumentData(), + instrumentAmount: addDecimals(this.getAmount(), this.getDecimals()), + instrumentDecimals: this.getDecimals(), + side: toSolitaLegSide(this.getSide()), + }; } getBaseAssetAccount(): AccountMeta { diff --git a/packages/js/src/plugins/rfqModule/models/Rfq.ts b/packages/js/src/plugins/rfqModule/models/Rfq.ts index a720854b5..b95f45ce0 100644 --- a/packages/js/src/plugins/rfqModule/models/Rfq.ts +++ b/packages/js/src/plugins/rfqModule/models/Rfq.ts @@ -15,7 +15,6 @@ import { collateralMintCache } from '../../../plugins/collateralModule'; import { FixedSize, fromSolitaFixedSize } from './FixedSize'; import { OrderType, fromSolitaOrderType } from './OrderType'; import { StoredRfqState, fromSolitaStoredRfqState } from './StoredRfqState'; -import { psyoptionsAmericanInstrumentDataSerializer } from '@/plugins/psyoptionsAmericanInstrumentModule'; /** * This model captures all the relevant information about an RFQ diff --git a/packages/js/src/plugins/rfqModule/operations/prepareSettlement.ts b/packages/js/src/plugins/rfqModule/operations/prepareSettlement.ts index 760d9ef7c..e88b7e065 100644 --- a/packages/js/src/plugins/rfqModule/operations/prepareSettlement.ts +++ b/packages/js/src/plugins/rfqModule/operations/prepareSettlement.ts @@ -29,7 +29,6 @@ import { getOrCreateATAtxBuilder } from '../../../utils/ata'; import { InstrumentPdasClient } from '../../instrumentModule'; import { prepareAmericanOptions, - psyoptionsAmericanInstrumentDataSerializer, psyoptionsAmericanInstrumentProgram, } from '@/plugins/psyoptionsAmericanInstrumentModule'; import { diff --git a/packages/js/src/plugins/spotInstrumentModule/instruments.ts b/packages/js/src/plugins/spotInstrumentModule/instruments.ts index 066a854c4..0b80d3963 100644 --- a/packages/js/src/plugins/spotInstrumentModule/instruments.ts +++ b/packages/js/src/plugins/spotInstrumentModule/instruments.ts @@ -8,12 +8,15 @@ import { CreateOptionInstrumentsResult, LegInstrument, QuoteInstrument, - toLeg, } from '../instrumentModule'; import { Convergence } from '../../Convergence'; import { createSerializerFromFixableBeetArgsStruct } from '../../types'; -import { removeDecimals } from '../../utils/conversions'; -import { LegSide, fromSolitaLegSide } from '../rfqModule/models/LegSide'; +import { addDecimals, removeDecimals } from '../../utils/conversions'; +import { + LegSide, + fromSolitaLegSide, + toSolitaLegSide, +} from '../rfqModule/models/LegSide'; type InstrumentData = { mintAddress: PublicKey; @@ -93,7 +96,14 @@ export class SpotLegInstrument implements LegInstrument { return oracleAccount; } toLeg(): Leg { - return toLeg(this); + return { + instrumentProgram: this.getProgramId(), + baseAssetIndex: this.getBaseAssetIndex(), + instrumentData: this.serializeInstrumentData(), + instrumentAmount: addDecimals(this.getAmount(), this.getDecimals()), + instrumentDecimals: this.getDecimals(), + side: toSolitaLegSide(this.getSide()), + }; } static async create( convergence: Convergence, diff --git a/packages/js/tests/helpers.ts b/packages/js/tests/helpers.ts index ea830bacf..554cdb544 100644 --- a/packages/js/tests/helpers.ts +++ b/packages/js/tests/helpers.ts @@ -19,7 +19,6 @@ import { PsyoptionsAmericanInstrument, SpotLegInstrument, Mint, - psyoptionsAmericanInstrumentDataSerializer, } from '../src'; import { getUserKp, RPC_ENDPOINT } from '../../validator'; import { BASE_MINT_BTC_PK, QUOTE_MINT_PK } from './constants'; From 4383e1c5edfc0f7fa8aa9a757b40a79c8582aab4 Mon Sep 17 00:00:00 2001 From: Nagaprasadvr Date: Mon, 25 Sep 2023 09:23:19 +0530 Subject: [PATCH 07/13] fix build errors --- packages/js/src/plugins/instrumentModule/types.ts | 2 +- packages/js/src/plugins/spotInstrumentModule/instruments.ts | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/js/src/plugins/instrumentModule/types.ts b/packages/js/src/plugins/instrumentModule/types.ts index fa1f3059d..e65b8b410 100644 --- a/packages/js/src/plugins/instrumentModule/types.ts +++ b/packages/js/src/plugins/instrumentModule/types.ts @@ -6,7 +6,7 @@ import { Convergence } from '../../Convergence'; import { LegSide } from '../rfqModule/models/LegSide'; export interface LegInstrumentParser { - parseFromLeg(convergence: Convergence, leg: Leg): LegInstrument; + parseFromLeg(convergence: Convergence, leg: Leg): Promise; } export type CreateOptionInstrumentsResult = TransactionInstruction[]; diff --git a/packages/js/src/plugins/spotInstrumentModule/instruments.ts b/packages/js/src/plugins/spotInstrumentModule/instruments.ts index 0b80d3963..65f44329d 100644 --- a/packages/js/src/plugins/spotInstrumentModule/instruments.ts +++ b/packages/js/src/plugins/spotInstrumentModule/instruments.ts @@ -161,7 +161,10 @@ export class SpotLegInstrument implements LegInstrument { } export const spotLegInstrumentParser = { - parseFromLeg(convergence: Convergence, leg: Leg): SpotLegInstrument { + async parseFromLeg( + convergence: Convergence, + leg: Leg + ): Promise { const { side, instrumentAmount, From 8c9ab302fbf655649a8d74b7fc58dbc5488418ce Mon Sep 17 00:00:00 2001 From: Nagaprasadvr Date: Mon, 25 Sep 2023 09:39:25 +0530 Subject: [PATCH 08/13] optimise code --- .../plugins/rfqModule/operations/confirmResponse.ts | 10 +++++----- .../rfqModule/operations/finalizeRfqConstruction.ts | 11 +++++------ .../src/plugins/rfqModule/operations/respondToRfq.ts | 10 +++++----- 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/packages/js/src/plugins/rfqModule/operations/confirmResponse.ts b/packages/js/src/plugins/rfqModule/operations/confirmResponse.ts index ab2cde5b9..57640e6f2 100644 --- a/packages/js/src/plugins/rfqModule/operations/confirmResponse.ts +++ b/packages/js/src/plugins/rfqModule/operations/confirmResponse.ts @@ -196,12 +196,12 @@ export const confirmResponseBuilder = async ( const rfqModel = await convergence.rfqs().findRfqByAddress({ address: rfq }); - let baseAssetAccounts = rfqModel.legs.map((leg) => leg.getBaseAssetAccount()); - let oracleAccounts = await Promise.all( - rfqModel.legs.map((leg) => leg.getOracleAccount()) + const baseAssetAccounts = removeDuplicateAccountMeta( + rfqModel.legs.map((leg) => leg.getBaseAssetAccount()) + ); + const oracleAccounts = removeDuplicateAccountMeta( + await Promise.all(rfqModel.legs.map((leg) => leg.getOracleAccount())) ); - baseAssetAccounts = removeDuplicateAccountMeta(baseAssetAccounts); - oracleAccounts = removeDuplicateAccountMeta(oracleAccounts); return TransactionBuilder.make() .setFeePayer(payer) diff --git a/packages/js/src/plugins/rfqModule/operations/finalizeRfqConstruction.ts b/packages/js/src/plugins/rfqModule/operations/finalizeRfqConstruction.ts index 15053e605..ac00b9ce3 100644 --- a/packages/js/src/plugins/rfqModule/operations/finalizeRfqConstruction.ts +++ b/packages/js/src/plugins/rfqModule/operations/finalizeRfqConstruction.ts @@ -211,13 +211,12 @@ export const finalizeRfqConstructionBuilder = async ( isWritable: false, }; - let baseAssetAccounts = legs.map((leg) => leg.getBaseAssetAccount()); - let oracleAccounts = await Promise.all( - legs.map((leg) => leg.getOracleAccount()) + const baseAssetAccounts = removeDuplicateAccountMeta( + legs.map((leg) => leg.getBaseAssetAccount()) + ); + const oracleAccounts = removeDuplicateAccountMeta( + await Promise.all(legs.map((leg) => leg.getOracleAccount())) ); - - baseAssetAccounts = removeDuplicateAccountMeta(baseAssetAccounts); - oracleAccounts = removeDuplicateAccountMeta(oracleAccounts); anchorRemainingAccounts.push( configAccount, diff --git a/packages/js/src/plugins/rfqModule/operations/respondToRfq.ts b/packages/js/src/plugins/rfqModule/operations/respondToRfq.ts index ba849493c..1a2a53df3 100644 --- a/packages/js/src/plugins/rfqModule/operations/respondToRfq.ts +++ b/packages/js/src/plugins/rfqModule/operations/respondToRfq.ts @@ -258,12 +258,12 @@ export const respondToRfqBuilder = async ( rfqModel ); - let baseAssetAccounts = rfqModel.legs.map((leg) => leg.getBaseAssetAccount()); - let oracleAccounts = await Promise.all( - rfqModel.legs.map((leg) => leg.getOracleAccount()) + const baseAssetAccounts = removeDuplicateAccountMeta( + rfqModel.legs.map((leg) => leg.getBaseAssetAccount()) + ); + const oracleAccounts = removeDuplicateAccountMeta( + await Promise.all(rfqModel.legs.map((leg) => leg.getOracleAccount())) ); - baseAssetAccounts = removeDuplicateAccountMeta(baseAssetAccounts); - oracleAccounts = removeDuplicateAccountMeta(oracleAccounts); return TransactionBuilder.make() .setFeePayer(maker) From 58924b149a4ddc8c18ad559b0d54da50741b5739 Mon Sep 17 00:00:00 2001 From: Nagaprasadvr Date: Mon, 25 Sep 2023 09:44:54 +0530 Subject: [PATCH 09/13] remove unnecessary await in fetching baseAssetAccount --- packages/js/src/plugins/rfqModule/operations/addLegsToRfq.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/js/src/plugins/rfqModule/operations/addLegsToRfq.ts b/packages/js/src/plugins/rfqModule/operations/addLegsToRfq.ts index 050a82c95..b08a21f7e 100644 --- a/packages/js/src/plugins/rfqModule/operations/addLegsToRfq.ts +++ b/packages/js/src/plugins/rfqModule/operations/addLegsToRfq.ts @@ -137,8 +137,8 @@ export const addLegsToRfqBuilder = async ( .map((ins) => ins.getValidationAccounts()) .flat(); - const baseAssetAccounts = await Promise.all( - instruments.map((instrument) => instrument.getBaseAssetAccount()) + const baseAssetAccounts = instruments.map((instrument) => + instrument.getBaseAssetAccount() ); const rfqProgram = convergence.programs().getRfq(programs); From f18799402d7c60bb71d1dddf6b295c4c5e2cd1de Mon Sep 17 00:00:00 2001 From: Nagaprasadvr Date: Mon, 25 Sep 2023 12:15:45 +0530 Subject: [PATCH 10/13] remove redundant methods --- packages/js/src/plugins/instrumentModule/methods.ts | 9 --------- 1 file changed, 9 deletions(-) diff --git a/packages/js/src/plugins/instrumentModule/methods.ts b/packages/js/src/plugins/instrumentModule/methods.ts index 04789603b..ce7e41ebd 100644 --- a/packages/js/src/plugins/instrumentModule/methods.ts +++ b/packages/js/src/plugins/instrumentModule/methods.ts @@ -1,6 +1,5 @@ import { QuoteAsset, legBeet } from '@convergence-rfq/rfq'; -import { AccountMeta } from '@solana/web3.js'; import { createSerializerFromFixableBeetArgsStruct } from '../../types'; import { LegInstrument, QuoteInstrument } from './types'; @@ -13,14 +12,6 @@ export function getSerializedLegLength(legInstrument: LegInstrument) { return serializeAsLeg(legInstrument).length; } -export function getProgramAccount(legInstrument: LegInstrument): AccountMeta { - return { - pubkey: legInstrument.getProgramId(), - isSigner: false, - isWritable: false, - }; -} - export function toQuote(legInstrument: QuoteInstrument): QuoteAsset { return { instrumentProgram: legInstrument.getProgramId(), From 4032b90d0d069557b1c8d613556fc781ff50df43 Mon Sep 17 00:00:00 2001 From: Nagaprasadvr Date: Wed, 27 Sep 2023 13:01:14 +0530 Subject: [PATCH 11/13] remove pr comments --- .../src/plugins/instrumentModule/methods.ts | 57 +++++++++++++- .../js/src/plugins/instrumentModule/types.ts | 7 +- .../instrument.ts | 74 +------------------ .../instrument.ts | 68 +---------------- packages/js/src/plugins/rfqModule/helpers.ts | 16 +++- .../js/src/plugins/rfqModule/models/Rfq.ts | 2 +- .../rfqModule/operations/addLegsToRfq.ts | 10 ++- .../rfqModule/operations/cleanUpResponse.ts | 2 +- .../operations/cleanUpResponseLegs.ts | 2 +- .../rfqModule/operations/confirmResponse.ts | 12 ++- .../plugins/rfqModule/operations/createRfq.ts | 12 ++- .../operations/finalizeRfqConstruction.ts | 14 +++- .../operations/partiallySettleLegs.ts | 2 +- .../partlyRevertSettlementPreparation.ts | 2 +- .../operations/prepareMoreLegsSettlement.ts | 7 +- .../rfqModule/operations/prepareSettlement.ts | 14 ++-- .../rfqModule/operations/respondToRfq.ts | 12 ++- .../operations/revertSettlementPreparation.ts | 2 +- .../plugins/rfqModule/operations/settle.ts | 2 +- .../spotInstrumentModule/instruments.ts | 65 ++-------------- .../integration/psyoptionsAmerican.spec.ts | 1 - 21 files changed, 149 insertions(+), 234 deletions(-) diff --git a/packages/js/src/plugins/instrumentModule/methods.ts b/packages/js/src/plugins/instrumentModule/methods.ts index ce7e41ebd..23e70991c 100644 --- a/packages/js/src/plugins/instrumentModule/methods.ts +++ b/packages/js/src/plugins/instrumentModule/methods.ts @@ -1,11 +1,66 @@ import { QuoteAsset, legBeet } from '@convergence-rfq/rfq'; +import { AccountMeta, PublicKey } from '@solana/web3.js'; import { createSerializerFromFixableBeetArgsStruct } from '../../types'; +import { toSolitaLegSide } from '../rfqModule/models'; import { LegInstrument, QuoteInstrument } from './types'; +import { addDecimals } from '@/utils/conversions'; +import { Convergence } from '@/Convergence'; export function serializeAsLeg(legInstrument: LegInstrument) { const legSerializer = createSerializerFromFixableBeetArgsStruct(legBeet); - return legSerializer.serialize(legInstrument.toLeg()); + return legSerializer.serialize(toLeg(legInstrument)); +} + +export function toLeg(legInstrument: LegInstrument) { + return { + instrumentProgram: legInstrument.getProgramId(), + baseAssetIndex: legInstrument.getBaseAssetIndex(), + instrumentData: legInstrument.serializeInstrumentData(), + instrumentAmount: addDecimals( + legInstrument.getAmount(), + legInstrument.getDecimals() + ), + instrumentDecimals: legInstrument.getDecimals(), + side: toSolitaLegSide(legInstrument.getSide()), + }; +} + +export function getBaseAssetAccount( + legInstrument: LegInstrument, + cvg: Convergence +): AccountMeta { + const baseAsset = cvg + .protocol() + .pdas() + .baseAsset({ index: legInstrument.getBaseAssetIndex().value }); + + const baseAssetAccount: AccountMeta = { + pubkey: baseAsset, + isSigner: false, + isWritable: false, + }; + + return baseAssetAccount; +} + +export async function getOracleAccount( + baseAsset: PublicKey, + cvg: Convergence +): Promise { + const baseAssetModel = await cvg + .protocol() + .findBaseAssetByAddress({ address: baseAsset }); + + if (!baseAssetModel.priceOracle.address) { + throw Error('Base asset does not have a price oracle!'); + } + const oracleAccount = { + pubkey: baseAssetModel.priceOracle.address, + isSigner: false, + isWritable: false, + }; + return oracleAccount; } export function getSerializedLegLength(legInstrument: LegInstrument) { diff --git a/packages/js/src/plugins/instrumentModule/types.ts b/packages/js/src/plugins/instrumentModule/types.ts index e65b8b410..2aa6eade4 100644 --- a/packages/js/src/plugins/instrumentModule/types.ts +++ b/packages/js/src/plugins/instrumentModule/types.ts @@ -18,13 +18,10 @@ export interface LegInstrument { getDecimals: () => number; getSide: () => LegSide; serializeInstrumentData: () => Buffer; - getBaseAssetMint(): PublicKey; - getBaseAssetAccount(): AccountMeta; - getOracleAccount(): Promise; + getExchangeAssetMint(): PublicKey; getValidationAccounts(): AccountMeta[]; getPreparationsBeforeRfqCreation(): Promise; - getUnderlyingBaseAssetMint(): PublicKey; - toLeg(): Leg; + getBaseAssetMint(): PublicKey; } // TODO add registration of quote instruments diff --git a/packages/js/src/plugins/psyoptionsAmericanInstrumentModule/instrument.ts b/packages/js/src/plugins/psyoptionsAmericanInstrumentModule/instrument.ts index 9be1181ff..d08ea256a 100644 --- a/packages/js/src/plugins/psyoptionsAmericanInstrumentModule/instrument.ts +++ b/packages/js/src/plugins/psyoptionsAmericanInstrumentModule/instrument.ts @@ -1,9 +1,4 @@ -import { - AccountMeta, - Keypair, - PublicKey, - TransactionInstruction, -} from '@solana/web3.js'; +import { Keypair, PublicKey, TransactionInstruction } from '@solana/web3.js'; import { Leg, BaseAssetIndex } from '@convergence-rfq/rfq'; import { OptionMarketWithKey } from '@mithraic-labs/psy-american'; import { OptionType } from '@mithraic-labs/tokenized-euros'; @@ -20,11 +15,7 @@ import { import { addDecimals, removeDecimals } from '../../utils/conversions'; import { Convergence } from '../../Convergence'; import { createSerializerFromFixableBeetArgsStruct } from '../../types'; -import { - LegSide, - fromSolitaLegSide, - toSolitaLegSide, -} from '../rfqModule/models/LegSide'; +import { LegSide, fromSolitaLegSide } from '../rfqModule/models/LegSide'; import { CvgWallet, NoopWallet } from '../../utils/Wallets'; import { GetOrCreateATAtxBuilderReturnType, @@ -83,25 +74,8 @@ export class PsyoptionsAmericanInstrument implements LegInstrument { getBaseAssetIndex = () => this.baseAssetIndex; getDecimals = () => PsyoptionsAmericanInstrument.decimals; getSide = () => this.side; - toLeg(): Leg { - return { - instrumentProgram: this.getProgramId(), - baseAssetIndex: this.getBaseAssetIndex(), - instrumentData: this.serializeInstrumentData(), - instrumentAmount: addDecimals(this.getAmount(), this.getDecimals()), - instrumentDecimals: this.getDecimals(), - side: toSolitaLegSide(this.getSide()), - }; - } async getPreparationsBeforeRfqCreation(): Promise { - if (!this.underlyingAssetMint) { - throw new Error('Missing underlying asset mint'); - } - if (!this.stableAssetMint) { - throw new Error('Missing stable asset mint'); - } - const optionMarketIxs = await getPsyAmericanMarketIxs( this.convergence, this.underlyingAssetMint, @@ -114,47 +88,13 @@ export class PsyoptionsAmericanInstrument implements LegInstrument { ); return optionMarketIxs; } - getBaseAssetAccount(): AccountMeta { - const baseAsset = this.convergence - .protocol() - .pdas() - .baseAsset({ index: this.baseAssetIndex.value }); - - const baseAssetAccount: AccountMeta = { - pubkey: baseAsset, - isSigner: false, - isWritable: false, - }; - return baseAssetAccount; - } getBaseAssetMint(): PublicKey { - return this.optionMint; - } - - getUnderlyingBaseAssetMint(): PublicKey { return this.underlyingAssetMint; } - async getOracleAccount(): Promise { - const baseAsset = this.convergence - .protocol() - .pdas() - .baseAsset({ index: this.baseAssetIndex.value }); - - const baseAssetModel = await this.convergence - .protocol() - .findBaseAssetByAddress({ address: baseAsset }); - - if (!baseAssetModel.priceOracle.address) { - throw Error('Base asset does not have a price oracle!'); - } - const oracleAccount = { - pubkey: baseAssetModel.priceOracle.address, - isSigner: false, - isWritable: false, - }; - return oracleAccount; + getExchangeAssetMint(): PublicKey { + return this.optionMint; } static async create( @@ -233,12 +173,6 @@ export class PsyoptionsAmericanInstrument implements LegInstrument { } getValidationAccounts() { - if (!this.underlyingAssetMint) { - throw new Error('Missing underlying asset mint'); - } - if (!this.stableAssetMint) { - throw new Error('Missing stable asset mint'); - } const mintInfoPda = this.convergence .rfqs() .pdas() diff --git a/packages/js/src/plugins/psyoptionsEuropeanInstrumentModule/instrument.ts b/packages/js/src/plugins/psyoptionsEuropeanInstrumentModule/instrument.ts index a69b578a5..830201e89 100644 --- a/packages/js/src/plugins/psyoptionsEuropeanInstrumentModule/instrument.ts +++ b/packages/js/src/plugins/psyoptionsEuropeanInstrumentModule/instrument.ts @@ -23,11 +23,7 @@ import { addDecimals, removeDecimals } from '../../utils/conversions'; import { assert } from '../../utils/assert'; import { Convergence } from '../../Convergence'; import { createSerializerFromFixableBeetArgsStruct } from '../../types'; -import { - LegSide, - fromSolitaLegSide, - toSolitaLegSide, -} from '../rfqModule/models/LegSide'; +import { LegSide, fromSolitaLegSide } from '../rfqModule/models/LegSide'; import { CvgWallet } from '@/utils'; export const createEuropeanProgram = async (convergence: Convergence) => { @@ -128,15 +124,6 @@ export class PsyoptionsEuropeanInstrument implements LegInstrument { getDecimals = () => PsyoptionsEuropeanInstrument.decimals; getSide = () => this.side; async getPreparationsBeforeRfqCreation(): Promise { - if (!this.underlyingAssetMint) { - throw new Error('Missing underlying asset mint'); - } - if (!this.stableAssetMint) { - throw new Error('Missing stable asset mint'); - } - if (!this.oracleAddress) { - throw new Error('Missing oracle address'); - } const optionMarketIxs = await getPsyEuropeanMarketIxs( this.convergence, this.underlyingAssetMint, @@ -151,60 +138,14 @@ export class PsyoptionsEuropeanInstrument implements LegInstrument { return optionMarketIxs; } - toLeg(): Leg { - return { - instrumentProgram: this.getProgramId(), - baseAssetIndex: this.getBaseAssetIndex(), - instrumentData: this.serializeInstrumentData(), - instrumentAmount: addDecimals(this.getAmount(), this.getDecimals()), - instrumentDecimals: this.getDecimals(), - side: toSolitaLegSide(this.getSide()), - }; - } - getBaseAssetAccount(): AccountMeta { - const baseAsset = this.convergence - .protocol() - .pdas() - .baseAsset({ index: this.baseAssetIndex.value }); - - const baseAssetAccount: AccountMeta = { - pubkey: baseAsset, - isSigner: false, - isWritable: false, - }; - - return baseAssetAccount; - } - getBaseAssetMint(): PublicKey { + getExchangeAssetMint(): PublicKey { return this.optionMint; } - - getUnderlyingBaseAssetMint(): PublicKey { + getBaseAssetMint(): PublicKey { return this.underlyingAssetMint; } - async getOracleAccount(): Promise { - const baseAsset = this.convergence - .protocol() - .pdas() - .baseAsset({ index: this.baseAssetIndex.value }); - - const baseAssetModel = await this.convergence - .protocol() - .findBaseAssetByAddress({ address: baseAsset }); - - if (!baseAssetModel.priceOracle.address) { - throw Error('Base asset does not have a price oracle!'); - } - const oracleAccount = { - pubkey: baseAssetModel.priceOracle.address, - isSigner: false, - isWritable: false, - }; - return oracleAccount; - } - static async create( convergence: Convergence, underlyingMint: Mint, @@ -270,9 +211,6 @@ export class PsyoptionsEuropeanInstrument implements LegInstrument { /** Helper method to get validation accounts for a Psyoptions European instrument. */ getValidationAccounts() { - if (!this.underlyingAssetMint) { - throw new Error('Missing underlying asset mint'); - } return [ { pubkey: this.getProgramId(), diff --git a/packages/js/src/plugins/rfqModule/helpers.ts b/packages/js/src/plugins/rfqModule/helpers.ts index d6ce9ae67..7f631349e 100644 --- a/packages/js/src/plugins/rfqModule/helpers.ts +++ b/packages/js/src/plugins/rfqModule/helpers.ts @@ -1,5 +1,5 @@ -import { AccountMeta } from '@solana/web3.js'; import { Sha256 } from '@aws-crypto/sha256-js'; +import { AccountMeta } from '@solana/web3.js'; import { Confirmation, Quote, @@ -125,3 +125,17 @@ export function extractLegsMultiplier( } throw new Error('Invalid fixed size'); } + +export const removeDuplicateAccountMeta = ( + accountMeta: AccountMeta[] +): AccountMeta[] => { + const uniqueAccountMeta: AccountMeta[] = []; + for (let i = 0; i < accountMeta.length; i++) { + if ( + !uniqueAccountMeta.find((x) => x.pubkey.equals(accountMeta[i].pubkey)) + ) { + uniqueAccountMeta.push(accountMeta[i]); + } + } + return uniqueAccountMeta; +}; diff --git a/packages/js/src/plugins/rfqModule/models/Rfq.ts b/packages/js/src/plugins/rfqModule/models/Rfq.ts index b95f45ce0..80cb679d9 100644 --- a/packages/js/src/plugins/rfqModule/models/Rfq.ts +++ b/packages/js/src/plugins/rfqModule/models/Rfq.ts @@ -98,7 +98,7 @@ export const toRfq = async ( convergence: Convergence, account: RfqAccount ): Promise => { - const quoteAsset = await SpotQuoteInstrument.parseFromQuote( + const quoteAsset = SpotQuoteInstrument.parseFromQuote( convergence, account.data.quoteAsset ); diff --git a/packages/js/src/plugins/rfqModule/operations/addLegsToRfq.ts b/packages/js/src/plugins/rfqModule/operations/addLegsToRfq.ts index b08a21f7e..b7bdeb6b5 100644 --- a/packages/js/src/plugins/rfqModule/operations/addLegsToRfq.ts +++ b/packages/js/src/plugins/rfqModule/operations/addLegsToRfq.ts @@ -14,7 +14,11 @@ import { TransactionBuilder, TransactionBuilderOptions, } from '../../../utils/TransactionBuilder'; -import { LegInstrument } from '../../../plugins/instrumentModule'; +import { + LegInstrument, + getBaseAssetAccount, + toLeg, +} from '@/plugins/instrumentModule'; const Key = 'AddLegsToRfqOperation' as const; @@ -132,13 +136,13 @@ export const addLegsToRfqBuilder = async ( const protocol = protocolPdaClient.protocol(); const { taker = convergence.identity(), instruments, rfq } = params; - const legs = instruments.map((ins) => ins.toLeg()); + const legs = instruments.map((ins) => toLeg(ins)); const legAccounts = instruments .map((ins) => ins.getValidationAccounts()) .flat(); const baseAssetAccounts = instruments.map((instrument) => - instrument.getBaseAssetAccount() + getBaseAssetAccount(instrument, convergence) ); const rfqProgram = convergence.programs().getRfq(programs); diff --git a/packages/js/src/plugins/rfqModule/operations/cleanUpResponse.ts b/packages/js/src/plugins/rfqModule/operations/cleanUpResponse.ts index 691ceeffb..04b9bf195 100644 --- a/packages/js/src/plugins/rfqModule/operations/cleanUpResponse.ts +++ b/packages/js/src/plugins/rfqModule/operations/cleanUpResponse.ts @@ -162,7 +162,7 @@ export const cleanUpResponseBuilder = async ( index: i, }); - const baseAssetMint = leg.getBaseAssetMint(); + const baseAssetMint = leg.getExchangeAssetMint(); const legAccounts: AccountMeta[] = [ { pubkey: firstToPrepare, diff --git a/packages/js/src/plugins/rfqModule/operations/cleanUpResponseLegs.ts b/packages/js/src/plugins/rfqModule/operations/cleanUpResponseLegs.ts index e2f3fb2d8..2bbd840d5 100644 --- a/packages/js/src/plugins/rfqModule/operations/cleanUpResponseLegs.ts +++ b/packages/js/src/plugins/rfqModule/operations/cleanUpResponseLegs.ts @@ -175,7 +175,7 @@ export const cleanUpResponseLegsBuilder = async ( }); const leg = rfqModel.legs[i]; - const baseAssetMint = leg.getBaseAssetMint(); + const baseAssetMint = leg.getExchangeAssetMint(); const legAccounts: AccountMeta[] = [ { diff --git a/packages/js/src/plugins/rfqModule/operations/confirmResponse.ts b/packages/js/src/plugins/rfqModule/operations/confirmResponse.ts index 57640e6f2..1aaeefa15 100644 --- a/packages/js/src/plugins/rfqModule/operations/confirmResponse.ts +++ b/packages/js/src/plugins/rfqModule/operations/confirmResponse.ts @@ -17,6 +17,10 @@ import { import { ResponseSide, toSolitaQuoteSide } from '../models/ResponseSide'; import { toSolitaOverrideLegMultiplierBps } from '../models/Confirmation'; import { removeDuplicateAccountMeta } from '../helpers'; +import { + getBaseAssetAccount, + getOracleAccount, +} from '@/plugins/instrumentModule'; const Key = 'ConfirmResponseOperation' as const; @@ -197,10 +201,14 @@ export const confirmResponseBuilder = async ( const rfqModel = await convergence.rfqs().findRfqByAddress({ address: rfq }); const baseAssetAccounts = removeDuplicateAccountMeta( - rfqModel.legs.map((leg) => leg.getBaseAssetAccount()) + rfqModel.legs.map((leg) => getBaseAssetAccount(leg, convergence)) ); const oracleAccounts = removeDuplicateAccountMeta( - await Promise.all(rfqModel.legs.map((leg) => leg.getOracleAccount())) + await Promise.all( + baseAssetAccounts.map((baseAsset) => + getOracleAccount(baseAsset.pubkey, convergence) + ) + ) ); return TransactionBuilder.make() diff --git a/packages/js/src/plugins/rfqModule/operations/createRfq.ts b/packages/js/src/plugins/rfqModule/operations/createRfq.ts index 96a0d5c6b..edcd4ff09 100644 --- a/packages/js/src/plugins/rfqModule/operations/createRfq.ts +++ b/packages/js/src/plugins/rfqModule/operations/createRfq.ts @@ -23,9 +23,11 @@ import { } from '../../../types'; import { Convergence } from '../../../Convergence'; import { + getBaseAssetAccount, LegInstrument, // LegInstrumentInputData, QuoteInstrument, + toLeg, toQuote, } from '../../../plugins/instrumentModule'; import { OrderType, toSolitaOrderType } from '../models/OrderType'; @@ -305,7 +307,7 @@ export const createRfqBuilder = async ( } = params; let { expectedLegsSize } = params; - const legs = instruments.map((ins) => ins.toLeg()); + const legs = instruments.map((ins) => toLeg(ins)); const expectedLegsSizeValue = calculateExpectedLegsSize(instruments); expectedLegsSize = expectedLegsSize ?? expectedLegsSizeValue; @@ -331,7 +333,9 @@ export const createRfqBuilder = async ( }, ]; - let baseAssetAccounts = instruments.map((ins) => ins.getBaseAssetAccount()); + let baseAssetAccounts = instruments.map((ins) => + getBaseAssetAccount(ins, convergence) + ); let legAccounts = instruments .map((ins) => ins.getValidationAccounts()) .flat(); @@ -380,7 +384,9 @@ export const createRfqBuilder = async ( legAccounts = instrumentsToAdd .map((ins) => ins.getValidationAccounts()) .flat(); - baseAssetAccounts = instrumentsToAdd.map((i) => i.getBaseAssetAccount()); + baseAssetAccounts = instrumentsToAdd.map((i) => + getBaseAssetAccount(i, convergence) + ); rfqBuilder = TransactionBuilder.make() .setFeePayer(payer) .setContext({ diff --git a/packages/js/src/plugins/rfqModule/operations/finalizeRfqConstruction.ts b/packages/js/src/plugins/rfqModule/operations/finalizeRfqConstruction.ts index ac00b9ce3..5d442ac05 100644 --- a/packages/js/src/plugins/rfqModule/operations/finalizeRfqConstruction.ts +++ b/packages/js/src/plugins/rfqModule/operations/finalizeRfqConstruction.ts @@ -17,7 +17,11 @@ import { } from '../../../types'; import { Convergence } from '../../../Convergence'; import { removeDuplicateAccountMeta } from '../helpers'; -import { LegInstrument } from '@/plugins/instrumentModule'; +import { + getBaseAssetAccount, + getOracleAccount, + LegInstrument, +} from '@/plugins/instrumentModule'; const Key = 'FinalizeRfqConstructionOperation' as const; @@ -212,10 +216,14 @@ export const finalizeRfqConstructionBuilder = async ( }; const baseAssetAccounts = removeDuplicateAccountMeta( - legs.map((leg) => leg.getBaseAssetAccount()) + legs.map((leg) => getBaseAssetAccount(leg, convergence)) ); const oracleAccounts = removeDuplicateAccountMeta( - await Promise.all(legs.map((leg) => leg.getOracleAccount())) + await Promise.all( + baseAssetAccounts.map((baseAsset) => + getOracleAccount(baseAsset.pubkey, convergence) + ) + ) ); anchorRemainingAccounts.push( diff --git a/packages/js/src/plugins/rfqModule/operations/partiallySettleLegs.ts b/packages/js/src/plugins/rfqModule/operations/partiallySettleLegs.ts index b2c3b670d..f028b4410 100644 --- a/packages/js/src/plugins/rfqModule/operations/partiallySettleLegs.ts +++ b/packages/js/src/plugins/rfqModule/operations/partiallySettleLegs.ts @@ -177,7 +177,7 @@ export const partiallySettleLegsBuilder = async ( rfqModel, }); - const baseAssetMint = leg.getBaseAssetMint(); + const baseAssetMint = leg.getExchangeAssetMint(); const legAccounts: AccountMeta[] = [ //`escrow` diff --git a/packages/js/src/plugins/rfqModule/operations/partlyRevertSettlementPreparation.ts b/packages/js/src/plugins/rfqModule/operations/partlyRevertSettlementPreparation.ts index 8af616f1f..2cd74abda 100644 --- a/packages/js/src/plugins/rfqModule/operations/partlyRevertSettlementPreparation.ts +++ b/packages/js/src/plugins/rfqModule/operations/partlyRevertSettlementPreparation.ts @@ -178,7 +178,7 @@ export const partlyRevertSettlementPreparationBuilder = async ( }; const leg = rfqModel.legs[i]; - const baseAssetMint = leg.getBaseAssetMint(); + const baseAssetMint = leg.getExchangeAssetMint(); const legAccounts: AccountMeta[] = [ //`escrow` diff --git a/packages/js/src/plugins/rfqModule/operations/prepareMoreLegsSettlement.ts b/packages/js/src/plugins/rfqModule/operations/prepareMoreLegsSettlement.ts index cc20f8983..e195c1e33 100644 --- a/packages/js/src/plugins/rfqModule/operations/prepareMoreLegsSettlement.ts +++ b/packages/js/src/plugins/rfqModule/operations/prepareMoreLegsSettlement.ts @@ -207,7 +207,7 @@ export const prepareMoreLegsSettlementBuilder = async ( }); const leg = rfqModel.legs[i]; - const baseAssetMint = leg.getBaseAssetMint(); + const baseAssetMint = leg.getExchangeAssetMint(); const legAccounts: AccountMeta[] = [ // `caller @@ -218,11 +218,6 @@ export const prepareMoreLegsSettlementBuilder = async ( }, // `caller_token_account` { - // pubkey: convergence.tokens().pdas().associatedTokenAccount({ - // mint: baseAssetMint!.address, - // owner: caller.publicKey, - // programs, - // }), pubkey: await getOrCreateATA( convergence, baseAssetMint, diff --git a/packages/js/src/plugins/rfqModule/operations/prepareSettlement.ts b/packages/js/src/plugins/rfqModule/operations/prepareSettlement.ts index e88b7e065..2a7dc4845 100644 --- a/packages/js/src/plugins/rfqModule/operations/prepareSettlement.ts +++ b/packages/js/src/plugins/rfqModule/operations/prepareSettlement.ts @@ -204,13 +204,13 @@ export const prepareSettlementBuilder = async ( const spotInstrumentProgram = convergence.programs().getSpotInstrument(); - const baseAssetMints: Mint[] = []; + const exchangeAssetMints: Mint[] = []; for (const leg of rfqModel.legs) { - const baseAssetMintPubkey = leg.getBaseAssetMint(); - const baseAssetMint = await convergence + const exchangeAssetMintPubkey = leg.getExchangeAssetMint(); + const exchangeAssetMint = await convergence .tokens() - .findMintByAddress({ address: baseAssetMintPubkey }); - baseAssetMints.push(baseAssetMint); + .findMintByAddress({ address: exchangeAssetMintPubkey }); + exchangeAssetMints.push(exchangeAssetMint); } const anchorRemainingAccounts: AccountMeta[] = []; @@ -274,7 +274,7 @@ export const prepareSettlementBuilder = async ( const { ataPubKey, txBuilder } = await getOrCreateATAtxBuilder( convergence, - baseAssetMints[legIndex].address, + exchangeAssetMints[legIndex].address, caller.publicKey, programs ); @@ -297,7 +297,7 @@ export const prepareSettlementBuilder = async ( }, // `mint` { - pubkey: baseAssetMints[legIndex].address, + pubkey: exchangeAssetMints[legIndex].address, isSigner: false, isWritable: false, }, diff --git a/packages/js/src/plugins/rfqModule/operations/respondToRfq.ts b/packages/js/src/plugins/rfqModule/operations/respondToRfq.ts index 1a2a53df3..e0319f051 100644 --- a/packages/js/src/plugins/rfqModule/operations/respondToRfq.ts +++ b/packages/js/src/plugins/rfqModule/operations/respondToRfq.ts @@ -18,6 +18,10 @@ import { import { Quote, Rfq } from '../models'; import { toSolitaQuote } from '../models/Quote'; import { removeDuplicateAccountMeta } from '../helpers'; +import { + getBaseAssetAccount, + getOracleAccount, +} from '@/plugins/instrumentModule'; const getNextResponsePdaAndDistinguisher = async ( cvg: Convergence, @@ -259,10 +263,14 @@ export const respondToRfqBuilder = async ( ); const baseAssetAccounts = removeDuplicateAccountMeta( - rfqModel.legs.map((leg) => leg.getBaseAssetAccount()) + rfqModel.legs.map((leg) => getBaseAssetAccount(leg, convergence)) ); const oracleAccounts = removeDuplicateAccountMeta( - await Promise.all(rfqModel.legs.map((leg) => leg.getOracleAccount())) + await Promise.all( + baseAssetAccounts.map((baseAsset) => + getOracleAccount(baseAsset.pubkey, convergence) + ) + ) ); return TransactionBuilder.make() diff --git a/packages/js/src/plugins/rfqModule/operations/revertSettlementPreparation.ts b/packages/js/src/plugins/rfqModule/operations/revertSettlementPreparation.ts index 95098962a..45afa4e04 100644 --- a/packages/js/src/plugins/rfqModule/operations/revertSettlementPreparation.ts +++ b/packages/js/src/plugins/rfqModule/operations/revertSettlementPreparation.ts @@ -172,7 +172,7 @@ export const revertSettlementPreparationBuilder = async ( const leg = rfqModel.legs[i]; - const baseAssetMint = leg.getBaseAssetMint(); + const baseAssetMint = leg.getExchangeAssetMint(); const legAccounts: AccountMeta[] = [ //`escrow` diff --git a/packages/js/src/plugins/rfqModule/operations/settle.ts b/packages/js/src/plugins/rfqModule/operations/settle.ts index 3ecd96020..0e80b268e 100644 --- a/packages/js/src/plugins/rfqModule/operations/settle.ts +++ b/packages/js/src/plugins/rfqModule/operations/settle.ts @@ -161,7 +161,7 @@ export const settleBuilder = async ( const leg = rfqModel.legs[legIndex]; const { receiver } = legs[legIndex]; - const baseAssetMint = leg.getBaseAssetMint(); + const baseAssetMint = leg.getExchangeAssetMint(); const instrumentProgramAccount: AccountMeta = { pubkey: rfqModel.legs[legIndex].getProgramId(), diff --git a/packages/js/src/plugins/spotInstrumentModule/instruments.ts b/packages/js/src/plugins/spotInstrumentModule/instruments.ts index 65f44329d..e0de245f5 100644 --- a/packages/js/src/plugins/spotInstrumentModule/instruments.ts +++ b/packages/js/src/plugins/spotInstrumentModule/instruments.ts @@ -1,4 +1,4 @@ -import { AccountMeta, PublicKey } from '@solana/web3.js'; +import { PublicKey } from '@solana/web3.js'; import { Leg, BaseAssetIndex, QuoteAsset } from '@convergence-rfq/rfq'; import { FixableBeetArgsStruct } from '@convergence-rfq/beet'; import { publicKey } from '@convergence-rfq/beet-solana'; @@ -11,12 +11,8 @@ import { } from '../instrumentModule'; import { Convergence } from '../../Convergence'; import { createSerializerFromFixableBeetArgsStruct } from '../../types'; -import { addDecimals, removeDecimals } from '../../utils/conversions'; -import { - LegSide, - fromSolitaLegSide, - toSolitaLegSide, -} from '../rfqModule/models/LegSide'; +import { removeDecimals } from '../../utils/conversions'; +import { LegSide, fromSolitaLegSide } from '../rfqModule/models/LegSide'; type InstrumentData = { mintAddress: PublicKey; @@ -53,58 +49,14 @@ export class SpotLegInstrument implements LegInstrument { async getPreparationsBeforeRfqCreation(): Promise { return []; } - getBaseAssetAccount(): AccountMeta { - const baseAsset = this.convergence - .protocol() - .pdas() - .baseAsset({ index: this.baseAssetIndex.value }); - - const baseAssetAccount: AccountMeta = { - pubkey: baseAsset, - isSigner: false, - isWritable: false, - }; - - return baseAssetAccount; - } getBaseAssetMint(): PublicKey { return this.mintAddress; } - getUnderlyingBaseAssetMint(): PublicKey { + getExchangeAssetMint(): PublicKey { return this.mintAddress; } - async getOracleAccount(): Promise { - const baseAsset = this.convergence - .protocol() - .pdas() - .baseAsset({ index: this.baseAssetIndex.value }); - - const baseAssetModel = await this.convergence - .protocol() - .findBaseAssetByAddress({ address: baseAsset }); - - if (!baseAssetModel.priceOracle.address) { - throw Error('Base asset does not have a price oracle!'); - } - const oracleAccount = { - pubkey: baseAssetModel.priceOracle.address, - isSigner: false, - isWritable: false, - }; - return oracleAccount; - } - toLeg(): Leg { - return { - instrumentProgram: this.getProgramId(), - baseAssetIndex: this.getBaseAssetIndex(), - instrumentData: this.serializeInstrumentData(), - instrumentAmount: addDecimals(this.getAmount(), this.getDecimals()), - instrumentDecimals: this.getDecimals(), - side: toSolitaLegSide(this.getSide()), - }; - } static async create( convergence: Convergence, mint: Mint, @@ -161,10 +113,7 @@ export class SpotLegInstrument implements LegInstrument { } export const spotLegInstrumentParser = { - async parseFromLeg( - convergence: Convergence, - leg: Leg - ): Promise { + parseFromLeg(convergence: Convergence, leg: Leg): SpotLegInstrument { const { side, instrumentAmount, @@ -197,10 +146,10 @@ export class SpotQuoteInstrument implements QuoteInstrument { getProgramId = () => this.convergence.programs().getSpotInstrument().address; getDecimals = () => this.decimals; - static async parseFromQuote( + static parseFromQuote( convergence: Convergence, quote: QuoteAsset - ): Promise { + ): QuoteInstrument { const { instrumentData, instrumentDecimals } = quote; const { mintAddress } = SpotLegInstrument.deserializeInstrumentData( Buffer.from(instrumentData) diff --git a/packages/js/tests/integration/psyoptionsAmerican.spec.ts b/packages/js/tests/integration/psyoptionsAmerican.spec.ts index 2b9a21b7c..e441bfe25 100644 --- a/packages/js/tests/integration/psyoptionsAmerican.spec.ts +++ b/packages/js/tests/integration/psyoptionsAmerican.spec.ts @@ -66,7 +66,6 @@ describe('integration.psyoptionsAmerican', () => { const settlementResponse = await settleRfq(takerCvg, rfq, rfqResponse); expect(settlementResponse.response).toHaveProperty('signature'); - // TODO: Check balances }); From b5c7ebf6294057aecfc2db37d552c0d03baf5732 Mon Sep 17 00:00:00 2001 From: Nagaprasadvr Date: Wed, 27 Sep 2023 13:12:30 +0530 Subject: [PATCH 12/13] change baseAssetMint to exchangeAssetMint --- .../js/src/plugins/rfqModule/operations/cleanUpResponse.ts | 4 ++-- .../src/plugins/rfqModule/operations/cleanUpResponseLegs.ts | 4 ++-- .../src/plugins/rfqModule/operations/partiallySettleLegs.ts | 4 ++-- .../operations/partlyRevertSettlementPreparation.ts | 4 ++-- .../rfqModule/operations/prepareMoreLegsSettlement.ts | 6 +++--- .../rfqModule/operations/revertSettlementPreparation.ts | 4 ++-- packages/js/src/plugins/rfqModule/operations/settle.ts | 4 ++-- 7 files changed, 15 insertions(+), 15 deletions(-) diff --git a/packages/js/src/plugins/rfqModule/operations/cleanUpResponse.ts b/packages/js/src/plugins/rfqModule/operations/cleanUpResponse.ts index 04b9bf195..4b2a18b7b 100644 --- a/packages/js/src/plugins/rfqModule/operations/cleanUpResponse.ts +++ b/packages/js/src/plugins/rfqModule/operations/cleanUpResponse.ts @@ -162,7 +162,7 @@ export const cleanUpResponseBuilder = async ( index: i, }); - const baseAssetMint = leg.getExchangeAssetMint(); + const exchangeAssetMint = leg.getExchangeAssetMint(); const legAccounts: AccountMeta[] = [ { pubkey: firstToPrepare, @@ -176,7 +176,7 @@ export const cleanUpResponseBuilder = async ( }, { pubkey: convergence.tokens().pdas().associatedTokenAccount({ - mint: baseAssetMint, + mint: exchangeAssetMint, owner: dao, programs, }), diff --git a/packages/js/src/plugins/rfqModule/operations/cleanUpResponseLegs.ts b/packages/js/src/plugins/rfqModule/operations/cleanUpResponseLegs.ts index 2bbd840d5..56e7b5ae9 100644 --- a/packages/js/src/plugins/rfqModule/operations/cleanUpResponseLegs.ts +++ b/packages/js/src/plugins/rfqModule/operations/cleanUpResponseLegs.ts @@ -175,7 +175,7 @@ export const cleanUpResponseLegsBuilder = async ( }); const leg = rfqModel.legs[i]; - const baseAssetMint = leg.getExchangeAssetMint(); + const exchangeAssetMint = leg.getExchangeAssetMint(); const legAccounts: AccountMeta[] = [ { @@ -191,7 +191,7 @@ export const cleanUpResponseLegsBuilder = async ( { pubkey: await getOrCreateATA( convergence, - baseAssetMint, + exchangeAssetMint, protocol.authority ), isSigner: false, diff --git a/packages/js/src/plugins/rfqModule/operations/partiallySettleLegs.ts b/packages/js/src/plugins/rfqModule/operations/partiallySettleLegs.ts index f028b4410..07a2d233f 100644 --- a/packages/js/src/plugins/rfqModule/operations/partiallySettleLegs.ts +++ b/packages/js/src/plugins/rfqModule/operations/partiallySettleLegs.ts @@ -177,7 +177,7 @@ export const partiallySettleLegsBuilder = async ( rfqModel, }); - const baseAssetMint = leg.getExchangeAssetMint(); + const exchangeAssetMint = leg.getExchangeAssetMint(); const legAccounts: AccountMeta[] = [ //`escrow` @@ -192,7 +192,7 @@ export const partiallySettleLegsBuilder = async ( .tokens() .pdas() .associatedTokenAccount({ - mint: baseAssetMint, + mint: exchangeAssetMint, owner: receiver === 'maker' ? maker : taker, programs, }), diff --git a/packages/js/src/plugins/rfqModule/operations/partlyRevertSettlementPreparation.ts b/packages/js/src/plugins/rfqModule/operations/partlyRevertSettlementPreparation.ts index 2cd74abda..53612712a 100644 --- a/packages/js/src/plugins/rfqModule/operations/partlyRevertSettlementPreparation.ts +++ b/packages/js/src/plugins/rfqModule/operations/partlyRevertSettlementPreparation.ts @@ -178,7 +178,7 @@ export const partlyRevertSettlementPreparationBuilder = async ( }; const leg = rfqModel.legs[i]; - const baseAssetMint = leg.getExchangeAssetMint(); + const exchangeAssetMint = leg.getExchangeAssetMint(); const legAccounts: AccountMeta[] = [ //`escrow` @@ -193,7 +193,7 @@ export const partlyRevertSettlementPreparationBuilder = async ( .tokens() .pdas() .associatedTokenAccount({ - mint: baseAssetMint, + mint: exchangeAssetMint, owner: side === 'maker' ? responseModel.maker : rfqModel.taker, programs, }), diff --git a/packages/js/src/plugins/rfqModule/operations/prepareMoreLegsSettlement.ts b/packages/js/src/plugins/rfqModule/operations/prepareMoreLegsSettlement.ts index e195c1e33..73a2d8068 100644 --- a/packages/js/src/plugins/rfqModule/operations/prepareMoreLegsSettlement.ts +++ b/packages/js/src/plugins/rfqModule/operations/prepareMoreLegsSettlement.ts @@ -207,7 +207,7 @@ export const prepareMoreLegsSettlementBuilder = async ( }); const leg = rfqModel.legs[i]; - const baseAssetMint = leg.getExchangeAssetMint(); + const exchangeAssetMint = leg.getExchangeAssetMint(); const legAccounts: AccountMeta[] = [ // `caller @@ -220,7 +220,7 @@ export const prepareMoreLegsSettlementBuilder = async ( { pubkey: await getOrCreateATA( convergence, - baseAssetMint, + exchangeAssetMint, caller.publicKey, programs ), @@ -229,7 +229,7 @@ export const prepareMoreLegsSettlementBuilder = async ( }, // `mint` { - pubkey: baseAssetMint, + pubkey: exchangeAssetMint, isSigner: false, isWritable: false, }, diff --git a/packages/js/src/plugins/rfqModule/operations/revertSettlementPreparation.ts b/packages/js/src/plugins/rfqModule/operations/revertSettlementPreparation.ts index 45afa4e04..c0fc784ac 100644 --- a/packages/js/src/plugins/rfqModule/operations/revertSettlementPreparation.ts +++ b/packages/js/src/plugins/rfqModule/operations/revertSettlementPreparation.ts @@ -172,7 +172,7 @@ export const revertSettlementPreparationBuilder = async ( const leg = rfqModel.legs[i]; - const baseAssetMint = leg.getExchangeAssetMint(); + const exchangeAssetMint = leg.getExchangeAssetMint(); const legAccounts: AccountMeta[] = [ //`escrow` @@ -187,7 +187,7 @@ export const revertSettlementPreparationBuilder = async ( .tokens() .pdas() .associatedTokenAccount({ - mint: baseAssetMint, + mint: exchangeAssetMint, owner: side === 'maker' ? responseModel.maker : rfqModel.taker, programs, }), diff --git a/packages/js/src/plugins/rfqModule/operations/settle.ts b/packages/js/src/plugins/rfqModule/operations/settle.ts index 0e80b268e..ce3622bf3 100644 --- a/packages/js/src/plugins/rfqModule/operations/settle.ts +++ b/packages/js/src/plugins/rfqModule/operations/settle.ts @@ -161,7 +161,7 @@ export const settleBuilder = async ( const leg = rfqModel.legs[legIndex]; const { receiver } = legs[legIndex]; - const baseAssetMint = leg.getExchangeAssetMint(); + const exchangeAssetMint = leg.getExchangeAssetMint(); const instrumentProgramAccount: AccountMeta = { pubkey: rfqModel.legs[legIndex].getProgramId(), @@ -190,7 +190,7 @@ export const settleBuilder = async ( .tokens() .pdas() .associatedTokenAccount({ - mint: baseAssetMint, + mint: exchangeAssetMint, owner: receiver === 'maker' ? maker : taker, programs, }), From 2b58be9834fd1e073a5cff88e449740e5ec25c86 Mon Sep 17 00:00:00 2001 From: Nagaprasadvr Date: Wed, 25 Oct 2023 11:43:04 +0530 Subject: [PATCH 13/13] make parseLeg sync --- .../js/src/plugins/instrumentModule/plugin.ts | 4 +-- .../js/src/plugins/instrumentModule/types.ts | 3 +- .../instrument.ts | 30 ++++++++-------- .../instrument.ts | 34 +++++++++---------- .../js/src/plugins/rfqModule/models/Rfq.ts | 10 ++---- .../spotInstrumentModule/instruments.ts | 3 -- 6 files changed, 37 insertions(+), 47 deletions(-) diff --git a/packages/js/src/plugins/instrumentModule/plugin.ts b/packages/js/src/plugins/instrumentModule/plugin.ts index 5445d85b0..23c3a7f6a 100644 --- a/packages/js/src/plugins/instrumentModule/plugin.ts +++ b/packages/js/src/plugins/instrumentModule/plugin.ts @@ -26,7 +26,7 @@ export const instrumentModule = (): ConvergencePlugin => ({ legInstrumentParsers.push([programAddress, factory]); }; - convergence.parseLegInstrument = async function (leg: SolitaLeg) { + convergence.parseLegInstrument = function (leg: SolitaLeg) { const factory = legInstrumentParsers.find(([key]) => leg.instrumentProgram.equals(key) )?.[1]; @@ -48,7 +48,7 @@ declare module '../../Convergence' { programAddress: PublicKey, factory: LegInstrumentParser ): void; - parseLegInstrument(leg: SolitaLeg): Promise; + parseLegInstrument(leg: SolitaLeg): LegInstrument; } } diff --git a/packages/js/src/plugins/instrumentModule/types.ts b/packages/js/src/plugins/instrumentModule/types.ts index 2aa6eade4..2440ef21b 100644 --- a/packages/js/src/plugins/instrumentModule/types.ts +++ b/packages/js/src/plugins/instrumentModule/types.ts @@ -6,7 +6,7 @@ import { Convergence } from '../../Convergence'; import { LegSide } from '../rfqModule/models/LegSide'; export interface LegInstrumentParser { - parseFromLeg(convergence: Convergence, leg: Leg): Promise; + parseFromLeg(convergence: Convergence, leg: Leg): LegInstrument; } export type CreateOptionInstrumentsResult = TransactionInstruction[]; @@ -21,7 +21,6 @@ export interface LegInstrument { getExchangeAssetMint(): PublicKey; getValidationAccounts(): AccountMeta[]; getPreparationsBeforeRfqCreation(): Promise; - getBaseAssetMint(): PublicKey; } // TODO add registration of quote instruments diff --git a/packages/js/src/plugins/psyoptionsAmericanInstrumentModule/instrument.ts b/packages/js/src/plugins/psyoptionsAmericanInstrumentModule/instrument.ts index d08ea256a..8df0292a6 100644 --- a/packages/js/src/plugins/psyoptionsAmericanInstrumentModule/instrument.ts +++ b/packages/js/src/plugins/psyoptionsAmericanInstrumentModule/instrument.ts @@ -66,8 +66,8 @@ export class PsyoptionsAmericanInstrument implements LegInstrument { readonly baseAssetIndex: BaseAssetIndex, readonly amount: number, readonly side: LegSide, - readonly underlyingAssetMint: PublicKey, - readonly stableAssetMint: PublicKey + readonly underlyingAssetMint?: PublicKey, + readonly stableAssetMint?: PublicKey ) {} getAmount = () => this.amount; @@ -76,6 +76,11 @@ export class PsyoptionsAmericanInstrument implements LegInstrument { getSide = () => this.side; async getPreparationsBeforeRfqCreation(): Promise { + if (!this.underlyingAssetMint) + throw Error('Underlying asset mint is not defined'); + + if (!this.stableAssetMint) throw Error('Stable asset mint is not defined'); + const optionMarketIxs = await getPsyAmericanMarketIxs( this.convergence, this.underlyingAssetMint, @@ -89,10 +94,6 @@ export class PsyoptionsAmericanInstrument implements LegInstrument { return optionMarketIxs; } - getBaseAssetMint(): PublicKey { - return this.underlyingAssetMint; - } - getExchangeAssetMint(): PublicKey { return this.optionMint; } @@ -173,6 +174,10 @@ export class PsyoptionsAmericanInstrument implements LegInstrument { } getValidationAccounts() { + if (!this.underlyingAssetMint) + throw Error('Underlying asset mint is not defined'); + if (!this.stableAssetMint) throw Error('Stable asset mint is not defined'); + const mintInfoPda = this.convergence .rfqs() .pdas() @@ -238,10 +243,10 @@ export class PsyoptionsAmericanInstrument implements LegInstrument { } export const psyoptionsAmericanInstrumentParser = { - async parseFromLeg( + parseFromLeg( convergence: Convergence, leg: Leg - ): Promise { + ): PsyoptionsAmericanInstrument { const { side, instrumentAmount, instrumentData, baseAssetIndex } = leg; const [ { @@ -258,11 +263,6 @@ export const psyoptionsAmericanInstrumentParser = { Buffer.from(instrumentData) ); - const optionMeta = await PsyoptionsAmericanInstrument.fetchMeta( - convergence, - metaKey - ); - return new PsyoptionsAmericanInstrument( convergence, optionType, @@ -278,9 +278,7 @@ export const psyoptionsAmericanInstrumentParser = { metaKey, baseAssetIndex, removeDecimals(instrumentAmount, PsyoptionsAmericanInstrument.decimals), - fromSolitaLegSide(side), - optionMeta.underlyingAssetMint, - optionMeta.quoteAssetMint + fromSolitaLegSide(side) ); }, }; diff --git a/packages/js/src/plugins/psyoptionsEuropeanInstrumentModule/instrument.ts b/packages/js/src/plugins/psyoptionsEuropeanInstrumentModule/instrument.ts index 830201e89..b63d1a772 100644 --- a/packages/js/src/plugins/psyoptionsEuropeanInstrumentModule/instrument.ts +++ b/packages/js/src/plugins/psyoptionsEuropeanInstrumentModule/instrument.ts @@ -114,9 +114,9 @@ export class PsyoptionsEuropeanInstrument implements LegInstrument { readonly baseAssetIndex: BaseAssetIndex, readonly amount: number, readonly side: LegSide, - readonly underlyingAssetMint: PublicKey, - readonly stableAssetMint: PublicKey, - readonly oracleAddress: PublicKey + readonly underlyingAssetMint?: PublicKey, + readonly stableAssetMint?: PublicKey, + readonly oracleAddress?: PublicKey ) {} getBaseAssetIndex = () => this.baseAssetIndex; @@ -124,6 +124,15 @@ export class PsyoptionsEuropeanInstrument implements LegInstrument { getDecimals = () => PsyoptionsEuropeanInstrument.decimals; getSide = () => this.side; async getPreparationsBeforeRfqCreation(): Promise { + if (!this.underlyingAssetMint) { + throw Error('Underlying asset mint is undefined'); + } + if (!this.stableAssetMint) { + throw Error('Stable asset mint is undefined'); + } + if (!this.oracleAddress) { + throw Error('Oracle address is undefined'); + } const optionMarketIxs = await getPsyEuropeanMarketIxs( this.convergence, this.underlyingAssetMint, @@ -142,9 +151,6 @@ export class PsyoptionsEuropeanInstrument implements LegInstrument { getExchangeAssetMint(): PublicKey { return this.optionMint; } - getBaseAssetMint(): PublicKey { - return this.underlyingAssetMint; - } static async create( convergence: Convergence, @@ -211,6 +217,8 @@ export class PsyoptionsEuropeanInstrument implements LegInstrument { /** Helper method to get validation accounts for a Psyoptions European instrument. */ getValidationAccounts() { + if (!this.underlyingAssetMint) + throw Error('Underlying asset mint is undefined'); return [ { pubkey: this.getProgramId(), @@ -274,10 +282,10 @@ export class PsyoptionsEuropeanInstrument implements LegInstrument { } export const psyoptionsEuropeanInstrumentParser = { - async parseFromLeg( + parseFromLeg( convergence: Convergence, leg: Leg - ): Promise { + ): PsyoptionsEuropeanInstrument { const { side, instrumentAmount, instrumentData, baseAssetIndex } = leg; const [ { @@ -294,11 +302,6 @@ export const psyoptionsEuropeanInstrumentParser = { Buffer.from(instrumentData) ); - const optionMeta = await PsyoptionsEuropeanInstrument.fetchMeta( - convergence, - metaKey - ); - return new PsyoptionsEuropeanInstrument( convergence, optionType, @@ -314,10 +317,7 @@ export const psyoptionsEuropeanInstrumentParser = { metaKey, baseAssetIndex, removeDecimals(instrumentAmount, PsyoptionsEuropeanInstrument.decimals), - fromSolitaLegSide(side), - optionMeta.underlyingMint, - optionMeta.stableMint, - optionMeta.oracle + fromSolitaLegSide(side) ); }, }; diff --git a/packages/js/src/plugins/rfqModule/models/Rfq.ts b/packages/js/src/plugins/rfqModule/models/Rfq.ts index 80cb679d9..92ba8aa03 100644 --- a/packages/js/src/plugins/rfqModule/models/Rfq.ts +++ b/packages/js/src/plugins/rfqModule/models/Rfq.ts @@ -104,13 +104,9 @@ export const toRfq = async ( ); const collateralMint = await collateralMintCache.get(convergence); const collateralDecimals = collateralMint.decimals; - - const legs: LegInstrument[] = []; - - for (const leg of account.data.legs) { - const legInstrument = await convergence.parseLegInstrument(leg); - legs.push(legInstrument); - } + const legs = account.data.legs.map((leg) => + convergence.parseLegInstrument(leg) + ); return { model: 'rfq', diff --git a/packages/js/src/plugins/spotInstrumentModule/instruments.ts b/packages/js/src/plugins/spotInstrumentModule/instruments.ts index e0de245f5..e3dd54856 100644 --- a/packages/js/src/plugins/spotInstrumentModule/instruments.ts +++ b/packages/js/src/plugins/spotInstrumentModule/instruments.ts @@ -49,9 +49,6 @@ export class SpotLegInstrument implements LegInstrument { async getPreparationsBeforeRfqCreation(): Promise { return []; } - getBaseAssetMint(): PublicKey { - return this.mintAddress; - } getExchangeAssetMint(): PublicKey { return this.mintAddress;