import { bignum } from '@metaplex-foundation/beet' import { Commitment, Connection, GetAccountInfoConfig, PublicKey, TransactionInstruction } from '@solana/web3.js' import { PriceFeedPDADeriver } from './pda-deriver' import * as accounts from '../generated/solita/pricefeed/accounts' import * as instructions from '../generated/solita/pricefeed/instructions' import * as types from '../generated/solita/pricefeed/types' export { accounts, instructions, types } export { PROGRAM_ID } from '../generated/solita/pricefeed' /** * Class representing the PriceFeed. */ export class PriceFeed { deriver: PriceFeedPDADeriver /** * Creates an instance of the PriceFeed class. * * @param {PublicKey} program - The public key of the program. */ constructor(public readonly program: PublicKey) { this.deriver = new PriceFeedPDADeriver(this.program) } /** * Initializes the price feed. * * @param {Connection} connection - The Solana connection object. * @param {PublicKey} payer - The public key of the payer. * @param {PublicKey} admin - The public key of the admin. * @param {PublicKey[]} updaters - The list of public keys of the updaters. * @param {Commitment | GetAccountInfoConfig} [commitmentOrConfig] - Optional commitment or configuration. * * @returns {Promise} The transaction instruction. */ async initPriceFeed( connection: Connection, payer: PublicKey, admin: PublicKey, updaters: PublicKey[], commitmentOrConfig?: Commitment | GetAccountInfoConfig ): Promise { const [priceFeed] = this.deriver.priceFeed() const info = await connection.getAccountInfo(priceFeed, commitmentOrConfig) if (info) { throw new Error('Pricefeed already initialized') } return instructions.createInitPriceFeedInstruction( { payer, priceFeed, } satisfies instructions.InitPriceFeedInstructionAccounts, { params: { admin, updaters, } satisfies types.InitPriceFeedParams, } satisfies instructions.InitPriceFeedInstructionArgs, this.program ) } /** * Sets the price feed. * * @param {PublicKey} admin - The public key of the admin. * @param {PublicKey[]} updaters - The list of public keys of the updaters. * @param {bignum} priceRatioDenominator - The price ratio denominator. * @param {number} arbitrumCompressionPercent - The Arbitrum compression percentage. * * @returns {TransactionInstruction} The transaction instruction. */ setPriceFeed( admin: PublicKey, updaters: PublicKey[], priceRatioDenominator: bignum, arbitrumCompressionPercent: number ): TransactionInstruction { const [priceFeed] = this.deriver.priceFeed() return instructions.createSetPriceFeedInstruction( { admin, priceFeed, } satisfies instructions.SetPriceFeedInstructionAccounts, { params: { updaters, priceRatioDenominator, arbitrumCompressionPercent, } satisfies types.SetPriceFeedParams, } satisfies instructions.SetPriceFeedInstructionArgs, this.program ) } /** * Sets the price. * * @param {PublicKey} updater - The public key of the updater. * @param {number} dstEid - The destination EID. * @param {bignum} priceRatio - The price ratio. * @param {bignum} gasPriceInUnit - The gas price in unit. * @param {number} gasPerByte - The gas per byte. * @param {types.ModelType | null} modelType - The model type. * * @returns {TransactionInstruction} The transaction instruction. */ setPrice( updater: PublicKey, dstEid: number, priceRatio: bignum, gasPriceInUnit: bignum, gasPerByte: number, modelType: types.ModelType | null ): TransactionInstruction { const EID_MODULUS = 30000 dstEid = dstEid % EID_MODULUS const [priceFeed] = this.deriver.priceFeed() return instructions.createSetPriceInstruction( { updater, priceFeed, } satisfies instructions.SetPriceInstructionAccounts, { params: { dstEid, params: { priceRatio, gasPriceInUnit, gasPerByte, modelType, }, } satisfies types.SetPriceParams, } satisfies instructions.SetPriceInstructionArgs, this.program ) } /** * Sets the SOL price. * * @param {PublicKey} updater - The public key of the updater. * @param {bignum | null} nativeTokenPriceUsd - The native token price in USD. * * @returns {TransactionInstruction} The transaction instruction. */ setSolPrice(updater: PublicKey, nativeTokenPriceUsd: bignum | null): TransactionInstruction { const [priceFeed] = this.deriver.priceFeed() return instructions.createSetSolPriceInstruction( { priceFeed, updater, } satisfies instructions.SetSolPriceInstructionAccounts, { params: { nativeTokenPriceUsd, } satisfies types.SetSolPriceParams, } satisfies instructions.SetSolPriceInstructionArgs, this.program ) } /** * Transfers the admin role. * * @param {PublicKey} admin - The public key of the current admin. * @param {PublicKey} newAdmin - The public key of the new admin. * * @returns {TransactionInstruction} The transaction instruction. */ transferAdmin(admin: PublicKey, newAdmin: PublicKey): TransactionInstruction { const [priceFeed] = this.deriver.priceFeed() return instructions.createTransferAdminInstruction( { admin, priceFeed, } satisfies instructions.TransferAdminInstructionAccounts, { params: { admin: newAdmin, } satisfies types.TransferAdminParams, } satisfies instructions.TransferAdminInstructionArgs, this.program ) } /** * Retrieves the price feed account. * * @param {Connection} connection - The Solana connection object. * @param {Commitment | GetAccountInfoConfig} [commitmentOrConfig] - Optional commitment or configuration. * * @returns {Promise} The price feed account or null if not found. */ async getPriceFeed( connection: Connection, commitmentOrConfig?: Commitment | GetAccountInfoConfig ): Promise { const [priceFeed] = this.deriver.priceFeed() try { return await accounts.PriceFeed.fromAccountAddress(connection, priceFeed, commitmentOrConfig) } catch (e) { return null } } }