UNPKG

@drift-labs/sdk

Version:
1,909 lines (1,663 loc) • 122 kB
import { PublicKey, SystemProgram, SYSVAR_RENT_PUBKEY, TransactionInstruction, TransactionSignature, } from '@solana/web3.js'; import { FeeStructure, OracleGuardRails, OracleSource, ExchangeStatus, MarketStatus, ContractTier, AssetTier, SpotFulfillmentConfigStatus, IfRebalanceConfigParams, } from './types'; import { DEFAULT_MARKET_NAME, encodeName } from './userName'; import { BN } from '@coral-xyz/anchor'; import * as anchor from '@coral-xyz/anchor'; import { getDriftStateAccountPublicKeyAndNonce, getSpotMarketPublicKey, getSpotMarketVaultPublicKey, getPerpMarketPublicKey, getInsuranceFundVaultPublicKey, getSerumOpenOrdersPublicKey, getSerumFulfillmentConfigPublicKey, getPhoenixFulfillmentConfigPublicKey, getProtocolIfSharesTransferConfigPublicKey, getPrelaunchOraclePublicKey, getOpenbookV2FulfillmentConfigPublicKey, getPythPullOraclePublicKey, getUserStatsAccountPublicKey, getHighLeverageModeConfigPublicKey, getPythLazerOraclePublicKey, getProtectedMakerModeConfigPublicKey, getFuelOverflowAccountPublicKey, getTokenProgramForSpotMarket, getIfRebalanceConfigPublicKey, } from './addresses/pda'; import { squareRootBN } from './math/utils'; import { TOKEN_PROGRAM_ID } from '@solana/spl-token'; import { DriftClient } from './driftClient'; import { PEG_PRECISION, QUOTE_SPOT_MARKET_INDEX, ZERO, ONE, BASE_PRECISION, PRICE_PRECISION, } from './constants/numericConstants'; import { calculateTargetPriceTrade } from './math/trade'; import { calculateAmmReservesAfterSwap, getSwapDirection } from './math/amm'; import { PROGRAM_ID as PHOENIX_PROGRAM_ID } from '@ellipsis-labs/phoenix-sdk'; import { DRIFT_ORACLE_RECEIVER_ID } from './config'; import { getFeedIdUint8Array } from './util/pythOracleUtils'; import { FUEL_RESET_LOG_ACCOUNT } from './constants/txConstants'; const OPENBOOK_PROGRAM_ID = new PublicKey( 'opnb2LAfJYbRMAHHvqjCwQxanZn7ReEHp1k81EohpZb' ); export class AdminClient extends DriftClient { public async initialize( usdcMint: PublicKey, _adminControlsPrices: boolean ): Promise<[TransactionSignature]> { const stateAccountRPCResponse = await this.connection.getParsedAccountInfo( await this.getStatePublicKey() ); if (stateAccountRPCResponse.value !== null) { throw new Error('Clearing house already initialized'); } const [driftStatePublicKey] = await getDriftStateAccountPublicKeyAndNonce( this.program.programId ); const initializeIx = await this.program.instruction.initialize({ accounts: { admin: this.isSubscribed ? this.getStateAccount().admin : this.wallet.publicKey, state: driftStatePublicKey, quoteAssetMint: usdcMint, rent: SYSVAR_RENT_PUBKEY, driftSigner: this.getSignerPublicKey(), systemProgram: anchor.web3.SystemProgram.programId, tokenProgram: TOKEN_PROGRAM_ID, }, }); const tx = await this.buildTransaction(initializeIx); const { txSig } = await super.sendTransaction(tx, [], this.opts); return [txSig]; } public async initializeSpotMarket( mint: PublicKey, optimalUtilization: number, optimalRate: number, maxRate: number, oracle: PublicKey, oracleSource: OracleSource, initialAssetWeight: number, maintenanceAssetWeight: number, initialLiabilityWeight: number, maintenanceLiabilityWeight: number, imfFactor = 0, liquidatorFee = 0, ifLiquidationFee = 0, activeStatus = true, assetTier = AssetTier.COLLATERAL, scaleInitialAssetWeightStart = ZERO, withdrawGuardThreshold = ZERO, orderTickSize = ONE, orderStepSize = ONE, ifTotalFactor = 0, name = DEFAULT_MARKET_NAME, marketIndex?: number ): Promise<TransactionSignature> { const spotMarketIndex = marketIndex ?? this.getStateAccount().numberOfSpotMarkets; const initializeIx = await this.getInitializeSpotMarketIx( mint, optimalUtilization, optimalRate, maxRate, oracle, oracleSource, initialAssetWeight, maintenanceAssetWeight, initialLiabilityWeight, maintenanceLiabilityWeight, imfFactor, liquidatorFee, ifLiquidationFee, activeStatus, assetTier, scaleInitialAssetWeightStart, withdrawGuardThreshold, orderTickSize, orderStepSize, ifTotalFactor, name, marketIndex ); const tx = await this.buildTransaction(initializeIx); const { txSig } = await this.sendTransaction(tx, [], this.opts); await this.accountSubscriber.addSpotMarket(spotMarketIndex); await this.accountSubscriber.addOracle({ source: oracleSource, publicKey: oracle, }); await this.accountSubscriber.setSpotOracleMap(); return txSig; } public async getInitializeSpotMarketIx( mint: PublicKey, optimalUtilization: number, optimalRate: number, maxRate: number, oracle: PublicKey, oracleSource: OracleSource, initialAssetWeight: number, maintenanceAssetWeight: number, initialLiabilityWeight: number, maintenanceLiabilityWeight: number, imfFactor = 0, liquidatorFee = 0, ifLiquidationFee = 0, activeStatus = true, assetTier = AssetTier.COLLATERAL, scaleInitialAssetWeightStart = ZERO, withdrawGuardThreshold = ZERO, orderTickSize = ONE, orderStepSize = ONE, ifTotalFactor = 0, name = DEFAULT_MARKET_NAME, marketIndex?: number ): Promise<TransactionInstruction> { const spotMarketIndex = marketIndex ?? this.getStateAccount().numberOfSpotMarkets; const spotMarket = await getSpotMarketPublicKey( this.program.programId, spotMarketIndex ); const spotMarketVault = await getSpotMarketVaultPublicKey( this.program.programId, spotMarketIndex ); const insuranceFundVault = await getInsuranceFundVaultPublicKey( this.program.programId, spotMarketIndex ); const tokenProgram = (await this.connection.getAccountInfo(mint)).owner; const nameBuffer = encodeName(name); const initializeIx = await this.program.instruction.initializeSpotMarket( optimalUtilization, optimalRate, maxRate, oracleSource, initialAssetWeight, maintenanceAssetWeight, initialLiabilityWeight, maintenanceLiabilityWeight, imfFactor, liquidatorFee, ifLiquidationFee, activeStatus, assetTier, scaleInitialAssetWeightStart, withdrawGuardThreshold, orderTickSize, orderStepSize, ifTotalFactor, nameBuffer, { accounts: { admin: this.isSubscribed ? this.getStateAccount().admin : this.wallet.publicKey, state: await this.getStatePublicKey(), spotMarket, spotMarketVault, insuranceFundVault, driftSigner: this.getSignerPublicKey(), spotMarketMint: mint, oracle, rent: SYSVAR_RENT_PUBKEY, systemProgram: anchor.web3.SystemProgram.programId, tokenProgram, }, } ); return initializeIx; } public async deleteInitializedSpotMarket( marketIndex: number ): Promise<TransactionSignature> { const deleteInitializeMarketIx = await this.getDeleteInitializedSpotMarketIx(marketIndex); const tx = await this.buildTransaction(deleteInitializeMarketIx); const { txSig } = await this.sendTransaction(tx, [], this.opts); return txSig; } public async getDeleteInitializedSpotMarketIx( marketIndex: number ): Promise<TransactionInstruction> { const spotMarketPublicKey = await getSpotMarketPublicKey( this.program.programId, marketIndex ); const spotMarketVaultPublicKey = await getSpotMarketVaultPublicKey( this.program.programId, marketIndex ); const insuranceFundVaultPublicKey = await getInsuranceFundVaultPublicKey( this.program.programId, marketIndex ); return await this.program.instruction.deleteInitializedSpotMarket( marketIndex, { accounts: { state: await this.getStatePublicKey(), admin: this.isSubscribed ? this.getStateAccount().admin : this.wallet.publicKey, spotMarket: spotMarketPublicKey, spotMarketVault: spotMarketVaultPublicKey, insuranceFundVault: insuranceFundVaultPublicKey, driftSigner: this.getSignerPublicKey(), tokenProgram: TOKEN_PROGRAM_ID, }, } ); } public async initializeSerumFulfillmentConfig( marketIndex: number, serumMarket: PublicKey, serumProgram: PublicKey ): Promise<TransactionSignature> { const initializeIx = await this.getInitializeSerumFulfillmentConfigIx( marketIndex, serumMarket, serumProgram ); const tx = await this.buildTransaction(initializeIx); const { txSig } = await this.sendTransaction(tx, [], this.opts); return txSig; } public async getInitializeSerumFulfillmentConfigIx( marketIndex: number, serumMarket: PublicKey, serumProgram: PublicKey ): Promise<TransactionInstruction> { const serumOpenOrders = getSerumOpenOrdersPublicKey( this.program.programId, serumMarket ); const serumFulfillmentConfig = getSerumFulfillmentConfigPublicKey( this.program.programId, serumMarket ); return await this.program.instruction.initializeSerumFulfillmentConfig( marketIndex, { accounts: { admin: this.isSubscribed ? this.getStateAccount().admin : this.wallet.publicKey, state: await this.getStatePublicKey(), baseSpotMarket: this.getSpotMarketAccount(marketIndex).pubkey, quoteSpotMarket: this.getQuoteSpotMarketAccount().pubkey, driftSigner: this.getSignerPublicKey(), serumProgram, serumMarket, serumOpenOrders, rent: SYSVAR_RENT_PUBKEY, systemProgram: anchor.web3.SystemProgram.programId, serumFulfillmentConfig, }, } ); } public async initializePhoenixFulfillmentConfig( marketIndex: number, phoenixMarket: PublicKey ): Promise<TransactionSignature> { const initializeIx = await this.getInitializePhoenixFulfillmentConfigIx( marketIndex, phoenixMarket ); const tx = await this.buildTransaction(initializeIx); const { txSig } = await this.sendTransaction(tx, [], this.opts); return txSig; } public async getInitializePhoenixFulfillmentConfigIx( marketIndex: number, phoenixMarket: PublicKey ): Promise<TransactionInstruction> { const phoenixFulfillmentConfig = getPhoenixFulfillmentConfigPublicKey( this.program.programId, phoenixMarket ); return await this.program.instruction.initializePhoenixFulfillmentConfig( marketIndex, { accounts: { admin: this.isSubscribed ? this.getStateAccount().admin : this.wallet.publicKey, state: await this.getStatePublicKey(), baseSpotMarket: this.getSpotMarketAccount(marketIndex).pubkey, quoteSpotMarket: this.getQuoteSpotMarketAccount().pubkey, driftSigner: this.getSignerPublicKey(), phoenixMarket: phoenixMarket, phoenixProgram: PHOENIX_PROGRAM_ID, rent: SYSVAR_RENT_PUBKEY, systemProgram: anchor.web3.SystemProgram.programId, phoenixFulfillmentConfig, }, } ); } public async initializeOpenbookV2FulfillmentConfig( marketIndex: number, openbookMarket: PublicKey ): Promise<TransactionSignature> { const initializeIx = await this.getInitializeOpenbookV2FulfillmentConfigIx( marketIndex, openbookMarket ); const tx = await this.buildTransaction(initializeIx); const { txSig } = await this.sendTransaction(tx, [], this.opts); return txSig; } public async getInitializeOpenbookV2FulfillmentConfigIx( marketIndex: number, openbookMarket: PublicKey ): Promise<TransactionInstruction> { const openbookFulfillmentConfig = getOpenbookV2FulfillmentConfigPublicKey( this.program.programId, openbookMarket ); return this.program.instruction.initializeOpenbookV2FulfillmentConfig( marketIndex, { accounts: { baseSpotMarket: this.getSpotMarketAccount(marketIndex).pubkey, quoteSpotMarket: this.getQuoteSpotMarketAccount().pubkey, state: await this.getStatePublicKey(), openbookV2Program: OPENBOOK_PROGRAM_ID, openbookV2Market: openbookMarket, driftSigner: this.getSignerPublicKey(), openbookV2FulfillmentConfig: openbookFulfillmentConfig, admin: this.isSubscribed ? this.getStateAccount().admin : this.wallet.publicKey, rent: SYSVAR_RENT_PUBKEY, systemProgram: anchor.web3.SystemProgram.programId, }, } ); } public async initializePerpMarket( marketIndex: number, priceOracle: PublicKey, baseAssetReserve: BN, quoteAssetReserve: BN, periodicity: BN, pegMultiplier: BN = PEG_PRECISION, oracleSource: OracleSource = OracleSource.PYTH, contractTier: ContractTier = ContractTier.SPECULATIVE, marginRatioInitial = 2000, marginRatioMaintenance = 500, liquidatorFee = 0, ifLiquidatorFee = 10000, imfFactor = 0, activeStatus = true, baseSpread = 0, maxSpread = 142500, maxOpenInterest = ZERO, maxRevenueWithdrawPerPeriod = ZERO, quoteMaxInsurance = ZERO, orderStepSize = BASE_PRECISION.divn(10000), orderTickSize = PRICE_PRECISION.divn(100000), minOrderSize = BASE_PRECISION.divn(10000), concentrationCoefScale = ONE, curveUpdateIntensity = 0, ammJitIntensity = 0, name = DEFAULT_MARKET_NAME ): Promise<TransactionSignature> { const currentPerpMarketIndex = this.getStateAccount().numberOfMarkets; const initializeMarketIx = await this.getInitializePerpMarketIx( marketIndex, priceOracle, baseAssetReserve, quoteAssetReserve, periodicity, pegMultiplier, oracleSource, contractTier, marginRatioInitial, marginRatioMaintenance, liquidatorFee, ifLiquidatorFee, imfFactor, activeStatus, baseSpread, maxSpread, maxOpenInterest, maxRevenueWithdrawPerPeriod, quoteMaxInsurance, orderStepSize, orderTickSize, minOrderSize, concentrationCoefScale, curveUpdateIntensity, ammJitIntensity, name ); const tx = await this.buildTransaction(initializeMarketIx); const { txSig } = await this.sendTransaction(tx, [], this.opts); while (this.getStateAccount().numberOfMarkets <= currentPerpMarketIndex) { await this.fetchAccounts(); } await this.accountSubscriber.addPerpMarket(marketIndex); await this.accountSubscriber.addOracle({ source: oracleSource, publicKey: priceOracle, }); await this.accountSubscriber.setPerpOracleMap(); return txSig; } public async getInitializePerpMarketIx( marketIndex: number, priceOracle: PublicKey, baseAssetReserve: BN, quoteAssetReserve: BN, periodicity: BN, pegMultiplier: BN = PEG_PRECISION, oracleSource: OracleSource = OracleSource.PYTH, contractTier: ContractTier = ContractTier.SPECULATIVE, marginRatioInitial = 2000, marginRatioMaintenance = 500, liquidatorFee = 0, ifLiquidatorFee = 10000, imfFactor = 0, activeStatus = true, baseSpread = 0, maxSpread = 142500, maxOpenInterest = ZERO, maxRevenueWithdrawPerPeriod = ZERO, quoteMaxInsurance = ZERO, orderStepSize = BASE_PRECISION.divn(10000), orderTickSize = PRICE_PRECISION.divn(100000), minOrderSize = BASE_PRECISION.divn(10000), concentrationCoefScale = ONE, curveUpdateIntensity = 0, ammJitIntensity = 0, name = DEFAULT_MARKET_NAME ): Promise<TransactionInstruction> { const perpMarketPublicKey = await getPerpMarketPublicKey( this.program.programId, marketIndex ); const nameBuffer = encodeName(name); return await this.program.instruction.initializePerpMarket( marketIndex, baseAssetReserve, quoteAssetReserve, periodicity, pegMultiplier, oracleSource, contractTier, marginRatioInitial, marginRatioMaintenance, liquidatorFee, ifLiquidatorFee, imfFactor, activeStatus, baseSpread, maxSpread, maxOpenInterest, maxRevenueWithdrawPerPeriod, quoteMaxInsurance, orderStepSize, orderTickSize, minOrderSize, concentrationCoefScale, curveUpdateIntensity, ammJitIntensity, nameBuffer, { accounts: { state: await this.getStatePublicKey(), admin: this.isSubscribed ? this.getStateAccount().admin : this.wallet.publicKey, oracle: priceOracle, perpMarket: perpMarketPublicKey, rent: SYSVAR_RENT_PUBKEY, systemProgram: anchor.web3.SystemProgram.programId, }, } ); } public async initializePredictionMarket( perpMarketIndex: number ): Promise<TransactionSignature> { const updatePerpMarketConcentrationCoefIx = await this.getInitializePredictionMarketIx(perpMarketIndex); const tx = await this.buildTransaction(updatePerpMarketConcentrationCoefIx); const { txSig } = await this.sendTransaction(tx, [], this.opts); return txSig; } public async getInitializePredictionMarketIx( perpMarketIndex: number ): Promise<TransactionInstruction> { return await this.program.instruction.initializePredictionMarket({ accounts: { state: await this.getStatePublicKey(), admin: this.isSubscribed ? this.getStateAccount().admin : this.wallet.publicKey, perpMarket: await getPerpMarketPublicKey( this.program.programId, perpMarketIndex ), }, }); } public async deleteInitializedPerpMarket( marketIndex: number ): Promise<TransactionSignature> { const deleteInitializeMarketIx = await this.getDeleteInitializedPerpMarketIx(marketIndex); const tx = await this.buildTransaction(deleteInitializeMarketIx); const { txSig } = await this.sendTransaction(tx, [], this.opts); return txSig; } public async getDeleteInitializedPerpMarketIx( marketIndex: number ): Promise<TransactionInstruction> { const perpMarketPublicKey = await getPerpMarketPublicKey( this.program.programId, marketIndex ); return await this.program.instruction.deleteInitializedPerpMarket( marketIndex, { accounts: { state: await this.getStatePublicKey(), admin: this.isSubscribed ? this.getStateAccount().admin : this.wallet.publicKey, perpMarket: perpMarketPublicKey, }, } ); } public async moveAmmPrice( perpMarketIndex: number, baseAssetReserve: BN, quoteAssetReserve: BN, sqrtK?: BN ): Promise<TransactionSignature> { const moveAmmPriceIx = await this.getMoveAmmPriceIx( perpMarketIndex, baseAssetReserve, quoteAssetReserve, sqrtK ); const tx = await this.buildTransaction(moveAmmPriceIx); const { txSig } = await this.sendTransaction(tx, [], this.opts); return txSig; } public async getMoveAmmPriceIx( perpMarketIndex: number, baseAssetReserve: BN, quoteAssetReserve: BN, sqrtK?: BN ): Promise<TransactionInstruction> { const marketPublicKey = await getPerpMarketPublicKey( this.program.programId, perpMarketIndex ); if (sqrtK == undefined) { sqrtK = squareRootBN(baseAssetReserve.mul(quoteAssetReserve)); } return await this.program.instruction.moveAmmPrice( baseAssetReserve, quoteAssetReserve, sqrtK, { accounts: { state: await this.getStatePublicKey(), admin: this.isSubscribed ? this.getStateAccount().admin : this.wallet.publicKey, perpMarket: marketPublicKey, }, } ); } public async updateK( perpMarketIndex: number, sqrtK: BN ): Promise<TransactionSignature> { const updateKIx = await this.getUpdateKIx(perpMarketIndex, sqrtK); const tx = await this.buildTransaction(updateKIx); const { txSig } = await this.sendTransaction(tx, [], this.opts); return txSig; } public async getUpdateKIx( perpMarketIndex: number, sqrtK: BN ): Promise<TransactionInstruction> { return await this.program.instruction.updateK(sqrtK, { accounts: { state: await this.getStatePublicKey(), admin: this.isSubscribed ? this.getStateAccount().admin : this.wallet.publicKey, perpMarket: await getPerpMarketPublicKey( this.program.programId, perpMarketIndex ), oracle: this.getPerpMarketAccount(perpMarketIndex).amm.oracle, }, }); } public async recenterPerpMarketAmm( perpMarketIndex: number, pegMultiplier: BN, sqrtK: BN ): Promise<TransactionSignature> { const recenterPerpMarketAmmIx = await this.getRecenterPerpMarketAmmIx( perpMarketIndex, pegMultiplier, sqrtK ); const tx = await this.buildTransaction(recenterPerpMarketAmmIx); const { txSig } = await this.sendTransaction(tx, [], this.opts); return txSig; } public async getRecenterPerpMarketAmmIx( perpMarketIndex: number, pegMultiplier: BN, sqrtK: BN ): Promise<TransactionInstruction> { const marketPublicKey = await getPerpMarketPublicKey( this.program.programId, perpMarketIndex ); return await this.program.instruction.recenterPerpMarketAmm( pegMultiplier, sqrtK, { accounts: { state: await this.getStatePublicKey(), admin: this.isSubscribed ? this.getStateAccount().admin : this.wallet.publicKey, perpMarket: marketPublicKey, }, } ); } public async recenterPerpMarketAmmCrank( perpMarketIndex: number, depth?: BN ): Promise<TransactionSignature> { const recenterPerpMarketAmmIx = await this.getRecenterPerpMarketAmmCrankIx( perpMarketIndex, depth ); const tx = await this.buildTransaction(recenterPerpMarketAmmIx); const { txSig } = await this.sendTransaction(tx, [], this.opts); return txSig; } public async getRecenterPerpMarketAmmCrankIx( perpMarketIndex: number, depth: BN ): Promise<TransactionInstruction> { return await this.program.instruction.recenterPerpMarketAmmCrank( depth ?? null, { accounts: { admin: this.useHotWalletAdmin ? this.wallet.publicKey : this.getStateAccount().admin, state: await this.getStatePublicKey(), perpMarket: await getPerpMarketPublicKey( this.program.programId, perpMarketIndex ), spotMarket: await getSpotMarketPublicKey( this.program.programId, QUOTE_SPOT_MARKET_INDEX ), oracle: this.getPerpMarketAccount(perpMarketIndex).amm.oracle, }, } ); } public async updatePerpMarketConcentrationScale( perpMarketIndex: number, concentrationScale: BN ): Promise<TransactionSignature> { const updatePerpMarketConcentrationCoefIx = await this.getUpdatePerpMarketConcentrationScaleIx( perpMarketIndex, concentrationScale ); const tx = await this.buildTransaction(updatePerpMarketConcentrationCoefIx); const { txSig } = await this.sendTransaction(tx, [], this.opts); return txSig; } public async getUpdatePerpMarketConcentrationScaleIx( perpMarketIndex: number, concentrationScale: BN ): Promise<TransactionInstruction> { return await this.program.instruction.updatePerpMarketConcentrationCoef( concentrationScale, { accounts: { state: await this.getStatePublicKey(), admin: this.isSubscribed ? this.getStateAccount().admin : this.wallet.publicKey, perpMarket: await getPerpMarketPublicKey( this.program.programId, perpMarketIndex ), }, } ); } public async moveAmmToPrice( perpMarketIndex: number, targetPrice: BN ): Promise<TransactionSignature> { const moveAmmPriceIx = await this.getMoveAmmToPriceIx( perpMarketIndex, targetPrice ); const tx = await this.buildTransaction(moveAmmPriceIx); const { txSig } = await this.sendTransaction(tx, [], this.opts); return txSig; } public async getMoveAmmToPriceIx( perpMarketIndex: number, targetPrice: BN ): Promise<TransactionInstruction> { const perpMarket = this.getPerpMarketAccount(perpMarketIndex); const [direction, tradeSize, _] = calculateTargetPriceTrade( perpMarket, targetPrice, new BN(1000), 'quote', undefined //todo ); const [newQuoteAssetAmount, newBaseAssetAmount] = calculateAmmReservesAfterSwap( perpMarket.amm, 'quote', tradeSize, getSwapDirection('quote', direction) ); const perpMarketPublicKey = await getPerpMarketPublicKey( this.program.programId, perpMarketIndex ); return await this.program.instruction.moveAmmPrice( newBaseAssetAmount, newQuoteAssetAmount, perpMarket.amm.sqrtK, { accounts: { state: await this.getStatePublicKey(), admin: this.isSubscribed ? this.getStateAccount().admin : this.wallet.publicKey, perpMarket: perpMarketPublicKey, }, } ); } public async repegAmmCurve( newPeg: BN, perpMarketIndex: number ): Promise<TransactionSignature> { const repegAmmCurveIx = await this.getRepegAmmCurveIx( newPeg, perpMarketIndex ); const tx = await this.buildTransaction(repegAmmCurveIx); const { txSig } = await this.sendTransaction(tx, [], this.opts); return txSig; } public async getRepegAmmCurveIx( newPeg: BN, perpMarketIndex: number ): Promise<TransactionInstruction> { const perpMarketPublicKey = await getPerpMarketPublicKey( this.program.programId, perpMarketIndex ); const ammData = this.getPerpMarketAccount(perpMarketIndex).amm; return await this.program.instruction.repegAmmCurve(newPeg, { accounts: { state: await this.getStatePublicKey(), admin: this.isSubscribed ? this.getStateAccount().admin : this.wallet.publicKey, oracle: ammData.oracle, perpMarket: perpMarketPublicKey, }, }); } public async updatePerpMarketAmmOracleTwap( perpMarketIndex: number ): Promise<TransactionSignature> { const updatePerpMarketAmmOracleTwapIx = await this.getUpdatePerpMarketAmmOracleTwapIx(perpMarketIndex); const tx = await this.buildTransaction(updatePerpMarketAmmOracleTwapIx); const { txSig } = await this.sendTransaction(tx, [], this.opts); return txSig; } public async getUpdatePerpMarketAmmOracleTwapIx( perpMarketIndex: number ): Promise<TransactionInstruction> { const ammData = this.getPerpMarketAccount(perpMarketIndex).amm; const perpMarketPublicKey = await getPerpMarketPublicKey( this.program.programId, perpMarketIndex ); return await this.program.instruction.updatePerpMarketAmmOracleTwap({ accounts: { state: await this.getStatePublicKey(), admin: this.isSubscribed ? this.getStateAccount().admin : this.wallet.publicKey, oracle: ammData.oracle, perpMarket: perpMarketPublicKey, }, }); } public async resetPerpMarketAmmOracleTwap( perpMarketIndex: number ): Promise<TransactionSignature> { const resetPerpMarketAmmOracleTwapIx = await this.getResetPerpMarketAmmOracleTwapIx(perpMarketIndex); const tx = await this.buildTransaction(resetPerpMarketAmmOracleTwapIx); const { txSig } = await this.sendTransaction(tx, [], this.opts); return txSig; } public async getResetPerpMarketAmmOracleTwapIx( perpMarketIndex: number ): Promise<TransactionInstruction> { const ammData = this.getPerpMarketAccount(perpMarketIndex).amm; const perpMarketPublicKey = await getPerpMarketPublicKey( this.program.programId, perpMarketIndex ); return await this.program.instruction.resetPerpMarketAmmOracleTwap({ accounts: { state: await this.getStatePublicKey(), admin: this.isSubscribed ? this.getStateAccount().admin : this.wallet.publicKey, oracle: ammData.oracle, perpMarket: perpMarketPublicKey, }, }); } public async depositIntoPerpMarketFeePool( perpMarketIndex: number, amount: BN, sourceVault: PublicKey ): Promise<TransactionSignature> { const depositIntoPerpMarketFeePoolIx = await this.getDepositIntoPerpMarketFeePoolIx( perpMarketIndex, amount, sourceVault ); const tx = await this.buildTransaction(depositIntoPerpMarketFeePoolIx); const { txSig } = await this.sendTransaction(tx, [], this.opts); return txSig; } public async getDepositIntoPerpMarketFeePoolIx( perpMarketIndex: number, amount: BN, sourceVault: PublicKey ): Promise<TransactionInstruction> { const spotMarket = this.getQuoteSpotMarketAccount(); return await this.program.instruction.depositIntoPerpMarketFeePool(amount, { accounts: { admin: this.isSubscribed ? this.getStateAccount().admin : this.wallet.publicKey, state: await this.getStatePublicKey(), perpMarket: await getPerpMarketPublicKey( this.program.programId, perpMarketIndex ), sourceVault, driftSigner: this.getSignerPublicKey(), quoteSpotMarket: spotMarket.pubkey, spotMarketVault: spotMarket.vault, tokenProgram: TOKEN_PROGRAM_ID, }, }); } public async updatePerpMarketPnlPool( perpMarketIndex: number, amount: BN ): Promise<TransactionSignature> { const updatePerpMarketPnlPoolIx = await this.getUpdatePerpMarketPnlPoolIx( perpMarketIndex, amount ); const tx = await this.buildTransaction(updatePerpMarketPnlPoolIx); const { txSig } = await this.sendTransaction(tx, [], this.opts); return txSig; } public async getUpdatePerpMarketPnlPoolIx( perpMarketIndex: number, amount: BN ): Promise<TransactionInstruction> { return await this.program.instruction.updatePerpMarketPnlPool(amount, { accounts: { admin: this.isSubscribed ? this.getStateAccount().admin : this.wallet.publicKey, state: await this.getStatePublicKey(), perpMarket: await getPerpMarketPublicKey( this.program.programId, perpMarketIndex ), spotMarket: this.getQuoteSpotMarketAccount().pubkey, spotMarketVault: this.getQuoteSpotMarketAccount().vault, }, }); } public async depositIntoSpotMarketVault( spotMarketIndex: number, amount: BN, sourceVault: PublicKey ): Promise<TransactionSignature> { const depositIntoPerpMarketFeePoolIx = await this.getDepositIntoSpotMarketVaultIx( spotMarketIndex, amount, sourceVault ); const tx = await this.buildTransaction(depositIntoPerpMarketFeePoolIx); const { txSig } = await this.sendTransaction(tx, [], this.opts); return txSig; } public async getDepositIntoSpotMarketVaultIx( spotMarketIndex: number, amount: BN, sourceVault: PublicKey ): Promise<TransactionInstruction> { const spotMarket = this.getSpotMarketAccount(spotMarketIndex); const remainingAccounts = []; this.addTokenMintToRemainingAccounts(spotMarket, remainingAccounts); if (this.isTransferHook(spotMarket)) { await this.addExtraAccountMetasToRemainingAccounts( spotMarket.mint, remainingAccounts ); } const tokenProgram = this.getTokenProgramForSpotMarket(spotMarket); return await this.program.instruction.depositIntoSpotMarketVault(amount, { accounts: { admin: this.useHotWalletAdmin ? this.wallet.publicKey : this.getStateAccount().admin, state: await this.getStatePublicKey(), sourceVault, spotMarket: spotMarket.pubkey, spotMarketVault: spotMarket.vault, tokenProgram, }, remainingAccounts, }); } public async updateAdmin(admin: PublicKey): Promise<TransactionSignature> { const updateAdminIx = await this.getUpdateAdminIx(admin); const tx = await this.buildTransaction(updateAdminIx); const { txSig } = await this.sendTransaction(tx, [], this.opts); return txSig; } public async getUpdateAdminIx( admin: PublicKey ): Promise<TransactionInstruction> { return await this.program.instruction.updateAdmin(admin, { accounts: { admin: this.isSubscribed ? this.getStateAccount().admin : this.wallet.publicKey, state: await this.getStatePublicKey(), }, }); } public async updatePerpMarketCurveUpdateIntensity( perpMarketIndex: number, curveUpdateIntensity: number ): Promise<TransactionSignature> { const updatePerpMarketCurveUpdateIntensityIx = await this.getUpdatePerpMarketCurveUpdateIntensityIx( perpMarketIndex, curveUpdateIntensity ); const tx = await this.buildTransaction( updatePerpMarketCurveUpdateIntensityIx ); const { txSig } = await this.sendTransaction(tx, [], this.opts); return txSig; } public async getUpdatePerpMarketCurveUpdateIntensityIx( perpMarketIndex: number, curveUpdateIntensity: number ): Promise<TransactionInstruction> { return await this.program.instruction.updatePerpMarketCurveUpdateIntensity( curveUpdateIntensity, { accounts: { admin: this.useHotWalletAdmin ? this.wallet.publicKey : this.getStateAccount().admin, state: await this.getStatePublicKey(), perpMarket: await getPerpMarketPublicKey( this.program.programId, perpMarketIndex ), }, } ); } public async updatePerpMarketTargetBaseAssetAmountPerLp( perpMarketIndex: number, targetBaseAssetAmountPerLP: number ): Promise<TransactionSignature> { const updatePerpMarketTargetBaseAssetAmountPerLpIx = await this.getUpdatePerpMarketTargetBaseAssetAmountPerLpIx( perpMarketIndex, targetBaseAssetAmountPerLP ); const tx = await this.buildTransaction( updatePerpMarketTargetBaseAssetAmountPerLpIx ); const { txSig } = await this.sendTransaction(tx, [], this.opts); return txSig; } public async updatePerpMarketAmmSummaryStats( perpMarketIndex: number, updateAmmSummaryStats?: boolean, quoteAssetAmountWithUnsettledLp?: BN, netUnsettledFundingPnl?: BN, excludeTotalLiqFee?: boolean ): Promise<TransactionSignature> { const updatePerpMarketMarginRatioIx = await this.getUpdatePerpMarketAmmSummaryStatsIx( perpMarketIndex, updateAmmSummaryStats, quoteAssetAmountWithUnsettledLp, netUnsettledFundingPnl, excludeTotalLiqFee ); const tx = await this.buildTransaction(updatePerpMarketMarginRatioIx); const { txSig } = await this.sendTransaction(tx, [], this.opts); return txSig; } public async getUpdatePerpMarketAmmSummaryStatsIx( perpMarketIndex: number, updateAmmSummaryStats?: boolean, quoteAssetAmountWithUnsettledLp?: BN, netUnsettledFundingPnl?: BN, excludeTotalLiqFee?: boolean ): Promise<TransactionInstruction> { return await this.program.instruction.updatePerpMarketAmmSummaryStats( { updateAmmSummaryStats: updateAmmSummaryStats ?? null, quoteAssetAmountWithUnsettledLp: quoteAssetAmountWithUnsettledLp ?? null, netUnsettledFundingPnl: netUnsettledFundingPnl ?? null, excludeTotalLiqFee: excludeTotalLiqFee ?? null, }, { accounts: { admin: this.useHotWalletAdmin ? this.wallet.publicKey : this.getStateAccount().admin, state: await this.getStatePublicKey(), perpMarket: await getPerpMarketPublicKey( this.program.programId, perpMarketIndex ), spotMarket: await getSpotMarketPublicKey( this.program.programId, QUOTE_SPOT_MARKET_INDEX ), oracle: this.getPerpMarketAccount(perpMarketIndex).amm.oracle, }, } ); } public async getUpdatePerpMarketTargetBaseAssetAmountPerLpIx( perpMarketIndex: number, targetBaseAssetAmountPerLP: number ): Promise<TransactionInstruction> { return await this.program.instruction.updatePerpMarketTargetBaseAssetAmountPerLp( targetBaseAssetAmountPerLP, { accounts: { admin: this.isSubscribed ? this.getStateAccount().admin : this.wallet.publicKey, state: await this.getStatePublicKey(), perpMarket: await getPerpMarketPublicKey( this.program.programId, perpMarketIndex ), }, } ); } public async updatePerpMarketMarginRatio( perpMarketIndex: number, marginRatioInitial: number, marginRatioMaintenance: number ): Promise<TransactionSignature> { const updatePerpMarketMarginRatioIx = await this.getUpdatePerpMarketMarginRatioIx( perpMarketIndex, marginRatioInitial, marginRatioMaintenance ); const tx = await this.buildTransaction(updatePerpMarketMarginRatioIx); const { txSig } = await this.sendTransaction(tx, [], this.opts); return txSig; } public async getUpdatePerpMarketMarginRatioIx( perpMarketIndex: number, marginRatioInitial: number, marginRatioMaintenance: number ): Promise<TransactionInstruction> { return await this.program.instruction.updatePerpMarketMarginRatio( marginRatioInitial, marginRatioMaintenance, { accounts: { admin: this.isSubscribed ? this.getStateAccount().admin : this.wallet.publicKey, state: await this.getStatePublicKey(), perpMarket: await getPerpMarketPublicKey( this.program.programId, perpMarketIndex ), }, } ); } public async updatePerpMarketHighLeverageMarginRatio( perpMarketIndex: number, marginRatioInitial: number, marginRatioMaintenance: number ): Promise<TransactionSignature> { const updatePerpMarketHighLeverageMarginRatioIx = await this.getUpdatePerpMarketHighLeverageMarginRatioIx( perpMarketIndex, marginRatioInitial, marginRatioMaintenance ); const tx = await this.buildTransaction( updatePerpMarketHighLeverageMarginRatioIx ); const { txSig } = await this.sendTransaction(tx, [], this.opts); return txSig; } public async getUpdatePerpMarketHighLeverageMarginRatioIx( perpMarketIndex: number, marginRatioInitial: number, marginRatioMaintenance: number ): Promise<TransactionInstruction> { return await this.program.instruction.updatePerpMarketHighLeverageMarginRatio( marginRatioInitial, marginRatioMaintenance, { accounts: { admin: this.isSubscribed ? this.getStateAccount().admin : this.wallet.publicKey, state: await this.getStatePublicKey(), perpMarket: await getPerpMarketPublicKey( this.program.programId, perpMarketIndex ), }, } ); } public async updatePerpMarketImfFactor( perpMarketIndex: number, imfFactor: number, unrealizedPnlImfFactor: number ): Promise<TransactionSignature> { const updatePerpMarketImfFactorIx = await this.getUpdatePerpMarketImfFactorIx( perpMarketIndex, imfFactor, unrealizedPnlImfFactor ); const tx = await this.buildTransaction(updatePerpMarketImfFactorIx); const { txSig } = await this.sendTransaction(tx, [], this.opts); return txSig; } public async getUpdatePerpMarketImfFactorIx( perpMarketIndex: number, imfFactor: number, unrealizedPnlImfFactor: number ): Promise<TransactionInstruction> { return await this.program.instruction.updatePerpMarketImfFactor( imfFactor, unrealizedPnlImfFactor, { accounts: { admin: this.isSubscribed ? this.getStateAccount().admin : this.wallet.publicKey, state: await this.getStatePublicKey(), perpMarket: await getPerpMarketPublicKey( this.program.programId, perpMarketIndex ), }, } ); } public async updatePerpMarketBaseSpread( perpMarketIndex: number, baseSpread: number ): Promise<TransactionSignature> { const updatePerpMarketBaseSpreadIx = await this.getUpdatePerpMarketBaseSpreadIx(perpMarketIndex, baseSpread); const tx = await this.buildTransaction(updatePerpMarketBaseSpreadIx); const { txSig } = await this.sendTransaction(tx, [], this.opts); return txSig; } public async getUpdatePerpMarketBaseSpreadIx( perpMarketIndex: number, baseSpread: number ): Promise<TransactionInstruction> { return await this.program.instruction.updatePerpMarketBaseSpread( baseSpread, { accounts: { admin: this.isSubscribed ? this.getStateAccount().admin : this.wallet.publicKey, state: await this.getStatePublicKey(), perpMarket: await getPerpMarketPublicKey( this.program.programId, perpMarketIndex ), }, } ); } public async updateAmmJitIntensity( perpMarketIndex: number, ammJitIntensity: number ): Promise<TransactionSignature> { const updateAmmJitIntensityIx = await this.getUpdateAmmJitIntensityIx( perpMarketIndex, ammJitIntensity ); const tx = await this.buildTransaction(updateAmmJitIntensityIx); const { txSig } = await this.sendTransaction(tx, [], this.opts); return txSig; } public async getUpdateAmmJitIntensityIx( perpMarketIndex: number, ammJitIntensity: number ): Promise<TransactionInstruction> { return await this.program.instruction.updateAmmJitIntensity( ammJitIntensity, { accounts: { admin: this.useHotWalletAdmin ? this.wallet.publicKey : this.getStateAccount().admin, state: await this.getStatePublicKey(), perpMarket: await getPerpMarketPublicKey( this.program.programId, perpMarketIndex ), }, } ); } public async updatePerpMarketName( perpMarketIndex: number, name: string ): Promise<TransactionSignature> { const updatePerpMarketNameIx = await this.getUpdatePerpMarketNameIx( perpMarketIndex, name ); const tx = await this.buildTransaction(updatePerpMarketNameIx); const { txSig } = await this.sendTransaction(tx, [], this.opts); return txSig; } public async getUpdatePerpMarketNameIx( perpMarketIndex: number, name: string ): Promise<TransactionInstruction> { const nameBuffer = encodeName(name); return await this.program.instruction.updatePerpMarketName(nameBuffer, { accounts: { admin: this.isSubscribed ? this.getStateAccount().admin : this.wallet.publicKey, state: await this.getStatePublicKey(), perpMarket: await getPerpMarketPublicKey( this.program.programId, perpMarketIndex ), }, }); } public async updateSpotMarketName( spotMarketIndex: number, name: string ): Promise<TransactionSignature> { const updateSpotMarketNameIx = await this.getUpdateSpotMarketNameIx( spotMarketIndex, name ); const tx = await this.buildTransaction(updateSpotMarketNameIx); const { txSig } = await this.sendTransaction(tx, [], this.opts); return txSig; } public async getUpdateSpotMarketNameIx( spotMarketIndex: number, name: string ): Promise<TransactionInstruction> { const nameBuffer = encodeName(name); return await this.program.instruction.updateSpotMarketName(nameBuffer, { accounts: { admin: this.isSubscribed ? this.getStateAccount().admin : this.wallet.publicKey, state: await this.getStatePublicKey(), spotMarket: await getSpotMarketPublicKey( this.program.programId, spotMarketIndex ), }, }); } public async updateSpotMarketPoolId( spotMarketIndex: number, poolId: number ): Promise<TransactionSignature> { const updateSpotMarketPoolIdIx = await this.getUpdateSpotMarketPoolIdIx( spotMarketIndex, poolId ); const tx = await this.buildTransaction(updateSpotMarketPoolIdIx); const { txSig } = await this.sendTransaction(tx, [], this.opts); return txSig; } public async getUpdateSpotMarketPoolIdIx( spotMarketIndex: number, poolId: number ): Promise<TransactionInstruction> { return await this.program.instruction.updateSpotMarketPoolId(poolId, { accounts: { admin: this.isSubscribed ? this.getStateAccount().admin : this.wallet.publicKey, state: await this.getStatePublicKey(), spotMarket: await getSpotMarketPublicKey( this.program.programId, spotMarketIndex ), }, }); } public async updatePerpMarketPerLpBase( perpMarketIndex: number, perLpBase: number ): Promise<TransactionSignature> { const updatePerpMarketPerLpBaseIx = await this.getUpdatePerpMarketPerLpBaseIx(perpMarketIndex, perLpBase); const tx = await this.buildTransaction(updatePerpMarketPerLpBaseIx); const { txSig } = await this.sendTransaction(tx, [], this.opts); return txSig; } public async getUpdatePerpMarketPerLpBaseIx( perpMarketIndex: number, perLpBase: number ): Promise<TransactionInstruction> { const perpMarketPublicKey = await getPerpMarketPublicKey( this.program.programId, perpMarketIndex ); return await this.program.instruction.updatePerpMarketPerLpBase(perLpBase, { accounts: { admin: this.isSubscribed ? this.getStateAccount().admin : this.wallet.publicKey, state: await this.getStatePublicKey(), perpMarket: perpMarketPublicKey, }, }); } public async updatePerpMarketMaxSpread( perpMarketIndex: number, maxSpread: number ): Promise<TransactionSignature> { const updatePerpMarketMaxSpreadIx = await this.getUpdatePerpMarketMaxSpreadIx(perpMarketIndex, maxSpread); const tx = await this.buildTransaction(updatePerpMarketMaxSpreadIx); const { txSig } = await this.sendTransaction(tx, [], this.opts); return txSig; } public async getUpdatePerpMarketMaxSpreadIx( perpMarketIndex: number, maxSpread: number ): Promise<TransactionInstruction> { const perpMarketPublicKey = await getPerpMarketPublicKey( this.program.programId, perpMarketIndex ); return await this.program.instruction.updatePerpMarketMaxSpread(maxSpread, { accounts: { admin: this.isSubscribed ? this.getStateAccount().admin : this.wallet.publicKey, state: await this.getStatePublicKey(), perpMarket: perpMarketPublicKey, }, }); } public async updatePerpFeeStructure( feeStructure: FeeStructure ): Promise<TransactionSignature> { const updatePerpFeeStructureIx = await this.getUpdatePerpFeeStructureIx( feeStructure ); const tx = await this.buildTransaction(updatePerpFeeStructureIx); const { txSig } = await this.sendTransaction(tx, [], this.opts); return txSig; } public async getUpdatePerpFeeStructureIx( feeStructure: FeeStructure ): Promise<TransactionInstruction> { return this.program.instruction.updatePerpFeeStructure(feeStructure, { accounts: { admin: this.isSubscribed ? this.getStateAccount().admin : this.wallet.publicKey, state: await this.getStatePublicKey(), }, }); } public async updateSpotFeeStructure( feeStructure: FeeStructure ): Promise<TransactionSignature> { const updateSpotFeeStructureIx = await this.getUpdateSpotFeeStructureIx( feeStructure ); const tx = await this.buildTransaction(updateSpotFeeStructureIx); const { txSig } = await this.sendTransaction(tx, [], this.opts); return txSig; } public async getUpdateSpotFeeStructureIx( feeStructure: FeeStructure ): Promise<TransactionInstruction> { return await this.program.instruction.updateSpotFeeStructure(feeStructure, { accounts: { admin: this.isSubscribed ? this.getStateAccount().admin : this.wallet.publicKey, state: await this.getStatePublicKey(), }, }); } public async updateInitialPctToLiquidate( initialPctToLiquidate: number ): Promise<TransactionSignature> { const updateInitialPctToLiquidateIx = await this.getUpdateInitialPctToLiquidateIx(initialPctToLiquidate); const tx = await this.buildTransaction(updateInitialPctToLiquidateIx); const { txSig } = await this.sendTransaction(tx, [], this.opts); return txSig; } public async getUpdateInitialPctToLiquidateIx( initialPctToLiquidate: number ): Promise<TransactionInstruction> { return await this.program.instruction.updateInitialPctToLiquidate( initialPctToLiquidate, { accounts: { admin: this.isSubscribed ? this.getStateAccount().admin : this.wallet.publicKey, state: await this.getStatePublicKey(), }, } ); } public async updateLiquidationDuration( liquidationDuration: number ): Promise<TransactionSignature> { const updateLiquidationDurationIx = await this.getUpdateLiquidationDurationIx(liquidationDuration); const tx = await this.buildTransaction(updateLiquidationDurationIx); const { txSig } = await this.sendTransaction(tx, [], this.opts); return txSig; } public async getUpdateLiquidationDurationIx( liquidationDuration: number ): Promise<TransactionInstruction> { return await this.program.instruction.updateLiquidationDuration( liquidationDuration, { accounts: { admin: this.isSubscribed ? this.getStateAccount().admin : this.wallet.publicKey, state: await this.getStatePublicKey(), }, } ); } public async updateLiquidationMarginBufferRatio( updateLiquidationMarginBufferRatio: number ): Promise<TransactionSignature> { const updateLiquidationMarginBufferRatioIx = await this.getUpdateLiquidationMarginBufferRatioIx( updateLiquidationMarginBufferRatio ); const tx = await this.buildTransaction( updateLiquidationMarginBufferRatioIx ); const { txSig } = await this.sendTransaction(tx, [], this.opts); return txSig; } public async getUpdateLiquidationMarginBufferRatioIx( updateLiquidationMarginBufferRatio: number ): Promise<TransactionInstruction> { return await this.program.instruction.updateLiquidationMarginBufferRatio( updateLiquidationMarginBufferRatio, { accounts: { admin: this.isSubscribed ? this.getStateAccount().admin : this.wallet.publicKey, state: await this.getStatePublicKey(), }, } ); } public async updateOracleGuardRails( oracleGuardRails: OracleGuardRails ): Promise<TransactionSignature> { const updateOracleGuardRailsIx = await this.getUpdateOracleGuardRailsIx( oracleGuardRails ); const tx = await this.buildTransaction(updateOracleGuardRailsIx); const { txSig } = await this.sendTransaction(tx, [], this.opts); return txSig; } public async getUpdateOracleGuardRailsIx( oracleGuardRails: OracleGuardRails ): Promise<TransactionInstruction> { return await this.program.instruction.updateOracleGuardRails( oracleGuardRails, { accounts: { admin: this.isSubscribed ? this.getStateAccount().admin : this.wallet.publicKey, state: await this.getStatePublicKey(), }, } ); } public async updateStateSettlementDuration( settlementDuration: number ): Promise<TransactionSignature> { const updateStateSettlementDurationIx = await this.getUpdateStateSettlementDurationIx(settlementDuration); const tx = await this.buildTransaction(updateStateSettlementDurationIx); const { txSig } = await this.sendTransaction(tx, [], this.opts); return txSig; } public async getUpdateStateSettlementDurationIx( settlementDuration: number ): Promise<TransactionInstruction> { return await this.program.instruction.updateStateSettlementDuration( settlementDuration, { accounts: { admin: this.isSubscribed ? this.getStateAccount().admin : this.wallet.publicKey, state: await this.getStatePublicKey(), }, } ); } public async updateStateMaxNumberOfSubAccounts( maxNumberOfSubAccounts: number ): Promise<TransactionSignature> { con