-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Sdk 331 account management should be moved to instruments #246
Changes from 15 commits
ac27352
d196d8c
96a5c5e
d369a61
0a26c64
007cf27
f8f7475
3407b44
9e75249
4c363cd
4383e1c
a8a7e0b
8c9ab30
58924b1
f187994
a11d32b
4032b90
b5c7ebf
2b58be9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,86 +1,21 @@ | ||
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 { 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 { | ||
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) { | ||
return serializeAsLeg(legInstrument).length; | ||
} | ||
|
||
export function getProgramAccount(legInstrument: LegInstrument): AccountMeta { | ||
return { | ||
pubkey: legInstrument.getProgramId(), | ||
isSigner: false, | ||
isWritable: false, | ||
}; | ||
} | ||
|
||
export function getValidationAccounts( | ||
legInstrument: LegInstrument | ||
): AccountMeta[] { | ||
return [getProgramAccount(legInstrument)].concat( | ||
legInstrument.getValidationAccounts() | ||
); | ||
} | ||
|
||
export function toQuote(legInstrument: QuoteInstrument): QuoteAsset { | ||
return { | ||
instrumentProgram: legInstrument.getProgramId(), | ||
instrumentData: legInstrument.serializeInstrumentData(), | ||
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!'); | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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<LegInstrument>; | ||
} | ||
|
||
export type CreateOptionInstrumentsResult = TransactionInstruction[]; | ||
|
@@ -18,8 +18,13 @@ export interface LegInstrument { | |
getDecimals: () => number; | ||
getSide: () => LegSide; | ||
serializeInstrumentData: () => Buffer; | ||
getBaseAssetMint(): PublicKey; | ||
getBaseAssetAccount(): AccountMeta; | ||
getOracleAccount(): Promise<AccountMeta>; | ||
getValidationAccounts(): AccountMeta[]; | ||
getPreparationsBeforeRfqCreation(): Promise<CreateOptionInstrumentsResult>; | ||
getUnderlyingBaseAssetMint(): PublicKey; | ||
toLeg(): Leg; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A lot of those method are option-specific, but not generic. For example, they can be confusing when applied to spot instrument, rename getUnderlyingBaseAssetMint |
||
} | ||
|
||
// TODO add registration of quote instruments | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,9 @@ | ||
import { Keypair, PublicKey, TransactionInstruction } from '@solana/web3.js'; | ||
import { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. File |
||
AccountMeta, | ||
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'; | ||
|
@@ -15,7 +20,11 @@ import { | |
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, | ||
|
@@ -66,14 +75,25 @@ 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 | ||
) {} | ||
|
||
getBaseAssetIndex = () => this.baseAssetIndex; | ||
getAmount = () => this.amount; | ||
getBaseAssetIndex = () => this.baseAssetIndex; | ||
getDecimals = () => PsyoptionsAmericanInstrument.decimals; | ||
getSide = () => this.side; | ||
toLeg(): Leg { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similar blocks of code found in 3 locations. Consider refactoring. |
||
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<CreateOptionInstrumentsResult> { | ||
if (!this.underlyingAssetMint) { | ||
throw new Error('Missing underlying asset mint'); | ||
|
@@ -94,6 +114,48 @@ export class PsyoptionsAmericanInstrument implements LegInstrument { | |
); | ||
return optionMarketIxs; | ||
} | ||
getBaseAssetAccount(): AccountMeta { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similar blocks of code found in 3 locations. Consider refactoring. |
||
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<AccountMeta> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Similar blocks of code found in 3 locations. Consider refactoring. |
||
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, | ||
|
@@ -186,6 +248,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, | ||
|
@@ -237,10 +304,10 @@ export class PsyoptionsAmericanInstrument implements LegInstrument { | |
} | ||
|
||
export const psyoptionsAmericanInstrumentParser = { | ||
parseFromLeg( | ||
async parseFromLeg( | ||
convergence: Convergence, | ||
leg: Leg | ||
): PsyoptionsAmericanInstrument { | ||
): Promise<PsyoptionsAmericanInstrument> { | ||
const { side, instrumentAmount, instrumentData, baseAssetIndex } = leg; | ||
const [ | ||
{ | ||
|
@@ -257,6 +324,11 @@ export const psyoptionsAmericanInstrumentParser = { | |
Buffer.from(instrumentData) | ||
); | ||
|
||
const optionMeta = await PsyoptionsAmericanInstrument.fetchMeta( | ||
convergence, | ||
metaKey | ||
); | ||
|
||
return new PsyoptionsAmericanInstrument( | ||
convergence, | ||
optionType, | ||
|
@@ -272,7 +344,9 @@ export const psyoptionsAmericanInstrumentParser = { | |
metaKey, | ||
baseAssetIndex, | ||
removeDecimals(instrumentAmount, PsyoptionsAmericanInstrument.decimals), | ||
fromSolitaLegSide(side) | ||
fromSolitaLegSide(side), | ||
optionMeta.underlyingAssetMint, | ||
optionMeta.quoteAssetMint | ||
); | ||
}, | ||
}; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why to move this logic to the instrument interface? The logic in each instrument is the same and is a clone of this logic