@raydium-io/raydium-sdk-v2
Version:
An SDK for building applications on top of Raydium.
1 lines • 1.31 MB
Source Map (JSON)
{"version":3,"sources":["../../../src/raydium/farm/farm.ts","../../../src/common/accountInfo.ts","../../../src/common/logger.ts","../../../src/common/bignumber.ts","../../../src/module/amount.ts","../../../src/module/formatter.ts","../../../src/module/fraction.ts","../../../src/common/constant.ts","../../../src/raydium/token/constant.ts","../../../src/module/token.ts","../../../src/common/pubKey.ts","../../../src/module/currency.ts","../../../src/module/percent.ts","../../../src/module/price.ts","../../../src/raydium/raydium.ts","../../../src/api/api.ts","../../../src/api/url.ts","../../../src/raydium/account/account.ts","../../../src/common/txTool/txTool.ts","../../../src/common/txTool/lookupTable.ts","../../../src/common/txTool/txType.ts","../../../src/common/txTool/txUtils.ts","../../../src/raydium/moduleBase.ts","../../../src/raydium/account/instruction.ts","../../../src/raydium/account/util.ts","../../../node_modules/@noble/hashes/src/_assert.ts","../../../node_modules/@noble/hashes/src/utils.ts","../../../node_modules/@noble/hashes/src/_md.ts","../../../node_modules/@noble/hashes/src/sha256.ts","../../../src/marshmallow/index.ts","../../../src/marshmallow/buffer-layout.ts","../../../src/raydium/account/layout.ts","../../../src/raydium/liquidity/liquidity.ts","../../../src/common/pda.ts","../../../src/common/transfer.ts","../../../src/raydium/farm/config.ts","../../../src/common/programId.ts","../../../src/raydium/farm/layout.ts","../../../src/raydium/farm/util.ts","../../../src/common/utility.ts","../../../src/raydium/farm/instruction.ts","../../../src/raydium/clmm/instrument.ts","../../../src/raydium/clmm/libraries/constants.ts","../../../src/raydium/clmm/layout.ts","../../../src/raydium/clmm/clmm.ts","../../../src/raydium/token/utils.ts","../../../src/raydium/token/layout.ts","../../../src/raydium/clmm/libraries/bigNum.ts","../../../src/raydium/clmm/libraries/limitOrder.ts","../../../src/raydium/clmm/libraries/tickArrayUtil.ts","../../../src/raydium/clmm/libraries/liquidityMath.ts","../../../src/raydium/clmm/libraries/pool.ts","../../../src/raydium/clmm/libraries/swapSimulator.ts","../../../src/raydium/clmm/libraries/swapMath.ts","../../../src/raydium/clmm/libraries/position.ts","../../../src/raydium/clmm/libraries/utils.ts","../../../src/raydium/clmm/libraries/pda.ts","../../../src/raydium/liquidity/constant.ts","../../../src/raydium/liquidity/instruction.ts","../../../src/raydium/liquidity/layout.ts","../../../src/raydium/liquidity/stable.ts","../../../src/raydium/liquidity/utils.ts","../../../src/raydium/liquidity/serum.ts","../../../src/raydium/marketV2/createMarket.ts","../../../src/raydium/marketV2/instrument.ts","../../../src/raydium/marketV2/layout.ts","../../../src/raydium/cpmm/cpmm.ts","../../../src/raydium/cpmm/curve/calculator.ts","../../../src/raydium/cpmm/curve/constantProduct.ts","../../../src/raydium/cpmm/curve/fee.ts","../../../src/common/fee.ts","../../../src/raydium/cpmm/instruction.ts","../../../src/raydium/cpmm/pda.ts","../../../src/raydium/cpmm/layout.ts","../../../src/raydium/tradeV2/trade.ts","../../../src/raydium/launchpad/instrument.ts","../../../src/raydium/launchpad/layout.ts","../../../src/raydium/launchpad/pda.ts","../../../src/raydium/launchpad/util.ts","../../../src/raydium/launchpad/curve/constantProductCurve.ts","../../../src/raydium/launchpad/curve/curve.ts","../../../src/raydium/launchpad/curve/fixedPriceCurve.ts","../../../src/raydium/launchpad/curve/linearPriceCurve.ts","../../../src/raydium/launchpad/curve/func.ts","../../../src/raydium/launchpad/launchpad.ts","../../../src/raydium/serum/id.ts","../../../src/raydium/serum/layout.ts","../../../src/raydium/serum/serum.ts","../../../src/raydium/tradeV2/instrument.ts","../../../src/raydium/utils1216/utils1216.ts","../../../src/raydium/token/token.ts","../../../src/common/lodash.ts"],"sourcesContent":["import { PublicKey, SystemProgram } from \"@solana/web3.js\";\nimport { createAssociatedTokenAccountIdempotentInstruction } from \"@solana/spl-token\";\nimport { getMultipleAccountsInfo, parseBigNumberish } from \"@/common\";\n\nimport { ApiV3Token, FormatFarmKeyOut } from \"../../api/type\";\nimport { AddInstructionParam, jsonInfo2PoolKeys } from \"@/common\";\nimport { getATAAddress } from \"@/common/pda\";\nimport { DEVNET_PROGRAM_ID, FARM_PROGRAM_ID_V6 } from \"@/common/programId\";\nimport { SOLMint, solToWSol, WSOLMint } from \"@/common/pubKey\";\nimport { MakeMultiTxData, MakeTxData } from \"@/common/txTool/txTool\";\nimport { InstructionType, TxVersion } from \"@/common/txTool/txType\";\nimport { generatePubKey } from \"../account/util\";\n\nimport Decimal from \"decimal.js\";\nimport { FormatFarmInfoOut, FormatFarmKeyOutV6 } from \"../../api/type\";\nimport { ComputeBudgetConfig, TxTipConfig } from \"../../raydium/type\";\nimport { createWSolAccountInstructions } from \"../account/instruction\";\nimport { BN_ZERO } from \"../clmm\";\nimport ModuleBase from \"../moduleBase\";\nimport { TOKEN_WSOL } from \"../token/constant\";\nimport {\n FARM_LOCK_MINT,\n FARM_LOCK_VAULT,\n FARM_PROGRAM_TO_VERSION,\n FARM_VERSION_TO_LEDGER_LAYOUT,\n FARM_VERSION_TO_STATE_LAYOUT,\n isValidFarmVersion,\n poolTypeV6,\n validateFarmRewards,\n} from \"./config\";\nimport {\n createAssociatedLedgerAccountInstruction,\n makeAddNewRewardInstruction,\n makeCreateFarmInstruction,\n makeCreatorWithdrawFarmRewardInstruction,\n makeDepositInstructionV3,\n makeDepositInstructionV5,\n makeDepositInstructionV6,\n makeRestartRewardInstruction,\n makeWithdrawInstructionV3,\n makeWithdrawInstructionV4,\n makeWithdrawInstructionV5,\n makeWithdrawInstructionV6,\n} from \"./instruction\";\nimport { FarmLedger, farmStateV6Layout } from \"./layout\";\nimport {\n CreateFarm,\n CreateFarmExtInfo,\n FarmDWParam,\n FarmPosition,\n FarmRewardInfo,\n FarmRewardInfoConfig,\n RewardInfoKey,\n UpdateFarmReward,\n UpdateFarmRewards,\n} from \"./type\";\nimport {\n calFarmRewardAmount,\n farmRewardInfoToConfig,\n getAssociatedAuthority,\n getAssociatedLedgerAccount,\n getAssociatedLedgerPoolAccount,\n getFarmLedgerLayout,\n} from \"./util\";\nimport BN from \"bn.js\";\n\nexport default class Farm extends ModuleBase {\n // token account needed\n private async _getUserRewardInfo({ payer, rewardInfo }: { payer: PublicKey; rewardInfo: FarmRewardInfo }): Promise<{\n rewardPubKey?: PublicKey;\n newInstruction?: AddInstructionParam;\n }> {\n if (rewardInfo.mint.equals(SOLMint)) {\n const txInstructions = await createWSolAccountInstructions({\n connection: this.scope.connection,\n owner: this.scope.ownerPubKey,\n payer,\n amount: calFarmRewardAmount({\n ...rewardInfo,\n openTime: rewardInfo.openTime.toString(),\n endTime: rewardInfo.endTime.toString(),\n }),\n });\n return {\n rewardPubKey: txInstructions.addresses.newAccount,\n newInstruction: txInstructions,\n };\n }\n\n return {\n rewardPubKey: await this.scope.account.getCreatedTokenAccount({\n mint: rewardInfo.mint,\n associatedOnly: false,\n })!,\n };\n }\n\n // token account needed\n public async create<T extends TxVersion>({\n poolInfo: propPoolInfo,\n rewardInfos,\n payer,\n programId = FARM_PROGRAM_ID_V6,\n txVersion,\n feePayer,\n lockProgram,\n }: CreateFarm<T>): Promise<MakeTxData<T, CreateFarmExtInfo>> {\n this.checkDisabled();\n this.scope.checkOwner();\n\n const lpMint = new PublicKey(propPoolInfo.lpMint.address);\n const poolInfo = {\n lpMint,\n lockInfo: { lockMint: lockProgram?.mint ?? FARM_LOCK_MINT, lockVault: lockProgram?.vault ?? FARM_LOCK_VAULT },\n version: 6,\n rewardInfos,\n programId,\n };\n\n const txBuilder = this.createTxBuilder(feePayer);\n const payerPubKey = payer ?? this.scope.ownerPubKey;\n const farmKeyPair = generatePubKey({ fromPublicKey: payerPubKey, programId: poolInfo.programId });\n const lamports = await this.scope.connection.getMinimumBalanceForRentExemption(farmStateV6Layout.span);\n\n txBuilder.addInstruction({\n instructions: [\n SystemProgram.createAccountWithSeed({\n fromPubkey: payerPubKey,\n basePubkey: payerPubKey,\n seed: farmKeyPair.seed,\n newAccountPubkey: farmKeyPair.publicKey,\n lamports,\n space: farmStateV6Layout.span,\n programId: poolInfo.programId,\n }),\n ],\n });\n\n const { publicKey: authority, nonce } = getAssociatedAuthority({\n programId: new PublicKey(poolInfo.programId),\n poolId: farmKeyPair.publicKey,\n });\n\n const lpVault = getAssociatedLedgerPoolAccount({\n programId: poolInfo.programId,\n poolId: farmKeyPair.publicKey,\n mint: poolInfo.lpMint,\n type: \"lpVault\",\n });\n\n const rewardInfoConfig: FarmRewardInfoConfig[] = [];\n const rewardInfoKey: RewardInfoKey[] = [];\n\n for (const rewardInfo of poolInfo.rewardInfos) {\n if (rewardInfo.openTime >= rewardInfo.endTime)\n this.logAndCreateError(\"start time error\", \"rewardInfo.rewardOpenTime\", rewardInfo.openTime.toString());\n if (isNaN(poolTypeV6[rewardInfo.rewardType])) this.logAndCreateError(\"rewardType error\", rewardInfo.rewardType);\n if (Number(rewardInfo.perSecond) <= 0) this.logAndCreateError(\"rewardPerSecond error\", rewardInfo.perSecond);\n\n rewardInfoConfig.push(farmRewardInfoToConfig(rewardInfo));\n\n const { rewardPubKey, newInstruction } = await this._getUserRewardInfo({\n rewardInfo,\n payer: payerPubKey,\n });\n if (newInstruction) txBuilder.addInstruction(newInstruction);\n\n if (!rewardPubKey) this.logAndCreateError(\"cannot found target token accounts\", this.scope.account.tokenAccounts);\n\n const rewardMint = rewardInfo.mint.equals(SOLMint) ? new PublicKey(TOKEN_WSOL.address) : rewardInfo.mint;\n rewardInfoKey.push({\n rewardMint,\n rewardVault: getAssociatedLedgerPoolAccount({\n programId: poolInfo.programId,\n poolId: farmKeyPair.publicKey,\n mint: rewardMint,\n type: \"rewardVault\",\n }),\n userRewardToken: rewardPubKey!,\n });\n }\n\n const { account: lockUserAccount, instructionParams } = await this.scope.account.getOrCreateTokenAccount({\n mint: new PublicKey(poolInfo.lockInfo.lockMint),\n owner: this.scope.ownerPubKey,\n skipCloseAccount: false,\n createInfo: {\n payer: this.scope.ownerPubKey,\n amount: 0,\n },\n associatedOnly: false,\n });\n instructionParams && txBuilder.addInstruction(instructionParams);\n if (!lockUserAccount)\n this.logAndCreateError(\"cannot found lock vault\", \"tokenAccounts\", this.scope.account.tokenAccounts);\n\n const { instruction, instructionType } = makeCreateFarmInstruction({\n farmId: farmKeyPair.publicKey,\n owner: this.scope.ownerPubKey,\n farmAuthority: authority,\n lpVault,\n lpMint: poolInfo.lpMint,\n lockVault: poolInfo.lockInfo.lockVault,\n lockMint: poolInfo.lockInfo.lockMint,\n lockUserAccount,\n programId: poolInfo.programId,\n rewardInfo: rewardInfoKey,\n rewardInfoConfig,\n nonce,\n });\n\n return txBuilder\n .addInstruction({\n instructions: [instruction],\n instructionTypes: [instructionType],\n })\n .versionBuild<CreateFarmExtInfo>({\n txVersion,\n extInfo: {\n farmId: farmKeyPair.publicKey,\n farmAuthority: authority,\n lpVault,\n lockUserAccount: lockUserAccount!,\n nonce,\n },\n }) as Promise<MakeTxData<T, CreateFarmExtInfo>>;\n }\n\n public async restartReward<T extends TxVersion>({\n farmInfo,\n payer,\n newRewardInfo,\n txVersion,\n feePayer,\n }: UpdateFarmReward): Promise<MakeTxData<T>> {\n const version = FARM_PROGRAM_TO_VERSION[farmInfo.programId];\n if (version !== 6) this.logAndCreateError(\"invalid farm version \", version);\n\n const farmInfoKeys = jsonInfo2PoolKeys((await this.scope.api.fetchFarmKeysById({ ids: farmInfo.id }))[0]);\n\n const farmKeys = {\n id: farmInfoKeys.id,\n rewardInfos: farmInfo.rewardInfos,\n lpVault: farmInfoKeys.lpVault,\n programId: farmInfoKeys.programId,\n };\n\n if (newRewardInfo.openTime >= newRewardInfo.endTime)\n this.logAndCreateError(\"start time error\", \"newRewardInfo\", newRewardInfo);\n\n const payerPubKey = payer || this.scope.ownerPubKey;\n\n const rewardMint = newRewardInfo.mint.equals(SOLMint) ? new PublicKey(TOKEN_WSOL.address) : newRewardInfo.mint;\n const rewardInfoIndex = farmKeys.rewardInfos.findIndex((item) =>\n new PublicKey(item.mint.address).equals(rewardMint),\n );\n const rewardInfo = farmInfoKeys.rewardInfos[rewardInfoIndex];\n\n if (!rewardInfo) this.logAndCreateError(\"configuration does not exist\", \"rewardMint\", rewardMint);\n\n const rewardVault = rewardInfo!.vault ?? SOLMint;\n const txBuilder = this.createTxBuilder(feePayer);\n\n const { rewardPubKey: userRewardTokenPub, newInstruction } = await this._getUserRewardInfo({\n rewardInfo: newRewardInfo,\n payer: payerPubKey,\n });\n if (newInstruction) txBuilder.addInstruction(newInstruction);\n\n if (!userRewardTokenPub)\n this.logAndCreateError(\"cannot found target token accounts\", this.scope.account.tokenAccounts);\n\n return txBuilder\n .addInstruction({\n instructions: [\n makeRestartRewardInstruction({\n payer: this.scope.ownerPubKey,\n rewardVault,\n userRewardTokenPub: userRewardTokenPub!,\n farmKeys,\n rewardInfo: newRewardInfo,\n }),\n ],\n instructionTypes: [InstructionType.FarmV6Restart],\n })\n .versionBuild({ txVersion }) as Promise<MakeTxData<T>>;\n }\n\n public async restartRewards<T extends TxVersion>({\n farmInfo,\n payer,\n newRewardInfos,\n txVersion,\n feePayer,\n }: UpdateFarmRewards<T>): Promise<MakeTxData<T>> {\n const version = FARM_PROGRAM_TO_VERSION[farmInfo.programId];\n if (version !== 6) this.logAndCreateError(\"invalid farm version \", version);\n\n const farmInfoKeys = jsonInfo2PoolKeys((await this.scope.api.fetchFarmKeysById({ ids: farmInfo.id }))[0]);\n\n const farmKeys = {\n id: farmInfoKeys.id,\n rewardInfos: farmInfo.rewardInfos,\n lpVault: farmInfoKeys.lpVault,\n programId: farmInfoKeys.programId,\n };\n\n newRewardInfos.forEach((reward) => {\n if (reward.openTime >= reward.endTime) this.logAndCreateError(\"start time error\", \"newRewardInfo\", reward);\n });\n\n const payerPubKey = payer || this.scope.ownerPubKey;\n const txBuilder = this.createTxBuilder(feePayer);\n\n for (const itemReward of newRewardInfos) {\n const rewardMint = itemReward.mint.equals(SOLMint) ? new PublicKey(TOKEN_WSOL.address) : itemReward.mint;\n const rewardInfoIndex = farmKeys.rewardInfos.findIndex((item) =>\n new PublicKey(item.mint.address).equals(rewardMint),\n );\n const rewardInfo = farmInfoKeys.rewardInfos[rewardInfoIndex];\n if (!rewardInfo) this.logAndCreateError(\"configuration does not exist\", \"rewardMint\", rewardMint);\n const rewardVault = rewardInfo!.vault ?? SOLMint;\n const { rewardPubKey: userRewardTokenPub, newInstruction } = await this._getUserRewardInfo({\n rewardInfo: itemReward,\n payer: payerPubKey,\n });\n if (newInstruction) txBuilder.addInstruction(newInstruction);\n if (!userRewardTokenPub)\n this.logAndCreateError(\"cannot found target token accounts\", this.scope.account.tokenAccounts);\n const ins = makeRestartRewardInstruction({\n payer: this.scope.ownerPubKey,\n rewardVault,\n userRewardTokenPub: userRewardTokenPub!,\n farmKeys,\n rewardInfo: itemReward,\n });\n txBuilder.addInstruction({\n instructions: [ins],\n instructionTypes: [InstructionType.FarmV6Restart],\n });\n }\n\n return txBuilder.versionBuild({ txVersion }) as Promise<MakeTxData<T>>;\n }\n\n public async addNewRewardToken<T extends TxVersion>(params: UpdateFarmReward): Promise<MakeTxData<T>> {\n const { txVersion, farmInfo, newRewardInfo, payer, feePayer } = params;\n const version = FARM_PROGRAM_TO_VERSION[farmInfo.programId];\n if (version !== 6) this.logAndCreateError(\"invalid farm version \", version);\n\n const farmKeys = jsonInfo2PoolKeys((await this.scope.api.fetchFarmKeysById({ ids: farmInfo.id }))[0]);\n const payerPubKey = payer ?? this.scope.ownerPubKey;\n const txBuilder = this.createTxBuilder(feePayer);\n\n const rewardMint = newRewardInfo.mint.equals(SOLMint) ? new PublicKey(TOKEN_WSOL.address) : newRewardInfo.mint;\n\n const rewardVault = getAssociatedLedgerPoolAccount({\n programId: new PublicKey(farmInfo.programId),\n poolId: new PublicKey(farmInfo.id),\n mint: rewardMint,\n type: \"rewardVault\",\n });\n\n const { rewardPubKey: userRewardTokenPub, newInstruction } = await this._getUserRewardInfo({\n rewardInfo: newRewardInfo,\n payer: payerPubKey,\n });\n if (newInstruction) txBuilder.addInstruction(newInstruction);\n\n if (!userRewardTokenPub)\n this.logAndCreateError(\"annot found target token accounts\", this.scope.account.tokenAccounts);\n\n newRewardInfo.mint = rewardMint;\n\n return txBuilder\n .addInstruction({\n instructions: [\n makeAddNewRewardInstruction({\n payer: this.scope.ownerPubKey,\n userRewardTokenPub: userRewardTokenPub!,\n farmKeys,\n rewardVault,\n rewardInfo: newRewardInfo,\n }),\n ],\n instructionTypes: [InstructionType.FarmV6CreatorAddReward],\n })\n .versionBuild({ txVersion }) as Promise<MakeTxData<T>>;\n }\n\n public async addNewRewardsToken<T extends TxVersion>(params: UpdateFarmRewards<T>): Promise<MakeTxData<T>> {\n const { txVersion, farmInfo, newRewardInfos, payer, feePayer } = params;\n const version = FARM_PROGRAM_TO_VERSION[farmInfo.programId];\n if (version !== 6) this.logAndCreateError(\"invalid farm version \", version);\n\n const farmKeys = jsonInfo2PoolKeys((await this.scope.api.fetchFarmKeysById({ ids: farmInfo.id }))[0]);\n const payerPubKey = payer ?? this.scope.ownerPubKey;\n const txBuilder = this.createTxBuilder(feePayer);\n\n for (const itemReward of newRewardInfos) {\n const rewardMint = itemReward.mint.equals(SOLMint) ? new PublicKey(TOKEN_WSOL.address) : itemReward.mint;\n const rewardVault = getAssociatedLedgerPoolAccount({\n programId: new PublicKey(farmInfo.programId),\n poolId: new PublicKey(farmInfo.id),\n mint: rewardMint,\n type: \"rewardVault\",\n });\n const { rewardPubKey: userRewardTokenPub, newInstruction } = await this._getUserRewardInfo({\n rewardInfo: itemReward,\n payer: payerPubKey,\n });\n if (newInstruction) txBuilder.addInstruction(newInstruction);\n if (!userRewardTokenPub)\n this.logAndCreateError(\"cannot found target token accounts\", this.scope.account.tokenAccounts);\n const ins = makeAddNewRewardInstruction({\n payer: this.scope.ownerPubKey,\n userRewardTokenPub: userRewardTokenPub!,\n farmKeys,\n rewardVault,\n rewardInfo: { ...itemReward, mint: rewardMint },\n });\n txBuilder.addInstruction({\n instructions: [ins],\n instructionTypes: [InstructionType.FarmV6CreatorAddReward],\n });\n }\n\n return txBuilder.versionBuild({ txVersion }) as Promise<MakeTxData<T>>;\n }\n\n public async deposit<T extends TxVersion>(params: FarmDWParam<T>): Promise<MakeTxData<T>> {\n const {\n txVersion,\n farmInfo,\n amount,\n feePayer,\n useSOLBalance,\n associatedOnly = true,\n checkCreateATAOwner = false,\n userAuxiliaryLedgers,\n computeBudgetConfig,\n txTipConfig,\n } = params;\n\n if (this.scope.availability.addFarm === false)\n this.logAndCreateError(\"farm deposit feature disabled in your region\");\n\n const { rewardInfos, programId } = farmInfo;\n const version = FARM_PROGRAM_TO_VERSION[programId];\n if (version === 4) this.logAndCreateError(\"V4 has suspended deposits:\", farmInfo.programId);\n if (!isValidFarmVersion(version)) this.logAndCreateError(\"invalid farm program:\", farmInfo.programId);\n const [farmProgramId, farmId] = [new PublicKey(farmInfo.programId), new PublicKey(farmInfo.id)];\n const farmKeys = (await this.scope.api.fetchFarmKeysById({ ids: farmInfo.id }))[0];\n\n const ledger = getAssociatedLedgerAccount({\n programId: farmProgramId,\n poolId: farmId,\n owner: this.scope.ownerPubKey,\n version: version as 3 | 5 | 6,\n });\n\n const txBuilder = this.createTxBuilder(feePayer);\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n const ownerMintToAccount: { [mint: string]: PublicKey } = {};\n for (const item of this.scope.account.tokenAccounts) {\n if (associatedOnly) {\n const ata = getATAAddress(this.scope.ownerPubKey, item.mint, item.programId).publicKey;\n if (item.publicKey && ata.equals(item.publicKey)) ownerMintToAccount[item.mint.toString()] = item.publicKey;\n } else {\n ownerMintToAccount[item.mint.toString()] = item.publicKey!;\n }\n }\n\n const lpMint = farmKeys.lpMint;\n const ownerLpTokenAccount = ownerMintToAccount[lpMint.address];\n if (!ownerLpTokenAccount) this.logAndCreateError(\"you don't have any lp\", \"lp zero\", ownerMintToAccount);\n\n const rewardAccounts: PublicKey[] = [];\n for (const itemReward of rewardInfos) {\n const rewardUseSOLBalance = useSOLBalance && itemReward.mint.address === WSOLMint.toString();\n\n let ownerRewardAccount = ownerMintToAccount[itemReward.mint.address];\n\n if (!ownerRewardAccount) {\n const { account: _ownerRewardAccount, instructionParams } = await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: itemReward.mint.programId,\n mint: new PublicKey(itemReward.mint.address),\n notUseTokenAccount: rewardUseSOLBalance,\n createInfo: {\n payer: feePayer || this.scope.ownerPubKey,\n amount: 0,\n },\n owner: this.scope.ownerPubKey,\n skipCloseAccount: !rewardUseSOLBalance,\n associatedOnly: rewardUseSOLBalance ? false : associatedOnly,\n checkCreateATAOwner,\n });\n ownerRewardAccount = _ownerRewardAccount!;\n instructionParams && txBuilder.addInstruction(instructionParams);\n }\n\n ownerMintToAccount[itemReward.mint.address] = ownerRewardAccount;\n rewardAccounts.push(ownerRewardAccount);\n }\n\n let ledgerInfo: FarmLedger | undefined = undefined;\n const ledgerData = await this.scope.connection.getAccountInfo(ledger);\n if (ledgerData) {\n const ledgerLayout = getFarmLedgerLayout(version)!;\n ledgerInfo = ledgerLayout.decode(ledgerData.data);\n }\n\n if (\n farmInfo.programId !== FARM_PROGRAM_ID_V6.toString() &&\n farmInfo.programId !== DEVNET_PROGRAM_ID.FARM_PROGRAM_ID_V6.toString() &&\n !ledgerInfo\n ) {\n const { instruction, instructionType } = createAssociatedLedgerAccountInstruction({\n id: farmId,\n programId: farmProgramId,\n version,\n ledger,\n owner: this.scope.ownerPubKey,\n });\n txBuilder.addInstruction({ instructions: [instruction], instructionTypes: [instructionType] });\n }\n\n const errorMsg = validateFarmRewards({\n version,\n rewardInfos,\n rewardTokenAccountsPublicKeys: rewardAccounts,\n });\n if (errorMsg) this.logAndCreateError(errorMsg);\n\n const insParams = {\n amount: parseBigNumberish(amount),\n owner: this.scope.ownerPubKey,\n farmInfo,\n farmKeys,\n lpAccount: ownerLpTokenAccount,\n rewardAccounts,\n userAuxiliaryLedgers: userAuxiliaryLedgers?.map((key) => new PublicKey(key)),\n };\n\n const newInstruction =\n version === 6\n ? makeDepositInstructionV6(insParams)\n : version === 5\n ? makeDepositInstructionV5(insParams)\n : makeDepositInstructionV3(insParams);\n\n const insType = {\n 3: InstructionType.FarmV3Deposit,\n 5: InstructionType.FarmV5Deposit,\n 6: InstructionType.FarmV6Deposit,\n };\n\n return txBuilder\n .addInstruction({\n instructions: [newInstruction],\n instructionTypes: [insType[version]],\n })\n .versionBuild({ txVersion }) as Promise<MakeTxData<T>>;\n }\n\n public async withdraw<T extends TxVersion>(params: FarmDWParam<T>): Promise<MakeTxData<T>> {\n const {\n txVersion,\n farmInfo,\n amount,\n deposited,\n useSOLBalance,\n feePayer,\n associatedOnly = true,\n checkCreateATAOwner = false,\n userAuxiliaryLedgers,\n computeBudgetConfig,\n txTipConfig,\n } = params;\n const { rewardInfos } = farmInfo;\n\n if (this.scope.availability.removeFarm === false)\n this.logAndCreateError(\"farm withdraw feature disabled in your region\");\n\n const version = FARM_PROGRAM_TO_VERSION[farmInfo.programId];\n\n if (!isValidFarmVersion(version)) this.logAndCreateError(\"invalid farm program:\", farmInfo.programId);\n\n const farmKeys = (await this.scope.api.fetchFarmKeysById({ ids: farmInfo.id }))[0];\n const txBuilder = this.createTxBuilder(feePayer);\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n const ownerMintToAccount: { [mint: string]: PublicKey } = {};\n for (const item of this.scope.account.tokenAccounts) {\n if (associatedOnly) {\n const ata = getATAAddress(this.scope.ownerPubKey, item.mint).publicKey;\n if (item.publicKey && ata.equals(item.publicKey)) ownerMintToAccount[item.mint.toString()] = item.publicKey;\n } else {\n ownerMintToAccount[item.mint.toString()] = item.publicKey!;\n }\n }\n\n if (version !== 4) {\n const ledger = getAssociatedLedgerAccount({\n programId: new PublicKey(farmInfo.programId),\n poolId: new PublicKey(farmInfo.id),\n owner: this.scope.ownerPubKey,\n version,\n });\n const ledgerData = await this.scope.connection.getAccountInfo(ledger);\n\n if (!ledgerData) {\n // user has old none ata farm vault and don't have ata vault\n if (version !== 6) {\n const { instruction, instructionType } = createAssociatedLedgerAccountInstruction({\n id: new PublicKey(farmKeys.id),\n programId: new PublicKey(farmKeys.programId),\n version,\n ledger,\n owner: this.scope.ownerPubKey,\n });\n txBuilder.addInstruction({ instructions: [instruction], instructionTypes: [instructionType] });\n }\n } else {\n const ledgerLayout = getFarmLedgerLayout(version)!;\n const ledgerInfo = ledgerLayout.decode(ledgerData!.data);\n if (ledgerInfo.deposited.isZero()) this.logAndCreateError(\"no deposited lp\", { farmId: farmInfo.id });\n }\n }\n\n if (deposited && deposited.isZero() && !(userAuxiliaryLedgers || []).length)\n this.logAndCreateError(\"no deposited lp\", { farmId: farmInfo.id });\n\n // if (!deposited && version !== 4) {\n // const ledger = getAssociatedLedgerAccount({\n // programId: new PublicKey(farmInfo.programId),\n // poolId: new PublicKey(farmInfo.id),\n // owner: this.scope.ownerPubKey,\n // version,\n // });\n // const ledgerData = await this.scope.connection.getAccountInfo(ledger);\n // if (!ledgerData) {\n // user has old not ata farm vault and don't have ata vault\n // if (version !== 6 && (userAuxiliaryLedgers || []).length > 0) {\n // const { instruction, instructionType } = createAssociatedLedgerAccountInstruction({\n // id: new PublicKey(farmKeys.id),\n // programId: new PublicKey(farmKeys.programId),\n // version,\n // ledger,\n // owner: this.scope.ownerPubKey,\n // });\n // txBuilder.addInstruction({ instructions: [instruction], instructionTypes: [instructionType] });\n // } else {\n // this.logAndCreateError(\"no lp data\", { farmId: farmInfo.id, version, ledgerData });\n // }\n // } else {\n // const ledgerLayout = getFarmLedgerLayout(version)!;\n // const ledgerInfo = ledgerLayout.decode(ledgerData!.data);\n // if (ledgerInfo.deposited.isZero()) this.logAndCreateError(\"no deposited lp\", { farmId: farmInfo.id });\n // }\n // } else if (deposited) {\n // if (deposited.isZero() && !(userAuxiliaryLedgers || []).length)\n // this.logAndCreateError(\"no deposited lp\", { farmId: farmInfo.id });\n // }\n\n const lpMint = farmKeys.lpMint.address;\n const lpMintUseSOLBalance = useSOLBalance && lpMint === WSOLMint.toString();\n\n let ownerLpTokenAccount = ownerMintToAccount[lpMint.toString()];\n if (!ownerLpTokenAccount) {\n const { account: _ownerRewardAccount, instructionParams } = await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: farmKeys.lpMint.programId,\n mint: new PublicKey(lpMint),\n notUseTokenAccount: lpMintUseSOLBalance,\n createInfo: {\n payer: feePayer || this.scope.ownerPubKey,\n amount: 0,\n },\n owner: this.scope.ownerPubKey,\n skipCloseAccount: true,\n associatedOnly: lpMintUseSOLBalance ? false : associatedOnly,\n checkCreateATAOwner,\n });\n ownerLpTokenAccount = _ownerRewardAccount!;\n instructionParams && txBuilder.addInstruction(instructionParams);\n }\n ownerMintToAccount[lpMint.toString()] = ownerLpTokenAccount;\n\n const rewardAccounts: PublicKey[] = [];\n for (const itemReward of rewardInfos) {\n const rewardUseSOLBalance = useSOLBalance && itemReward.mint.address === WSOLMint.toString();\n\n let ownerRewardAccount = ownerMintToAccount[itemReward.mint.address];\n if (!ownerRewardAccount) {\n const { account: _ownerRewardAccount, instructionParams } = await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: itemReward.mint.programId,\n mint: new PublicKey(itemReward.mint.address),\n notUseTokenAccount: rewardUseSOLBalance,\n createInfo: {\n payer: feePayer || this.scope.ownerPubKey,\n amount: 0,\n },\n owner: this.scope.ownerPubKey,\n skipCloseAccount: !rewardUseSOLBalance,\n associatedOnly: rewardUseSOLBalance ? false : associatedOnly,\n checkCreateATAOwner,\n });\n ownerRewardAccount = _ownerRewardAccount!;\n instructionParams && txBuilder.addInstruction(instructionParams);\n }\n\n ownerMintToAccount[itemReward.mint.address] = ownerRewardAccount;\n rewardAccounts.push(ownerRewardAccount);\n }\n\n const errorMsg = validateFarmRewards({\n version,\n rewardInfos,\n rewardTokenAccountsPublicKeys: rewardAccounts,\n });\n if (errorMsg) this.logAndCreateError(errorMsg);\n\n const insParams = {\n amount: parseBigNumberish(amount),\n owner: this.scope.ownerPubKey,\n farmInfo,\n farmKeys,\n lpAccount: ownerLpTokenAccount,\n rewardAccounts,\n userAuxiliaryLedgers: userAuxiliaryLedgers?.map((key) => new PublicKey(key)),\n };\n\n const newInstruction =\n version === 6\n ? makeWithdrawInstructionV6(insParams)\n : version === 5\n ? makeWithdrawInstructionV5(insParams)\n : version === 4\n ? makeWithdrawInstructionV4(insParams)\n : makeWithdrawInstructionV3(insParams);\n\n const insType = {\n 3: InstructionType.FarmV3Withdraw,\n 4: InstructionType.FarmV4Withdraw,\n 5: InstructionType.FarmV5Withdraw,\n 6: InstructionType.FarmV6Withdraw,\n };\n\n return txBuilder\n .addInstruction({\n instructions: [newInstruction],\n instructionTypes: [insType[version]],\n })\n .versionBuild({ txVersion }) as Promise<MakeTxData<T>>;\n }\n\n // token account needed\n public async withdrawFarmReward<T extends TxVersion>({\n farmInfo,\n withdrawMint,\n txVersion,\n computeBudgetConfig,\n txTipConfig,\n feePayer,\n }: {\n farmInfo: FormatFarmInfoOut;\n withdrawMint: PublicKey;\n payer?: PublicKey;\n computeBudgetConfig?: ComputeBudgetConfig;\n txTipConfig?: TxTipConfig;\n txVersion?: T;\n feePayer?: PublicKey;\n }): Promise<MakeTxData<T>> {\n this.scope.checkOwner();\n const farmKeys = jsonInfo2PoolKeys(\n (await this.scope.api.fetchFarmKeysById({ ids: farmInfo.id }))[0] as FormatFarmKeyOutV6,\n );\n const version = FARM_PROGRAM_TO_VERSION[farmInfo.programId];\n if (version !== 6) this.logAndCreateError(\"invalid farm version\", version);\n\n const rewardInfo = farmKeys.rewardInfos.find((r) => solToWSol(r.mint.address).equals(solToWSol(withdrawMint)));\n if (!rewardInfo) this.logAndCreateError(\"withdraw mint error\", \"rewardInfos\", farmInfo);\n\n const rewardVault = rewardInfo?.vault ?? SOLMint;\n const txBuilder = this.createTxBuilder(feePayer);\n\n let userRewardToken: PublicKey;\n\n if (withdrawMint.equals(SOLMint) || withdrawMint.equals(PublicKey.default)) {\n const txInstruction = await createWSolAccountInstructions({\n connection: this.scope.connection,\n owner: this.scope.ownerPubKey,\n payer: this.scope.ownerPubKey,\n amount: calFarmRewardAmount({\n ...rewardInfo,\n openTime: rewardInfo!.openTime as unknown as string,\n endTime: rewardInfo!.endTime as unknown as string,\n perSecond: new Decimal(rewardInfo!.perSecond).mul(10 ** rewardInfo!.mint.decimals).toString(),\n }),\n });\n userRewardToken = txInstruction.addresses.newAccount;\n txBuilder.addInstruction(txInstruction);\n } else {\n const selectUserRewardToken = await this.scope.account.getCreatedTokenAccount({\n mint: withdrawMint,\n });\n\n if (!selectUserRewardToken) {\n userRewardToken = await this.scope.account.getAssociatedTokenAccount(withdrawMint);\n txBuilder.addInstruction({\n instructions: [\n createAssociatedTokenAccountIdempotentInstruction(\n this.scope.ownerPubKey,\n userRewardToken,\n this.scope.ownerPubKey,\n withdrawMint,\n ),\n ],\n instructionTypes: [InstructionType.CreateATA],\n });\n } else {\n userRewardToken = selectUserRewardToken!;\n }\n }\n\n const { instruction, instructionType } = makeCreatorWithdrawFarmRewardInstruction({\n programId: farmKeys.programId,\n id: farmKeys.id,\n authority: farmKeys.authority,\n lpVault: farmKeys.lpVault,\n rewardVault,\n userRewardToken,\n owner: this.scope.ownerPubKey,\n });\n\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n return txBuilder\n .addInstruction({\n instructions: [instruction],\n instructionTypes: [instructionType],\n })\n .versionBuild({ txVersion }) as Promise<MakeTxData<T>>;\n }\n\n public async harvestAllRewards<T extends TxVersion = TxVersion.LEGACY>(params: {\n farmInfoList: Record<string, FormatFarmInfoOut>;\n feePayer?: PublicKey;\n useSOLBalance?: boolean;\n associatedOnly?: boolean;\n checkCreateATAOwner?: boolean;\n userAuxiliaryLedgers?: string[];\n txVersion?: T;\n computeBudgetConfig?: ComputeBudgetConfig;\n }): Promise<MakeMultiTxData<T>> {\n const {\n farmInfoList,\n useSOLBalance,\n feePayer,\n associatedOnly = true,\n checkCreateATAOwner = false,\n userAuxiliaryLedgers,\n txVersion,\n computeBudgetConfig,\n } = params;\n\n const txBuilder = this.createTxBuilder(feePayer);\n const ownerMintToAccount: { [mint: string]: PublicKey } = {};\n for (const item of this.scope.account.tokenAccounts) {\n if (associatedOnly) {\n const ata = getATAAddress(this.scope.ownerPubKey, item.mint).publicKey;\n if (item.publicKey && ata.equals(item.publicKey)) ownerMintToAccount[item.mint.toString()] = item.publicKey;\n } else {\n ownerMintToAccount[item.mint.toString()] = item.publicKey!;\n }\n }\n\n const allFarmKeys = await this.scope.api.fetchFarmKeysById({\n ids: Object.values(farmInfoList)\n .map((f) => f.id)\n .join(\",\"),\n });\n const farmKeyMap: { [key: string]: FormatFarmKeyOut } = allFarmKeys.reduce(\n (acc, cur) => ({ ...acc, [cur.id]: cur }),\n {},\n );\n for (const farmInfo of Object.values(farmInfoList)) {\n const { programId, lpMint: farmLpMint, rewardInfos, id } = farmInfo;\n const version = FARM_PROGRAM_TO_VERSION[programId];\n\n const lpMint = farmLpMint.address;\n const lpMintUseSOLBalance = useSOLBalance && lpMint === WSOLMint.toString();\n let ownerLpTokenAccount = ownerMintToAccount[lpMint];\n\n if (!ownerLpTokenAccount) {\n const { account: _ownerLpAccount, instructionParams } = await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: farmLpMint.programId,\n mint: new PublicKey(lpMint),\n notUseTokenAccount: lpMintUseSOLBalance,\n createInfo: {\n payer: feePayer || this.scope.ownerPubKey,\n amount: 0,\n },\n owner: this.scope.ownerPubKey,\n skipCloseAccount: true,\n associatedOnly: lpMintUseSOLBalance ? false : associatedOnly,\n checkCreateATAOwner,\n });\n ownerLpTokenAccount = _ownerLpAccount!;\n instructionParams && txBuilder.addInstruction(instructionParams);\n }\n ownerMintToAccount[lpMint.toString()] = ownerLpTokenAccount;\n\n const rewardAccounts: PublicKey[] = [];\n for (const itemReward of rewardInfos) {\n const rewardUseSOLBalance = useSOLBalance && itemReward.mint.address === WSOLMint.toString();\n\n let ownerRewardAccount = ownerMintToAccount[itemReward.mint.address];\n if (!ownerRewardAccount) {\n if (rewardUseSOLBalance) {\n const { account: _ownerRewardAccount, instructionParams } =\n await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: itemReward.mint.programId,\n mint: new PublicKey(itemReward.mint.address),\n notUseTokenAccount: rewardUseSOLBalance,\n createInfo: {\n payer: feePayer || this.scope.ownerPubKey,\n amount: 0,\n },\n owner: this.scope.ownerPubKey,\n skipCloseAccount: !rewardUseSOLBalance,\n associatedOnly: rewardUseSOLBalance ? false : associatedOnly,\n checkCreateATAOwner,\n });\n ownerRewardAccount = _ownerRewardAccount!;\n instructionParams && txBuilder.addInstruction(instructionParams);\n } else {\n const mint = new PublicKey(itemReward.mint.address);\n ownerRewardAccount = this.scope.account.getAssociatedTokenAccount(mint);\n txBuilder.addInstruction({\n instructions: [\n createAssociatedTokenAccountIdempotentInstruction(\n this.scope.ownerPubKey,\n ownerRewardAccount,\n this.scope.ownerPubKey,\n mint,\n ),\n ],\n });\n }\n }\n\n ownerMintToAccount[itemReward.mint.address] = ownerRewardAccount;\n rewardAccounts.push(ownerRewardAccount);\n }\n\n const farmKeys = farmKeyMap[id];\n const insParams = {\n amount: BN_ZERO,\n owner: this.scope.ownerPubKey,\n farmInfo,\n farmKeys,\n lpAccount: ownerLpTokenAccount,\n rewardAccounts,\n userAuxiliaryLedgers: userAuxiliaryLedgers?.map((key) => new PublicKey(key)),\n };\n\n const withdrawInstruction =\n version === 6\n ? makeWithdrawInstructionV6(insParams)\n : version === 5\n ? makeWithdrawInstructionV5(insParams)\n : makeWithdrawInstructionV3(insParams);\n\n const insType = {\n 3: InstructionType.FarmV3Withdraw,\n 5: InstructionType.FarmV5Withdraw,\n 6: InstructionType.FarmV6Withdraw,\n };\n\n txBuilder.addInstruction({\n instructions: [withdrawInstruction],\n instructionTypes: [insType[version]],\n });\n }\n\n if (txVersion === TxVersion.LEGACY)\n return txBuilder.sizeCheckBuild({ computeBudgetConfig }) as Promise<MakeMultiTxData<T>>;\n return txBuilder.sizeCheckBuildV0({ computeBudgetConfig }) as Promise<MakeMultiTxData<T>>;\n }\n\n public async fetchFarmBalances(): Promise<\n {\n farmInfo: FormatFarmInfoOut;\n pendingRewards: { mint: ApiV3Token; amount: string }[];\n }[]\n > {\n const data = await this.scope.api.fetchFarmPositions(this.scope.ownerPubKey.toBase58());\n const all = new Map<string, FarmPosition>();\n const allFarms = new Map<string, FarmPosition>();\n\n Object.keys(data || {}).forEach((lpMint) => {\n Object.keys(data[lpMint]).forEach((farmId) => {\n Object.keys(data[lpMint][farmId]).forEach((userVault) => {\n const d = {\n ...data[lpMint][farmId][userVault],\n farmId,\n lpMint,\n userVault,\n };\n // set pos data by mint\n const prevData = all.get(lpMint);\n\n all.set(lpMint, {\n lpMint,\n hasAmount: prevData?.hasAmount || new Decimal(d.lpAmount || 0).gt(0),\n hasV1Data: prevData?.hasV1Data || d.version === \"V1\",\n totalLpAmount: new Decimal(prevData?.totalLpAmount ?? 0).add(d.lpAmount || 0).toString(),\n totalV1LpAmount:\n d.version === \"V1\"\n ? new Decimal(prevData?.totalV1LpAmount ?? 0).add(d.lpAmount || 0).toString()\n : prevData?.totalV1LpAmount ?? \"0\",\n data: [...(prevData?.data || []), d],\n });\n\n // set pos data by farm\n const prevFarmData = allFarms.get(farmId);\n d.programId;\n allFarms.set(farmId, {\n lpMint,\n hasAmount: prevFarmData?.hasAmount || new Decimal(d.lpAmount || 0).gt(0),\n hasV1Data: prevFarmData?.hasV1Data || d.version === \"V1\",\n totalLpAmount: new Decimal(prevFarmData?.totalLpAmount ?? 0).add(d.lpAmount || 0).toString(),\n totalV1LpAmount:\n d.version === \"V1\"\n ? new Decimal(prevFarmData?.totalV1LpAmount ?? 0).add(d.lpAmount || 0).toString()\n : prevFarmData?.totalV1LpAmount ?? \"0\",\n data: [...(prevFarmData?.data || []), d],\n });\n });\n });\n all.set(lpMint, {\n ...all.get(lpMint)!,\n totalLpAmount: new Decimal(all.get(lpMint)?.totalLpAmount ?? 0).toString(),\n });\n });\n\n const vaults = Array.from(allFarms)\n .map((d) => d[1].data)\n .flat();\n\n const farmInfos = await this.scope.api.fetchFarmInfoById({\n ids: vaults.map((d) => d.farmId).join(\",\"),\n });\n\n const vaultData = await getMultipleAccountsInfo(\n this.scope.connection,\n vaults.map((d) => new PublicKey(d.userVault)),\n );\n\n const farmData = await getMultipleAccountsInfo(\n this.scope.connection,\n vaults.map((d) => new PublicKey(d.farmId)),\n );\n\n const farmBalance = farmData.map((f, idx) => {\n if (!f || !vaultData[idx]) return undefined;\n const version = FARM_PROGRAM_TO_VERSION[vaults[idx].programId];\n if (!FARM_VERSION_TO_STATE_LAYOUT[version] || !FARM_VERSION_TO_LEDGER_LAYOUT[version]) return undefined;\n\n const decodeData = FARM_VERSION_TO_LEDGER_LAYOUT[version]!.decode(vaultData[idx]!.data);\n const farmData = FARM_VERSION_TO_STATE_LAYOUT[version]!.decode(f.data);\n let multiplier: BN;\n if (farmData.version === 6) {\n multiplier = farmData.rewardMultiplier ?? new BN(10).pow(new BN(9));\n } else {\n multiplier = farmData.rewardInfos.length === 1 ? new BN(10).pow(new BN(9)) : new BN(10).pow(new BN(15));\n }\n const farm = farmInfos[idx];\n\n const pendingRewards: { mint: ApiV3Token; amount: string }[] = farmData\n ? farmData.rewardInfos.map((rewardInfo, index) => {\n const rewardDebt = decodeData.rewardDebts[index];\n let pendingReward = decodeData.deposited\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n .mul(farmData?.version === 6 ? rewardInfo.accRewardPerShare : rewardInfo.perShareReward)\n .div(multiplier)\n .sub(rewardDebt);\n\n if (pendingReward.lt(new BN(0))) pendingReward = new BN(0);\n return {\n mint: farm.rewardInfos[index]?.mint,\n amount: pendingReward.toString(),\n };\n })\n : [];\n\n return {\n ...decodeData,\n ...farmData,\n farmInfo: farm,\n pendingRewards,\n };\n });\n\n return farmBalance.filter(Boolean) as {\n farmInfo: FormatFarmInfoOut;\n pendingRewards: { mint: ApiV3Token; amount: string }[];\n }[];\n }\n}\n","import { AccountInfo, Commitment, Connection, PublicKey } from \"@solana/web3.js\";\nimport { ReturnTypeFetchMultipleMintInfos } from \"../raydium/type\";\nimport { WSOLMint, chunkArray, solToWSol } from \"./\";\nimport { createLogger } from \"./logger\";\nimport { MINT_SIZE, TOKEN_PROGRAM_ID, getTransferFeeConfig, unpackMint } from \"@solana/spl-token\";\n\ninterface MultipleAccountsJsonRpcResponse {\n jsonrpc: string;\n id: string;\n error?: {\n code: number;\n message: string;\n };\n result: {\n context: { slot: number };\n value: { data: Array<string>; executable: boolean; lamports: number; owner: string; rentEpoch: number }[];\n };\n}\n\nexport interface GetMultipleAccountsInfoConfig {\n batchRequest?: boolean;\n commitment?: Commitment;\n chunkCount?: number;\n}\n\nconst logger = createLogger(\"Raydium_accountInfo_util\");\n\nexport async function getMultipleAccountsInfo(\n connection: Connection,\n publicKeys: PublicKey[],\n config?: GetMultipleAccountsInfoConfig,\n): Promise<(AccountInfo<Buffer> | null)[]> {\n const {\n batchRequest,\n commitment = \"confirmed\",\n chunkCount = 100,\n } = {\n batchRequest: false,\n ...config,\n };\n\n const chunkedKeys = chunkArray(publicKeys, chunkCount);\n let results: (AccountInfo<Buffer> | null)[][] = new Array(chunkedKeys.length).fill([]);\n\n if (batchRequest) {\n const batch = chunkedKeys.map((keys) => {\n const args = connection._buildArgs([keys.map((key) => key.toBase58())], commitment, \"base64\");\n return {\n methodName: \"getMultipleAccounts\",\n args,\n };\n });\n\n const _batch = chunkArray(batch, 10);\n\n const unsafeResponse: MultipleAccountsJsonRpcResponse[] = await (\n await Promise.all(_batch.map(async (i) => await (connection as any)._rpcBatchRequest(i)))\n ).flat();\n results = unsafeResponse.map((unsafeRes: MultipleAccountsJsonRpcResponse) => {\n if (unsafeRes.error)\n logger.logWithError(`failed to get info for multiple accounts, RPC_ERROR, ${unsafeRes.error.message}`);\n\n return unsafeRes.result.value.map((accountInfo) => {\n if (accountInfo) {\n const { data, executable, lamports, owner, rentEpoch } = accountInfo;\n\n if (data.length !== 2 && data[1] !== \"base64\") logger.logWithError(`info must be base64 encoded, RPC_ERROR`);\n\n return {\n data: Buffer.from(data[0], \"base64\"),\n executable,\n lamports,\n owner: new PublicKey(owner),\n rentEpoch,\n };\n }\n return null;\n });\n });\n } else {\n try {\n results = (await Promise.all(\n chunkedKeys.map((keys) => connection.getMultipleAccountsInfo(keys, commitment)),\n )) as (AccountInfo<Buffer> | null)[][];\n } catch (error) {\n if (error instanceof Error) {\n logger.logWithError(`failed to get info for multiple accounts, RPC_ERROR, ${error.message}`);\n }\n }\n }\n\n return results.flat();\n}\n\nexport async function getMultipleAccountsInfoWithCustomFlags<T extends { pubkey: PublicKey }>(\n connection: Connection,\n publicKeysWithCustomFlag: T[],\n config?: GetMultipleAccountsInfoConfig,\n): Promise<({ accountInfo: AccountInfo<Buffer> | null } & T)[]> {\n const multipleAccountsInfo = await getMultipleAccountsInfo(\n connection,\n publicKeysWithCustomFlag.map((o) => o.pubkey),\n config,\n );\n\n return publicKeysWithCustomFlag.map((o, idx) => ({ ...o, accountInfo: multipleAccountsInfo[idx] }));\n}\n\nexport enum AccountType {\n Uninitialized,\n Mint,\n Account,\n}\nexport const ACCOUNT_TYPE_SIZE = 1;\n\nexport async function fetchMultipleMintInfos({\n connection,\n mints,\n config,\n}: {\n connection: Connection;\n mints: PublicKey[];\n config?: { batchRequest?: boolean };\n}): Promise<ReturnTypeFetchMultipleMintInfos> {\n if (mints.length === 0) return {};\n const mintInfos = await getMultipleAccountsInfoWithCustomFlags(\n connection,\n mints.map((i) => ({ pubkey: solToWSol(i) })),\n config,\n );\n\n const mintK: ReturnTypeFetchMultipleMintInfos = {};\n for (const i of mintInfos) {\n if (!i.accountInfo || i.accountInfo.data.length < MINT_SIZE) {\n console.log(\"invalid mint account\", i.pubkey.toBase58());\n continue;\n }\n const t = unpackMint(i.pubkey, i.accountInfo, i.accountInfo?.owner);\n mintK[i.pubkey.toString()] = {\n ...t,\n programId: i.accountInfo?.owner || TOKEN_PROGRAM_ID,\n feeConfig: getTransferFeeConfig(t) ?? undefined,\n };\n }\n mintK[PublicKey.default.toBase58()] = mintK[WSOLMint.toBase58()];\n\n return mintK;\n}\n","import { get, set } from \"lodash\";\n\nexport type ModuleName = \"Common.Api\";\n\nexport enum LogLevel {\n Error,\n Warning,\n Info,\n Debug,\n}\nexport class Logger {\n private logLevel: LogLevel;\n private name: string;\n constructor(params: { name: string; logLevel?: LogLevel }) {\n this.logLevel = params.logLevel !== undefined ? params.logLevel : LogLevel.Error;\n this.name = params.name;\n }\n\n set level(logLevel: LogLevel) {\n this.logLevel = logLevel;\n }\n get time(): string {\n return Date.now().toString();\n }\n get moduleName(): string {\n return this.name;\n }\n\n private isLogLevel(level: LogLevel): boolean {\n return level <= this.logLevel;\n }\n\n public error(...props): Logger {\n if (!this.isLogLevel(LogLevel.Error)) return this;\n console.error(this.time, this.name, \"sdk logger error\", ...props);\n return this;\n }\n\n public logWithError(...props): Logger {\n // this.error(...props)\n const msg = props.map((arg) => (typeof arg === \"object\" ? JSON.stringify(arg) : arg)).join(\", \");\n throw new Error(msg);\n }\n\n public warning(...props): Logger {\n if (!this.isLogLevel(LogLevel.Warning)) return this;\n console.warn(this.time, this.name, \"sdk logger warning\", ...props);\n return this;\n }\n\n public info(...props): Logger {\n if (!this.isLogLevel(LogLevel.Info)) return this;\n console.info(this.time, this.name, \"sdk logger info\", ...props);\n return this;\n }\n\n public debug(...props): Logger {\n if (!this.isLogLevel(LogLevel.Debug)) return this;\n console.debug(this.time, this.name, \"sdk logger debug\", ...props);\n return this;\n }\n}\n\nconst moduleLoggers: { [key in ModuleName]?: Logger } = {};\nconst moduleLevels: { [key in ModuleName]?: LogLevel } = {};\n\nexport function createLogger(moduleName: string): Logger {\n let logger = get(moduleLoggers, moduleName);\n if (!logger) {\n // default level is error\n const logLevel = get(moduleLevels, moduleName);\n\n logger = new Logger({ name: moduleName, logLevel });\n set(moduleLoggers, moduleName, logger);\n }\n\n return logger;\n}\n\nexport function setLoggerLevel(moduleName: string, level: LogLevel): void {\n set(moduleLevels, moduleName, level);\n\n const logger = get(moduleLoggers, moduleName);\n if (logger) logger.level = level;\n}\n","import BN from \"bn.js\";\nimport Decimal from \"decimal.js\";\nimport { CurrencyAmount, TokenAmount } from \"../module/amount\";\nimport { Currency } from \"../module/currency\";\nimport { Fraction } from \"../module/fraction\";\nimport { Percent } from \"../module/percent\";\nimport { Price } from \"../module/price\";\nimport { Token } from \"../module/token\";\nimport { SplToken, TokenJson } from \"../raydium/token/type\";\nimport { parseBigNumberish } from \"./constant\";\nimport { mul } from \"./fractionUtil\";\nimport { BN_ZERO } from \"@/raydium\";\n\nexport const BN_TWO = new BN(2);\nexport const BN_THREE = new BN(3);\nexport const BN_FIVE = new BN(5);\nexport const BN_TEN = new BN(10);\nexport const BN_100 = new BN(100);\nexport const BN_1000 = new BN(1000);\nexport const BN_10000 = new BN(10000);\nexport type BigNumberish = BN | string | number | bigint;\nexport type Numberish = number | string | bigint | Fraction | BN;\n\nexport function tenExponential(shift: BigNumberish): BN {\n return BN_TEN.pow(parseBigNumberish(shift));\n}\n\n/**\n *\n * @example\n * getIntInfo(0.34) => { numerator: '34', denominator: '100'}\n * getIntInfo('0.34') //=> { numerator: '34', denominator: '100'}\n */\nexport function parseNumberInfo(n: Numberish | undefined): {\n denominator: string;\n numerator: string;\n sign?: string;\n int?: string;\n dec?: string;\n} {\n if (n === undefined) return { denominator: \"1\", numerator: \"0\" };\n if (n instanceof BN) {\n return { numerator: n.toString(), denominator: \"1\" };\n }\n\n if (n instanceof Fraction) {\n return { denominator: n.denominator.toString(), numerator: n.numerator.toString() };\n }\n\n const s = String(n);\n const [, sign = \"\", int = \"\", dec = \"\"] = s.replace(\",\", \"\").match(/(-?)(\\d*)\\.?(\\d*)/) ?? [];\n const denominator = \"1\" + \"0\".repeat(dec.length);\n const numerator = sign + (int === \"0\" ? \"\" : int) + dec || \"0\";\n return { denominator, numerator, sign, int, dec };\n}\n\n// round up\nexport function divCeil(a: BN, b: BN): BN {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n const dm = a.divmod(b);\n\n // Fast case - exact division\n if (dm.mod.isZero()) return dm.div;\n\n if (a.isNeg() === b.isNeg()) {\n return dm.div.iaddn(1);\n } else {\n return dm.div; // 負數截尾後本身就是 Ceil 值\n }\n}\n\nexport function shakeFractionDecimal(n: Fraction): string {\n const [, sign = \"\", int = \"\"] = n.toFixed(2).match(/(-?)(\\d*)\\.?(\\d*)/) ?? [];\n return `${sign}${int}`;\n}\n\nexport function toBN(n: Numberish, decimal: BigNumberish = 0): BN {\n if (n instanceof BN) return n;\n return new BN(shakeFractionDecimal(toFraction(n).mul(BN_TEN.pow(new BN(String(decimal))))));\n}\n\nexport function toFraction(value: Numberish): Fraction {\n // to complete math format(may have decimal), not int\n if (value instanceof Percent) return new Fraction(value.numerator, value.denominator);\n\n if (value instanceof Price) return value.adjusted;\n\n // to complete math format(may have decimal), not BN\n if (value instanceof TokenAmount)\n try {\n return toFraction(value.toExact());\n } catch {\n return new Fraction(BN_ZERO);\n }\n\n // do not ideal with other fraction value\n if (value instanceof Fraction) return value;\n\n // wrap to Fraction\n const n = String(value);\n const details = parseNumberInfo(n);\n return new Fraction(details.numerator, details.denominator);\n}\n\nexport function ceilDiv(tokenAmount: BN, feeNumerator: BN, feeDenominator: BN): BN {\n return tokenAmount.mul(feeNumerator).add(feeDenominator).sub(new BN(1)).div(feeDenominator);\n}\n\nexport function floorDiv(tokenAmount: BN, feeNumerator: BN, feeDenominator: BN): BN {\n return tokenAmount.mul(feeNumerator).div(feeDenominator);\n}\n\n/**\n * @example\n * toPercent(3.14) // => Percent { 314.00% }\n * toPercent(3.14, { alreadyDecimaled: true }) // => Percent {3.14%}\n */\nexport function toPercent(\n n: Numberish,\n options?: { /* usually used for backend data */ alreadyDecimaled?: boolean },\n): Percent {\n const { numerator, denominator } = parseNumberInfo(n);\n return new Percent(new BN(numerator), new BN(denominator).mul(options?.alreadyDecimaled ? new BN(100) : new BN(1)));\n}\n\nexport function toTokenPrice(params: {\n token: TokenJson | Token | SplToken;\n numberPrice: Numberish;\n decimalDone?: boolean;\n}): Price {\n const { token, numberPrice, decimalDone } = params;\n const usdCurrency = new Token({ mint: \"\", decimals: 6, symbol: \"usd\", name: \"usd\", skipMint: true });\n const { numerator, denominator } = parseNumberInfo(numberPrice);\n const parsedNumerator = decimalDone ? new BN(numerator).mul(BN_TEN.pow(new BN(token.decimals))) : numerator;\n const parsedDenominator = new BN(denominator).mul(BN_TEN.pow(new BN(usdCurrency.decimals)));\n\n return new Price({\n baseToken: usdCurrency,\n denominator: parsedDenominator.toString(),\n quoteToken: new Token({ ...token, skipMint: true, mint: \"\" }),\n numerator: parsedNumerator.toString(),\n });\n}\n\nexport function toUsdCurrency(amount: Numberish): CurrencyAmount {\n const usdCurrency = new Currency({ decimals: 6, symbol: \"usd\", name: \"usd\" });\n const amountBigNumber = toBN(mul(amount, 10 ** usdCurrency.decimals)!);\n return new CurrencyAmount(usdCurrency, amountBigNumber);\n}\n\nexport function toTotalPrice(amount: Numberish | undefined, price: Price | undefined): CurrencyAmount {\n if (!price || !amount) return toUsdCurrency(0);\n return toUsdCurrency(mul(amount, price)!);\n}\n\nexport function decimalToFraction(n: Decimal | undefined): Fraction | undefined {\n if (n == null) return undefined;\n const { numerator, denominator } = parseNumberInfo(n.toString());\n return new Fraction(numerator, denominator);\n}\n\nexport function isDecimal(val: unknown): boolean {\n return val instanceof Decimal;\n}\n\n// export function recursivelyDecimalToFraction<T>(info: T): ReplaceType<T, Decimal, Fraction> {\n// // @ts-expect-error no need type for inner code\n// return isDecimal(info)\n// ? decimalToFraction(info as any)\n// : Array.isArray(info)\n// ? info.map((k) => recursivelyDecimalToFraction(k))\n// : notInnerObject(info)\n// ? Object.fromEntries(Object.entries(info as any).map(([k, v]) => [k, recursivelyDecimalToFraction(v)]))\n// : info;\n// }\n","import _Big from \"big.js\";\nimport BN from \"bn.js\";\n\nimport { BigNumberish, BN_TEN } from \"../common/bignumber\";\nimport { createLogger, Logger } from \"../common/logger\";\n\nimport { parseBigNumberish, Rounding } from \"../common\";\nimport { Currency } from \"./currency\";\nimport toFormat, { WrappedBig } from \"./formatter\";\nimport { Fraction } from \"./fraction\";\nimport { Token } from \"./token\";\n\nconst logger = createLogger(\"Raydium_amount\");\n\nconst Big = toFormat(_Big);\ntype Big = WrappedBig;\n\nexport function splitNumber(num: string, decimals: number): [string, string] {\n let integral = \"0\";\n let fractional = \"0\";\n\n if (num.includes(\".\")) {\n const splited = num.split(\".\");\n if (splited.length === 2) {\n [integral, fractional] = splited;\n fractional = fractional.padEnd(decimals, \"0\");\n } else {\n logger.logWithError(`invalid number string, num: ${num}`);\n }\n } else {\n integral = num;\n }\n\n // fix decimals is 0\n return [integral, fractional.slice(0, decimals) || fractional];\n}\n\nexport class TokenAmount extends Fraction {\n public readonly token: Token;\n protected logger: Logger;\n\n public constructor(token: Token, amount: BigNumberish, isRaw = true, name?: string) {\n let parsedAmount = new BN(0);\n const multiplier = BN_TEN.pow(new BN(token.decimals));\n\n if (isRaw) {\n parsedAmount = parseBigNumberish(amount);\n } else {\n let integralAmount = new BN(0);\n let fractionalAmount = new BN(0);\n\n // parse fractional string\n if (typeof amount === \"string\" || typeof amount === \"number\" || typeof amount === \"bigint\") {\n const [integral, fractional] = splitNumber(amount.toString(), token.decimals);\n integralAmount = parseBigNumberish(integral);\n fractionalAmount = parseBigNumberish(fractional);\n }\n\n integralAmount = integralAmount.mul(multiplier);\n parsedAmount = integralAmount.add(fractionalAmount);\n }\n\n super(parsedAmount, multiplier);\n this.logger = createLogger(name || \"TokenAmount\");\n this.token = token;\n }\n\n public get raw(): BN {\n return this.numerator;\n }\n public isZero(): boolean {\n return this.raw.isZero();\n }\n public gt(other: TokenAmount): boolean {\n if (!this.token.equals(other.token)) this.logger.logWithError(\"gt token not equals\");\n return this.raw.gt(other.raw);\n }\n\n /**\n * a less than b\n */\n public lt(other: TokenAmount): boolean {\n if (!this.token.equals(other.token)) this.logger.logWithError(\"lt token not equals\");\n return this.raw.lt(other.raw);\n }\n\n public add(other: TokenAmount): TokenAmount {\n if (!this.token.equals(other.token)) this.logger.logWithError(\"add token not equals\");\n return new TokenAmount(this.token, this.raw.add(other.raw));\n }\n\n public subtract(other: TokenAmount): TokenAmount {\n if (!this.token.equals(other.token)) this.logger.logWithError(\"sub token not equals\");\n return new TokenAmount(this.token, this.raw.sub(other.raw));\n }\n\n public toSignificant(\n significantDigits = this.token.decimals,\n format?: object,\n rounding: Rounding = Rounding.ROUND_DOWN,\n ): string {\n return super.toSignificant(significantDigits, format, rounding);\n }\n\n /**\n * To fixed\n *\n * @example\n * ```\n * 1 -> 1.000000000\n * 1.234 -> 1.234000000\n * 1.123456789876543 -> 1.123456789\n * ```\n */\n public toFixed(\n decimalPlaces = this.token.decimals,\n format?: object,\n rounding: Rounding = Rounding.ROUND_DOWN,\n ): string {\n if (decimalPlaces > this.token.decimals) this.logger.logWithError(\"decimals overflow\");\n return super.toFixed(decimalPlaces, format, rounding);\n }\n\n /**\n * To exact\n *\n * @example\n * ```\n * 1 -> 1\n * 1.234 -> 1.234\n * 1.123456789876543 -> 1.123456789\n * ```\n */\n public toExact(format: object = { groupSeparator: \"\" }): string {\n Big.DP = this.token.decimals;\n return new Big(this.numerator.toString()).div(this.denominator.toString()).toFormat(format);\n }\n}\n\nexport class CurrencyAmount extends Fraction {\n public readonly currency: Currency;\n protected logger: Logger;\n\n public constructor(currency: Currency, amount: BigNumberish, isRaw = true, name?: string) {\n let parsedAmount = new BN(0);\n const multiplier = BN_TEN.pow(new BN(currency.decimals));\n\n if (isRaw) {\n parsedAmount = parseBigNumberish(amount);\n } else {\n let integralAmount = new BN(0);\n let fractionalAmount = new BN(0);\n\n // parse fractional string\n if (typeof amount === \"string\" || typeof amount === \"number\" || typeof amount === \"bigint\") {\n const [integral, fractional] = splitNumber(amount.toString(), currency.decimals);\n integralAmount = parseBigNumberish(integral);\n fractionalAmount = parseBigNumberish(fractional);\n }\n\n integralAmount = integralAmount.mul(multiplier);\n parsedAmount = integralAmount.add(fractionalAmount);\n }\n\n super(parsedAmount, multiplier);\n this.logger = createLogger(name || \"TokenAmount\");\n this.currency = currency;\n }\n\n public get raw(): BN {\n return this.numerator;\n }\n\n public isZero(): boolean {\n return this.raw.isZero();\n }\n\n /**\n * a greater than b\n */\n public gt(other: CurrencyAmount): boolean {\n if (!this.currency.equals(other.currency)) this.logger.logWithError(\"gt currency not equals\");\n return this.raw.gt(other.raw);\n }\n\n /**\n * a less than b\n */\n public lt(other: CurrencyAmount): boolean {\n if (!this.currency.equals(other.currency)) this.logger.logWithError(\"lt currency not equals\");\n return this.raw.lt(other.raw);\n }\n\n public add(other: CurrencyAmount): CurrencyAmount {\n if (!this.currency.equals(other.currency)) this.logger.logWithError(\"add currency not equals\");\n return new CurrencyAmount(this.currency, this.raw.add(other.raw));\n }\n\n public sub(other: CurrencyAmount): CurrencyAmount {\n if (!this.currency.equals(other.currency)) this.logger.logWithError(\"sub currency not equals\");\n return new CurrencyAmount(this.currency, this.raw.sub(other.raw));\n }\n\n public toSignificant(\n significantDigits = this.currency.decimals,\n format?: object,\n rounding: Rounding = Rounding.ROUND_DOWN,\n ): string {\n return super.toSignificant(significantDigits, format, rounding);\n }\n\n /**\n * To fixed\n *\n * @example\n * ```\n * 1 -> 1.000000000\n * 1.234 -> 1.234000000\n * 1.123456789876543 -> 1.123456789\n * ```\n */\n public toFixed(\n decimalPlaces = this.currency.decimals,\n format?: object,\n rounding: Rounding = Rounding.ROUND_DOWN,\n ): string {\n if (decimalPlaces > this.currency.decimals) this.logger.logWithError(\"decimals overflow\");\n\n return super.toFixed(decimalPlaces, format, rounding);\n }\n\n /**\n * To exact\n *\n * @example\n * ```\n * 1 -> 1\n * 1.234 -> 1.234\n * 1.123456789876543 -> 1.123456789\n * ```\n */\n public toExact(format: object = { groupSeparator: \"\" }): string {\n Big.DP = this.currency.decimals;\n return new Big(this.numerator.toString()).div(this.denominator.toString()).toFormat(format);\n }\n}\n","import Big, { BigConstructor, BigSource, RoundingMode } from \"big.js\";\nimport Decimal, { Config, Numeric } from \"decimal.js-light\";\nimport _toFarmat from \"toformat\";\n\ntype TakeStatic<T> = { [P in keyof T]: T[P] };\ninterface FormatOptions {\n decimalSeparator?: string;\n groupSeparator?: string;\n groupSize?: number;\n fractionGroupSeparator?: string;\n fractionGroupSize?: number;\n}\ninterface WrappedBigConstructor extends TakeStatic<BigConstructor> {\n new (value: BigSource): WrappedBig;\n (value: BigSource): WrappedBig;\n (): WrappedBigConstructor;\n\n format: FormatOptions;\n}\nexport interface WrappedBig extends Big {\n add(n: BigSource): WrappedBig;\n abs(): WrappedBig;\n div(n: BigSource): WrappedBig;\n minus(n: BigSource): WrappedBig;\n mod(n: BigSource): WrappedBig;\n mul(n: BigSource): WrappedBig;\n plus(n: BigSource): WrappedBig;\n pow(exp: number): WrappedBig;\n round(dp?: number, rm?: RoundingMode): WrappedBig;\n sqrt(): WrappedBig;\n sub(n: BigSource): WrappedBig;\n times(n: BigSource): WrappedBig;\n toFormat(): string;\n toFormat(options: FormatOptions): string;\n toFormat(fractionLength: number): string;\n toFormat(fractionLength: number, options: FormatOptions): string;\n toFormat(fractionLength: number, missionUnknown: number): string;\n toFormat(fractionLength: number, missionUnknown: number, options: FormatOptions): string;\n}\n\ntype DecimalConstructor = typeof Decimal;\ninterface WrappedDecimalConstructor extends TakeStatic<DecimalConstructor> {\n new (value: Numeric): WrappedDecimal;\n clone(config?: Config): WrappedDecimalConstructor;\n config(config: Config): WrappedDecimal;\n set(config: Config): WrappedDecimal;\n format: FormatOptions;\n}\nexport interface WrappedDecimal extends Decimal {\n absoluteValue(): WrappedDecimal;\n abs(): WrappedDecimal;\n dividedBy(y: Numeric): WrappedDecimal;\n div(y: Numeric): WrappedDecimal;\n dividedToIntegerBy(y: Numeric): WrappedDecimal;\n idiv(y: Numeric): WrappedDecimal;\n logarithm(base?: Numeric): WrappedDecimal;\n log(base?: Numeric): WrappedDecimal;\n minus(y: Numeric): WrappedDecimal;\n sub(y: Numeric): WrappedDecimal;\n modulo(y: Numeric): WrappedDecimal;\n mod(y: Numeric): WrappedDecimal;\n naturalExponetial(): WrappedDecimal;\n exp(): WrappedDecimal;\n naturalLogarithm(): WrappedDecimal;\n ln(): WrappedDecimal;\n negated(): WrappedDecimal;\n neg(): WrappedDecimal;\n plus(y: Numeric): WrappedDecimal;\n add(y: Numeric): WrappedDecimal;\n squareRoot(): WrappedDecimal;\n sqrt(): WrappedDecimal;\n times(y: Numeric): WrappedDecimal;\n mul(y: Numeric): WrappedDecimal;\n toWrappedDecimalPlaces(dp?: number, rm?: number): WrappedDecimal;\n todp(dp?: number, rm?: number): WrappedDecimal;\n toInteger(): WrappedDecimal;\n toint(): WrappedDecimal;\n toPower(y: Numeric): WrappedDecimal;\n pow(y: Numeric): WrappedDecimal;\n toSignificantDigits(sd?: number, rm?: number): WrappedDecimal;\n tosd(sd?: number, rm?: number): WrappedDecimal;\n toFormat(options: FormatOptions): string;\n toFormat(fractionLength: number): string;\n toFormat(fractionLength: number, options: FormatOptions): string;\n toFormat(fractionLength: number, missionUnknown: number): string;\n toFormat(fractionLength: number, missionUnknown: number, options: FormatOptions): string;\n}\n\nconst toFormat: {\n (fn: BigConstructor): WrappedBigConstructor;\n (fn: DecimalConstructor): WrappedDecimalConstructor;\n} = _toFarmat;\nexport default toFormat;\n","import _Big from \"big.js\";\nimport BN from \"bn.js\";\nimport _Decimal from \"decimal.js-light\";\n\nimport { BigNumberish } from \"../common/bignumber\";\nimport { createLogger } from \"../common/logger\";\n\nimport { parseBigNumberish, Rounding } from \"../common/constant\";\nimport toFormat, { WrappedBig } from \"./formatter\";\n\nconst logger = createLogger(\"module/fraction\");\n\nconst Big = toFormat(_Big);\ntype Big = WrappedBig;\n\nconst Decimal = toFormat(_Decimal);\n\nconst toSignificantRounding = {\n [Rounding.ROUND_DOWN]: Decimal.ROUND_DOWN,\n [Rounding.ROUND_HALF_UP]: Decimal.ROUND_HALF_UP,\n [Rounding.ROUND_UP]: Decimal.ROUND_UP,\n};\n\nconst toFixedRounding = {\n [Rounding.ROUND_DOWN]: _Big.roundDown,\n [Rounding.ROUND_HALF_UP]: _Big.roundHalfUp,\n [Rounding.ROUND_UP]: _Big.roundUp,\n};\n\nexport class Fraction {\n public readonly numerator: BN;\n public readonly denominator: BN;\n\n public constructor(numerator: BigNumberish, denominator: BigNumberish = new BN(1)) {\n this.numerator = parseBigNumberish(numerator);\n this.denominator = parseBigNumberish(denominator);\n }\n\n public get quotient(): BN {\n return this.numerator.div(this.denominator);\n }\n\n public invert(): Fraction {\n return new Fraction(this.denominator, this.numerator);\n }\n\n public add(other: Fraction | BigNumberish): Fraction {\n const otherParsed = other instanceof Fraction ? other : new Fraction(parseBigNumberish(other));\n\n if (this.denominator.eq(otherParsed.denominator)) {\n return new Fraction(this.numerator.add(otherParsed.numerator), this.denominator);\n }\n\n return new Fraction(\n this.numerator.mul(otherParsed.denominator).add(otherParsed.numerator.mul(this.denominator)),\n this.denominator.mul(otherParsed.denominator),\n );\n }\n\n public sub(other: Fraction | BigNumberish): Fraction {\n const otherParsed = other instanceof Fraction ? other : new Fraction(parseBigNumberish(other));\n\n if (this.denominator.eq(otherParsed.denominator)) {\n return new Fraction(this.numerator.sub(otherParsed.numerator), this.denominator);\n }\n\n return new Fraction(\n this.numerator.mul(otherParsed.denominator).sub(otherParsed.numerator.mul(this.denominator)),\n this.denominator.mul(otherParsed.denominator),\n );\n }\n\n public mul(other: Fraction | BigNumberish): Fraction {\n const otherParsed = other instanceof Fraction ? other : new Fraction(parseBigNumberish(other));\n\n return new Fraction(this.numerator.mul(otherParsed.numerator), this.denominator.mul(otherParsed.denominator));\n }\n\n public div(other: Fraction | BigNumberish): Fraction {\n const otherParsed = other instanceof Fraction ? other : new Fraction(parseBigNumberish(other));\n\n return new Fraction(this.numerator.mul(otherParsed.denominator), this.denominator.mul(otherParsed.numerator));\n }\n\n public toSignificant(\n significantDigits: number,\n format: object = { groupSeparator: \"\" },\n rounding: Rounding = Rounding.ROUND_HALF_UP,\n ): string {\n if (!Number.isInteger(significantDigits)) logger.logWithError(`${significantDigits} is not an integer.`);\n if (significantDigits <= 0) logger.logWithError(`${significantDigits} is not positive.`);\n\n Decimal.set({ precision: significantDigits + 1, rounding: toSignificantRounding[rounding] });\n const quotient = new Decimal(this.numerator.toString())\n .div(this.denominator.toString())\n .toSignificantDigits(significantDigits);\n return quotient.toFormat(quotient.decimalPlaces(), format);\n }\n\n public toFixed(\n decimalPlaces: number,\n format: object = { groupSeparator: \"\" },\n rounding: Rounding = Rounding.ROUND_HALF_UP,\n ): string {\n if (!Number.isInteger(decimalPlaces)) logger.logWithError(`${decimalPlaces} is not an integer.`);\n if (decimalPlaces < 0) logger.logWithError(`${decimalPlaces} is negative.`);\n\n Big.DP = decimalPlaces;\n Big.RM = toFixedRounding[rounding] || 1;\n return new Big(this.numerator.toString()).div(this.denominator.toString()).toFormat(decimalPlaces, format);\n }\n\n public isZero(): boolean {\n return this.numerator.isZero();\n }\n}\n","import BN from \"bn.js\";\nimport { BigNumberish } from \"./bignumber\";\nimport { createLogger } from \"./logger\";\n\nexport enum Rounding {\n ROUND_DOWN,\n ROUND_HALF_UP,\n ROUND_UP,\n}\n\nconst MAX_SAFE = 0x1fffffffffffff;\n\nexport function parseBigNumberish(value: BigNumberish): BN {\n const logger = createLogger(\"Raydium_parseBigNumberish\");\n // BN\n if (value instanceof BN) {\n return value;\n }\n\n if (typeof value === \"string\") {\n if (value.match(/^-?[0-9]+$/)) {\n return new BN(value);\n }\n logger.logWithError(`invalid BigNumberish string: ${value}`);\n }\n\n if (typeof value === \"number\") {\n if (value % 1) {\n logger.logWithError(`BigNumberish number underflow: ${value}`);\n }\n\n if (value >= MAX_SAFE || value <= -MAX_SAFE) {\n logger.logWithError(`BigNumberish number overflow: ${value}`);\n }\n\n return new BN(String(value));\n }\n\n if (typeof value === \"bigint\") {\n return new BN(value.toString());\n }\n logger.error(`invalid BigNumberish value: ${value}`);\n return new BN(0); // never reach, because logWithError will throw error\n}","import { PublicKey } from \"@solana/web3.js\";\nimport { TOKEN_PROGRAM_ID } from \"@solana/spl-token\";\nimport { TokenInfo } from \"./type\";\n\nexport const SOL_INFO: TokenInfo = {\n chainId: 101,\n address: PublicKey.default.toBase58(),\n programId: TOKEN_PROGRAM_ID.toBase58(),\n decimals: 9,\n symbol: \"SOL\",\n name: \"solana\",\n logoURI: `https://img-v1.raydium.io/icon/So11111111111111111111111111111111111111112.png`,\n tags: [],\n priority: 2,\n type: \"raydium\",\n extensions: {\n coingeckoId: \"solana\",\n },\n};\n\nexport const TOKEN_WSOL: TokenInfo = {\n chainId: 101,\n address: \"So11111111111111111111111111111111111111112\",\n programId: TOKEN_PROGRAM_ID.toBase58(),\n decimals: 9,\n symbol: \"WSOL\",\n name: \"Wrapped SOL\",\n logoURI: `https://img-v1.raydium.io/icon/So11111111111111111111111111111111111111112.png`,\n tags: [],\n priority: 2,\n type: \"raydium\",\n extensions: {\n coingeckoId: \"solana\",\n },\n};\n","import { PublicKey } from \"@solana/web3.js\";\n\nimport { PublicKeyish, SOLMint, validateAndParsePublicKey } from \"../common/pubKey\";\nimport { TOKEN_WSOL } from \"../raydium/token/constant\";\n\n/**\n * A token is any fungible financial instrument on Solana, including SOL and all SPL tokens.\n */\nexport interface TokenProps {\n mint: PublicKeyish;\n decimals: number;\n symbol?: string;\n name?: string;\n skipMint?: boolean;\n isToken2022?: boolean;\n}\n\nexport class Token {\n public readonly symbol?: string;\n public readonly name?: string;\n public readonly decimals: number;\n public readonly isToken2022: boolean;\n\n public readonly mint: PublicKey;\n public static readonly WSOL: Token = new Token({\n ...TOKEN_WSOL,\n mint: TOKEN_WSOL.address,\n });\n\n /**\n *\n * @param mint - pass \"sol\" as mint will auto generate wsol token config\n */\n public constructor({ mint, decimals, symbol, name, skipMint = false, isToken2022 = false }: TokenProps) {\n if (mint === SOLMint.toBase58() || (mint instanceof PublicKey && SOLMint.equals(mint))) {\n this.decimals = TOKEN_WSOL.decimals;\n this.symbol = TOKEN_WSOL.symbol;\n this.name = TOKEN_WSOL.name;\n this.mint = new PublicKey(TOKEN_WSOL.address);\n this.isToken2022 = false;\n return;\n }\n\n this.decimals = decimals;\n this.symbol = symbol || mint.toString().substring(0, 6);\n this.name = name || mint.toString().substring(0, 6);\n this.mint = skipMint ? PublicKey.default : validateAndParsePublicKey({ publicKey: mint });\n this.isToken2022 = isToken2022;\n }\n\n public equals(other: Token): boolean {\n // short circuit on reference equality\n if (this === other) {\n return true;\n }\n return this.mint.equals(other.mint);\n }\n}\n","import { AccountMeta, PublicKey, SystemProgram, SYSVAR_RENT_PUBKEY } from \"@solana/web3.js\";\nimport { TOKEN_PROGRAM_ID } from \"@solana/spl-token\";\n\ninterface AccountMetaProps {\n pubkey: PublicKey;\n isSigner?: boolean;\n isWritable?: boolean;\n}\n\nexport function accountMeta({ pubkey, isSigner = false, isWritable = true }: AccountMetaProps): AccountMeta {\n return {\n pubkey,\n isWritable,\n isSigner,\n };\n}\n\nexport const commonSystemAccountMeta = [\n accountMeta({ pubkey: TOKEN_PROGRAM_ID, isWritable: false }),\n accountMeta({ pubkey: SystemProgram.programId, isWritable: false }),\n accountMeta({ pubkey: SYSVAR_RENT_PUBKEY, isWritable: false }),\n];\n\nexport type PublicKeyish = PublicKey | string;\n\nexport function validateAndParsePublicKey({\n publicKey: orgPubKey,\n transformSol,\n}: {\n publicKey: PublicKeyish;\n transformSol?: boolean;\n}): PublicKey {\n const publicKey = tryParsePublicKey(orgPubKey.toString());\n\n if (publicKey instanceof PublicKey) {\n if (transformSol && publicKey.equals(SOLMint)) return WSOLMint;\n return publicKey;\n }\n\n if (transformSol && publicKey.toString() === SOLMint.toBase58()) return WSOLMint;\n\n if (typeof publicKey === \"string\") {\n if (publicKey === PublicKey.default.toBase58()) return PublicKey.default;\n try {\n const key = new PublicKey(publicKey);\n return key;\n } catch {\n throw new Error(\"invalid public key\");\n }\n }\n\n throw new Error(\"invalid public key\");\n}\n\nexport function tryParsePublicKey(v: string): PublicKey | string {\n try {\n return new PublicKey(v);\n } catch (e) {\n return v;\n }\n}\n\nexport const MEMO_PROGRAM_ID = new PublicKey(\"MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr\");\nexport const RENT_PROGRAM_ID = new PublicKey(\"SysvarRent111111111111111111111111111111111\");\nexport const CLOCK_PROGRAM_ID = new PublicKey(\"SysvarC1ock11111111111111111111111111111111\");\nexport const METADATA_PROGRAM_ID = new PublicKey(\"metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s\");\nexport const INSTRUCTION_PROGRAM_ID = new PublicKey(\"Sysvar1nstructions1111111111111111111111111\");\nexport const SYSTEM_PROGRAM_ID = SystemProgram.programId;\n\nexport const RAYMint = new PublicKey(\"4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R\");\nexport const PAIMint = new PublicKey(\"Ea5SjE2Y6yvCeW5dYTn7PYMuW5ikXkvbGdcmSnXeaLjS\");\nexport const SRMMint = new PublicKey(\"SRMuApVNdxXokk5GT7XD5cUUgXMBCoAz2LHeuAoKWRt\");\nexport const USDCMint = new PublicKey(\"EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v\");\nexport const USDTMint = new PublicKey(\"Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB\");\nexport const mSOLMint = new PublicKey(\"mSoLzYCxHdYgdzU16g5QSh3i5K3z3KZK7ytfqcJm7So\");\nexport const stSOLMint = new PublicKey(\"7dHbWXmci3dT8UFYWYZweBLXgycu7Y3iL6trKn1Y7ARj\");\nexport const USDHMint = new PublicKey(\"USDH1SM1ojwWUga67PGrgFWUHibbjqMvuMaDkRJTgkX\");\nexport const NRVMint = new PublicKey(\"NRVwhjBQiUPYtfDT5zRBVJajzFQHaBUNtC7SNVvqRFa\");\nexport const ANAMint = new PublicKey(\"ANAxByE6G2WjFp7A4NqtWYXb3mgruyzZYg3spfxe6Lbo\");\nexport const ETHMint = new PublicKey(\"7vfCXTUXx5WJV5JADk17DUJ4ksgau7utNKj4b963voxs\");\nexport const WSOLMint = new PublicKey(\"So11111111111111111111111111111111111111112\");\nexport const SOLMint = PublicKey.default;\n\nexport function solToWSol(mint: PublicKeyish): PublicKey {\n return validateAndParsePublicKey({ publicKey: mint, transformSol: true });\n}\n","import { SOL_INFO } from \"../raydium/token/constant\";\n\nimport { Token } from \"./token\";\n\ninterface CurrencyProps {\n decimals: number;\n symbol?: string;\n name?: string;\n}\n/**\n * A currency is any fungible financial instrument on Solana, including SOL and all SPL tokens.\n * The only instance of the base class `Currency` is SOL.\n */\nexport class Currency {\n public readonly symbol?: string;\n public readonly name?: string;\n public readonly decimals: number;\n\n /**\n * The only instance of the base class `Currency`.\n */\n public static readonly SOL: Currency = new Currency(SOL_INFO);\n\n /**\n * Constructs an instance of the base class `Currency`. The only instance of the base class `Currency` is `Currency.SOL`.\n * @param decimals - decimals of the currency\n * @param symbol - symbol of the currency\n * @param name - name of the currency\n */\n public constructor({ decimals, symbol = \"UNKNOWN\", name = \"UNKNOWN\" }: CurrencyProps) {\n this.decimals = decimals;\n this.symbol = symbol;\n this.name = name;\n }\n\n public equals(other: Currency): boolean {\n return this === other;\n }\n}\n\n/**\n * Compares two currencies for equality\n */\nexport function currencyEquals(currencyA: Currency, currencyB: Currency): boolean {\n if (currencyA instanceof Token && currencyB instanceof Token) {\n return currencyA.equals(currencyB);\n } else if (currencyA instanceof Token || currencyB instanceof Token) {\n return false;\n } else {\n return currencyA === currencyB;\n }\n}\n","import BN from \"bn.js\";\nimport { Rounding } from \"../common\";\nimport { Fraction } from \"./fraction\";\n\nexport const _100_PERCENT = new Fraction(new BN(100));\n\nexport class Percent extends Fraction {\n public toSignificant(significantDigits = 5, format?: object, rounding?: Rounding): string {\n return this.mul(_100_PERCENT).toSignificant(significantDigits, format, rounding);\n }\n\n public toFixed(decimalPlaces = 2, format?: object, rounding?: Rounding): string {\n return this.mul(_100_PERCENT).toFixed(decimalPlaces, format, rounding);\n }\n}\n","import { Rounding } from \"../common\";\nimport { BigNumberish, tenExponential } from \"../common/bignumber\";\nimport { createLogger } from \"../common/logger\";\n\nimport { Fraction } from \"./fraction\";\nimport { Token } from \"./token\";\n\nconst logger = createLogger(\"Raydium_price\");\n\ninterface PriceProps {\n baseToken: Token;\n denominator: BigNumberish;\n quoteToken: Token;\n numerator: BigNumberish;\n}\n\nexport class Price extends Fraction {\n public readonly baseToken: Token; // input i.e. denominator\n public readonly quoteToken: Token; // output i.e. numerator\n // used to adjust the raw fraction w/r/t the decimals of the {base,quote}Token\n public readonly scalar: Fraction;\n\n // denominator and numerator _must_ be raw, i.e. in the native representation\n public constructor(params: PriceProps) {\n const { baseToken, quoteToken, numerator, denominator } = params;\n super(numerator, denominator);\n\n this.baseToken = baseToken;\n this.quoteToken = quoteToken;\n this.scalar = new Fraction(tenExponential(baseToken.decimals), tenExponential(quoteToken.decimals));\n }\n\n public get raw(): Fraction {\n return new Fraction(this.numerator, this.denominator);\n }\n\n public get adjusted(): Fraction {\n return super.mul(this.scalar);\n }\n\n public invert(): Price {\n return new Price({\n baseToken: this.quoteToken,\n quoteToken: this.baseToken,\n denominator: this.numerator,\n numerator: this.denominator,\n });\n }\n\n public mul(other: Price): Price {\n if (this.quoteToken !== other.baseToken) logger.logWithError(\"mul token not equals\");\n\n const fraction = super.mul(other);\n return new Price({\n baseToken: this.baseToken,\n quoteToken: other.quoteToken,\n denominator: fraction.denominator,\n numerator: fraction.numerator,\n });\n }\n\n public toSignificant(significantDigits = this.quoteToken.decimals, format?: object, rounding?: Rounding): string {\n return this.adjusted.toSignificant(significantDigits, format, rounding);\n }\n\n public toFixed(decimalPlaces = this.quoteToken.decimals, format?: object, rounding?: Rounding): string {\n return this.adjusted.toFixed(decimalPlaces, format, rounding);\n }\n}\n","import { Connection, Keypair, PublicKey, EpochInfo, Commitment } from \"@solana/web3.js\";\nimport { merge } from \"lodash\";\n\nimport { Api, API_URL_CONFIG, ApiV3TokenRes, ApiV3Token, JupTokenType, AvailabilityCheckAPI3 } from \"../api\";\nimport { EMPTY_CONNECTION, EMPTY_OWNER } from \"../common/error\";\nimport { createLogger, Logger } from \"../common/logger\";\nimport { Owner } from \"../common/owner\";\nimport { Cluster } from \"../solana\";\n\nimport Account, { TokenAccountDataProp } from \"./account/account\";\nimport Farm from \"./farm/farm\";\nimport Liquidity from \"./liquidity/liquidity\";\nimport { Clmm } from \"./clmm\";\nimport Cpmm from \"./cpmm/cpmm\";\nimport TradeV2 from \"./tradeV2/trade\";\nimport Utils1216 from \"./utils1216\";\nimport MarketV2 from \"./marketV2\";\nimport Launchpad from \"./launchpad/launchpad\";\n\nimport TokenModule from \"./token/token\";\nimport { SignAllTransactions } from \"./type\";\n\nexport interface RaydiumLoadParams extends TokenAccountDataProp, Omit<RaydiumApiBatchRequestParams, \"api\"> {\n /* ================= solana ================= */\n // solana web3 connection\n connection: Connection;\n // solana cluster/network/env\n cluster?: Cluster;\n // user public key\n owner?: PublicKey | Keypair;\n /* ================= api ================= */\n // api request interval in ms, -1 means never request again, 0 means always use fresh data, default is 5 mins (5 * 60 * 1000)\n apiRequestInterval?: number;\n // api request timeout in ms, default is 10 secs (10 * 1000)\n apiRequestTimeout?: number;\n apiCacheTime?: number;\n signAllTransactions?: SignAllTransactions;\n urlConfigs?: API_URL_CONFIG;\n logRequests?: boolean;\n logCount?: number;\n jupTokenType?: JupTokenType;\n disableFeatureCheck?: boolean;\n disableLoadToken?: boolean;\n blockhashCommitment?: Commitment;\n loopMultiTxStatus?: boolean;\n}\n\nexport interface RaydiumApiBatchRequestParams {\n api: Api;\n defaultChainTimeOffset?: number;\n defaultChainTime?: number;\n}\n\nexport type RaydiumConstructorParams = Required<RaydiumLoadParams> & RaydiumApiBatchRequestParams;\n\ninterface DataBase<T> {\n fetched: number;\n data: T;\n extInfo?: Record<string, any>;\n}\ninterface ApiData {\n tokens?: DataBase<ApiV3Token[]>;\n\n // v3 data\n tokenList?: DataBase<ApiV3TokenRes>;\n jupTokenList?: DataBase<ApiV3Token[]>;\n}\n\nexport class Raydium {\n public cluster: Cluster;\n public farm: Farm;\n public account: Account;\n public liquidity: Liquidity;\n public clmm: Clmm;\n public cpmm: Cpmm;\n public tradeV2: TradeV2;\n public utils1216: Utils1216;\n public marketV2: MarketV2;\n public token: TokenModule;\n public launchpad: Launchpad;\n public rawBalances: Map<string, string> = new Map();\n public apiData: ApiData;\n public availability: Partial<AvailabilityCheckAPI3>;\n public blockhashCommitment: Commitment;\n public loopMultiTxStatus?: boolean;\n\n private _connection: Connection;\n private _owner: Owner | undefined;\n public api: Api;\n private _apiCacheTime: number;\n private _signAllTransactions?: SignAllTransactions;\n private logger: Logger;\n private _chainTime?: {\n fetched: number;\n value: {\n chainTime: number;\n offset: number;\n };\n };\n private _epochInfo?: {\n fetched: number;\n value: EpochInfo;\n };\n\n constructor(config: RaydiumConstructorParams) {\n const {\n connection,\n cluster,\n owner,\n api,\n defaultChainTime,\n defaultChainTimeOffset,\n apiCacheTime,\n blockhashCommitment = \"confirmed\",\n loopMultiTxStatus,\n } = config;\n\n this._connection = connection;\n this.cluster = cluster || \"mainnet\";\n this._owner = owner ? new Owner(owner) : undefined;\n this._signAllTransactions = config.signAllTransactions;\n this.blockhashCommitment = blockhashCommitment;\n this.loopMultiTxStatus = loopMultiTxStatus;\n\n this.api = api;\n this._apiCacheTime = apiCacheTime || 5 * 60 * 1000;\n this.logger = createLogger(\"Raydium\");\n this.farm = new Farm({ scope: this, moduleName: \"Raydium_Farm\" });\n this.account = new Account({\n scope: this,\n moduleName: \"Raydium_Account\",\n tokenAccounts: config.tokenAccounts,\n tokenAccountRawInfos: config.tokenAccountRawInfos,\n });\n this.liquidity = new Liquidity({ scope: this, moduleName: \"Raydium_LiquidityV2\" });\n this.token = new TokenModule({ scope: this, moduleName: \"Raydium_tokenV2\" });\n this.tradeV2 = new TradeV2({ scope: this, moduleName: \"Raydium_tradeV2\" });\n this.clmm = new Clmm({ scope: this, moduleName: \"Raydium_clmm\" });\n this.cpmm = new Cpmm({ scope: this, moduleName: \"Raydium_cpmm\" });\n this.utils1216 = new Utils1216({ scope: this, moduleName: \"Raydium_utils1216\" });\n this.marketV2 = new MarketV2({ scope: this, moduleName: \"Raydium_marketV2\" });\n this.launchpad = new Launchpad({ scope: this, moduleName: \"Raydium_lauchpad\" });\n\n this.availability = {};\n const now = new Date().getTime();\n this.apiData = {};\n\n if (defaultChainTimeOffset)\n this._chainTime = {\n fetched: now,\n value: {\n chainTime: defaultChainTime || Date.now() - defaultChainTimeOffset,\n offset: defaultChainTimeOffset,\n },\n };\n }\n\n static async load(config: RaydiumLoadParams): Promise<Raydium> {\n const custom: Required<RaydiumLoadParams> = merge(\n // default\n {\n cluster: \"mainnet\",\n owner: null,\n apiRequestInterval: 5 * 60 * 1000,\n apiRequestTimeout: 10 * 1000,\n },\n config,\n );\n const { cluster, apiRequestTimeout, logCount, logRequests, urlConfigs } = custom;\n\n const api = new Api({ cluster, timeout: apiRequestTimeout, urlConfigs, logCount, logRequests });\n const raydium = new Raydium({\n ...custom,\n api,\n });\n\n await raydium.fetchAvailabilityStatus(config.disableFeatureCheck ?? true);\n if (!config.disableLoadToken)\n await raydium.token.load({\n type: config.jupTokenType,\n });\n\n return raydium;\n }\n\n get owner(): Owner | undefined {\n return this._owner;\n }\n get ownerPubKey(): PublicKey {\n if (!this._owner) throw new Error(EMPTY_OWNER);\n return this._owner.publicKey;\n }\n public setOwner(owner?: PublicKey | Keypair): Raydium {\n this._owner = owner ? new Owner(owner) : undefined;\n this.account.resetTokenAccounts();\n return this;\n }\n get connection(): Connection {\n if (!this._connection) throw new Error(EMPTY_CONNECTION);\n return this._connection;\n }\n public setConnection(connection: Connection): Raydium {\n this._connection = connection;\n return this;\n }\n get signAllTransactions(): SignAllTransactions | undefined {\n return this._signAllTransactions;\n }\n public setSignAllTransactions(signAllTransactions?: SignAllTransactions): Raydium {\n this._signAllTransactions = signAllTransactions;\n return this;\n }\n\n public checkOwner(): void {\n if (!this.owner) {\n console.error(EMPTY_OWNER);\n throw new Error(EMPTY_OWNER);\n }\n }\n\n private isCacheInvalidate(time: number): boolean {\n return new Date().getTime() - time > this._apiCacheTime;\n }\n\n public async fetchChainTime(): Promise<void> {\n try {\n const data = await this.api.getChainTimeOffset();\n this._chainTime = {\n fetched: Date.now(),\n value: {\n chainTime: Date.now() + data.offset * 1000,\n offset: data.offset * 1000,\n },\n };\n } catch {\n this._chainTime = undefined;\n }\n }\n\n public async fetchV3TokenList(forceUpdate?: boolean): Promise<ApiV3TokenRes> {\n if (this.apiData.tokenList && !this.isCacheInvalidate(this.apiData.tokenList.fetched) && !forceUpdate)\n return this.apiData.tokenList.data;\n try {\n const raydiumList = await this.api.getTokenList();\n const dataObject = {\n fetched: Date.now(),\n data: raydiumList,\n };\n this.apiData.tokenList = dataObject;\n\n return dataObject.data;\n } catch (e) {\n console.error(e);\n return {\n mintList: [],\n blacklist: [],\n whiteList: [],\n };\n }\n }\n\n public async fetchJupTokenList(forceUpdate?: boolean): Promise<ApiV3Token[]> {\n if (this.cluster === \"devnet\") return [];\n const prevFetched = this.apiData.jupTokenList;\n if (prevFetched && !this.isCacheInvalidate(prevFetched.fetched) && !forceUpdate) return prevFetched.data;\n try {\n const jupList = await this.api.getJupTokenList();\n\n this.apiData.jupTokenList = {\n fetched: Date.now(),\n data: jupList.map((t) => ({\n ...t,\n mintAuthority: t.mint_authority || undefined,\n freezeAuthority: t.freeze_authority || undefined,\n })),\n };\n\n return this.apiData.jupTokenList.data;\n } catch (e) {\n console.error(e);\n return [];\n }\n }\n\n get chainTimeData(): { offset: number; chainTime: number } | undefined {\n return this._chainTime?.value;\n }\n\n public async chainTimeOffset(): Promise<number> {\n if (this._chainTime && Date.now() - this._chainTime.fetched <= 1000 * 60 * 5) return this._chainTime.value.offset;\n await this.fetchChainTime();\n return this._chainTime?.value.offset || 0;\n }\n\n public async currentBlockChainTime(): Promise<number> {\n if (this._chainTime && Date.now() - this._chainTime.fetched <= 1000 * 60 * 5)\n return this._chainTime.value.chainTime;\n await this.fetchChainTime();\n return this._chainTime?.value.chainTime || Date.now();\n }\n\n public async fetchEpochInfo(): Promise<EpochInfo> {\n if (this._epochInfo && Date.now() - this._epochInfo.fetched <= 1000 * 30) return this._epochInfo.value;\n this._epochInfo = {\n fetched: Date.now(),\n value: await this.connection.getEpochInfo(),\n };\n return this._epochInfo.value;\n }\n\n public async fetchAvailabilityStatus(skipCheck?: boolean): Promise<Partial<AvailabilityCheckAPI3>> {\n if (skipCheck) return {};\n try {\n const data = await this.api.fetchAvailabilityStatus();\n const isAllDisabled = data.all === false;\n this.availability = {\n all: data.all,\n swap: isAllDisabled ? false : data.swap,\n createConcentratedPosition: isAllDisabled ? false : data.createConcentratedPosition,\n addConcentratedPosition: isAllDisabled ? false : data.addConcentratedPosition,\n addStandardPosition: isAllDisabled ? false : data.addStandardPosition,\n removeConcentratedPosition: isAllDisabled ? false : data.removeConcentratedPosition,\n removeStandardPosition: isAllDisabled ? false : data.removeStandardPosition,\n addFarm: isAllDisabled ? false : data.addFarm,\n removeFarm: isAllDisabled ? false : data.removeFarm,\n };\n return data;\n } catch {\n return {};\n }\n }\n}\n","import axios, { AxiosInstance } from \"axios\";\n\nimport { createLogger, sleep } from \"../common\";\nimport { Cluster } from \"../solana\";\n\nimport {\n ApiClmmConfigInfo,\n ApiCpmmConfigInfo,\n ApiV3Token,\n FetchPoolParams,\n PoolsApiReturn,\n ApiV3PoolInfoItem,\n PoolKeys,\n FormatFarmInfoOut,\n FormatFarmKeyOut,\n AvailabilityCheckAPI3,\n PoolFetchType,\n JupToken,\n ApiLaunchConfig,\n ApiClmmDynamicConfigInfo,\n FarmPositionData,\n CpmmLockInfo,\n} from \"./type\";\nimport { API_URLS, API_URL_CONFIG, DEV_API_URLS } from \"./url\";\nimport { updateReqHistory } from \"./utils\";\nimport { PublicKey } from \"@solana/web3.js\";\nimport { solToWSol } from \"../common\";\n\nconst logger = createLogger(\"Raydium_Api\");\nconst poolKeysCache: Map<string, PoolKeys> = new Map();\nconst cacheLaunchConfigs: Map<Cluster, ApiLaunchConfig[]> = new Map();\n\nexport async function endlessRetry<T>(name: string, call: () => Promise<T>, interval = 1000): Promise<T> {\n let result: T | undefined;\n\n while (result == undefined) {\n try {\n logger.debug(`Request ${name} through endlessRetry`);\n result = await call();\n } catch (err) {\n logger.error(`Request ${name} failed, retry after ${interval} ms`, err);\n await sleep(interval);\n }\n }\n\n return result;\n}\n\nexport interface ApiProps {\n cluster: Cluster;\n timeout: number;\n logRequests?: boolean;\n logCount?: number;\n urlConfigs?: API_URL_CONFIG;\n}\n\nexport class Api {\n public cluster: Cluster;\n\n public api: AxiosInstance;\n public logCount: number;\n\n public urlConfigs: API_URL_CONFIG;\n\n constructor({ cluster, timeout, logRequests, logCount, urlConfigs }: ApiProps) {\n this.cluster = cluster;\n this.urlConfigs = urlConfigs || {};\n this.logCount = logCount || 1000;\n\n this.api = axios.create({\n baseURL: this.urlConfigs.BASE_HOST || (this.cluster === \"devnet\" ? DEV_API_URLS.BASE_HOST : API_URLS.BASE_HOST),\n timeout,\n });\n\n this.api.interceptors.request.use(\n (config) => {\n // before request\n const { method, baseURL, url } = config;\n\n logger.debug(`${method?.toUpperCase()} ${baseURL}${url}`);\n\n return config;\n },\n (error) => {\n // request error\n logger.error(`Request failed`);\n\n return Promise.reject(error);\n },\n );\n this.api.interceptors.response.use(\n (response) => {\n // 2xx\n const { config, data, status } = response;\n const { method, baseURL, url } = config;\n\n if (logRequests) {\n updateReqHistory({\n status,\n url: `${baseURL}${url}`,\n params: config.params,\n data,\n logCount: this.logCount,\n });\n }\n\n logger.debug(`${method?.toUpperCase()} ${baseURL}${url} ${status}`);\n\n return data;\n },\n (error) => {\n // https://axios-http.com/docs/handling_errors\n // not 2xx\n const { config, response = {} } = error;\n const { status } = response;\n const { method, baseURL, url } = config;\n\n if (logRequests) {\n updateReqHistory({\n status,\n url: `${baseURL}${url}`,\n params: config.params,\n data: error.message,\n logCount: this.logCount,\n });\n }\n\n logger.error(`${method.toUpperCase()} ${baseURL}${url} ${status || error.message}`);\n\n return Promise.reject(error);\n },\n );\n }\n\n async getClmmConfigs(): Promise<ApiClmmConfigInfo[]> {\n const res = await this.api.get(this.urlConfigs.CLMM_CONFIG || API_URLS.CLMM_CONFIG);\n return res.data;\n }\n\n async getClmmDynamicConfigs(): Promise<ApiClmmDynamicConfigInfo[]> {\n const res = await this.api.get(this.urlConfigs.CLMM_DYNAMIC_CONFIG || API_URLS.CLMM_DYNAMIC_CONFIG);\n return res.data;\n }\n\n async getCpmmConfigs(): Promise<ApiCpmmConfigInfo[]> {\n const res = await this.api.get(this.urlConfigs.CPMM_CONFIG || API_URLS.CPMM_CONFIG);\n return res.data;\n }\n\n async getClmmPoolLines(poolId: string): Promise<{ price: string; liquidity: string }[]> {\n const res = await this.api.get(`${this.urlConfigs.POOL_POSITION_LINE || API_URLS.POOL_POSITION_LINE}?id=${poolId}`);\n return res.data;\n }\n\n async getBlockSlotCountForSecond(endpointUrl?: string): Promise<number> {\n if (!endpointUrl) return 2;\n const res: {\n id: string;\n jsonrpc: string;\n result: { numSlots: number; numTransactions: number; samplePeriodSecs: number; slot: number }[];\n } = await axios.post(endpointUrl, {\n id: \"getRecentPerformanceSamples\",\n jsonrpc: \"2.0\",\n method: \"getRecentPerformanceSamples\",\n params: [4],\n });\n const slotList = res.result.map((data) => data.numSlots);\n return slotList.reduce((a, b) => a + b, 0) / slotList.length / 60;\n }\n\n async getChainTimeOffset(): Promise<{ offset: number }> {\n const res = await this.api.get(this.urlConfigs.CHAIN_TIME || API_URLS.CHAIN_TIME);\n return res.data;\n }\n\n async getRpcs(): Promise<{\n rpcs: { batch: boolean; name: string; url: string; weight: number }[];\n strategy: string;\n }> {\n return this.api.get(this.urlConfigs.RPCS || API_URLS.RPCS);\n }\n\n async getTokenList(): Promise<{ mintList: ApiV3Token[]; blacklist: string[]; whiteList: string[] }> {\n const res = await this.api.get(this.urlConfigs.TOKEN_LIST || API_URLS.TOKEN_LIST);\n return res.data;\n }\n\n async getJupTokenList(): Promise<\n (ApiV3Token & {\n freeze_authority: string | null;\n mint_authority: string | null;\n permanent_delegate: string | null;\n minted_at: string;\n })[]\n > {\n const r: JupToken[] = await this.api.get(\"\", {\n baseURL: this.urlConfigs.JUP_TOKEN_LIST || API_URLS.JUP_TOKEN_LIST,\n });\n return r.map((t) => ({\n ...t,\n chainId: 101,\n programId: t.tokenProgram,\n address: t.id,\n logoURI: t.icon,\n extensions: {},\n freeze_authority: null,\n permanent_delegate: null,\n mint_authority: t.mintAuthority || null,\n minted_at: Date.now().toString(),\n }));\n }\n\n async getTokenInfo(mint: (string | PublicKey)[]): Promise<ApiV3Token[]> {\n const res = await this.api.get(\n (this.urlConfigs.MINT_INFO_ID || API_URLS.MINT_INFO_ID) + `?mints=${mint.map((m) => m.toString()).join(\",\")}`,\n );\n return res.data;\n }\n\n async getPoolList(props: FetchPoolParams = {}): Promise<PoolsApiReturn> {\n const { type = \"all\", sort = \"liquidity\", order = \"desc\", showFarms = false, nextPageId, pageSize = 100 } = props;\n const res = await this.api.get<PoolsApiReturn>(\n (this.urlConfigs.POOL_LIST || API_URLS.POOL_LIST) +\n `?size=${pageSize}&hasReward=${showFarms}${type && type !== \"all\" ? `&poolType=${type}` : \"\"}${\n sort ? `&sortField=${sort}` : \"\"\n }${order ? `&sortType=${order}` : \"\"}${nextPageId ? `&nextPageId=${nextPageId}` : \"\"}`,\n );\n return res.data;\n }\n\n async fetchPoolById(props: { ids: string }): Promise<ApiV3PoolInfoItem[]> {\n const { ids } = props;\n const res = await this.api.get((this.urlConfigs.POOL_SEARCH_BY_ID || API_URLS.POOL_SEARCH_BY_ID) + `?ids=${ids}`);\n return res.data;\n }\n\n async fetchPoolKeysById(props: { idList: string[] }): Promise<PoolKeys[]> {\n const { idList } = props;\n\n const cacheList: PoolKeys[] = [];\n\n const readyList = idList.filter((poolId) => {\n if (poolKeysCache.has(poolId)) {\n cacheList.push(poolKeysCache.get(poolId)!);\n return false;\n }\n return true;\n });\n\n let data: PoolKeys[] = [];\n if (readyList.length) {\n const res = await this.api.get<PoolKeys[]>(\n (this.urlConfigs.POOL_KEY_BY_ID || API_URLS.POOL_KEY_BY_ID) + `?ids=${readyList.join(\",\")}`,\n );\n data = res.data.filter(Boolean);\n data.forEach((poolKey) => {\n poolKeysCache.set(poolKey.id, poolKey);\n });\n }\n\n return cacheList.concat(data);\n }\n\n async fetchPoolByMints(\n props: {\n mint1: string | PublicKey;\n mint2?: string | PublicKey;\n } & FetchPoolParams,\n ): Promise<PoolsApiReturn> {\n const { mint1: propMint1, mint2: propMint2, type = PoolFetchType.All, sort, order = \"desc\", nextPageId } = props;\n\n const [mint1, mint2] = [\n propMint1 ? solToWSol(propMint1).toBase58() : propMint1,\n propMint2 && propMint2 !== \"undefined\" ? solToWSol(propMint2).toBase58() : \"\",\n ];\n const [baseMint, quoteMint] = mint2 && mint1 > mint2 ? [mint2, mint1] : [mint1, mint2];\n\n if (!mint1 && !mint2) throw new Error(\"not search mints provided\");\n const res = await this.api.get(\n (this.urlConfigs.POOL_SEARCH_MINT || API_URLS.POOL_SEARCH_MINT) +\n `?size=100&mint1=${baseMint}${quoteMint ? `&mint2=${quoteMint}` : \"\"}${\n type && type !== \"all\" ? `&poolType=${type}` : \"\"\n }${sort ? `&sortField=${sort}` : \"\"}${order ? `&sortType=${order}` : \"\"}${\n nextPageId ? `&nextPageId=${nextPageId}` : \"\"\n }`,\n );\n return res.data;\n }\n\n async fetchPoolByLpMints(props: { ids: string }): Promise<ApiV3PoolInfoItem[]> {\n const { ids } = props;\n const res = await this.api.get((this.urlConfigs.POOL_SEARCH_LP || API_URLS.POOL_SEARCH_LP) + `?lps=${ids}`);\n return res.data;\n }\n\n async fetchFarmInfoById(props: { ids: string }): Promise<FormatFarmInfoOut[]> {\n const { ids } = props;\n\n const res = await this.api.get<FormatFarmInfoOut[]>(\n (this.urlConfigs.FARM_INFO || API_URLS.FARM_INFO) + `?ids=${ids}`,\n );\n return res.data;\n }\n\n async fetchFarmKeysById(props: { ids: string }): Promise<FormatFarmKeyOut[]> {\n const { ids } = props;\n\n const res = await this.api.get<FormatFarmKeyOut[]>(\n (this.urlConfigs.FARM_KEYS || API_URLS.FARM_KEYS) + `?ids=${ids}`,\n );\n return res.data;\n }\n\n async fetchAvailabilityStatus(): Promise<AvailabilityCheckAPI3> {\n const res = await this.api.get<AvailabilityCheckAPI3>(\n this.urlConfigs.CHECK_AVAILABILITY || API_URLS.CHECK_AVAILABILITY,\n );\n return res.data;\n }\n\n async fetchLaunchConfigs(): Promise<ApiLaunchConfig[]> {\n if (cacheLaunchConfigs.get(this.cluster)?.length) {\n return cacheLaunchConfigs.get(this.cluster)!;\n }\n const res = await this.api.get<{\n id: string;\n success: boolean;\n data: ApiLaunchConfig[];\n }>(\n this.cluster === \"devnet\"\n ? \"https://launch-mint-v1-devnet.raydium.io/main/configs\"\n : \"https://launch-mint-v1.raydium.io/main/configs\",\n );\n cacheLaunchConfigs.set(this.cluster, res.data.data);\n return res.data.data;\n }\n\n /**\n * {\n * [lpMint]: {\n * [farmId]: {\n * [userVault]: data\n * }\n * }\n * }\n */\n async fetchFarmPositions(owner = \"\"): Promise<FarmPositionData> {\n const res = await this.api.get<FarmPositionData>(\n `${this.urlConfigs.OWNER_BASE_HOST || API_URLS.OWNER_BASE_HOST}` +\n (this.urlConfigs.OWNER_STAKE_FARMS || API_URLS.OWNER_STAKE_FARMS).replace(\"{owner}\", owner),\n );\n return res.data;\n }\n\n async fetchCpmmLockInfo(key: string | PublicKey): Promise<CpmmLockInfo> {\n const res = await this.api.get(`${this.urlConfigs.CPMM_LOCK || API_URLS.CPMM_LOCK}?id=${key.toString()}`);\n return res as unknown as CpmmLockInfo;\n }\n}\n","export const API_URLS = {\n BASE_HOST: \"https://api-v3.raydium.io\",\n OWNER_BASE_HOST: \"https://owner-v1.raydium.io\",\n SERVICE_BASE_HOST: \"https://service.raydium.io\",\n MONITOR_BASE_HOST: \"https://monitor.raydium.io\",\n SERVICE_1_BASE_HOST: \"https://service-v1.raydium.io\",\n TEMP_HOST: \"https://temp-api-v1.raydium.io\",\n\n SEND_TRANSACTION: \"/send-transaction\",\n FARM_ARP: \"/main/farm/info\",\n FARM_ARP_LINE: \"/main/farm-apr-tv\",\n\n CLMM_CONFIG: \"/main/clmm-config\",\n CPMM_CONFIG: \"/main/cpmm-config\",\n\n CLMM_DYNAMIC_CONFIG: \"/main/clmm-dynamic-config\",\n\n VERSION: \"/main/version\",\n\n // api v3\n CHECK_AVAILABILITY: \"/v3/main/AvailabilityCheckAPI\",\n RPCS: \"/main/rpcs\",\n INFO: \"/main/info\",\n STAKE_POOLS: \"/main/stake-pools\",\n CHAIN_TIME: \"/main/chain-time\",\n\n TOKEN_LIST: \"/mint/list\",\n MINT_INFO_ID: \"/mint/ids\",\n\n JUP_TOKEN_LIST: \"https://lite-api.jup.ag/tokens/v2/tag?query=verified\",\n /**\n * poolType: Concentrated / Standard // optional\n * sortField: liquidity / volume24h / fee24h / apr24h (more time unit 7d/30d e.g. volume27d) // optional\n * sortType: desc / asc // optional\n * size: 100\n * hasReward: true or false // optional\n */\n POOL_LIST: \"/pools/info/list-v2\",\n /**\n * ?ids=idList.join(',')\n */\n POOL_SEARCH_BY_ID: \"/pools/info/ids\",\n /**\n * mint1/mint2: search pool by mint\n * poolSortField: {liquidity | volume_24h / 7d / 30d | fee_24h / 7d / 30d | apr_24h / 7d / 30d}\n * poolType: {all, concentrated, standard, allFarm, concentratedFarm, standardFarm}\n * sortType: {desc/asc}\n * page: number\n * pageSize: number\n */\n POOL_SEARCH_MINT: \"/pools/info/list-v2\",\n /** ?lps=lpList.join(',') */\n POOL_SEARCH_LP: \"/pools/info/lps\",\n /** ?ids=idList.join(',') */\n POOL_KEY_BY_ID: \"/pools/key/ids\",\n /** ?id=string */\n POOL_LIQUIDITY_LINE: \"/pools/line/liquidity\",\n POOL_POSITION_LINE: \"/pools/line/position\",\n\n FARM_INFO: \"/farms/info/ids\",\n /** ?lp=string&pageSize=100&page=number */\n FARM_LP_INFO: \"/farms/info/lp\",\n FARM_KEYS: \"/farms/key/ids\",\n\n OWNER_CREATED_FARM: \"/create-pool/{owner}\",\n OWNER_STAKE_FARMS: \"/position/stake/{owner}\",\n OWNER_LOCK_POSITION: \"/position/clmm-lock/{owner}\",\n SWAP_HOST: \"https://transaction-v1.raydium.io\",\n SWAP_COMPUTE: \"/compute/\",\n SWAP_TX: \"/transaction/\",\n MINT_PRICE: \"/mint/price\",\n MIGRATE_CONFIG: \"/main/migrate-lp\",\n PRIORITY_FEE: \"/main/auto-fee\",\n\n CPMM_LOCK: \"https://dynamic-ipfs.raydium.io/lock/cpmm/position\",\n\n LAUNCH_AUTH_HOST: \"https://launch-auth-v1.raydium.io\",\n LAUNCH_COMMENT_HOST: \"hhttps://launch-forum-v1.raydium.io\",\n LAUNCH_HISTORY_HOST: \"https://launch-history-v1.raydium.io\",\n LAUNCH_MINT_HOST: \"https://launch-mint-v1.raydium.io\",\n};\n\nexport const DEV_API_URLS = {\n ...API_URLS,\n BASE_HOST: \"https://api-v3-devnet.raydium.io\",\n OWNER_BASE_HOST: \"https://owner-v1-devnet.raydium.io\",\n SWAP_HOST: \"https://transaction-v1-devnet.raydium.io\",\n CPMM_LOCK: \"https://dynamic-ipfs-devnet.raydium.io/lock/cpmm/position\",\n TEMP_HOST: \"https://temp-api-v1-devnet.raydium.io\",\n\n LAUNCH_AUTH_HOST: \"https://launch-auth-v1-devnet.raydium.io\",\n LAUNCH_COMMENT_HOST: \"https://launch-forum-v1-devnet.raydium.io\",\n LAUNCH_HISTORY_HOST: \"https://launch-history-v1-devnet.raydium.io\",\n LAUNCH_MINT_HOST: \"https://launch-mint-v1-devnet.raydium.io\",\n};\n\nexport type API_URL_CONFIG = Partial<typeof API_URLS>;\n","import { Commitment, PublicKey, SystemProgram, TransactionInstruction } from \"@solana/web3.js\";\nimport { BigNumberish, getATAAddress, InstructionType, WSOLMint } from \"@/common\";\nimport {\n AccountLayout,\n createAssociatedTokenAccountIdempotentInstruction,\n TOKEN_PROGRAM_ID,\n TOKEN_2022_PROGRAM_ID,\n} from \"@solana/spl-token\";\nimport { AddInstructionParam } from \"@/common/txTool/txTool\";\n\nimport ModuleBase, { ModuleBaseProps } from \"../moduleBase\";\nimport {\n closeAccountInstruction,\n createWSolAccountInstructions,\n initTokenAccountInstruction,\n makeTransferInstruction,\n} from \"./instruction\";\nimport { GetOrCreateTokenAccountParams, HandleTokenAccountParams, TokenAccount, TokenAccountRaw } from \"./types\";\nimport { generatePubKey, parseTokenAccountResp } from \"./util\";\n\nexport interface TokenAccountDataProp {\n tokenAccounts?: TokenAccount[];\n tokenAccountRawInfos?: TokenAccountRaw[];\n notSubscribeAccountChange?: boolean;\n}\nexport default class Account extends ModuleBase {\n private _tokenAccounts: TokenAccount[] = [];\n private _tokenAccountRawInfos: TokenAccountRaw[] = [];\n private _accountChangeListenerId?: number;\n private _accountListener: ((data: TokenAccountDataProp) => void)[] = [];\n private _clientOwnedToken = false;\n private _notSubscribeAccountChange = false;\n private _accountFetchTime = 0;\n\n constructor(params: TokenAccountDataProp & ModuleBaseProps) {\n super(params);\n const { tokenAccounts, tokenAccountRawInfos, notSubscribeAccountChange } = params;\n this._tokenAccounts = tokenAccounts || [];\n this._tokenAccountRawInfos = tokenAccountRawInfos || [];\n this._notSubscribeAccountChange = notSubscribeAccountChange ?? true;\n this._clientOwnedToken = !!(tokenAccounts || tokenAccountRawInfos);\n }\n\n get tokenAccounts(): TokenAccount[] {\n return this._tokenAccounts;\n }\n get tokenAccountRawInfos(): TokenAccountRaw[] {\n return this._tokenAccountRawInfos;\n }\n\n set notSubscribeAccountChange(subscribe: boolean) {\n this._notSubscribeAccountChange = subscribe;\n }\n\n public updateTokenAccount({ tokenAccounts, tokenAccountRawInfos }: TokenAccountDataProp): Account {\n if (tokenAccounts) this._tokenAccounts = tokenAccounts;\n if (tokenAccountRawInfos) this._tokenAccountRawInfos = tokenAccountRawInfos;\n this._accountChangeListenerId && this.scope.connection.removeAccountChangeListener(this._accountChangeListenerId);\n this._accountChangeListenerId = undefined;\n this._clientOwnedToken = true;\n return this;\n }\n\n public addAccountChangeListener(cbk: (data: TokenAccountDataProp) => void): Account {\n this._accountListener.push(cbk);\n return this;\n }\n\n public removeAccountChangeListener(cbk: (data: TokenAccountDataProp) => void): Account {\n this._accountListener = this._accountListener.filter((listener) => listener !== cbk);\n return this;\n }\n\n public getAssociatedTokenAccount(mint: PublicKey, programId?: PublicKey): PublicKey {\n return getATAAddress(this.scope.ownerPubKey, mint, programId).publicKey;\n }\n\n public resetTokenAccounts(): void {\n if (this._clientOwnedToken) return;\n this._tokenAccounts = [];\n this._tokenAccountRawInfos = [];\n }\n\n public async fetchWalletTokenAccounts(config?: { forceUpdate?: boolean; commitment?: Commitment }): Promise<{\n tokenAccounts: TokenAccount[];\n tokenAccountRawInfos: TokenAccountRaw[];\n }> {\n if (\n this._clientOwnedToken ||\n (!config?.forceUpdate &&\n this._tokenAccounts.length &&\n Date.now() - this._accountFetchTime < (this._notSubscribeAccountChange ? 1000 * 5 : 1000 * 60 * 3))\n ) {\n return {\n tokenAccounts: this._tokenAccounts,\n tokenAccountRawInfos: this._tokenAccountRawInfos,\n };\n }\n this.scope.checkOwner();\n\n const defaultConfig = {};\n const customConfig = { ...defaultConfig, ...config };\n\n const [solAccountResp, ownerTokenAccountResp, ownerToken2022AccountResp] = await Promise.all([\n this.scope.connection.getAccountInfo(this.scope.ownerPubKey, customConfig.commitment),\n this.scope.connection.getTokenAccountsByOwner(\n this.scope.ownerPubKey,\n { programId: TOKEN_PROGRAM_ID },\n customConfig.commitment,\n ),\n this.scope.connection.getTokenAccountsByOwner(\n this.scope.ownerPubKey,\n { programId: TOKEN_2022_PROGRAM_ID },\n customConfig.commitment,\n ),\n ]);\n\n const { tokenAccounts, tokenAccountRawInfos } = parseTokenAccountResp({\n owner: this.scope.ownerPubKey,\n solAccountResp,\n tokenAccountResp: {\n context: ownerTokenAccountResp.context,\n value: [...ownerTokenAccountResp.value, ...ownerToken2022AccountResp.value],\n },\n });\n\n this._tokenAccounts = tokenAccounts;\n this._tokenAccountRawInfos = tokenAccountRawInfos;\n\n this._accountFetchTime = Date.now();\n\n if (!this._notSubscribeAccountChange) {\n this._accountChangeListenerId && this.scope.connection.removeAccountChangeListener(this._accountChangeListenerId);\n this._accountChangeListenerId = this.scope.connection.onAccountChange(\n this.scope.ownerPubKey,\n () => {\n this.fetchWalletTokenAccounts({ forceUpdate: true });\n this._accountListener.forEach((cb) =>\n cb({ tokenAccounts: this._tokenAccounts, tokenAccountRawInfos: this._tokenAccountRawInfos }),\n );\n },\n { commitment: config?.commitment },\n );\n }\n\n return { tokenAccounts, tokenAccountRawInfos };\n }\n\n public clearAccountChangeCkb(): void {\n if (this._accountChangeListenerId !== undefined)\n this.scope.connection.removeAccountChangeListener(this._accountChangeListenerId);\n }\n\n // user token account needed, old _selectTokenAccount\n public async getCreatedTokenAccount({\n mint,\n programId = TOKEN_PROGRAM_ID,\n associatedOnly = true,\n }: {\n mint: PublicKey;\n programId?: PublicKey;\n associatedOnly?: boolean;\n }): Promise<PublicKey | undefined> {\n await this.fetchWalletTokenAccounts();\n const tokenAccounts = this._tokenAccounts\n .filter(({ mint: accountMint }) => accountMint?.equals(mint))\n // sort by balance\n .sort((a, b) => (a.amount.lt(b.amount) ? 1 : -1));\n\n const ata = this.getAssociatedTokenAccount(mint, programId);\n for (const tokenAccount of tokenAccounts) {\n const { publicKey } = tokenAccount;\n if (publicKey) {\n if (!associatedOnly || (associatedOnly && ata.equals(publicKey))) return publicKey;\n }\n }\n }\n\n // old _selectOrCreateTokenAccount\n public async getOrCreateTokenAccount(params: GetOrCreateTokenAccountParams): Promise<{\n account?: PublicKey;\n instructionParams?: AddInstructionParam;\n }> {\n await this.fetchWalletTokenAccounts();\n const {\n mint,\n createInfo,\n associatedOnly,\n owner,\n notUseTokenAccount = false,\n skipCloseAccount = false,\n checkCreateATAOwner = false,\n assignSeed,\n } = params;\n const tokenProgram = new PublicKey(params.tokenProgram || TOKEN_PROGRAM_ID);\n const ata = this.getAssociatedTokenAccount(mint, new PublicKey(tokenProgram));\n const accounts = (notUseTokenAccount ? [] : this.tokenAccountRawInfos)\n .filter((i) => i.accountInfo.mint.equals(mint) && (!associatedOnly || i.pubkey.equals(ata)))\n .sort((a, b) => (a.accountInfo.amount.lt(b.accountInfo.amount) ? 1 : -1));\n // find token or don't need create\n if (createInfo === undefined || accounts.length > 0) {\n return accounts.length > 0 ? { account: accounts[0].pubkey } : {};\n }\n\n const newTxInstructions: AddInstructionParam = {\n instructions: [],\n endInstructions: [],\n signers: [],\n instructionTypes: [],\n endInstructionTypes: [],\n };\n\n if (associatedOnly) {\n const _createATAIns = createAssociatedTokenAccountIdempotentInstruction(\n createInfo.payer || owner,\n ata,\n owner,\n mint,\n tokenProgram,\n );\n const _ataInTokenAcc = this.tokenAccountRawInfos.find((i) => i.pubkey.equals(ata));\n if (checkCreateATAOwner) {\n const ataInfo = await this.scope.connection.getAccountInfo(ata);\n if (ataInfo === null) {\n newTxInstructions.instructions?.push(_createATAIns);\n newTxInstructions.instructionTypes!.push(InstructionType.CreateATA);\n } else if (\n ataInfo.owner.equals(tokenProgram) &&\n AccountLayout.decode(ataInfo.data).mint.equals(mint) &&\n AccountLayout.decode(ataInfo.data).owner.equals(owner)\n ) {\n /* empty */\n } else {\n throw Error(`create ata check error -> mint: ${mint.toString()}, ata: ${ata.toString()}`);\n }\n } else if (_ataInTokenAcc === undefined) {\n newTxInstructions.instructions!.push(_createATAIns);\n newTxInstructions.instructionTypes!.push(InstructionType.CreateATA);\n }\n if (mint.equals(WSOLMint) && createInfo.amount) {\n const txInstruction = await createWSolAccountInstructions({\n connection: this.scope.connection,\n owner: this.scope.ownerPubKey,\n payer: createInfo.payer || this.scope.ownerPubKey,\n amount: createInfo.amount ?? 0,\n skipCloseAccount,\n });\n newTxInstructions.instructions!.push(...(txInstruction.instructions || []));\n newTxInstructions.endInstructions!.push(...(txInstruction.endInstructions || []));\n newTxInstructions.instructionTypes!.push(...(txInstruction.instructionTypes || []));\n newTxInstructions.endInstructionTypes!.push(...(txInstruction.endInstructionTypes || []));\n\n if (createInfo.amount) {\n newTxInstructions.instructions!.push(\n makeTransferInstruction({\n source: txInstruction.addresses.newAccount,\n destination: ata,\n owner: this.scope.ownerPubKey,\n amount: createInfo.amount,\n tokenProgram: TOKEN_PROGRAM_ID,\n }),\n );\n newTxInstructions.instructionTypes!.push(InstructionType.TransferAmount);\n }\n }\n\n if (!skipCloseAccount && _ataInTokenAcc === undefined) {\n newTxInstructions.endInstructions!.push(\n closeAccountInstruction({\n owner,\n payer: createInfo.payer || owner,\n tokenAccount: ata,\n programId: tokenProgram,\n }),\n );\n newTxInstructions.endInstructionTypes!.push(InstructionType.CloseAccount);\n }\n\n return { account: ata, instructionParams: newTxInstructions };\n } else {\n const newTokenAccount = generatePubKey({ fromPublicKey: owner, programId: tokenProgram, assignSeed });\n const balanceNeeded = await this.scope.connection.getMinimumBalanceForRentExemption(AccountLayout.span);\n\n const createAccountIns = SystemProgram.createAccountWithSeed({\n fromPubkey: owner,\n basePubkey: owner,\n seed: newTokenAccount.seed,\n newAccountPubkey: newTokenAccount.publicKey,\n lamports: balanceNeeded + Number(createInfo.amount?.toString() ?? 0),\n space: AccountLayout.span,\n programId: tokenProgram,\n });\n\n newTxInstructions.instructions!.push(\n createAccountIns,\n initTokenAccountInstruction({\n mint,\n tokenAccount: newTokenAccount.publicKey,\n owner: this.scope.ownerPubKey,\n programId: tokenProgram,\n }),\n );\n newTxInstructions.instructionTypes!.push(InstructionType.CreateAccount);\n newTxInstructions.instructionTypes!.push(InstructionType.InitAccount);\n if (!skipCloseAccount) {\n newTxInstructions.endInstructions!.push(\n closeAccountInstruction({\n owner,\n payer: createInfo.payer || owner,\n tokenAccount: newTokenAccount.publicKey,\n programId: tokenProgram,\n }),\n );\n newTxInstructions.endInstructionTypes!.push(InstructionType.CloseAccount);\n }\n return { account: newTokenAccount.publicKey, instructionParams: newTxInstructions };\n }\n // }\n }\n\n public async checkOrCreateAta({\n mint,\n programId = TOKEN_PROGRAM_ID,\n autoUnwrapWSOLToSOL,\n }: {\n mint: PublicKey;\n programId?: PublicKey;\n autoUnwrapWSOLToSOL?: boolean;\n }): Promise<{ pubKey: PublicKey; newInstructions: AddInstructionParam }> {\n await this.fetchWalletTokenAccounts();\n let tokenAccountAddress = this.scope.account.tokenAccounts.find(\n ({ mint: accountTokenMint }) => accountTokenMint?.toBase58() === mint.toBase58(),\n )?.publicKey;\n\n const owner = this.scope.ownerPubKey;\n const newTxInstructions: AddInstructionParam = {};\n\n if (!tokenAccountAddress) {\n const ataAddress = this.getAssociatedTokenAccount(mint, programId);\n const instruction = await createAssociatedTokenAccountIdempotentInstruction(\n owner,\n ataAddress,\n owner,\n mint,\n programId,\n );\n newTxInstructions.instructions = [instruction];\n newTxInstructions.instructionTypes = [InstructionType.CreateATA];\n tokenAccountAddress = ataAddress;\n }\n if (autoUnwrapWSOLToSOL && WSOLMint.toBase58() === mint.toBase58()) {\n newTxInstructions.endInstructions = [\n closeAccountInstruction({ owner, payer: owner, tokenAccount: tokenAccountAddress, programId }),\n ];\n newTxInstructions.endInstructionTypes = [InstructionType.CloseAccount];\n }\n\n return {\n pubKey: tokenAccountAddress,\n newInstructions: newTxInstructions,\n };\n }\n\n // old _handleTokenAccount\n public async handleTokenAccount(\n params: HandleTokenAccountParams,\n ): Promise<AddInstructionParam & { tokenAccount: PublicKey }> {\n const {\n side,\n amount,\n mint,\n programId = TOKEN_PROGRAM_ID,\n tokenAccount,\n payer = this.scope.ownerPubKey,\n bypassAssociatedCheck,\n skipCloseAccount,\n checkCreateATAOwner,\n } = params;\n\n const ata = this.getAssociatedTokenAccount(mint, programId);\n\n if (new PublicKey(WSOLMint).equals(mint)) {\n const txInstruction = await createWSolAccountInstructions({\n connection: this.scope.connection,\n owner: this.scope.ownerPubKey,\n payer,\n amount,\n skipCloseAccount,\n });\n return { tokenAccount: txInstruction.addresses.newAccount, ...txInstruction };\n } else if (!tokenAccount || (side === \"out\" && !ata.equals(tokenAccount) && !bypassAssociatedCheck)) {\n const instructions: TransactionInstruction[] = [];\n const _createATAIns = createAssociatedTokenAccountIdempotentInstruction(\n this.scope.ownerPubKey,\n ata,\n this.scope.ownerPubKey,\n mint,\n programId,\n );\n\n if (checkCreateATAOwner) {\n const ataInfo = await this.scope.connection.getAccountInfo(ata);\n if (ataInfo === null) {\n instructions.push(_createATAIns);\n } else if (\n ataInfo.owner.equals(TOKEN_PROGRAM_ID) &&\n AccountLayout.decode(ataInfo.data).mint.equals(mint) &&\n AccountLayout.decode(ataInfo.data).owner.equals(this.scope.ownerPubKey)\n ) {\n /* empty */\n } else {\n throw Error(`create ata check error -> mint: ${mint.toString()}, ata: ${ata.toString()}`);\n }\n } else {\n instructions.push(_createATAIns);\n }\n\n return {\n tokenAccount: ata,\n instructions,\n instructionTypes: [InstructionType.CreateATA],\n };\n }\n\n return { tokenAccount };\n }\n\n public async processTokenAccount(props: {\n mint: PublicKey;\n programId?: PublicKey;\n amount?: BigNumberish;\n useSOLBalance?: boolean;\n handleTokenAccount?: boolean;\n feePayer?: PublicKey;\n }): Promise<Promise<AddInstructionParam & { tokenAccount?: PublicKey }>> {\n const { mint, programId = TOKEN_PROGRAM_ID, amount, useSOLBalance, handleTokenAccount, feePayer } = props;\n let tokenAccount: PublicKey | undefined;\n const txBuilder = this.createTxBuilder(feePayer);\n\n if (mint.equals(new PublicKey(WSOLMint)) && useSOLBalance) {\n // mintA\n const { tokenAccount: _tokenAccount, ...instructions } = await this.handleTokenAccount({\n side: \"in\",\n amount: amount || 0,\n mint,\n bypassAssociatedCheck: true,\n programId,\n });\n tokenAccount = _tokenAccount;\n txBuilder.addInstruction(instructions);\n } else {\n tokenAccount = await this.getCreatedTokenAccount({\n mint,\n associatedOnly: false,\n programId,\n });\n if (!tokenAccount && handleTokenAccount) {\n const { tokenAccount: _tokenAccount, ...instructions } = await this.scope.account.handleTokenAccount({\n side: \"in\",\n amount: 0,\n mint,\n bypassAssociatedCheck: true,\n programId,\n });\n tokenAccount = _tokenAccount;\n txBuilder.addInstruction(instructions);\n }\n }\n\n return { tokenAccount, ...txBuilder.AllTxData };\n }\n}\n","import {\n Commitment,\n Connection,\n PublicKey,\n sendAndConfirmTransaction,\n SignatureResult,\n Signer,\n SystemProgram,\n Transaction,\n TransactionInstruction,\n TransactionMessage,\n VersionedTransaction,\n} from \"@solana/web3.js\";\nimport axios from \"axios\";\n\nimport { Api } from \"../../api\";\nimport { ComputeBudgetConfig, SignAllTransactions, TxTipConfig } from \"../../raydium/type\";\nimport { Cluster } from \"../../solana\";\nimport { Owner } from \"../owner\";\nimport { CacheLTA, getDevLookupTableCache, getMainLookupTableCache, getMultipleLookupTableInfo } from \"./lookupTable\";\nimport { InstructionType, TxVersion } from \"./txType\";\nimport {\n addComputeBudget,\n checkLegacyTxSize,\n checkV0TxSize,\n confirmTransaction,\n getRecentBlockHash,\n printSimulate,\n} from \"./txUtils\";\n\ninterface SolanaFeeInfo {\n min: number;\n max: number;\n avg: number;\n priorityTx: number;\n nonVotes: number;\n priorityRatio: number;\n avgCuPerBlock: number;\n blockspaceUsageRatio: number;\n}\ntype SolanaFeeInfoJson = {\n \"1\": SolanaFeeInfo;\n \"5\": SolanaFeeInfo;\n \"15\": SolanaFeeInfo;\n};\n\ninterface ExecuteParams {\n skipPreflight?: boolean;\n recentBlockHash?: string;\n sendAndConfirm?: boolean;\n notSendToRpc?: boolean;\n}\n\ninterface TxBuilderInit {\n connection: Connection;\n feePayer: PublicKey;\n cluster: Cluster;\n owner?: Owner;\n blockhashCommitment?: Commitment;\n loopMultiTxStatus?: boolean;\n api?: Api;\n signAllTransactions?: SignAllTransactions;\n}\n\nexport interface AddInstructionParam {\n addresses?: Record<string, PublicKey>;\n instructions?: TransactionInstruction[];\n endInstructions?: TransactionInstruction[];\n lookupTableAddress?: string[];\n signers?: Signer[];\n instructionTypes?: string[];\n endInstructionTypes?: string[];\n}\n\nexport interface TxBuildData<T = Record<string, any>> {\n builder: TxBuilder;\n transaction: Transaction;\n instructionTypes: string[];\n signers: Signer[];\n execute: (params?: ExecuteParams) => Promise<{ txId: string; signedTx: Transaction }>;\n extInfo: T;\n}\n\nexport interface TxV0BuildData<T = Record<string, any>> extends Omit<TxBuildData<T>, \"transaction\" | \"execute\"> {\n builder: TxBuilder;\n transaction: VersionedTransaction;\n buildProps?: {\n lookupTableCache?: CacheLTA;\n lookupTableAddress?: string[];\n };\n execute: (params?: ExecuteParams) => Promise<{ txId: string; signedTx: VersionedTransaction }>;\n}\n\ntype TxUpdateParams = {\n txId: string;\n status: \"success\" | \"error\" | \"sent\";\n signedTx: Transaction | VersionedTransaction;\n};\nexport interface MultiTxExecuteParam extends ExecuteParams {\n sequentially: boolean;\n skipTxCount?: number;\n onTxUpdate?: (completeTxs: TxUpdateParams[]) => void;\n}\nexport interface MultiTxBuildData<T = Record<string, any>> {\n builder: TxBuilder;\n transactions: Transaction[];\n instructionTypes: string[];\n signers: Signer[][];\n execute: (executeParams?: MultiTxExecuteParam) => Promise<{ txIds: string[]; signedTxs: Transaction[] }>;\n extInfo: T;\n}\n\nexport interface MultiTxV0BuildData<T = Record<string, any>>\n extends Omit<MultiTxBuildData<T>, \"transactions\" | \"execute\"> {\n builder: TxBuilder;\n transactions: VersionedTransaction[];\n buildProps?: {\n lookupTableCache?: CacheLTA;\n lookupTableAddress?: string[];\n };\n execute: (executeParams?: MultiTxExecuteParam) => Promise<{ txIds: string[]; signedTxs: VersionedTransaction[] }>;\n}\n\nexport type MakeMultiTxData<T = TxVersion.LEGACY, O = Record<string, any>> = T extends TxVersion.LEGACY\n ? MultiTxBuildData<O>\n : MultiTxV0BuildData<O>;\n\nexport type MakeTxData<T = TxVersion.LEGACY, O = Record<string, any>> = T extends TxVersion.LEGACY\n ? TxBuildData<O>\n : TxV0BuildData<O>;\n\nconst LOOP_INTERVAL = 2000;\n\nexport class TxBuilder {\n private connection: Connection;\n private owner?: Owner;\n private instructions: TransactionInstruction[] = [];\n private endInstructions: TransactionInstruction[] = [];\n private lookupTableAddress: string[] = [];\n private signers: Signer[] = [];\n private instructionTypes: string[] = [];\n private endInstructionTypes: string[] = [];\n private feePayer: PublicKey;\n private cluster: Cluster;\n private signAllTransactions?: SignAllTransactions;\n private blockhashCommitment?: Commitment;\n private loopMultiTxStatus: boolean;\n\n constructor(params: TxBuilderInit) {\n this.connection = params.connection;\n this.feePayer = params.feePayer;\n this.signAllTransactions = params.signAllTransactions;\n this.owner = params.owner;\n this.cluster = params.cluster;\n this.blockhashCommitment = params.blockhashCommitment;\n this.loopMultiTxStatus = !!params.loopMultiTxStatus;\n }\n\n get AllTxData(): {\n instructions: TransactionInstruction[];\n endInstructions: TransactionInstruction[];\n signers: Signer[];\n instructionTypes: string[];\n endInstructionTypes: string[];\n lookupTableAddress: string[];\n } {\n return {\n instructions: this.instructions,\n endInstructions: this.endInstructions,\n signers: this.signers,\n instructionTypes: this.instructionTypes,\n endInstructionTypes: this.endInstructionTypes,\n lookupTableAddress: this.lookupTableAddress,\n };\n }\n\n get allInstructions(): TransactionInstruction[] {\n return [...this.instructions, ...this.endInstructions];\n }\n\n public async getComputeBudgetConfig(): Promise<ComputeBudgetConfig | undefined> {\n const json = (\n await axios.get<SolanaFeeInfoJson>(`https://solanacompass.com/api/fees?cacheFreshTime=${5 * 60 * 1000}`)\n ).data;\n const { avg } = json?.[15] ?? {};\n if (!avg) return undefined;\n return {\n units: 600000,\n microLamports: Math.min(Math.ceil((avg * 1000000) / 600000), 25000),\n };\n }\n\n public addCustomComputeBudget(config?: ComputeBudgetConfig): boolean {\n if (config) {\n const { instructions, instructionTypes } = addComputeBudget(config);\n this.instructions.unshift(...instructions);\n this.instructionTypes.unshift(...instructionTypes);\n return true;\n }\n return false;\n }\n\n public addTipInstruction(tipConfig?: TxTipConfig): boolean {\n if (tipConfig) {\n this.endInstructions.push(\n SystemProgram.transfer({\n fromPubkey: tipConfig.feePayer ?? this.feePayer,\n toPubkey: new PublicKey(tipConfig.address),\n lamports: BigInt(tipConfig.amount.toString()),\n }),\n );\n this.endInstructionTypes.push(InstructionType.TransferTip);\n return true;\n }\n return false;\n }\n\n public async calComputeBudget({\n config: propConfig,\n defaultIns,\n }: {\n config?: ComputeBudgetConfig;\n defaultIns?: TransactionInstruction[];\n }): Promise<void> {\n try {\n const config = propConfig || (await this.getComputeBudgetConfig());\n if (this.addCustomComputeBudget(config)) return;\n defaultIns && this.instructions.unshift(...defaultIns);\n } catch {\n defaultIns && this.instructions.unshift(...defaultIns);\n }\n }\n\n public addInstruction({\n instructions = [],\n endInstructions = [],\n signers = [],\n instructionTypes = [],\n endInstructionTypes = [],\n lookupTableAddress = [],\n }: AddInstructionParam): TxBuilder {\n this.instructions.push(...instructions);\n this.endInstructions.push(...endInstructions);\n this.signers.push(...signers);\n this.instructionTypes.push(...instructionTypes);\n this.endInstructionTypes.push(...endInstructionTypes);\n this.lookupTableAddress.push(...lookupTableAddress.filter((address) => address !== PublicKey.default.toString()));\n return this;\n }\n\n public async versionBuild<O = Record<string, any>>({\n txVersion,\n extInfo,\n lookupTableAddress,\n }: {\n txVersion?: TxVersion;\n extInfo?: O;\n lookupTableAddress?: string[];\n }): Promise<MakeTxData<TxVersion.LEGACY, O> | MakeTxData<TxVersion.V0, O>> {\n if (txVersion === TxVersion.V0)\n return (await this.buildV0({ ...(extInfo || {}), lookupTableAddress })) as unknown as MakeTxData<TxVersion.V0, O>;\n return this.build<O>(extInfo) as MakeTxData<TxVersion.LEGACY, O>;\n }\n\n public build<O = Record<string, any>>(extInfo?: O): MakeTxData<TxVersion.LEGACY, O> {\n const transaction = new Transaction();\n if (this.allInstructions.length) transaction.add(...this.allInstructions);\n transaction.feePayer = this.feePayer;\n if (this.owner?.signer && !this.signers.some((s) => s.publicKey.equals(this.owner!.publicKey)))\n this.signers.push(this.owner.signer);\n\n return {\n builder: this,\n transaction,\n signers: this.signers,\n instructionTypes: [...this.instructionTypes, ...this.endInstructionTypes],\n execute: async (params) => {\n const { recentBlockHash: propBlockHash, skipPreflight = true, sendAndConfirm, notSendToRpc } = params || {};\n const recentBlockHash = propBlockHash ?? (await getRecentBlockHash(this.connection, this.blockhashCommitment));\n transaction.recentBlockhash = recentBlockHash;\n if (this.signers.length) transaction.sign(...this.signers);\n\n printSimulate([transaction]);\n if (this.owner?.isKeyPair) {\n const txId = sendAndConfirm\n ? await sendAndConfirmTransaction(\n this.connection,\n transaction,\n this.signers.find((s) => s.publicKey.equals(this.owner!.publicKey))\n ? this.signers\n : [...this.signers, this.owner.signer!],\n { skipPreflight },\n )\n : await this.connection.sendRawTransaction(transaction.serialize(), { skipPreflight });\n\n return {\n txId,\n signedTx: transaction,\n };\n }\n if (this.signAllTransactions) {\n const txs = await this.signAllTransactions([transaction]);\n if (this.signers.length) {\n for (const item of txs) {\n try {\n item.sign(...this.signers);\n } catch (e) {\n //\n }\n }\n }\n return {\n txId: notSendToRpc ? \"\" : await this.connection.sendRawTransaction(txs[0].serialize(), { skipPreflight }),\n signedTx: txs[0],\n };\n }\n throw new Error(\"please provide owner in keypair format or signAllTransactions function\");\n },\n extInfo: extInfo || ({} as O),\n };\n }\n\n public buildMultiTx<T = Record<string, any>>(params: {\n extraPreBuildData?: MakeTxData<TxVersion.LEGACY>[];\n extInfo?: T;\n }): MultiTxBuildData {\n const { extraPreBuildData = [], extInfo } = params;\n const { transaction } = this.build(extInfo);\n\n const filterExtraBuildData = extraPreBuildData.filter((data) => data.transaction.instructions.length > 0);\n\n const allTransactions: Transaction[] = [transaction, ...filterExtraBuildData.map((data) => data.transaction)];\n const allSigners: Signer[][] = [this.signers, ...filterExtraBuildData.map((data) => data.signers)];\n const allInstructionTypes: string[] = [\n ...this.instructionTypes,\n ...filterExtraBuildData.map((data) => data.instructionTypes).flat(),\n ];\n\n if (this.owner?.signer) {\n allSigners.forEach((signers) => {\n if (!signers.some((s) => s.publicKey.equals(this.owner!.publicKey))) this.signers.push(this.owner!.signer!);\n });\n }\n\n return {\n builder: this,\n transactions: allTransactions,\n signers: allSigners,\n instructionTypes: allInstructionTypes,\n execute: async (executeParams?: MultiTxExecuteParam) => {\n const {\n sequentially,\n onTxUpdate,\n skipTxCount = 0,\n recentBlockHash: propBlockHash,\n skipPreflight = true,\n } = executeParams || {};\n const recentBlockHash = propBlockHash ?? (await getRecentBlockHash(this.connection, this.blockhashCommitment));\n if (this.owner?.isKeyPair) {\n if (sequentially) {\n const txIds: string[] = [];\n let i = 0;\n for (const tx of allTransactions) {\n ++i;\n if (i <= skipTxCount) continue;\n const txId = await sendAndConfirmTransaction(\n this.connection,\n tx,\n this.signers.find((s) => s.publicKey.equals(this.owner!.publicKey))\n ? this.signers\n : [...this.signers, this.owner.signer!],\n { skipPreflight },\n );\n txIds.push(txId);\n }\n\n return {\n txIds,\n signedTxs: allTransactions,\n };\n }\n return {\n txIds: await await Promise.all(\n allTransactions.map(async (tx) => {\n tx.recentBlockhash = recentBlockHash;\n return await this.connection.sendRawTransaction(tx.serialize(), { skipPreflight });\n }),\n ),\n signedTxs: allTransactions,\n };\n }\n\n if (this.signAllTransactions) {\n const partialSignedTxs = allTransactions.map((tx, idx) => {\n tx.recentBlockhash = recentBlockHash;\n if (allSigners[idx].length) tx.sign(...allSigners[idx]);\n return tx;\n });\n printSimulate(partialSignedTxs);\n const signedTxs = await this.signAllTransactions(partialSignedTxs);\n if (sequentially) {\n let i = 0;\n const processedTxs: TxUpdateParams[] = [];\n const checkSendTx = async (): Promise<void> => {\n if (!signedTxs[i]) return;\n const txId = await this.connection.sendRawTransaction(signedTxs[i].serialize(), { skipPreflight });\n processedTxs.push({ txId, status: \"sent\", signedTx: signedTxs[i] });\n onTxUpdate?.([...processedTxs]);\n i++;\n let confirmed = false;\n // eslint-disable-next-line\n let intervalId: NodeJS.Timer | null = null,\n subSignatureId: number | null = null;\n const cbk = (signatureResult: SignatureResult): void => {\n intervalId !== null && clearInterval(intervalId);\n subSignatureId !== null && this.connection.removeSignatureListener(subSignatureId);\n const targetTxIdx = processedTxs.findIndex((tx) => tx.txId === txId);\n if (targetTxIdx > -1) {\n if (processedTxs[targetTxIdx].status === \"error\" || processedTxs[targetTxIdx].status === \"success\")\n return;\n processedTxs[targetTxIdx].status = signatureResult.err ? \"error\" : \"success\";\n }\n onTxUpdate?.([...processedTxs]);\n if (!signatureResult.err) checkSendTx();\n };\n\n if (this.loopMultiTxStatus)\n intervalId = setInterval(async () => {\n if (confirmed) {\n clearInterval(intervalId!);\n return;\n }\n try {\n const r = await this.connection.getTransaction(txId, {\n commitment: \"confirmed\",\n maxSupportedTransactionVersion: TxVersion.V0,\n });\n if (r) {\n confirmed = true;\n clearInterval(intervalId!);\n cbk({ err: r.meta?.err || null });\n console.log(\"tx status from getTransaction:\", txId);\n }\n } catch (e) {\n confirmed = true;\n clearInterval(intervalId!);\n console.error(\"getTransaction timeout:\", e, txId);\n }\n }, LOOP_INTERVAL);\n\n subSignatureId = this.connection.onSignature(\n txId,\n (result) => {\n if (confirmed) {\n this.connection.removeSignatureListener(subSignatureId!);\n return;\n }\n confirmed = true;\n cbk(result);\n },\n \"confirmed\",\n );\n this.connection.getSignatureStatus(txId);\n };\n await checkSendTx();\n return {\n txIds: processedTxs.map((d) => d.txId),\n signedTxs,\n };\n } else {\n const txIds: string[] = [];\n for (let i = 0; i < signedTxs.length; i += 1) {\n const txId = await this.connection.sendRawTransaction(signedTxs[i].serialize(), { skipPreflight });\n txIds.push(txId);\n }\n return {\n txIds,\n signedTxs,\n };\n }\n }\n throw new Error(\"please provide owner in keypair format or signAllTransactions function\");\n },\n extInfo: extInfo || {},\n };\n }\n\n public async versionMultiBuild<T extends TxVersion, O = Record<string, any>>({\n extraPreBuildData,\n txVersion,\n extInfo,\n }: {\n extraPreBuildData?: MakeTxData<TxVersion.V0>[] | MakeTxData<TxVersion.LEGACY>[];\n txVersion?: T;\n extInfo?: O;\n }): Promise<MakeMultiTxData<T, O>> {\n if (txVersion === TxVersion.V0)\n return (await this.buildV0MultiTx({\n extraPreBuildData: extraPreBuildData as MakeTxData<TxVersion.V0>[],\n buildProps: extInfo || {},\n })) as MakeMultiTxData<T, O>;\n return this.buildMultiTx<O>({\n extraPreBuildData: extraPreBuildData as MakeTxData<TxVersion.LEGACY>[],\n extInfo,\n }) as MakeMultiTxData<T, O>;\n }\n\n public async buildV0<O = Record<string, any>>(\n props?: O & {\n lookupTableCache?: CacheLTA;\n lookupTableAddress?: string[];\n forerunCreate?: boolean;\n recentBlockhash?: string;\n },\n ): Promise<MakeTxData<TxVersion.V0, O>> {\n const {\n lookupTableCache = {},\n lookupTableAddress = [],\n forerunCreate,\n recentBlockhash: propRecentBlockhash,\n ...extInfo\n } = props || {};\n\n const lookupTableAddressAccount = {\n ...(this.cluster === \"devnet\"\n ? await getDevLookupTableCache(this.connection)\n : await getMainLookupTableCache(this.connection)),\n ...lookupTableCache,\n };\n const allLTA = Array.from(new Set<string>([...lookupTableAddress, ...this.lookupTableAddress]));\n const needCacheLTA: PublicKey[] = [];\n for (const item of allLTA) {\n if (lookupTableAddressAccount[item] === undefined) needCacheLTA.push(new PublicKey(item));\n }\n const newCacheLTA = await getMultipleLookupTableInfo({ connection: this.connection, address: needCacheLTA });\n for (const [key, value] of Object.entries(newCacheLTA)) lookupTableAddressAccount[key] = value;\n\n const recentBlockhash = forerunCreate\n ? PublicKey.default.toBase58()\n : propRecentBlockhash ?? (await getRecentBlockHash(this.connection, this.blockhashCommitment));\n const messageV0 = new TransactionMessage({\n payerKey: this.feePayer,\n recentBlockhash,\n instructions: [...this.allInstructions],\n }).compileToV0Message(Object.values(lookupTableAddressAccount));\n if (this.owner?.signer && !this.signers.some((s) => s.publicKey.equals(this.owner!.publicKey)))\n this.signers.push(this.owner.signer);\n const transaction = new VersionedTransaction(messageV0);\n\n transaction.sign(this.signers);\n\n return {\n builder: this,\n transaction,\n signers: this.signers,\n instructionTypes: [...this.instructionTypes, ...this.endInstructionTypes],\n execute: async (params) => {\n const { skipPreflight = true, sendAndConfirm, notSendToRpc } = params || {};\n printSimulate([transaction]);\n if (this.owner?.isKeyPair) {\n const txId = await this.connection.sendTransaction(transaction, { skipPreflight });\n if (sendAndConfirm) {\n await confirmTransaction(this.connection, txId);\n }\n\n return {\n txId,\n signedTx: transaction,\n };\n }\n if (this.signAllTransactions) {\n const txs = await this.signAllTransactions<VersionedTransaction>([transaction]);\n if (this.signers.length) {\n for (const item of txs) {\n try {\n item.sign(this.signers);\n } catch (e) {\n //\n }\n }\n }\n return {\n txId: notSendToRpc ? \"\" : await this.connection.sendTransaction(txs[0], { skipPreflight }),\n signedTx: txs[0],\n };\n }\n throw new Error(\"please provide owner in keypair format or signAllTransactions function\");\n },\n extInfo: (extInfo || {}) as O,\n };\n }\n\n public async buildV0MultiTx<T = Record<string, any>>(params: {\n extraPreBuildData?: MakeTxData<TxVersion.V0>[];\n buildProps?: T & {\n lookupTableCache?: CacheLTA;\n lookupTableAddress?: string[];\n forerunCreate?: boolean;\n recentBlockhash?: string;\n };\n }): Promise<MultiTxV0BuildData> {\n const { extraPreBuildData = [], buildProps } = params;\n const { transaction } = await this.buildV0(buildProps);\n\n const filterExtraBuildData = extraPreBuildData.filter((data) => data.builder.instructions.length > 0);\n\n const allTransactions: VersionedTransaction[] = [\n transaction,\n ...filterExtraBuildData.map((data) => data.transaction),\n ];\n const allSigners: Signer[][] = [this.signers, ...filterExtraBuildData.map((data) => data.signers)];\n const allInstructionTypes: string[] = [\n ...this.instructionTypes,\n ...filterExtraBuildData.map((data) => data.instructionTypes).flat(),\n ];\n\n if (this.owner?.signer) {\n allSigners.forEach((signers) => {\n if (!signers.some((s) => s.publicKey.equals(this.owner!.publicKey))) this.signers.push(this.owner!.signer!);\n });\n }\n\n allTransactions.forEach(async (tx, idx) => {\n tx.sign(allSigners[idx]);\n });\n\n return {\n builder: this,\n transactions: allTransactions,\n signers: allSigners,\n instructionTypes: allInstructionTypes,\n buildProps,\n execute: async (executeParams?: MultiTxExecuteParam) => {\n const { sequentially, onTxUpdate, recentBlockHash: propBlockHash, skipPreflight = true } = executeParams || {};\n if (propBlockHash) allTransactions.forEach((tx) => (tx.message.recentBlockhash = propBlockHash));\n printSimulate(allTransactions);\n if (this.owner?.isKeyPair) {\n if (sequentially) {\n const txIds: string[] = [];\n for (const tx of allTransactions) {\n const txId = await this.connection.sendTransaction(tx, { skipPreflight });\n await confirmTransaction(this.connection, txId);\n txIds.push(txId);\n }\n\n return { txIds, signedTxs: allTransactions };\n }\n\n return {\n txIds: await Promise.all(\n allTransactions.map(async (tx) => {\n return await this.connection.sendTransaction(tx, { skipPreflight });\n }),\n ),\n signedTxs: allTransactions,\n };\n }\n\n if (this.signAllTransactions) {\n const signedTxs = await this.signAllTransactions(allTransactions);\n\n if (sequentially) {\n let i = 0;\n const processedTxs: TxUpdateParams[] = [];\n const checkSendTx = async (): Promise<void> => {\n if (!signedTxs[i]) return;\n const txId = await this.connection.sendTransaction(signedTxs[i], { skipPreflight });\n processedTxs.push({ txId, status: \"sent\", signedTx: signedTxs[i] });\n onTxUpdate?.([...processedTxs]);\n i++;\n\n let confirmed = false;\n // eslint-disable-next-line\n let intervalId: NodeJS.Timer | null = null,\n subSignatureId: number | null = null;\n const cbk = (signatureResult: SignatureResult): void => {\n intervalId !== null && clearInterval(intervalId);\n subSignatureId !== null && this.connection.removeSignatureListener(subSignatureId);\n const targetTxIdx = processedTxs.findIndex((tx) => tx.txId === txId);\n if (targetTxIdx > -1) {\n if (processedTxs[targetTxIdx].status === \"error\" || processedTxs[targetTxIdx].status === \"success\")\n return;\n processedTxs[targetTxIdx].status = signatureResult.err ? \"error\" : \"success\";\n }\n onTxUpdate?.([...processedTxs]);\n if (!signatureResult.err) checkSendTx();\n };\n\n if (this.loopMultiTxStatus)\n intervalId = setInterval(async () => {\n if (confirmed) {\n clearInterval(intervalId!);\n return;\n }\n try {\n const r = await this.connection.getTransaction(txId, {\n commitment: \"confirmed\",\n maxSupportedTransactionVersion: TxVersion.V0,\n });\n if (r) {\n confirmed = true;\n clearInterval(intervalId!);\n cbk({ err: r.meta?.err || null });\n console.log(\"tx status from getTransaction:\", txId);\n }\n } catch (e) {\n confirmed = true;\n clearInterval(intervalId!);\n console.error(\"getTransaction timeout:\", e, txId);\n }\n }, LOOP_INTERVAL);\n\n subSignatureId = this.connection.onSignature(\n txId,\n (result) => {\n if (confirmed) {\n this.connection.removeSignatureListener(subSignatureId!);\n return;\n }\n confirmed = true;\n cbk(result);\n },\n \"confirmed\",\n );\n this.connection.getSignatureStatus(txId);\n };\n checkSendTx();\n return {\n txIds: [],\n signedTxs,\n };\n } else {\n const txIds: string[] = [];\n for (let i = 0; i < signedTxs.length; i += 1) {\n const txId = await this.connection.sendTransaction(signedTxs[i], { skipPreflight });\n txIds.push(txId);\n }\n return { txIds, signedTxs };\n }\n }\n throw new Error(\"please provide owner in keypair format or signAllTransactions function\");\n },\n extInfo: buildProps || {},\n };\n }\n\n public async sizeCheckBuild(\n props?: Record<string, any> & { computeBudgetConfig?: ComputeBudgetConfig; splitIns?: TransactionInstruction[] },\n ): Promise<MultiTxBuildData> {\n const { splitIns = [], computeBudgetConfig, ...extInfo } = props || {};\n const computeBudgetData: { instructions: TransactionInstruction[]; instructionTypes: string[] } =\n computeBudgetConfig\n ? addComputeBudget(computeBudgetConfig)\n : {\n instructions: [],\n instructionTypes: [],\n };\n\n const signerKey: { [key: string]: Signer } = this.signers.reduce(\n (acc, cur) => ({ ...acc, [cur.publicKey.toBase58()]: cur }),\n {},\n );\n\n const allTransactions: Transaction[] = [];\n const allSigners: Signer[][] = [];\n\n let instructionQueue: TransactionInstruction[] = [];\n let splitInsIdx = 0;\n this.allInstructions.forEach((item) => {\n const _itemIns = [...instructionQueue, item];\n const _itemInsWithCompute = computeBudgetConfig ? [...computeBudgetData.instructions, ..._itemIns] : _itemIns;\n const _signerStrs = new Set<string>(\n _itemIns.map((i) => i.keys.filter((ii) => ii.isSigner).map((ii) => ii.pubkey.toString())).flat(),\n );\n const _signer = [..._signerStrs.values()].map((i) => new PublicKey(i));\n\n if (\n item !== splitIns[splitInsIdx] &&\n instructionQueue.length < 12 &&\n (checkLegacyTxSize({ instructions: _itemInsWithCompute, payer: this.feePayer, signers: _signer }) ||\n checkLegacyTxSize({ instructions: _itemIns, payer: this.feePayer, signers: _signer }))\n ) {\n // current ins add to queue still not exceed tx size limit\n instructionQueue.push(item);\n } else {\n if (instructionQueue.length === 0) throw Error(\"item ins too big\");\n splitInsIdx += item === splitIns[splitInsIdx] ? 1 : 0;\n // if add computeBudget still not exceed tx size limit\n if (\n checkLegacyTxSize({\n instructions: computeBudgetConfig\n ? [...computeBudgetData.instructions, ...instructionQueue]\n : [...instructionQueue],\n payer: this.feePayer,\n signers: _signer,\n })\n ) {\n allTransactions.push(new Transaction().add(...computeBudgetData.instructions, ...instructionQueue));\n } else {\n allTransactions.push(new Transaction().add(...instructionQueue));\n }\n allSigners.push(\n Array.from(\n new Set<string>(\n instructionQueue.map((i) => i.keys.filter((ii) => ii.isSigner).map((ii) => ii.pubkey.toString())).flat(),\n ),\n )\n .map((i) => signerKey[i])\n .filter((i) => i !== undefined),\n );\n instructionQueue = [item];\n }\n });\n\n if (instructionQueue.length > 0) {\n const _signerStrs = new Set<string>(\n instructionQueue.map((i) => i.keys.filter((ii) => ii.isSigner).map((ii) => ii.pubkey.toString())).flat(),\n );\n const _signers = [..._signerStrs.values()].map((i) => signerKey[i]).filter((i) => i !== undefined);\n\n if (\n checkLegacyTxSize({\n instructions: computeBudgetConfig\n ? [...computeBudgetData.instructions, ...instructionQueue]\n : [...instructionQueue],\n payer: this.feePayer,\n signers: _signers.map((s) => s.publicKey),\n })\n ) {\n allTransactions.push(new Transaction().add(...computeBudgetData.instructions, ...instructionQueue));\n } else {\n allTransactions.push(new Transaction().add(...instructionQueue));\n }\n allSigners.push(_signers);\n }\n allTransactions.forEach((tx) => (tx.feePayer = this.feePayer));\n\n if (this.owner?.signer) {\n allSigners.forEach((signers) => {\n if (!signers.some((s) => s.publicKey.equals(this.owner!.publicKey))) signers.push(this.owner!.signer!);\n });\n }\n\n return {\n builder: this,\n transactions: allTransactions,\n signers: allSigners,\n instructionTypes: this.instructionTypes,\n execute: async (executeParams?: MultiTxExecuteParam) => {\n const {\n sequentially,\n onTxUpdate,\n skipTxCount = 0,\n recentBlockHash: propBlockHash,\n skipPreflight = true,\n } = executeParams || {};\n const recentBlockHash = propBlockHash ?? (await getRecentBlockHash(this.connection, this.blockhashCommitment));\n allTransactions.forEach(async (tx, idx) => {\n tx.recentBlockhash = recentBlockHash;\n if (allSigners[idx].length) tx.sign(...allSigners[idx]);\n });\n printSimulate(allTransactions);\n if (this.owner?.isKeyPair) {\n if (sequentially) {\n let i = 0;\n const txIds: string[] = [];\n for (const tx of allTransactions) {\n ++i;\n if (i <= skipTxCount) {\n txIds.push(\"tx skipped\");\n continue;\n }\n const txId = await sendAndConfirmTransaction(\n this.connection,\n tx,\n this.signers.find((s) => s.publicKey.equals(this.owner!.publicKey))\n ? this.signers\n : [...this.signers, this.owner.signer!],\n { skipPreflight },\n );\n txIds.push(txId);\n }\n\n return {\n txIds,\n signedTxs: allTransactions,\n };\n }\n return {\n txIds: await Promise.all(\n allTransactions.map(async (tx) => {\n return await this.connection.sendRawTransaction(tx.serialize(), { skipPreflight });\n }),\n ),\n signedTxs: allTransactions,\n };\n }\n if (this.signAllTransactions) {\n const needSignedTx = await this.signAllTransactions(\n allTransactions.slice(skipTxCount, allTransactions.length),\n );\n const signedTxs = [...allTransactions.slice(0, skipTxCount), ...needSignedTx];\n if (sequentially) {\n let i = 0;\n const processedTxs: TxUpdateParams[] = [];\n const checkSendTx = async (): Promise<void> => {\n if (!signedTxs[i]) return;\n if (i < skipTxCount) {\n // success before, do not send again\n processedTxs.push({ txId: \"\", status: \"success\", signedTx: signedTxs[i] });\n onTxUpdate?.([...processedTxs]);\n i++;\n checkSendTx();\n }\n const txId = await this.connection.sendRawTransaction(signedTxs[i].serialize(), { skipPreflight });\n processedTxs.push({ txId, status: \"sent\", signedTx: signedTxs[i] });\n onTxUpdate?.([...processedTxs]);\n i++;\n\n let confirmed = false;\n // eslint-disable-next-line\n let intervalId: NodeJS.Timer | null = null,\n subSignatureId: number | null = null;\n const cbk = (signatureResult: SignatureResult): void => {\n intervalId !== null && clearInterval(intervalId);\n subSignatureId !== null && this.connection.removeSignatureListener(subSignatureId);\n const targetTxIdx = processedTxs.findIndex((tx) => tx.txId === txId);\n if (targetTxIdx > -1) {\n if (processedTxs[targetTxIdx].status === \"error\" || processedTxs[targetTxIdx].status === \"success\")\n return;\n processedTxs[targetTxIdx].status = signatureResult.err ? \"error\" : \"success\";\n }\n onTxUpdate?.([...processedTxs]);\n if (!signatureResult.err) checkSendTx();\n };\n\n if (this.loopMultiTxStatus)\n intervalId = setInterval(async () => {\n if (confirmed) {\n clearInterval(intervalId!);\n return;\n }\n try {\n const r = await this.connection.getTransaction(txId, {\n commitment: \"confirmed\",\n maxSupportedTransactionVersion: TxVersion.V0,\n });\n if (r) {\n confirmed = true;\n clearInterval(intervalId!);\n cbk({ err: r.meta?.err || null });\n console.log(\"tx status from getTransaction:\", txId);\n }\n } catch (e) {\n confirmed = true;\n clearInterval(intervalId!);\n console.error(\"getTransaction timeout:\", e, txId);\n }\n }, LOOP_INTERVAL);\n\n subSignatureId = this.connection.onSignature(\n txId,\n (result) => {\n if (confirmed) {\n this.connection.removeSignatureListener(subSignatureId!);\n return;\n }\n confirmed = true;\n cbk(result);\n },\n \"confirmed\",\n );\n this.connection.getSignatureStatus(txId);\n };\n await checkSendTx();\n return {\n txIds: processedTxs.map((d) => d.txId),\n signedTxs,\n };\n } else {\n const txIds: string[] = [];\n for (let i = 0; i < signedTxs.length; i += 1) {\n const txId = await this.connection.sendRawTransaction(signedTxs[i].serialize(), { skipPreflight });\n txIds.push(txId);\n }\n return { txIds, signedTxs };\n }\n }\n throw new Error(\"please provide owner in keypair format or signAllTransactions function\");\n },\n extInfo: extInfo || {},\n };\n }\n\n public async sizeCheckBuildV0(\n props?: Record<string, any> & {\n computeBudgetConfig?: ComputeBudgetConfig;\n lookupTableCache?: CacheLTA;\n lookupTableAddress?: string[];\n splitIns?: TransactionInstruction[];\n insCountLimit?: number;\n },\n ): Promise<MultiTxV0BuildData> {\n const {\n computeBudgetConfig,\n splitIns = [],\n lookupTableCache = {},\n lookupTableAddress = [],\n insCountLimit = 12,\n ...extInfo\n } = props || {};\n const lookupTableAddressAccount = {\n ...(this.cluster === \"devnet\"\n ? await getDevLookupTableCache(this.connection)\n : await getMainLookupTableCache(this.connection)),\n ...lookupTableCache,\n };\n const allLTA = Array.from(new Set<string>([...this.lookupTableAddress, ...lookupTableAddress]));\n const needCacheLTA: PublicKey[] = [];\n for (const item of allLTA) {\n if (lookupTableAddressAccount[item] === undefined) needCacheLTA.push(new PublicKey(item));\n }\n const newCacheLTA = await getMultipleLookupTableInfo({ connection: this.connection, address: needCacheLTA });\n for (const [key, value] of Object.entries(newCacheLTA)) lookupTableAddressAccount[key] = value;\n\n const computeBudgetData: { instructions: TransactionInstruction[]; instructionTypes: string[] } =\n computeBudgetConfig\n ? addComputeBudget(computeBudgetConfig)\n : {\n instructions: [],\n instructionTypes: [],\n };\n\n const blockHash = await getRecentBlockHash(this.connection, this.blockhashCommitment);\n\n const signerKey: { [key: string]: Signer } = this.signers.reduce(\n (acc, cur) => ({ ...acc, [cur.publicKey.toBase58()]: cur }),\n {},\n );\n const allTransactions: VersionedTransaction[] = [];\n const allSigners: Signer[][] = [];\n\n let instructionQueue: TransactionInstruction[] = [];\n let splitInsIdx = 0;\n this.allInstructions.forEach((item) => {\n const _itemIns = [...instructionQueue, item];\n const _itemInsWithCompute = computeBudgetConfig ? [...computeBudgetData.instructions, ..._itemIns] : _itemIns;\n if (\n item !== splitIns[splitInsIdx] &&\n instructionQueue.length < insCountLimit &&\n (checkV0TxSize({ instructions: _itemInsWithCompute, payer: this.feePayer, lookupTableAddressAccount }) ||\n checkV0TxSize({ instructions: _itemIns, payer: this.feePayer, lookupTableAddressAccount }))\n ) {\n // current ins add to queue still not exceed tx size limit\n instructionQueue.push(item);\n } else {\n if (instructionQueue.length === 0) throw Error(\"item ins too big\");\n splitInsIdx += item === splitIns[splitInsIdx] ? 1 : 0;\n const lookupTableAddress: undefined | CacheLTA = {};\n for (const item of [...new Set<string>(allLTA)]) {\n if (lookupTableAddressAccount[item] !== undefined) lookupTableAddress[item] = lookupTableAddressAccount[item];\n }\n // if add computeBudget still not exceed tx size limit\n if (\n computeBudgetConfig &&\n checkV0TxSize({\n instructions: [...computeBudgetData.instructions, ...instructionQueue],\n payer: this.feePayer,\n lookupTableAddressAccount,\n recentBlockhash: blockHash,\n })\n ) {\n const messageV0 = new TransactionMessage({\n payerKey: this.feePayer,\n recentBlockhash: blockHash,\n\n instructions: [...computeBudgetData.instructions, ...instructionQueue],\n }).compileToV0Message(Object.values(lookupTableAddressAccount));\n allTransactions.push(new VersionedTransaction(messageV0));\n } else {\n const messageV0 = new TransactionMessage({\n payerKey: this.feePayer,\n recentBlockhash: blockHash,\n instructions: [...instructionQueue],\n }).compileToV0Message(Object.values(lookupTableAddressAccount));\n allTransactions.push(new VersionedTransaction(messageV0));\n }\n allSigners.push(\n Array.from(\n new Set<string>(\n instructionQueue.map((i) => i.keys.filter((ii) => ii.isSigner).map((ii) => ii.pubkey.toString())).flat(),\n ),\n )\n .map((i) => signerKey[i])\n .filter((i) => i !== undefined),\n );\n instructionQueue = [item];\n }\n });\n\n if (instructionQueue.length > 0) {\n const _signerStrs = new Set<string>(\n instructionQueue.map((i) => i.keys.filter((ii) => ii.isSigner).map((ii) => ii.pubkey.toString())).flat(),\n );\n const _signers = [..._signerStrs.values()].map((i) => signerKey[i]).filter((i) => i !== undefined);\n\n if (\n computeBudgetConfig &&\n checkV0TxSize({\n instructions: [...computeBudgetData.instructions, ...instructionQueue],\n payer: this.feePayer,\n lookupTableAddressAccount,\n recentBlockhash: blockHash,\n })\n ) {\n const messageV0 = new TransactionMessage({\n payerKey: this.feePayer,\n recentBlockhash: blockHash,\n instructions: [...computeBudgetData.instructions, ...instructionQueue],\n }).compileToV0Message(Object.values(lookupTableAddressAccount));\n allTransactions.push(new VersionedTransaction(messageV0));\n } else {\n const messageV0 = new TransactionMessage({\n payerKey: this.feePayer,\n recentBlockhash: blockHash,\n instructions: [...instructionQueue],\n }).compileToV0Message(Object.values(lookupTableAddressAccount));\n allTransactions.push(new VersionedTransaction(messageV0));\n }\n\n allSigners.push(_signers);\n }\n\n if (this.owner?.signer) {\n allSigners.forEach((signers) => {\n if (!signers.some((s) => s.publicKey.equals(this.owner!.publicKey))) signers.push(this.owner!.signer!);\n });\n }\n\n allTransactions.forEach((tx, idx) => {\n tx.sign(allSigners[idx]);\n });\n\n return {\n builder: this,\n transactions: allTransactions,\n buildProps: props,\n signers: allSigners,\n instructionTypes: this.instructionTypes,\n execute: async (executeParams?: MultiTxExecuteParam) => {\n const {\n sequentially,\n onTxUpdate,\n skipTxCount = 0,\n recentBlockHash: propBlockHash,\n skipPreflight = true,\n } = executeParams || {};\n allTransactions.map(async (tx, idx) => {\n if (allSigners[idx].length) tx.sign(allSigners[idx]);\n if (propBlockHash) tx.message.recentBlockhash = propBlockHash;\n });\n printSimulate(allTransactions);\n if (this.owner?.isKeyPair) {\n if (sequentially) {\n let i = 0;\n const txIds: string[] = [];\n for (const tx of allTransactions) {\n ++i;\n if (i <= skipTxCount) {\n console.log(\"skip tx: \", i);\n txIds.push(\"tx skipped\");\n continue;\n }\n const txId = await this.connection.sendTransaction(tx, { skipPreflight });\n await confirmTransaction(this.connection, txId);\n\n txIds.push(txId);\n }\n\n return { txIds, signedTxs: allTransactions };\n }\n\n return {\n txIds: await Promise.all(\n allTransactions.map(async (tx) => {\n return await this.connection.sendTransaction(tx, { skipPreflight });\n }),\n ),\n signedTxs: allTransactions,\n };\n }\n if (this.signAllTransactions) {\n const needSignedTx = await this.signAllTransactions(\n allTransactions.slice(skipTxCount, allTransactions.length),\n );\n const signedTxs = [...allTransactions.slice(0, skipTxCount), ...needSignedTx];\n if (sequentially) {\n let i = 0;\n const processedTxs: TxUpdateParams[] = [];\n const checkSendTx = async (): Promise<void> => {\n if (!signedTxs[i]) return;\n if (i < skipTxCount) {\n // success before, do not send again\n processedTxs.push({ txId: \"\", status: \"success\", signedTx: signedTxs[i] });\n onTxUpdate?.([...processedTxs]);\n i++;\n checkSendTx();\n return;\n }\n const txId = await this.connection.sendTransaction(signedTxs[i], { skipPreflight });\n processedTxs.push({ txId, status: \"sent\", signedTx: signedTxs[i] });\n onTxUpdate?.([...processedTxs]);\n i++;\n\n let confirmed = false;\n // eslint-disable-next-line\n let intervalId: NodeJS.Timer | null = null,\n subSignatureId: number | null = null;\n const cbk = (signatureResult: SignatureResult): void => {\n intervalId !== null && clearInterval(intervalId);\n subSignatureId !== null && this.connection.removeSignatureListener(subSignatureId);\n const targetTxIdx = processedTxs.findIndex((tx) => tx.txId === txId);\n if (targetTxIdx > -1) {\n if (processedTxs[targetTxIdx].status === \"error\" || processedTxs[targetTxIdx].status === \"success\")\n return;\n processedTxs[targetTxIdx].status = signatureResult.err ? \"error\" : \"success\";\n }\n onTxUpdate?.([...processedTxs]);\n if (!signatureResult.err) checkSendTx();\n };\n\n if (this.loopMultiTxStatus)\n intervalId = setInterval(async () => {\n if (confirmed) {\n clearInterval(intervalId!);\n return;\n }\n try {\n const r = await this.connection.getTransaction(txId, {\n commitment: \"confirmed\",\n maxSupportedTransactionVersion: TxVersion.V0,\n });\n if (r) {\n confirmed = true;\n clearInterval(intervalId!);\n cbk({ err: r.meta?.err || null });\n console.log(\"tx status from getTransaction:\", txId);\n }\n } catch (e) {\n confirmed = true;\n clearInterval(intervalId!);\n console.error(\"getTransaction timeout:\", e, txId);\n }\n }, LOOP_INTERVAL);\n\n subSignatureId = this.connection.onSignature(\n txId,\n (result) => {\n if (confirmed) {\n this.connection.removeSignatureListener(subSignatureId!);\n return;\n }\n confirmed = true;\n cbk(result);\n },\n \"confirmed\",\n );\n this.connection.getSignatureStatus(txId);\n };\n checkSendTx();\n return {\n txIds: [],\n signedTxs,\n };\n } else {\n const txIds: string[] = [];\n for (let i = 0; i < signedTxs.length; i += 1) {\n const txId = await this.connection.sendTransaction(signedTxs[i], { skipPreflight });\n txIds.push(txId);\n }\n return { txIds, signedTxs };\n }\n }\n throw new Error(\"please provide owner in keypair format or signAllTransactions function\");\n },\n extInfo: extInfo || {},\n };\n }\n}\n","import { Connection, PublicKey, AddressLookupTableAccount } from \"@solana/web3.js\";\nimport { getMultipleAccountsInfo } from \"../accountInfo\";\n\nexport interface CacheLTA {\n [key: string]: AddressLookupTableAccount;\n}\n\nexport async function getMultipleLookupTableInfo({\n connection,\n address,\n cluster = \"mainnet\",\n}: {\n connection: Connection;\n address: PublicKey[];\n cluster?: \"mainnet\" | \"devnet\";\n}): Promise<CacheLTA> {\n const dataInfos = await getMultipleAccountsInfo(\n connection,\n [...new Set<string>(address.map((i) => i.toString()))].map((i) => new PublicKey(i)),\n );\n\n const outDict: CacheLTA = {};\n for (let i = 0; i < address.length; i++) {\n const info = dataInfos[i];\n const key = address[i];\n if (!info) continue;\n const lookupAccount = new AddressLookupTableAccount({\n key,\n state: AddressLookupTableAccount.deserialize(info.data),\n });\n outDict[key.toString()] = lookupAccount;\n\n if (cluster === \"devnet\") DEV_LOOKUP_TABLE_CACHE[key.toString()] = lookupAccount;\n else LOOKUP_TABLE_CACHE[key.toString()] = lookupAccount;\n }\n\n return outDict;\n}\n\nexport const LOOKUP_TABLE_CACHE: CacheLTA = {\n // AcL1Vo8oy1ULiavEcjSUcwfBSForXMudcZvDZy5nzJkU: new AddressLookupTableAccount({\n // key: new PublicKey(\"AcL1Vo8oy1ULiavEcjSUcwfBSForXMudcZvDZy5nzJkU\"),\n // state: AddressLookupTableAccount.deserialize(\n // Buffer.from(\n // \"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\",\n // \"base64\",\n // ),\n // ),\n // }),\n};\n\nexport const getMainLookupTableCache = async (connection: Connection) => {\n const altStr = \"AcL1Vo8oy1ULiavEcjSUcwfBSForXMudcZvDZy5nzJkU\";\n if (LOOKUP_TABLE_CACHE[altStr]) return LOOKUP_TABLE_CACHE;\n\n const devAlt = new PublicKey(altStr);\n const data = await connection.getAccountInfo(devAlt);\n if (!data) return LOOKUP_TABLE_CACHE;\n LOOKUP_TABLE_CACHE[altStr] = new AddressLookupTableAccount({\n key: devAlt,\n state: AddressLookupTableAccount.deserialize(data.data),\n });\n\n return LOOKUP_TABLE_CACHE;\n};\n\nexport const DEV_LOOKUP_TABLE_CACHE: CacheLTA = {};\nexport const getDevLookupTableCache = async (connection: Connection) => {\n const devAltStr = \"EFhMuDw1PKEuckuFRW9PavNfTH4LKP5uKHgyXDmWpFCq\";\n if (DEV_LOOKUP_TABLE_CACHE[devAltStr]) return DEV_LOOKUP_TABLE_CACHE;\n\n const devAlt = new PublicKey(devAltStr);\n const data = await connection.getAccountInfo(devAlt);\n if (!data) return DEV_LOOKUP_TABLE_CACHE;\n DEV_LOOKUP_TABLE_CACHE[devAltStr] = new AddressLookupTableAccount({\n key: devAlt,\n state: AddressLookupTableAccount.deserialize(data.data),\n });\n\n return DEV_LOOKUP_TABLE_CACHE;\n};\n","export enum TxVersion {\n \"V0\",\n \"LEGACY\",\n}\n\nexport const InstructionType = {\n CreateAccount: \"CreateAccount\",\n InitAccount: \"InitAccount\",\n CreateATA: \"CreateATA\",\n CloseAccount: \"CloseAccount\",\n TransferAmount: \"TransferAmount\",\n InitMint: \"InitMint\",\n MintTo: \"MintTo\",\n\n InitMarket: \"InitMarket\", // create market main ins\n Util1216OwnerClaim: \"Util1216OwnerClaim\", // owner claim token ins\n\n SetComputeUnitPrice: \"SetComputeUnitPrice\",\n SetComputeUnitLimit: \"SetComputeUnitLimit\",\n\n // CLMM\n ClmmCreatePool: \"ClmmCreatePool\",\n ClmmOpenPosition: \"ClmmOpenPosition\",\n ClmmIncreasePosition: \"ClmmIncreasePosition\",\n ClmmDecreasePosition: \"ClmmDecreasePosition\",\n ClmmClosePosition: \"ClmmClosePosition\",\n ClmmSwapBaseIn: \"ClmmSwapBaseIn\",\n ClmmSwapBaseOut: \"ClmmSwapBaseOut\",\n ClmmInitReward: \"ClmmInitReward\",\n ClmmSetReward: \"ClmmSetReward\",\n ClmmCollectReward: \"ClmmCollectReward\",\n ClmmLockPosition: \"ClmmLockPosition\",\n ClmmHarvestLockPosition: \"ClmmHarvestLockPosition\",\n\n AmmV4Swap: \"AmmV4Swap\",\n AmmV4AddLiquidity: \"AmmV4AddLiquidity\",\n AmmV4RemoveLiquidity: \"AmmV4RemoveLiquidity\",\n AmmV4SimulatePoolInfo: \"AmmV4SimulatePoolInfo\",\n AmmV4SwapBaseIn: \"AmmV4SwapBaseIn\",\n AmmV4SwapBaseOut: \"AmmV4SwapBaseOut\",\n AmmV4CreatePool: \"AmmV4CreatePool\",\n AmmV4InitPool: \"AmmV4InitPool\",\n\n AmmV5AddLiquidity: \"AmmV5AddLiquidity\",\n AmmV5RemoveLiquidity: \"AmmV5RemoveLiquidity\",\n AmmV5SimulatePoolInfo: \"AmmV5SimulatePoolInfo\",\n AmmV5SwapBaseIn: \"AmmV5SwapBaseIn\",\n AmmV5SwapBaseOut: \"AmmV5SwapBaseOut\",\n\n RouteSwap: \"RouteSwap\",\n RouteSwap1: \"RouteSwap1\",\n RouteSwap2: \"RouteSwap2\",\n\n FarmV3Deposit: \"FarmV3Deposit\",\n FarmV3Withdraw: \"FarmV3Withdraw\",\n FarmV3CreateLedger: \"FarmV3CreateLedger\",\n\n FarmV4Withdraw: \"FarmV4Withdraw\",\n\n FarmV5Deposit: \"FarmV5Deposit\",\n FarmV5Withdraw: \"FarmV5Withdraw\",\n FarmV5CreateLedger: \"FarmV5CreateLedger\",\n\n FarmV6Deposit: \"FarmV6Deposit\",\n FarmV6Withdraw: \"FarmV6Withdraw\",\n FarmV6Create: \"FarmV6Create\",\n FarmV6Restart: \"FarmV6Restart\",\n FarmV6CreatorAddReward: \"FarmV6CreatorAddReward\",\n FarmV6CreatorWithdraw: \"FarmV6CreatorWithdraw\",\n\n CpmmCreatePool: \"CpmmCreatePool\",\n CpmmAddLiquidity: \"CpmmAddLiquidity\",\n CpmmWithdrawLiquidity: \"CpmmWithdrawLiquidity\",\n CpmmSwapBaseIn: \"CpmmSwapBaseIn\",\n CpmmSwapBaseOut: \"CpmmSwapBaseOut\",\n\n CpmmLockLp: \"CpmmLockLp\",\n CpmmCollectLockFee: \"CpmmCollectLockFee\",\n TransferTip: \"TransferTip\",\n};\n","import {\n Commitment,\n ComputeBudgetProgram,\n Connection,\n EpochInfo,\n Keypair,\n PublicKey,\n SimulatedTransactionResponse,\n Transaction,\n TransactionInstruction,\n TransactionMessage,\n VersionedTransaction,\n} from \"@solana/web3.js\";\n\nimport { createLogger } from \"../logger\";\nimport { CacheLTA } from \"./lookupTable\";\nimport { InstructionType } from \"./txType\";\n\nimport { ComputeBudgetConfig } from \"../../raydium/type\";\nimport { TOKEN_PROGRAM_ID } from \"@solana/spl-token\";\n\nconst logger = createLogger(\"Raydium_txUtil\");\n\nexport const MAX_BASE64_SIZE = 1644;\n\nexport function addComputeBudget(config: ComputeBudgetConfig): {\n instructions: TransactionInstruction[];\n instructionTypes: string[];\n} {\n const ins: TransactionInstruction[] = [];\n const insTypes: string[] = [];\n if (config.microLamports) {\n ins.push(ComputeBudgetProgram.setComputeUnitPrice({ microLamports: config.microLamports }));\n insTypes.push(InstructionType.SetComputeUnitPrice);\n }\n if (config.units) {\n ins.push(ComputeBudgetProgram.setComputeUnitLimit({ units: config.units }));\n insTypes.push(InstructionType.SetComputeUnitLimit);\n }\n\n return {\n instructions: ins,\n instructionTypes: insTypes,\n };\n}\n\nexport async function getRecentBlockHash(connection: Connection, propsCommitment?: Commitment): Promise<string> {\n const commitment = propsCommitment ?? \"confirmed\";\n return (await connection.getLatestBlockhash?.({ commitment }))?.blockhash;\n}\n\nexport async function confirmTransaction(connection: Connection, txId: string): Promise<string> {\n connection.getSignatureStatuses([txId]);\n return new Promise((resolve, reject) => {\n const id = setTimeout(reject, 60 * 1000);\n connection.onSignature(\n txId,\n (signatureResult) => {\n clearTimeout(id);\n if (!signatureResult.err) {\n resolve(\"\");\n return;\n }\n reject(Object.assign(signatureResult.err, { txId }));\n },\n \"confirmed\",\n );\n });\n}\n\n/**\n * Forecast transaction size\n */\nexport function forecastTransactionSize(instructions: TransactionInstruction[], signers: PublicKey[]): boolean {\n if (instructions.length < 1) logger.logWithError(`no instructions provided: ${instructions.toString()}`);\n if (signers.length < 1) logger.logWithError(`no signers provided:, ${signers.toString()}`);\n\n const transaction = new Transaction();\n transaction.recentBlockhash = \"11111111111111111111111111111111\";\n transaction.feePayer = signers[0];\n transaction.add(...instructions);\n\n try {\n // eslint-disable-next-line\n // @ts-ignore\n return Buffer.from(transaction.serialize({ verifySignatures: false })).toString(\"base64\").length < MAX_BASE64_SIZE;\n } catch (error) {\n return false;\n }\n}\n\n/**\n * Simulates multiple instruction\n */\n/**\n * Simulates multiple instruction\n */\nexport async function simulateMultipleInstruction(\n connection: Connection,\n instructions: TransactionInstruction[],\n keyword: string,\n batchRequest = true,\n): Promise<string[]> {\n const feePayer = new PublicKey(\"RaydiumSimuLateTransaction11111111111111111\");\n\n const transactions: Transaction[] = [];\n\n let transaction = new Transaction();\n transaction.feePayer = feePayer;\n\n for (const instruction of instructions) {\n if (!forecastTransactionSize([...transaction.instructions, instruction], [feePayer])) {\n transactions.push(transaction);\n transaction = new Transaction();\n transaction.feePayer = feePayer;\n }\n transaction.add(instruction);\n }\n if (transaction.instructions.length > 0) {\n transactions.push(transaction);\n }\n\n let results: SimulatedTransactionResponse[] = [];\n\n try {\n results = await simulateTransaction(connection, transactions, batchRequest);\n if (results.find((i) => i.err !== null)) throw Error(\"rpc simulateTransaction error\");\n } catch (error) {\n if (error instanceof Error) {\n logger.logWithError(\"failed to simulate for instructions\", \"RPC_ERROR\", {\n message: error.message,\n });\n }\n }\n\n const logs: string[] = [];\n for (const result of results) {\n logger.debug(\"simulate result:\", result);\n\n if (result.logs) {\n const filteredLog = result.logs.filter((log) => log && log.includes(keyword));\n logger.debug(\"filteredLog:\", logs);\n if (!filteredLog.length) logger.logWithError(\"simulate log not match keyword\", \"keyword\", keyword);\n logs.push(...filteredLog);\n }\n }\n\n return logs;\n}\n\nexport function parseSimulateLogToJson(log: string, keyword: string): any {\n const results = log.match(/{[\"\\w:,]+}/g);\n if (!results || results.length !== 1) {\n return logger.logWithError(`simulate log fail to match json, keyword: ${keyword}`);\n }\n\n return results[0];\n}\n\nexport function parseSimulateValue(log: string, key: string): any {\n const reg = new RegExp(`\"${key}\":(\\\\d+)`, \"g\");\n\n const results = reg.exec(log);\n if (!results || results.length !== 2) {\n return logger.logWithError(`simulate log fail to match key\", key: ${key}`);\n }\n\n return results[1];\n}\n\nexport interface ProgramAddress {\n publicKey: PublicKey;\n nonce: number;\n}\nexport function findProgramAddress(\n seeds: Array<Buffer | Uint8Array>,\n programId: PublicKey,\n): {\n publicKey: PublicKey;\n nonce: number;\n} {\n const [publicKey, nonce] = PublicKey.findProgramAddressSync(seeds, programId);\n return { publicKey, nonce };\n}\n\nexport async function simulateTransaction(\n connection: Connection,\n transactions: Transaction[],\n batchRequest?: boolean,\n): Promise<any[]> {\n let results: any[] = [];\n if (batchRequest) {\n const getLatestBlockhash = await connection.getLatestBlockhash();\n\n const encodedTransactions: string[] = [];\n for (const transaction of transactions) {\n transaction.recentBlockhash = getLatestBlockhash.blockhash;\n transaction.lastValidBlockHeight = getLatestBlockhash.lastValidBlockHeight;\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n const message = transaction._compile();\n const signData = message.serialize();\n\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n const wireTransaction = transaction._serialize(signData);\n const encodedTransaction = wireTransaction.toString(\"base64\");\n\n encodedTransactions.push(encodedTransaction);\n }\n\n const batch = encodedTransactions.map((keys) => {\n const args = connection._buildArgs([keys], undefined, \"base64\");\n return {\n methodName: \"simulateTransaction\",\n args,\n };\n });\n\n const reqData: { methodName: string; args: any[] }[][] = [];\n const itemReqIndex = 20;\n for (let i = 0; i < Math.ceil(batch.length / itemReqIndex); i++) {\n reqData.push(batch.slice(i * itemReqIndex, (i + 1) * itemReqIndex));\n }\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n results = await (\n await Promise.all(\n reqData.map(async (i) => (await (connection as any)._rpcBatchRequest(i)).map((ii) => ii.result.value)),\n )\n ).flat();\n } else {\n try {\n results = await Promise.all(\n transactions.map(async (transaction) => await (await connection.simulateTransaction(transaction)).value),\n );\n } catch (error) {\n if (error instanceof Error) {\n logger.logWithError(\"failed to get info for multiple accounts\", \"RPC_ERROR\", {\n message: error.message,\n });\n }\n }\n }\n\n return results;\n}\n\nexport function checkLegacyTxSize({\n instructions,\n payer,\n signers,\n}: {\n instructions: TransactionInstruction[];\n payer: PublicKey;\n signers: PublicKey[];\n}): boolean {\n return forecastTransactionSize(instructions, [payer, ...signers]);\n}\n\nexport function checkV0TxSize({\n instructions,\n payer,\n lookupTableAddressAccount,\n recentBlockhash = Keypair.generate().publicKey.toString(),\n}: {\n instructions: TransactionInstruction[];\n payer: PublicKey;\n lookupTableAddressAccount?: CacheLTA;\n recentBlockhash?: string;\n}): boolean {\n const transactionMessage = new TransactionMessage({\n payerKey: payer,\n recentBlockhash,\n instructions,\n });\n\n const messageV0 = transactionMessage.compileToV0Message(Object.values(lookupTableAddressAccount ?? {}));\n try {\n const buildLength = Buffer.from(new VersionedTransaction(messageV0).serialize()).toString(\"base64\").length;\n return buildLength < MAX_BASE64_SIZE;\n } catch (error) {\n return false;\n }\n}\n\nlet epochInfoCache: { time: number; data?: EpochInfo } = {\n time: 0,\n data: undefined,\n};\n\nexport async function getEpochInfo(connection: Connection): Promise<EpochInfo> {\n if (!epochInfoCache.data || (Date.now() - epochInfoCache.time) / 1000 > 30) {\n const data = await connection.getEpochInfo();\n epochInfoCache = {\n time: Date.now(),\n data,\n };\n return data;\n } else {\n return epochInfoCache.data;\n }\n}\n\nexport const toBuffer = (arr: Buffer | Uint8Array | Array<number>): Buffer => {\n if (Buffer.isBuffer(arr)) {\n return arr;\n } else if (arr instanceof Uint8Array) {\n return Buffer.from(arr.buffer, arr.byteOffset, arr.byteLength);\n } else {\n return Buffer.from(arr);\n }\n};\n\nexport const txToBase64 = (transaction: Transaction | VersionedTransaction): string => {\n let serialized = transaction.serialize({ requireAllSignatures: false, verifySignatures: false });\n if (transaction instanceof VersionedTransaction) serialized = toBuffer(serialized);\n try {\n return serialized instanceof Buffer ? serialized.toString(\"base64\") : Buffer.from(serialized).toString(\"base64\");\n } catch {\n return serialized.toString(\"base64\");\n }\n};\n\nexport function printSimulate(transactions: Transaction[] | VersionedTransaction[]): string[] {\n const allBase64: string[] = [];\n transactions.forEach((transaction) => {\n if (transaction instanceof Transaction) {\n if (!transaction.recentBlockhash) transaction.recentBlockhash = TOKEN_PROGRAM_ID.toBase58();\n if (!transaction.feePayer) transaction.feePayer = Keypair.generate().publicKey;\n }\n allBase64.push(txToBase64(transaction));\n });\n console.log(\"simulate tx string:\", allBase64);\n\n return allBase64;\n}\n\nexport function transformTxToBase64(tx: Transaction | VersionedTransaction): string {\n let serialized = tx.serialize({ requireAllSignatures: false, verifySignatures: false });\n if (tx instanceof VersionedTransaction) serialized = toBuffer(serialized);\n return serialized.toString(\"base64\");\n}\n","import { PublicKey } from \"@solana/web3.js\";\n\nimport { createLogger, Logger } from \"../common/logger\";\nimport { TxBuilder } from \"../common/txTool/txTool\";\n\nimport { Raydium } from \"./\";\n\nexport interface ModuleBaseProps {\n scope: Raydium;\n moduleName: string;\n}\n\nconst joinMsg = (...args: (string | number | Record<string, any>)[]): string =>\n args\n .map((arg) => {\n try {\n return typeof arg === \"object\" ? JSON.stringify(arg) : arg;\n } catch {\n return arg;\n }\n })\n .join(\", \");\nexport default class ModuleBase {\n public scope: Raydium;\n private disabled = false;\n protected logger: Logger;\n\n constructor({ scope, moduleName }: ModuleBaseProps) {\n this.scope = scope;\n this.logger = createLogger(moduleName);\n }\n\n protected createTxBuilder(feePayer?: PublicKey): TxBuilder {\n this.scope.checkOwner();\n return new TxBuilder({\n connection: this.scope.connection,\n feePayer: feePayer || this.scope.ownerPubKey,\n cluster: this.scope.cluster,\n owner: this.scope.owner,\n blockhashCommitment: this.scope.blockhashCommitment,\n loopMultiTxStatus: this.scope.loopMultiTxStatus,\n api: this.scope.api,\n signAllTransactions: this.scope.signAllTransactions,\n });\n }\n\n public logDebug(...args: (string | number | Record<string, any>)[]): void {\n this.logger.debug(joinMsg(args));\n }\n\n public logInfo(...args: (string | number | Record<string, any>)[]): void {\n this.logger.info(joinMsg(args));\n }\n\n public logAndCreateError(...args: (string | number | Record<string, any>)[]): void {\n const message = joinMsg(args);\n throw new Error(message);\n }\n\n public checkDisabled(): void {\n if (this.disabled || !this.scope) this.logAndCreateError(\"module not working\");\n }\n}\n","import { Commitment, Connection, PublicKey, Signer, SystemProgram, TransactionInstruction } from \"@solana/web3.js\";\nimport BN from \"bn.js\";\nimport { BigNumberish, parseBigNumberish } from \"@/common\";\nimport {\n createCloseAccountInstruction,\n createInitializeAccountInstruction,\n createTransferInstruction,\n TOKEN_PROGRAM_ID,\n} from \"@solana/spl-token\";\nimport { AddInstructionParam } from \"@/common/txTool/txTool\";\nimport { InstructionType } from \"@/common/txTool/txType\";\nimport { TOKEN_WSOL } from \"../token/constant\";\nimport { generatePubKey } from \"./util\";\n\nimport { splAccountLayout } from \"./layout\";\n\nexport function initTokenAccountInstruction(params: {\n mint: PublicKey;\n tokenAccount: PublicKey;\n owner: PublicKey;\n programId?: PublicKey;\n}): TransactionInstruction {\n const { mint, tokenAccount, owner, programId = TOKEN_PROGRAM_ID } = params;\n return createInitializeAccountInstruction(tokenAccount, mint, owner, programId);\n}\n\nexport function closeAccountInstruction(params: {\n tokenAccount: PublicKey;\n payer: PublicKey;\n multiSigners?: Signer[];\n owner: PublicKey;\n programId?: PublicKey;\n}): TransactionInstruction {\n const { tokenAccount, payer, multiSigners = [], owner, programId = TOKEN_PROGRAM_ID } = params;\n return createCloseAccountInstruction(tokenAccount, payer, owner, multiSigners, programId);\n}\n\ninterface CreateWSolTokenAccount {\n connection: Connection;\n payer: PublicKey;\n owner: PublicKey;\n amount: BigNumberish;\n commitment?: Commitment;\n skipCloseAccount?: boolean;\n}\n/**\n * WrappedNative account = wsol account\n */\nexport async function createWSolAccountInstructions(params: CreateWSolTokenAccount): Promise<\n AddInstructionParam & {\n addresses: { newAccount: PublicKey };\n }\n> {\n const { connection, amount, commitment, payer, owner, skipCloseAccount } = params;\n\n const balanceNeeded = await connection.getMinimumBalanceForRentExemption(splAccountLayout.span, commitment);\n const lamports = parseBigNumberish(amount).add(new BN(balanceNeeded));\n const newAccount = generatePubKey({ fromPublicKey: payer, programId: TOKEN_PROGRAM_ID });\n\n return {\n addresses: { newAccount: newAccount.publicKey },\n signers: [],\n instructions: [\n SystemProgram.createAccountWithSeed({\n fromPubkey: payer,\n basePubkey: payer,\n seed: newAccount.seed,\n newAccountPubkey: newAccount.publicKey,\n lamports: lamports.toNumber(),\n space: splAccountLayout.span,\n programId: TOKEN_PROGRAM_ID,\n }),\n initTokenAccountInstruction({\n mint: new PublicKey(TOKEN_WSOL.address),\n tokenAccount: newAccount.publicKey,\n owner,\n programId: TOKEN_PROGRAM_ID,\n }),\n ],\n instructionTypes: [InstructionType.CreateAccount, InstructionType.InitAccount],\n endInstructionTypes: skipCloseAccount ? [] : [InstructionType.CloseAccount],\n endInstructions: skipCloseAccount\n ? []\n : [\n closeAccountInstruction({\n tokenAccount: newAccount.publicKey,\n payer,\n owner,\n }),\n ],\n };\n}\n\nexport function makeTransferInstruction({\n source,\n destination,\n owner,\n amount,\n multiSigners = [],\n tokenProgram = TOKEN_PROGRAM_ID,\n}: {\n source: PublicKey;\n destination: PublicKey;\n owner: PublicKey;\n amount: BigNumberish;\n multiSigners?: Signer[];\n tokenProgram?: PublicKey;\n}): TransactionInstruction {\n return createTransferInstruction(source, destination, owner, BigInt(String(amount)), multiSigners, tokenProgram);\n}\n","import { AccountInfo, GetProgramAccountsResponse, Keypair, PublicKey, RpcResponseAndContext } from \"@solana/web3.js\";\nimport BN from \"bn.js\";\nimport { getATAAddress } from \"../../common\";\nimport { TOKEN_PROGRAM_ID } from \"@solana/spl-token\";\nimport { sha256 } from \"@noble/hashes/sha256\";\nimport { splAccountLayout } from \"./layout\";\nimport { TokenAccount, TokenAccountRaw } from \"./types\";\n\nexport interface ParseTokenAccount {\n owner: PublicKey;\n solAccountResp?: AccountInfo<Buffer> | null;\n tokenAccountResp: RpcResponseAndContext<GetProgramAccountsResponse>;\n}\n\nexport function parseTokenAccountResp({ owner, solAccountResp, tokenAccountResp }: ParseTokenAccount): {\n tokenAccounts: TokenAccount[];\n tokenAccountRawInfos: TokenAccountRaw[];\n} {\n const tokenAccounts: TokenAccount[] = [];\n const tokenAccountRawInfos: TokenAccountRaw[] = [];\n\n for (const { pubkey, account } of tokenAccountResp.value) {\n const accountInfo = splAccountLayout.decode(account.data);\n const { mint, amount } = accountInfo;\n tokenAccounts.push({\n publicKey: pubkey,\n mint,\n amount,\n isAssociated: getATAAddress(owner, mint, account.owner).publicKey.equals(pubkey),\n isNative: false,\n programId: account.owner,\n });\n // todo programId should get from api\n tokenAccountRawInfos.push({ pubkey, accountInfo, programId: account.owner });\n }\n\n if (solAccountResp) {\n tokenAccounts.push({\n mint: PublicKey.default,\n amount: new BN(String(solAccountResp.lamports)),\n isNative: true,\n programId: solAccountResp.owner,\n });\n }\n\n return {\n tokenAccounts,\n tokenAccountRawInfos,\n };\n}\n\nexport function generatePubKey({\n fromPublicKey,\n programId = TOKEN_PROGRAM_ID,\n assignSeed,\n}: {\n fromPublicKey: PublicKey;\n programId: PublicKey;\n assignSeed?: string;\n}): { publicKey: PublicKey; seed: string } {\n const seed = assignSeed ? btoa(assignSeed).slice(0, 32) : Keypair.generate().publicKey.toBase58().slice(0, 32);\n const publicKey = createWithSeed(fromPublicKey, seed, programId);\n return { publicKey, seed };\n}\n\nfunction createWithSeed(fromPublicKey: PublicKey, seed: string, programId: PublicKey): PublicKey {\n const buffer = Buffer.concat([fromPublicKey.toBuffer(), Buffer.from(seed), programId.toBuffer()]);\n const publicKeyBytes = sha256(buffer);\n return new PublicKey(publicKeyBytes);\n}\n",null,null,null,null,"import { PublicKey } from \"@solana/web3.js\";\nimport BN, { isBN } from \"bn.js\";\n\nimport {\n bits,\n blob,\n Blob,\n Layout,\n offset as _offset,\n seq as _seq,\n Structure as _Structure,\n u32 as _u32,\n u8 as _u8,\n UInt,\n union as _union,\n Union as _Union,\n} from \"./buffer-layout\";\n\nexport * from \"./buffer-layout\";\nexport { blob };\n\nexport class BNLayout<P extends string = \"\"> extends Layout<BN, P> {\n blob: Layout<Buffer>;\n signed: boolean;\n\n constructor(span: number, signed: boolean, property?: P) {\n //@ts-expect-error type wrong for super()'s type different from extends, but it desn't matter\n super(span, property);\n this.blob = blob(span);\n this.signed = signed;\n }\n\n /** @override */\n decode(b: Buffer, offset = 0): BN {\n const num = new BN(this.blob.decode(b, offset), 10, \"le\");\n if (this.signed) {\n return num.fromTwos(this.span * 8).clone();\n }\n return num;\n }\n\n /** @override */\n encode(src: BN, b: Buffer, offset = 0): number {\n if (typeof src === \"number\") src = new BN(src); // src will pass a number accidently in union\n if (this.signed) {\n src = src.toTwos(this.span * 8);\n }\n return this.blob.encode(src.toArrayLike(Buffer, \"le\", this.span), b, offset);\n }\n}\n\nexport class WideBits<P extends string = \"\"> extends Layout<Record<string, boolean>, P> {\n _lower: any;\n _upper: any;\n // TODO: unknown\n constructor(property?: P) {\n //@ts-expect-error type wrong for super()'s type different from extends , but it desn't matter\n super(8, property);\n this._lower = bits(_u32(), false);\n this._upper = bits(_u32(), false);\n }\n\n addBoolean(property: string): void {\n if (this._lower.fields.length < 32) {\n this._lower.addBoolean(property);\n } else {\n this._upper.addBoolean(property);\n }\n }\n\n decode(b: Buffer, offset = 0): Record<string, boolean> {\n const lowerDecoded = this._lower.decode(b, offset);\n const upperDecoded = this._upper.decode(b, offset + this._lower.span);\n return { ...lowerDecoded, ...upperDecoded };\n }\n\n encode(src: any /* TEMP */, b: Buffer, offset = 0): any {\n return this._lower.encode(src, b, offset) + this._upper.encode(src, b, offset + this._lower.span);\n }\n}\n\nexport function u8<P extends string = \"\">(property?: P): UInt<number, P> {\n return new UInt(1, property);\n}\n\nexport function u32<P extends string = \"\">(property?: P): UInt<number, P> {\n return new UInt(4, property);\n}\n\nexport function u64<P extends string = \"\">(property?: P): BNLayout<P> {\n return new BNLayout(8, false, property);\n}\n\nexport function u128<P extends string = \"\">(property?: P): BNLayout<P> {\n return new BNLayout(16, false, property);\n}\n\nexport function i8<P extends string = \"\">(property?: P): BNLayout<P> {\n return new BNLayout(1, true, property);\n}\n\nexport function i64<P extends string = \"\">(property?: P): BNLayout<P> {\n return new BNLayout(8, true, property);\n}\n\nexport function i128<P extends string = \"\">(property?: P): BNLayout<P> {\n return new BNLayout(16, true, property);\n}\n\nexport class WrappedLayout<T, U, P extends string = \"\"> extends Layout<U, P> {\n layout: Layout<T>;\n decoder: (data: T) => U;\n encoder: (src: U) => T;\n\n constructor(layout: Layout<T>, decoder: (data: T) => U, encoder: (src: U) => T, property?: P) {\n //@ts-expect-error type wrong for super()'s type different from extends , but it desn't matter\n super(layout.span, property);\n this.layout = layout;\n this.decoder = decoder;\n this.encoder = encoder;\n }\n\n decode(b: Buffer, offset?: number): U {\n return this.decoder(this.layout.decode(b, offset));\n }\n\n encode(src: U, b: Buffer, offset?: number): number {\n return this.layout.encode(this.encoder(src), b, offset);\n }\n\n getSpan(b: Buffer, offset?: number): number {\n return this.layout.getSpan(b, offset);\n }\n}\n\nexport function publicKey<P extends string = \"\">(property?: P): Layout<PublicKey, P> {\n return new WrappedLayout(\n blob(32),\n (b: Buffer) => new PublicKey(b),\n (key: PublicKey) => key.toBuffer(),\n property,\n );\n}\n\nexport class OptionLayout<T, P> extends Layout<T | null, P> {\n layout: Layout<T>;\n discriminator: Layout<number>;\n\n constructor(layout: Layout<T>, property?: P) {\n //@ts-expect-error type wrong for super()'s type different from extends , but it desn't matter\n super(-1, property);\n this.layout = layout;\n this.discriminator = _u8();\n }\n\n encode(src: T | null, b: Buffer, offset = 0): number {\n if (src === null || src === undefined) {\n return this.discriminator.encode(0, b, offset);\n }\n this.discriminator.encode(1, b, offset);\n return this.layout.encode(src, b, offset + 1) + 1;\n }\n\n decode(b: Buffer, offset = 0): T | null {\n const discriminator = this.discriminator.decode(b, offset);\n if (discriminator === 0) {\n return null;\n } else if (discriminator === 1) {\n return this.layout.decode(b, offset + 1);\n }\n throw new Error(\"Invalid option \" + this.property);\n }\n\n getSpan(b: Buffer, offset = 0): number {\n const discriminator = this.discriminator.decode(b, offset);\n if (discriminator === 0) {\n return 1;\n } else if (discriminator === 1) {\n return this.layout.getSpan(b, offset + 1) + 1;\n }\n throw new Error(\"Invalid option \" + this.property);\n }\n}\n\nexport function option<T, P extends string = \"\">(layout: Layout<T>, property?: P): Layout<T | null, P> {\n return new OptionLayout<T, P>(layout, property);\n}\n\nexport function bool<P extends string = \"\">(property?: P): Layout<boolean, P> {\n return new WrappedLayout(_u8(), decodeBool, encodeBool, property);\n}\n\nexport function decodeBool(value: number): boolean {\n if (value === 0) {\n return false;\n } else if (value === 1) {\n return true;\n }\n throw new Error(\"Invalid bool: \" + value);\n}\n\nexport function encodeBool(value: boolean): number {\n return value ? 1 : 0;\n}\n\nexport function vec<T, P extends string = \"\">(elementLayout: Layout<T>, property?: P): Layout<T[], P> {\n const length = _u32(\"length\");\n const layout: Layout<{ values: T[] }> = struct([\n length,\n seq(elementLayout, _offset(length, -length.span), \"values\"),\n ]) as any; // Something I don't know\n return new WrappedLayout(\n layout,\n ({ values }) => values,\n (values) => ({ values }),\n property,\n );\n}\n\nexport function tagged<T, P extends string = \"\">(tag: BN, layout: Layout<T>, property?: P): Layout<T, P> {\n const wrappedLayout: Layout<{ tag: BN; data: T }> = struct([u64(\"tag\"), layout.replicate(\"data\")]) as any; // Something I don't know\n\n function decodeTag({ tag: receivedTag, data }: { tag: BN; data: T }): T {\n if (!receivedTag.eq(tag)) {\n throw new Error(\"Invalid tag, expected: \" + tag.toString(\"hex\") + \", got: \" + receivedTag.toString(\"hex\"));\n }\n return data;\n }\n\n return new WrappedLayout(wrappedLayout, decodeTag, (data) => ({ tag, data }), property);\n}\n\nexport function vecU8<P extends string = \"\">(property?: P): Layout<Buffer, P> {\n const length = _u32(\"length\");\n const layout: Layout<{ data: Buffer }> = struct([length, blob(_offset(length, -length.span), \"data\")]) as any; // Something I don't know\n return new WrappedLayout(\n layout,\n ({ data }) => data,\n (data) => ({ data }),\n property,\n );\n}\n\nexport function str<P extends string = \"\">(property?: P): Layout<string, P> {\n return new WrappedLayout(\n vecU8(),\n (data) => data.toString(\"utf-8\"),\n (s) => Buffer.from(s, \"utf-8\"),\n property,\n );\n}\n\nexport interface EnumLayout<T, P extends string = \"\"> extends Layout<T, P> {\n registry: Record<string, Layout<any>>;\n}\n\nexport function rustEnum<T, P extends string = \"\">(variants: Layout<any>[], property?: P): EnumLayout<T, P> {\n const unionLayout = _union(_u8(), property);\n variants.forEach((variant, index) => unionLayout.addVariant(index, variant, variant.property));\n return unionLayout as any; // ?why use UnionLayout? This must be a fault\n}\n\nexport function array<T, P extends string = \"\">(\n elementLayout: Layout<T>,\n length: number,\n property?: P,\n): Layout<T[], P> {\n const layout = struct([seq(elementLayout, length, \"values\")]) as any as Layout<{ values: T[] }>; // Something I don't know\n return new WrappedLayout(\n layout,\n ({ values }) => values,\n (values) => ({ values }),\n property,\n );\n}\n\nexport class Structure<T, P, D extends { [key: string]: any; }> extends _Structure<T, P, D> {\n /** @override */\n decode(b: Buffer, offset?: number): D {\n return super.decode(b, offset);\n }\n}\n\nexport function struct<T, P extends string = \"\">(\n fields: T,\n property?: P,\n decodePrefixes?: boolean,\n): T extends Layout<infer Value, infer Property>[]\n ? Structure<\n Value,\n P,\n {\n [K in Exclude<Extract<Property, string>, \"\">]: Extract<T[number], Layout<any, K>> extends Layout<infer V, any>\n ? V\n : any;\n }\n >\n : any {\n //@ts-expect-error this type is not quite satisfied the define, but, never no need to worry about.\n return new Structure(fields, property, decodePrefixes);\n}\n\nexport type GetLayoutSchemaFromStructure<T extends Structure<any, any, any>> = T extends Structure<any, any, infer S>\n ? S\n : any;\nexport type GetStructureFromLayoutSchema<S extends { [key: string]: any; }> = Structure<any, any, S>;\n\nexport class Union<Schema extends { [key: string]: any; }> extends _Union<Schema> {\n encodeInstruction(instruction: any): Buffer {\n const instructionMaxSpan = Math.max(...Object.values(this.registry).map((r) => r.span));\n const b = Buffer.alloc(instructionMaxSpan);\n return b.slice(0, this.encode(instruction, b));\n }\n\n decodeInstruction(instruction: any): Partial<Schema> {\n return this.decode(instruction);\n }\n}\nexport function union<UnionSchema extends { [key: string]: any } = any>(\n discr: any,\n defaultLayout?: any,\n property?: string,\n): Union<UnionSchema> {\n return new Union(discr, defaultLayout, property);\n}\n\nclass Zeros extends Blob {\n decode(b: Buffer, offset: number): Buffer {\n const slice = super.decode(b, offset);\n if (!slice.every((v) => v === 0)) {\n throw new Error(\"nonzero padding bytes\");\n }\n return slice;\n }\n}\n\nexport function zeros(length: number): Zeros {\n return new Zeros(length);\n}\n\nexport function seq<T, P extends string = \"\", AnotherP extends string = \"\">(\n elementLayout: Layout<T, P>,\n count: number | BN | Layout<BN | number, P>,\n property?: AnotherP,\n): Layout<T[], AnotherP> {\n let parsedCount: number;\n const superCount =\n typeof count === \"number\"\n ? count\n : isBN(count)\n ? count.toNumber()\n : new Proxy(count as unknown as Layout<number> /* pretend to be Layout<number> */, {\n get(target, property): any {\n if (!parsedCount) {\n // get count in targetLayout. note that count may be BN\n const countProperty = Reflect.get(target, \"count\");\n\n // let targetLayout's property:count be a number\n parsedCount = isBN(countProperty) ? countProperty.toNumber() : countProperty;\n\n // record the count\n Reflect.set(target, \"count\", parsedCount);\n }\n return Reflect.get(target, property);\n },\n set(target, property, value): any {\n if (property === \"count\") {\n parsedCount = value;\n }\n return Reflect.set(target, property, value);\n },\n });\n\n // @ts-expect-error force type\n return _seq(elementLayout, superCount, property);\n}\n","import {\n bits as _bits,\n BitStructure as _BitStructure,\n blob as _blob,\n Blob as _Blob,\n cstr as _cstr,\n f32 as _f32,\n f32be as _f32be,\n f64 as _f64,\n f64be as _f64be,\n greedy as _greedy,\n Layout as _Layout,\n ns64 as _ns64,\n ns64be as _ns64be,\n nu64 as _nu64,\n nu64be as _nu64be,\n offset as _offset,\n s16 as _s16,\n s16be as _s16be,\n s24 as _s24,\n s24be as _s24be,\n s32 as _s32,\n s32be as _s32be,\n s40 as _s40,\n s40be as _s40be,\n s48 as _s48,\n s48be as _s48be,\n s8 as _s8,\n seq as _seq,\n struct as _struct,\n Structure as _Structure,\n u16 as _u16,\n u16be as _u16be,\n u24 as _u24,\n u24be as _u24be,\n u32 as _u32,\n u32be as _u32be,\n u40 as _u40,\n u40be as _u40be,\n u48 as _u48,\n u48be as _u48be,\n u8 as _u8,\n UInt as _UInt,\n union as _union,\n Union as _Union,\n unionLayoutDiscriminator as _unionLayoutDiscriminator,\n utf8 as _utf8,\n} from \"@solana/buffer-layout\";\n\n//#region ------------------- Layout -------------------\nexport interface Layout<T = any, P = \"\"> {\n span: number;\n property?: P;\n decode(b: Buffer, offset?: number): T;\n encode(src: T, b: Buffer, offset?: number): number;\n getSpan(b: Buffer, offset?: number): number;\n replicate<AP extends string>(name: AP): Layout<T, AP>;\n}\nexport interface LayoutConstructor {\n new <T, P>(): Layout<T, P>; // for class extends syntex\n new <T, P>(span?: T, property?: P): Layout<T, P>;\n readonly prototype: Layout;\n}\nexport const Layout = _Layout as unknown as LayoutConstructor;\n//#endregion\n\n//#region ------------------- Structure -------------------\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport interface Structure<T = any, P = \"\", DecodeSchema extends { [key: string]: any } = any>\n extends Layout<DecodeSchema, P> {\n span: number;\n decode(b: Buffer, offset?: number): DecodeSchema;\n layoutFor<AP extends string>(property: AP): Layout<DecodeSchema[AP]>;\n offsetOf<AP extends string>(property: AP): number;\n}\ninterface StructureConstructor {\n new <T = any, P = \"\", DecodeSchema extends { [key: string]: any } = any>(): Structure<T, P, DecodeSchema>;\n new <T = any, P = \"\", DecodeSchema extends { [key: string]: any } = any>(\n fields: T,\n property?: P,\n decodePrefixes?: boolean,\n ): Structure<T, P, DecodeSchema>;\n}\nexport const Structure = _Structure as unknown as StructureConstructor;\n//#endregion\n\n//#region ------------------- Union -------------------\nexport interface Union<UnionSchema extends { [key: string]: any } = any> extends Layout {\n registry: object;\n decode(b: Buffer, offset?: number): Partial<UnionSchema>;\n addVariant(\n variant: number,\n layout: Structure<any, any, Partial<UnionSchema>> | Layout<any, keyof UnionSchema>,\n property?: string,\n ): any /* TEMP: code in Layout.js 1809 */;\n}\ninterface UnionConstructor {\n new <UnionSchema extends { [key: string]: any } = any>(): Union<UnionSchema>;\n new <UnionSchema extends { [key: string]: any } = any>(\n discr: Layout<any, any>,\n defaultLayout: Layout<any, any>,\n property?: string,\n ): Union<UnionSchema>;\n}\nexport const Union = _Union as unknown as UnionConstructor;\n//#endregion\n\n//#region ------------------- BitStructure -------------------\nexport type BitStructure<T = unknown /* TEMP */, P = \"\"> = Layout<T, P>;\ninterface BitStructureConstructor {\n new (...params: any[]): BitStructure;\n}\nexport const BitStructure = _BitStructure as BitStructureConstructor;\n//#endregion\n\n//#region ------------------- UInt -------------------\nexport type UInt<T = any, P = \"\"> = Layout<T, P>;\ninterface UIntConstructor {\n new <T, P>(span?: T, property?: P): UInt<T, P>;\n}\nexport const UInt = _UInt as UIntConstructor;\n//#endregion\n\n//#region ------------------- Blob -------------------\nexport type Blob<P extends string = \"\"> = Layout<Buffer, P>;\ninterface BlobConstructor {\n new (...params: ConstructorParameters<LayoutConstructor>): Blob;\n}\nexport const Blob = _Blob as unknown as BlobConstructor;\n//#endregion\n\nexport const greedy = _greedy as <P extends string = \"\">(elementSpan?: number, property?: P) => Layout<number, P>;\nexport const u8 = _u8 as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const u16 = _u16 as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const u24 = _u24 as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const u32 = _u32 as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const u40 = _u40 as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const u48 = _u48 as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const nu64 = _nu64 as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const u16be = _u16be as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const u24be = _u24be as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const u32be = _u32be as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const u40be = _u40be as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const u48be = _u48be as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const nu64be = _nu64be as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const s8 = _s8 as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const s16 = _s16 as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const s24 = _s24 as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const s32 = _s32 as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const s40 = _s40 as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const s48 = _s48 as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const ns64 = _ns64 as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const s16be = _s16be as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const s24be = _s24be as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const s32be = _s32be as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const s40be = _s40be as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const s48be = _s48be as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const ns64be = _ns64be as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const f32 = _f32 as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const f32be = _f32be as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const f64 = _f64 as <P extends string = \"\">(property?: P) => Layout<number, P>;\nexport const f64be = _f64be as <P extends string = \"\">(property?: P) => Layout<number, P>;\n\nexport const struct = _struct as <T, P extends string = \"\">(\n fields: T,\n property?: P,\n decodePrefixes?: boolean,\n) => T extends Layout<infer Value, infer Property>[]\n ? Structure<\n Value,\n P,\n {\n [K in Exclude<Extract<Property, string>, \"\">]: Extract<T[number], Layout<any, K>> extends Layout<infer V, any>\n ? V\n : any;\n }\n >\n : any;\n\nexport const seq = _seq as unknown as <T, P>(\n elementLayout: Layout<T, string>,\n count: number | Layout<number, string>,\n property?: P,\n) => Layout<T[]>;\nexport const union = _union as <UnionSchema extends { [key: string]: any } = any>(\n discr: Layout<any, any>,\n defaultLayout?: any,\n property?: string,\n) => Union<UnionSchema>;\nexport const unionLayoutDiscriminator = _unionLayoutDiscriminator as <P extends string = \"\">(\n layout: Layout<any, P>,\n property?: P,\n) => any;\nexport const blob = _blob as unknown as <P extends string = \"\">(\n length: number | Layout<number, P>,\n property?: P,\n) => Blob<P>;\nexport const cstr = _cstr as <P extends string = \"\">(property?: P) => Layout<string, P>;\nexport const utf8 = _utf8 as <P extends string = \"\">(maxSpan: number, property?: P) => Layout<string, P>;\nexport const bits = _bits as unknown as <T, P extends string = \"\">(\n word: Layout<T>,\n msb?: boolean,\n property?: P,\n) => BitStructure<T, P>; // TODO: not quite sure\nexport const offset = _offset as unknown as <T, P extends string = \"\">(\n layout: Layout<T, P>,\n offset?: number,\n property?: P,\n) => Layout<T, P>;\n\nexport type GetStructureSchema<T extends Structure> = T extends Structure<any, any, infer S> ? S : unknown;\n","import { publicKey, struct, u32, u64, u8 } from \"../../marshmallow\";\n\nexport const splAccountLayout = struct([\n publicKey(\"mint\"),\n publicKey(\"owner\"),\n u64(\"amount\"),\n u32(\"delegateOption\"),\n publicKey(\"delegate\"),\n u8(\"state\"),\n u32(\"isNativeOption\"),\n u64(\"isNative\"),\n u64(\"delegatedAmount\"),\n u32(\"closeAuthorityOption\"),\n publicKey(\"closeAuthority\"),\n]);\n","import { PublicKey, TransactionInstruction } from \"@solana/web3.js\";\nimport {\n AmmV4Keys,\n AmmV5Keys,\n ApiV3PoolInfoConcentratedItem,\n ApiV3PoolInfoStandardItem,\n FormatFarmInfoOutV6,\n} from \"../../api/type\";\nimport { AccountLayout, MintLayout, NATIVE_MINT, RawMint, TOKEN_PROGRAM_ID } from \"@solana/spl-token\";\nimport { getMultipleAccountsInfo, getMultipleAccountsInfoWithCustomFlags } from \"@/common/accountInfo\";\nimport { divCeil } from \"@/common/bignumber\";\nimport { getATAAddress } from \"@/common/pda\";\nimport { BNDivCeil } from \"@/common/transfer\";\nimport { MakeMultiTxData, MakeTxData } from \"@/common/txTool/txTool\";\nimport { InstructionType, TxVersion } from \"@/common/txTool/txType\";\nimport { Percent, Token, TokenAmount } from \"../../module\";\nimport {\n FARM_PROGRAM_TO_VERSION,\n FarmLedger,\n createAssociatedLedgerAccountInstruction,\n getAssociatedLedgerAccount,\n getFarmLedgerLayout,\n makeWithdrawInstructionV3,\n makeWithdrawInstructionV5,\n makeWithdrawInstructionV6,\n} from \"../../raydium/farm\";\nimport { ClmmInstrument } from \"../clmm/instrument\";\nimport ModuleBase, { ModuleBaseProps } from \"../moduleBase\";\nimport { toToken } from \"../token\";\nimport { ComputeBudgetConfig } from \"../type\";\nimport { LIQUIDITY_FEES_DENOMINATOR, LIQUIDITY_FEES_NUMERATOR, poolLpAuthority } from \"./constant\";\nimport {\n createPoolV4InstructionV2,\n makeAMMSwapInstruction,\n makeAMMSwapV2Instruction,\n makeAddLiquidityInstruction,\n removeLiquidityInstruction,\n} from \"./instruction\";\nimport { createPoolFeeLayout, liquidityStateV4Layout } from \"./layout\";\nimport { StableLayout, getDxByDyBaseIn, getDyByDxBaseIn, getStablePrice } from \"./stable\";\nimport {\n AddLiquidityParams,\n AmmRpcData,\n AmountSide,\n ComputeAmountInParam,\n ComputeAmountOutParam,\n CreateMarketAndPoolParam,\n CreatePoolAddress,\n CreatePoolParam,\n RemoveParams,\n SwapParam,\n LpBalanceInfo,\n} from \"./type\";\nimport { getAssociatedConfigId, getAssociatedPoolKeys, toAmmComputePoolInfo } from \"./utils\";\n\nimport { AMM_V4, DEVNET_PROGRAM_ID, FEE_DESTINATION_ID, OPEN_BOOK_PROGRAM, WSOLMint } from \"@/common\";\nimport BN from \"bn.js\";\nimport Decimal from \"decimal.js\";\nimport { generatePubKey } from \"../account\";\nimport { BN_ZERO } from \"../clmm\";\nimport { MarketExtInfo, makeCreateMarketInstruction } from \"../marketV2\";\n\nexport default class LiquidityModule extends ModuleBase {\n public stableLayout: StableLayout;\n\n constructor(params: ModuleBaseProps) {\n super(params);\n this.stableLayout = new StableLayout({\n connection: this.scope.connection,\n modelDataPubKey: this.scope.cluster === \"mainnet\" ? undefined : DEVNET_PROGRAM_ID.MODEL_DATA_PUBKEY,\n });\n }\n\n public async initLayout(): Promise<void> {\n await this.stableLayout.initStableModelLayout();\n }\n\n public async load(): Promise<void> {\n this.checkDisabled();\n }\n\n public computePairAmount({\n poolInfo,\n amount,\n // anotherToken,\n slippage,\n baseIn,\n }: {\n poolInfo: ApiV3PoolInfoStandardItem;\n amount: string | Decimal;\n slippage: Percent;\n baseIn?: boolean;\n }): { anotherAmount: TokenAmount; maxAnotherAmount: TokenAmount; minAnotherAmount: TokenAmount; liquidity: BN } {\n const inputAmount = new BN(new Decimal(amount).mul(10 ** poolInfo[baseIn ? \"mintA\" : \"mintB\"].decimals).toFixed(0));\n const _anotherToken = toToken(poolInfo[baseIn ? \"mintB\" : \"mintA\"]);\n\n const [baseReserve, quoteReserve] = [\n new BN(new Decimal(poolInfo.mintAmountA).mul(10 ** poolInfo.mintA.decimals).toString()),\n new BN(new Decimal(poolInfo.mintAmountB).mul(10 ** poolInfo.mintB.decimals).toString()),\n ];\n const lpAmount = new BN(\n new Decimal(poolInfo.lpAmount).mul(10 ** poolInfo.lpMint.decimals).toFixed(0, Decimal.ROUND_DOWN),\n );\n this.logDebug(\"baseReserve:\", baseReserve.toString(), \"quoteReserve:\", quoteReserve.toString());\n\n this.logDebug(\n \"tokenIn:\",\n baseIn ? poolInfo.mintA.symbol : poolInfo.mintB.symbol,\n \"amountIn:\",\n inputAmount.toString(),\n \"anotherToken:\",\n baseIn ? poolInfo.mintB.symbol : poolInfo.mintA.symbol,\n \"slippage:\",\n `${slippage.toSignificant()}%`,\n \"baseReserve\",\n baseReserve.toString(),\n \"quoteReserve\",\n quoteReserve.toString(),\n );\n\n // input is fixed\n const input = baseIn ? \"base\" : \"quote\";\n this.logDebug(\"input side:\", input);\n\n // round up\n let amountRaw = BN_ZERO;\n if (!inputAmount.isZero()) {\n amountRaw =\n input === \"base\"\n ? divCeil(inputAmount.mul(quoteReserve), baseReserve)\n : divCeil(inputAmount.mul(baseReserve), quoteReserve);\n }\n\n this.logDebug(\"amountRaw:\", amountRaw.toString(), \"lpAmount:\", lpAmount.toString());\n\n const liquidity = divCeil(inputAmount.mul(lpAmount), input === \"base\" ? baseReserve : quoteReserve);\n\n this.logDebug(\"liquidity:\", liquidity.toString());\n\n const _slippage = new Percent(new BN(1)).add(slippage);\n const _slippageMin = new Percent(new BN(1)).sub(slippage);\n const slippageAdjustedAmount = _slippage.mul(amountRaw).quotient;\n const slippageAdjustedMinAmount = _slippageMin.mul(amountRaw).quotient;\n\n const _anotherAmount = new TokenAmount(_anotherToken, amountRaw);\n const _maxAnotherAmount = new TokenAmount(_anotherToken, slippageAdjustedAmount);\n const _minAnotherAmount = new TokenAmount(_anotherToken, slippageAdjustedMinAmount);\n this.logDebug(\"anotherAmount:\", _anotherAmount.toFixed(), \"maxAnotherAmount:\", _maxAnotherAmount.toFixed());\n\n return {\n anotherAmount: _anotherAmount,\n maxAnotherAmount: _maxAnotherAmount,\n minAnotherAmount: _minAnotherAmount,\n liquidity,\n };\n }\n\n public async getAmmPoolKeys(poolId: string): Promise<AmmV4Keys | AmmV5Keys> {\n return ((await this.scope.api.fetchPoolKeysById({ idList: [poolId] })) as (AmmV4Keys | AmmV5Keys)[])[0];\n }\n\n public async addLiquidity<T extends TxVersion>(params: AddLiquidityParams<T>): Promise<MakeTxData<T>> {\n const {\n poolInfo,\n poolKeys: propPoolKeys,\n amountInA,\n amountInB,\n otherAmountMin,\n fixedSide,\n config,\n txVersion,\n computeBudgetConfig,\n txTipConfig,\n feePayer,\n } = params;\n\n if (this.scope.availability.addStandardPosition === false)\n this.logAndCreateError(\"add liquidity feature disabled in your region\");\n\n this.logDebug(\"amountInA:\", amountInA, \"amountInB:\", amountInB);\n if (amountInA.isZero() || amountInB.isZero())\n this.logAndCreateError(\"amounts must greater than zero\", \"amountInA & amountInB\", {\n amountInA: amountInA.toFixed(),\n amountInB: amountInB.toFixed(),\n });\n const { account } = this.scope;\n const { bypassAssociatedCheck, checkCreateATAOwner } = {\n // default\n ...{ bypassAssociatedCheck: false, checkCreateATAOwner: false },\n // custom\n ...config,\n };\n const [tokenA, tokenB] = [amountInA.token, amountInB.token];\n const tokenAccountA = await account.getCreatedTokenAccount({\n mint: tokenA.mint,\n associatedOnly: false,\n });\n const tokenAccountB = await account.getCreatedTokenAccount({\n mint: tokenB.mint,\n associatedOnly: false,\n });\n if (!tokenAccountA && !tokenAccountB)\n this.logAndCreateError(\"cannot found target token accounts\", \"tokenAccounts\", account.tokenAccounts);\n\n const lpTokenAccount = await account.getCreatedTokenAccount({\n mint: new PublicKey(poolInfo.lpMint.address),\n });\n\n const tokens = [tokenA, tokenB];\n const _tokenAccounts = [tokenAccountA, tokenAccountB];\n const rawAmounts = [amountInA.raw, amountInB.raw];\n\n // handle amount a & b and direction\n const sideA = amountInA.token.mint.toBase58() === poolInfo.mintA.address ? \"base\" : \"quote\";\n let _fixedSide: AmountSide = \"base\";\n if (![\"quote\", \"base\"].includes(sideA)) this.logAndCreateError(\"invalid fixedSide\", \"fixedSide\", fixedSide);\n if (sideA === \"quote\") {\n tokens.reverse();\n _tokenAccounts.reverse();\n rawAmounts.reverse();\n _fixedSide = fixedSide === \"a\" ? \"quote\" : \"base\";\n } else if (sideA === \"base\") {\n _fixedSide = fixedSide === \"a\" ? \"base\" : \"quote\";\n }\n\n const [baseToken, quoteToken] = tokens;\n const [baseTokenAccount, quoteTokenAccount] = _tokenAccounts;\n const [baseAmountRaw, quoteAmountRaw] = rawAmounts;\n\n const poolKeys = propPoolKeys ?? (await this.getAmmPoolKeys(poolInfo.id));\n\n const txBuilder = this.createTxBuilder(feePayer);\n\n const { tokenAccount: _baseTokenAccount, ...baseInstruction } = await account.handleTokenAccount({\n side: \"in\",\n amount: baseAmountRaw,\n mint: baseToken.mint,\n tokenAccount: baseTokenAccount,\n bypassAssociatedCheck,\n checkCreateATAOwner,\n });\n txBuilder.addInstruction(baseInstruction);\n const { tokenAccount: _quoteTokenAccount, ...quoteInstruction } = await account.handleTokenAccount({\n side: \"in\",\n amount: quoteAmountRaw,\n mint: quoteToken.mint,\n tokenAccount: quoteTokenAccount,\n bypassAssociatedCheck,\n checkCreateATAOwner,\n });\n txBuilder.addInstruction(quoteInstruction);\n const { tokenAccount: _lpTokenAccount, ...lpInstruction } = await account.handleTokenAccount({\n side: \"out\",\n amount: 0,\n mint: new PublicKey(poolInfo.lpMint.address),\n tokenAccount: lpTokenAccount,\n bypassAssociatedCheck,\n checkCreateATAOwner,\n });\n txBuilder.addInstruction(lpInstruction);\n txBuilder.addInstruction({\n instructions: [\n makeAddLiquidityInstruction({\n poolInfo,\n poolKeys: poolKeys as AmmV4Keys | AmmV5Keys,\n userKeys: {\n baseTokenAccount: _baseTokenAccount!,\n quoteTokenAccount: _quoteTokenAccount!,\n lpTokenAccount: _lpTokenAccount!,\n owner: this.scope.ownerPubKey,\n },\n baseAmountIn: baseAmountRaw,\n quoteAmountIn: quoteAmountRaw,\n otherAmountMin: otherAmountMin.raw,\n fixedSide: _fixedSide,\n }),\n ],\n instructionTypes: [\n poolInfo.pooltype.includes(\"StablePool\")\n ? InstructionType.AmmV5AddLiquidity\n : InstructionType.AmmV4AddLiquidity,\n ],\n lookupTableAddress: poolKeys.lookupTableAccount ? [poolKeys.lookupTableAccount] : [],\n });\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n if (txVersion === TxVersion.V0) return (await txBuilder.buildV0()) as MakeTxData<T>;\n return txBuilder.build() as MakeTxData<T>;\n }\n\n public async removeLiquidity<T extends TxVersion>(params: RemoveParams<T>): Promise<Promise<MakeTxData<T>>> {\n if (this.scope.availability.removeStandardPosition === false)\n this.logAndCreateError(\"remove liquidity feature disabled in your region\");\n const {\n poolInfo,\n poolKeys: propPoolKeys,\n lpAmount,\n baseAmountMin,\n quoteAmountMin,\n config,\n txVersion,\n computeBudgetConfig,\n txTipConfig,\n feePayer,\n } = params;\n const poolKeys = propPoolKeys ?? (await this.getAmmPoolKeys(poolInfo.id));\n const [baseMint, quoteMint, lpMint] = [\n new PublicKey(poolInfo.mintA.address),\n new PublicKey(poolInfo.mintB.address),\n new PublicKey(poolInfo.lpMint.address),\n ];\n this.logDebug(\"lpAmount:\", lpAmount);\n this.logDebug(\"baseAmountMin:\", baseAmountMin);\n this.logDebug(\"quoteAmountMin:\", quoteAmountMin);\n if (lpAmount.isZero()) this.logAndCreateError(\"amount must greater than zero\", \"lpAmount\", lpAmount.toString());\n\n const { account } = this.scope;\n const lpTokenAccount = await account.getCreatedTokenAccount({\n mint: lpMint,\n associatedOnly: false,\n });\n if (!lpTokenAccount) this.logAndCreateError(\"cannot found lpTokenAccount\", \"tokenAccounts\", account.tokenAccounts);\n\n const baseTokenAccount = await account.getCreatedTokenAccount({\n mint: baseMint,\n });\n const quoteTokenAccount = await account.getCreatedTokenAccount({\n mint: quoteMint,\n });\n\n const txBuilder = this.createTxBuilder(feePayer);\n const { bypassAssociatedCheck, checkCreateATAOwner } = {\n // default\n ...{ bypassAssociatedCheck: false, checkCreateATAOwner: false },\n // custom\n ...config,\n };\n\n const { tokenAccount: _baseTokenAccount, ...baseInstruction } = await account.handleTokenAccount({\n side: \"out\",\n amount: 0,\n mint: baseMint,\n tokenAccount: baseTokenAccount,\n bypassAssociatedCheck,\n checkCreateATAOwner,\n });\n txBuilder.addInstruction(baseInstruction);\n const { tokenAccount: _quoteTokenAccount, ...quoteInstruction } = await account.handleTokenAccount({\n side: \"out\",\n amount: 0,\n mint: quoteMint,\n tokenAccount: quoteTokenAccount,\n bypassAssociatedCheck,\n checkCreateATAOwner,\n });\n txBuilder.addInstruction(quoteInstruction);\n\n txBuilder.addInstruction({\n instructions: [\n removeLiquidityInstruction({\n poolInfo,\n poolKeys,\n userKeys: {\n lpTokenAccount: lpTokenAccount!,\n baseTokenAccount: _baseTokenAccount!,\n quoteTokenAccount: _quoteTokenAccount!,\n owner: this.scope.ownerPubKey,\n },\n lpAmount,\n baseAmountMin,\n quoteAmountMin,\n }),\n ],\n lookupTableAddress: poolKeys.lookupTableAccount ? [poolKeys.lookupTableAccount] : [],\n instructionTypes: [\n poolInfo.pooltype.includes(\"StablePool\")\n ? InstructionType.AmmV5RemoveLiquidity\n : InstructionType.AmmV4RemoveLiquidity,\n ],\n });\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n if (txVersion === TxVersion.V0) return (await txBuilder.buildV0()) as MakeTxData<T>;\n return txBuilder.build() as MakeTxData<T>;\n }\n\n public async removeAllLpAndCreateClmmPosition<T extends TxVersion>({\n poolInfo,\n clmmPoolInfo,\n removeLpAmount,\n createPositionInfo,\n farmInfo,\n userFarmLpAmount,\n base,\n computeBudgetConfig,\n payer,\n userAuxiliaryLedgers,\n tokenProgram = TOKEN_PROGRAM_ID,\n checkCreateATAOwner = true,\n getEphemeralSigners,\n txVersion,\n feePayer,\n }: {\n poolInfo: ApiV3PoolInfoStandardItem;\n clmmPoolInfo: ApiV3PoolInfoConcentratedItem;\n removeLpAmount: BN;\n createPositionInfo: {\n tickLower: number;\n tickUpper: number;\n baseAmount: BN;\n otherAmountMax: BN;\n };\n farmInfo?: FormatFarmInfoOutV6;\n userFarmLpAmount?: BN;\n userAuxiliaryLedgers?: PublicKey[];\n base: \"MintA\" | \"MintB\";\n payer?: PublicKey;\n computeBudgetConfig?: ComputeBudgetConfig;\n tokenProgram?: PublicKey;\n checkCreateATAOwner?: boolean;\n txVersion?: T;\n getEphemeralSigners?: (k: number) => any;\n feePayer?: PublicKey;\n }): Promise<MakeMultiTxData<T>> {\n if (\n this.scope.availability.removeStandardPosition === false ||\n this.scope.availability.createConcentratedPosition === false\n )\n this.logAndCreateError(\"remove liquidity or create position feature disabled in your region\");\n\n if (\n !(poolInfo.mintA.address === clmmPoolInfo.mintA.address || poolInfo.mintA.address === clmmPoolInfo.mintB.address)\n )\n throw Error(\"mint check error\");\n if (\n !(poolInfo.mintB.address === clmmPoolInfo.mintA.address || poolInfo.mintB.address === clmmPoolInfo.mintB.address)\n )\n throw Error(\"mint check error\");\n\n const txBuilder = this.createTxBuilder(feePayer);\n const mintToAccount: { [mint: string]: PublicKey } = {};\n for (const item of this.scope.account.tokenAccountRawInfos) {\n if (\n mintToAccount[item.accountInfo.mint.toString()] === undefined ||\n getATAAddress(this.scope.ownerPubKey, item.accountInfo.mint, TOKEN_PROGRAM_ID).publicKey.equals(item.pubkey)\n ) {\n mintToAccount[item.accountInfo.mint.toString()] = item.pubkey;\n }\n }\n\n const lpTokenAccount = mintToAccount[poolInfo.lpMint.address];\n if (lpTokenAccount === undefined) throw Error(\"find lp account error in trade accounts\");\n\n const amountIn = removeLpAmount.add(userFarmLpAmount ?? new BN(0));\n const mintBaseUseSOLBalance = poolInfo.mintA.address === Token.WSOL.mint.toString();\n const mintQuoteUseSOLBalance = poolInfo.mintB.address === Token.WSOL.mint.toString();\n\n const { account: baseTokenAccount, instructionParams: ownerTokenAccountBaseInstruction } =\n await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: TOKEN_PROGRAM_ID,\n mint: new PublicKey(poolInfo.mintA.address),\n owner: this.scope.ownerPubKey,\n\n createInfo: mintBaseUseSOLBalance\n ? {\n payer: this.scope.ownerPubKey,\n }\n : undefined,\n skipCloseAccount: !mintBaseUseSOLBalance,\n notUseTokenAccount: mintBaseUseSOLBalance,\n associatedOnly: true,\n checkCreateATAOwner,\n });\n txBuilder.addInstruction(ownerTokenAccountBaseInstruction || {});\n if (baseTokenAccount === undefined) throw new Error(\"base token account not found\");\n\n const { account: quoteTokenAccount, instructionParams: ownerTokenAccountQuoteInstruction } =\n await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: TOKEN_PROGRAM_ID,\n mint: new PublicKey(poolInfo.mintB.address),\n owner: this.scope.ownerPubKey,\n createInfo: mintQuoteUseSOLBalance\n ? {\n payer: this.scope.ownerPubKey!,\n amount: 0,\n }\n : undefined,\n skipCloseAccount: !mintQuoteUseSOLBalance,\n notUseTokenAccount: mintQuoteUseSOLBalance,\n associatedOnly: true,\n checkCreateATAOwner,\n });\n txBuilder.addInstruction(ownerTokenAccountQuoteInstruction || {});\n if (quoteTokenAccount === undefined) throw new Error(\"quote token account not found\");\n\n mintToAccount[poolInfo.mintA.address] = baseTokenAccount;\n mintToAccount[poolInfo.mintB.address] = quoteTokenAccount;\n\n if (farmInfo !== undefined && !userFarmLpAmount?.isZero()) {\n const farmVersion = FARM_PROGRAM_TO_VERSION[farmInfo.programId];\n const ledger = getAssociatedLedgerAccount({\n programId: new PublicKey(farmInfo.programId),\n poolId: new PublicKey(farmInfo.id),\n owner: this.scope.ownerPubKey,\n version: farmVersion as 3 | 5 | 6,\n });\n let ledgerInfo: FarmLedger | undefined = undefined;\n const ledgerData = await this.scope.connection.getAccountInfo(ledger);\n if (ledgerData) {\n const ledgerLayout = getFarmLedgerLayout(farmVersion)!;\n ledgerInfo = ledgerLayout.decode(ledgerData.data);\n }\n if (farmVersion !== 6 && !ledgerInfo) {\n const { instruction, instructionType } = createAssociatedLedgerAccountInstruction({\n id: new PublicKey(farmInfo.id),\n programId: new PublicKey(farmInfo.programId),\n version: farmVersion,\n ledger,\n owner: this.scope.ownerPubKey,\n });\n txBuilder.addInstruction({ instructions: [instruction], instructionTypes: [instructionType] });\n }\n\n const rewardTokenAccounts: PublicKey[] = [];\n for (const item of farmInfo.rewardInfos) {\n const rewardIsWsol = item.mint.address === Token.WSOL.mint.toString();\n if (mintToAccount[item.mint.address]) rewardTokenAccounts.push(mintToAccount[item.mint.address]);\n else {\n const { account: farmRewardAccount, instructionParams: ownerTokenAccountFarmInstruction } =\n await this.scope.account.getOrCreateTokenAccount({\n mint: new PublicKey(item.mint.address),\n tokenProgram,\n owner: this.scope.ownerPubKey,\n skipCloseAccount: !rewardIsWsol,\n createInfo: {\n payer: payer || this.scope.ownerPubKey,\n },\n associatedOnly: true,\n checkCreateATAOwner,\n });\n if (!farmRewardAccount) this.logAndCreateError(\"farm reward account not found:\", item.mint.address);\n ownerTokenAccountFarmInstruction && txBuilder.addInstruction(ownerTokenAccountFarmInstruction);\n rewardTokenAccounts.push(farmRewardAccount!);\n }\n }\n const farmKeys = (await this.scope.api.fetchFarmKeysById({ ids: farmInfo.id }))[0];\n const insParams = {\n userAuxiliaryLedgers,\n amount: userFarmLpAmount!,\n owner: this.scope.ownerPubKey,\n farmInfo,\n farmKeys,\n lpAccount: lpTokenAccount,\n rewardAccounts: rewardTokenAccounts,\n };\n const version = FARM_PROGRAM_TO_VERSION[farmInfo.programId];\n const newInstruction =\n version === 6\n ? makeWithdrawInstructionV6(insParams)\n : version === 5\n ? makeWithdrawInstructionV5(insParams)\n : makeWithdrawInstructionV3(insParams);\n const insType = {\n 3: InstructionType.FarmV3Withdraw,\n 5: InstructionType.FarmV5Withdraw,\n 6: InstructionType.FarmV6Withdraw,\n };\n txBuilder.addInstruction({\n instructions: [newInstruction],\n instructionTypes: [insType[version]],\n });\n }\n\n const poolKeys = await this.getAmmPoolKeys(poolInfo.id);\n\n const removeIns = removeLiquidityInstruction({\n poolInfo,\n poolKeys,\n userKeys: {\n lpTokenAccount,\n baseTokenAccount,\n quoteTokenAccount,\n owner: this.scope.ownerPubKey,\n },\n lpAmount: amountIn,\n baseAmountMin: 0,\n quoteAmountMin: 0,\n });\n\n txBuilder.addInstruction({\n instructions: [removeIns],\n instructionTypes: [\n !poolInfo.pooltype.includes(\"StablePool\")\n ? InstructionType.AmmV4RemoveLiquidity\n : InstructionType.AmmV5RemoveLiquidity,\n ],\n lookupTableAddress: poolKeys.lookupTableAccount ? [poolKeys.lookupTableAccount] : [],\n });\n\n const [tokenAccountA, tokenAccountB] =\n poolInfo.mintA.address === clmmPoolInfo.mintA.address\n ? [baseTokenAccount, quoteTokenAccount]\n : [quoteTokenAccount, baseTokenAccount];\n\n const clmmPoolKeys = await this.scope.clmm.getClmmPoolKeys(clmmPoolInfo.id);\n\n const createPositionIns = await ClmmInstrument.openPositionFromBaseInstructions({\n poolInfo: clmmPoolInfo,\n poolKeys: clmmPoolKeys,\n ownerInfo: {\n feePayer: this.scope.ownerPubKey,\n wallet: this.scope.ownerPubKey,\n tokenAccountA,\n tokenAccountB,\n },\n withMetadata: \"create\",\n ...createPositionInfo,\n liquidity: new BN(0),\n base,\n getEphemeralSigners,\n });\n\n txBuilder.addInstruction({\n instructions: [...createPositionIns.instructions],\n signers: createPositionIns.signers,\n instructionTypes: [...createPositionIns.instructionTypes],\n lookupTableAddress: clmmPoolKeys.lookupTableAccount ? [clmmPoolKeys.lookupTableAccount] : [],\n });\n\n if (txVersion === TxVersion.V0)\n return txBuilder.sizeCheckBuildV0({ computeBudgetConfig }) as Promise<MakeMultiTxData<T>>;\n return txBuilder.sizeCheckBuild({ computeBudgetConfig }) as Promise<MakeMultiTxData<T>>;\n }\n\n public async createPoolV4<T extends TxVersion>({\n programId,\n marketInfo,\n baseMintInfo,\n quoteMintInfo,\n baseAmount,\n quoteAmount,\n startTime,\n ownerInfo,\n associatedOnly = false,\n checkCreateATAOwner = false,\n tokenProgram,\n txVersion,\n feeDestinationId,\n computeBudgetConfig,\n txTipConfig,\n feePayer,\n }: CreatePoolParam<T>): Promise<MakeTxData<T, { address: CreatePoolAddress }>> {\n const payer = ownerInfo.feePayer || this.scope.owner?.publicKey;\n const mintAUseSOLBalance = ownerInfo.useSOLBalance && baseMintInfo.mint.equals(NATIVE_MINT);\n const mintBUseSOLBalance = ownerInfo.useSOLBalance && quoteMintInfo.mint.equals(NATIVE_MINT);\n\n const txBuilder = this.createTxBuilder(feePayer);\n\n const { account: ownerTokenAccountBase, instructionParams: ownerTokenAccountBaseInstruction } =\n await this.scope.account.getOrCreateTokenAccount({\n mint: baseMintInfo.mint,\n owner: this.scope.ownerPubKey,\n createInfo: mintAUseSOLBalance\n ? {\n payer: payer!,\n amount: baseAmount,\n }\n : undefined,\n notUseTokenAccount: mintAUseSOLBalance,\n skipCloseAccount: !mintAUseSOLBalance,\n associatedOnly: mintAUseSOLBalance ? false : associatedOnly,\n checkCreateATAOwner,\n });\n txBuilder.addInstruction(ownerTokenAccountBaseInstruction || {});\n\n const { account: ownerTokenAccountQuote, instructionParams: ownerTokenAccountQuoteInstruction } =\n await this.scope.account.getOrCreateTokenAccount({\n mint: quoteMintInfo.mint,\n owner: this.scope.ownerPubKey,\n createInfo: mintBUseSOLBalance\n ? {\n payer: payer!,\n amount: quoteAmount,\n }\n : undefined,\n\n notUseTokenAccount: mintBUseSOLBalance,\n skipCloseAccount: !mintBUseSOLBalance,\n associatedOnly: mintBUseSOLBalance ? false : associatedOnly,\n checkCreateATAOwner,\n });\n txBuilder.addInstruction(ownerTokenAccountQuoteInstruction || {});\n\n if (ownerTokenAccountBase === undefined || ownerTokenAccountQuote === undefined)\n throw Error(\"you don't has some token account\");\n\n const poolInfo = getAssociatedPoolKeys({\n version: 4,\n marketVersion: 3,\n marketId: marketInfo.marketId,\n baseMint: baseMintInfo.mint,\n quoteMint: quoteMintInfo.mint,\n baseDecimals: baseMintInfo.decimals,\n quoteDecimals: quoteMintInfo.decimals,\n programId,\n marketProgramId: marketInfo.programId,\n });\n\n const createPoolKeys = {\n programId,\n ammId: poolInfo.id,\n ammAuthority: poolInfo.authority,\n ammOpenOrders: poolInfo.openOrders,\n lpMint: poolInfo.lpMint,\n coinMint: poolInfo.baseMint,\n pcMint: poolInfo.quoteMint,\n coinVault: poolInfo.baseVault,\n pcVault: poolInfo.quoteVault,\n withdrawQueue: poolInfo.withdrawQueue,\n ammTargetOrders: poolInfo.targetOrders,\n poolTempLp: poolInfo.lpVault,\n marketProgramId: poolInfo.marketProgramId,\n marketId: poolInfo.marketId,\n ammConfigId: poolInfo.configId,\n feeDestinationId,\n };\n\n const { instruction, instructionType } = createPoolV4InstructionV2({\n ...createPoolKeys,\n userWallet: this.scope.ownerPubKey,\n userCoinVault: ownerTokenAccountBase,\n userPcVault: ownerTokenAccountQuote,\n userLpVault: getATAAddress(this.scope.ownerPubKey, poolInfo.lpMint, tokenProgram).publicKey,\n\n nonce: poolInfo.nonce,\n openTime: startTime,\n coinAmount: baseAmount,\n pcAmount: quoteAmount,\n });\n\n txBuilder.addInstruction({\n instructions: [instruction],\n instructionTypes: [instructionType],\n });\n\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n return txBuilder.versionBuild({\n txVersion,\n extInfo: {\n address: createPoolKeys,\n },\n }) as Promise<MakeTxData<T, { address: CreatePoolAddress }>>;\n }\n\n public async createMarketAndPoolV4<T extends TxVersion>({\n programId = AMM_V4,\n marketProgram = OPEN_BOOK_PROGRAM,\n feeDestinationId = FEE_DESTINATION_ID,\n tokenProgram,\n\n baseMintInfo,\n quoteMintInfo,\n baseAmount,\n quoteAmount,\n startTime,\n\n ownerInfo,\n lowestFeeMarket,\n assignSeed,\n\n associatedOnly = false,\n checkCreateATAOwner = false,\n\n lotSize = 1,\n tickSize = 0.01,\n\n txVersion,\n computeBudgetConfig,\n txTipConfig,\n feePayer,\n }: CreateMarketAndPoolParam<T>): Promise<\n MakeMultiTxData<T, { address: CreatePoolAddress & MarketExtInfo[\"address\"] }>\n > {\n const wallet = this.scope.ownerPubKey;\n const payer = ownerInfo.feePayer || this.scope.owner?.publicKey;\n const mintAUseSOLBalance = ownerInfo.useSOLBalance && baseMintInfo.mint.equals(NATIVE_MINT);\n const mintBUseSOLBalance = ownerInfo.useSOLBalance && quoteMintInfo.mint.equals(NATIVE_MINT);\n\n const seed = assignSeed\n ? `${baseMintInfo.mint.toBase58().slice(0, 7)}-${quoteMintInfo.mint.toBase58().slice(0, 7)}-${assignSeed}`\n : undefined;\n\n const market = generatePubKey({\n fromPublicKey: wallet,\n programId: marketProgram,\n assignSeed: seed ? `${seed}-market` : seed,\n });\n const requestQueue = generatePubKey({\n fromPublicKey: wallet,\n programId: marketProgram,\n assignSeed: seed ? `${seed}-request` : seed,\n });\n const eventQueue = generatePubKey({\n fromPublicKey: wallet,\n programId: marketProgram,\n assignSeed: seed ? `${seed}-event` : seed,\n });\n const bids = generatePubKey({\n fromPublicKey: wallet,\n programId: marketProgram,\n assignSeed: seed ? `${seed}-bids` : seed,\n });\n const asks = generatePubKey({\n fromPublicKey: wallet,\n programId: marketProgram,\n assignSeed: seed ? `${seed}-asks` : seed,\n });\n const baseVault = generatePubKey({\n fromPublicKey: wallet,\n programId: TOKEN_PROGRAM_ID,\n assignSeed: seed ? `${seed}-baseVault` : seed,\n });\n const quoteVault = generatePubKey({\n fromPublicKey: wallet,\n programId: TOKEN_PROGRAM_ID,\n assignSeed: seed ? `${seed}-quoteVault` : seed,\n });\n\n const feeRateBps = 0;\n const quoteDustThreshold = new BN(100);\n function getVaultOwnerAndNonce() {\n const vaultSignerNonce = new BN(0);\n // eslint-disable-next-line no-constant-condition\n while (true) {\n try {\n const vaultOwner = PublicKey.createProgramAddressSync(\n [market.publicKey.toBuffer(), vaultSignerNonce.toArrayLike(Buffer, \"le\", 8)],\n marketProgram,\n );\n return { vaultOwner, vaultSignerNonce };\n } catch (e) {\n vaultSignerNonce.iaddn(1);\n if (vaultSignerNonce.gt(new BN(25555))) throw Error(\"find vault owner error\");\n }\n }\n }\n const { vaultOwner, vaultSignerNonce } = getVaultOwnerAndNonce();\n const baseLotSize = new BN(Math.round(10 ** baseMintInfo.decimals * lotSize));\n const quoteLotSize = new BN(Math.round(lotSize * 10 ** quoteMintInfo.decimals * tickSize));\n\n if (baseLotSize.eq(BN_ZERO)) throw Error(\"lot size is too small\");\n if (quoteLotSize.eq(BN_ZERO)) throw Error(\"tick size or lot size is too small\");\n const allTxArr = await makeCreateMarketInstruction({\n connection: this.scope.connection,\n wallet: this.scope.ownerPubKey,\n marketInfo: {\n programId: marketProgram,\n vaultOwner,\n baseMint: baseMintInfo.mint,\n quoteMint: quoteMintInfo.mint,\n\n id: market,\n baseVault,\n quoteVault,\n requestQueue,\n eventQueue,\n bids,\n asks,\n\n feeRateBps,\n quoteDustThreshold,\n vaultSignerNonce,\n baseLotSize,\n quoteLotSize,\n lowestFeeMarket,\n },\n });\n\n const txBuilder = this.createTxBuilder(feePayer);\n txBuilder.addInstruction({\n instructions: allTxArr[0].transaction.instructions,\n signers: allTxArr[0].signer,\n });\n\n for await (const txData of allTxArr.slice(1, allTxArr.length)) {\n txBuilder.addInstruction({\n instructions: txData.transaction.instructions,\n signers: txData.signer,\n instructionTypes: txData.instructionTypes,\n });\n }\n\n const { account: ownerTokenAccountBase, instructionParams: ownerTokenAccountBaseInstruction } =\n await this.scope.account.getOrCreateTokenAccount({\n mint: baseMintInfo.mint,\n owner: this.scope.ownerPubKey,\n createInfo: mintAUseSOLBalance\n ? {\n payer: payer!,\n amount: baseAmount,\n }\n : undefined,\n notUseTokenAccount: mintAUseSOLBalance,\n skipCloseAccount: !mintAUseSOLBalance,\n associatedOnly: mintAUseSOLBalance ? false : associatedOnly,\n checkCreateATAOwner,\n assignSeed: mintAUseSOLBalance && seed ? `${seed}-wsol` : undefined,\n });\n\n txBuilder.addInstruction(ownerTokenAccountBaseInstruction || {});\n\n const { account: ownerTokenAccountQuote, instructionParams: ownerTokenAccountQuoteInstruction } =\n await this.scope.account.getOrCreateTokenAccount({\n mint: quoteMintInfo.mint,\n owner: this.scope.ownerPubKey,\n createInfo: mintBUseSOLBalance\n ? {\n payer: payer!,\n amount: quoteAmount,\n }\n : undefined,\n\n notUseTokenAccount: mintBUseSOLBalance,\n skipCloseAccount: !mintBUseSOLBalance,\n associatedOnly: mintBUseSOLBalance ? false : associatedOnly,\n checkCreateATAOwner,\n assignSeed: mintBUseSOLBalance && seed ? `${seed}-wsol` : undefined,\n });\n txBuilder.addInstruction(ownerTokenAccountQuoteInstruction || {});\n\n if (ownerTokenAccountBase === undefined) throw Error(\"you don't has base token account\");\n if (ownerTokenAccountQuote === undefined) throw Error(\"you don't has quote token account\");\n\n // create pool ins\n const poolInfo = getAssociatedPoolKeys({\n version: 4,\n marketVersion: 3,\n marketId: market.publicKey,\n baseMint: baseMintInfo.mint,\n quoteMint: quoteMintInfo.mint,\n baseDecimals: baseMintInfo.decimals,\n quoteDecimals: quoteMintInfo.decimals,\n programId,\n marketProgramId: marketProgram,\n });\n\n const createPoolKeys = {\n programId,\n ammId: poolInfo.id,\n ammAuthority: poolInfo.authority,\n ammOpenOrders: poolInfo.openOrders,\n lpMint: poolInfo.lpMint,\n coinMint: poolInfo.baseMint,\n pcMint: poolInfo.quoteMint,\n coinVault: poolInfo.baseVault,\n pcVault: poolInfo.quoteVault,\n withdrawQueue: poolInfo.withdrawQueue,\n ammTargetOrders: poolInfo.targetOrders,\n poolTempLp: poolInfo.lpVault,\n marketProgramId: poolInfo.marketProgramId,\n marketId: poolInfo.marketId,\n ammConfigId: poolInfo.configId,\n feeDestinationId,\n };\n\n const { instruction, instructionType } = createPoolV4InstructionV2({\n ...createPoolKeys,\n userWallet: this.scope.ownerPubKey,\n userCoinVault: ownerTokenAccountBase,\n userPcVault: ownerTokenAccountQuote,\n userLpVault: getATAAddress(this.scope.ownerPubKey, poolInfo.lpMint, tokenProgram).publicKey,\n\n nonce: poolInfo.nonce,\n openTime: startTime,\n coinAmount: baseAmount,\n pcAmount: quoteAmount,\n });\n\n txBuilder.addInstruction({\n instructions: [instruction],\n instructionTypes: [instructionType],\n });\n\n const splitIns =\n mintAUseSOLBalance || mintBUseSOLBalance\n ? ([\n ownerTokenAccountBaseInstruction?.instructions?.[0] || ownerTokenAccountQuoteInstruction?.instructions?.[0],\n ].filter((i) => !!i) as TransactionInstruction[])\n : undefined;\n\n if (txVersion === TxVersion.V0)\n return txBuilder.sizeCheckBuildV0({\n computeBudgetConfig,\n splitIns,\n address: {\n requestQueue: requestQueue.publicKey,\n eventQueue: eventQueue.publicKey,\n bids: bids.publicKey,\n asks: asks.publicKey,\n baseVault: baseVault.publicKey,\n quoteVault: quoteVault.publicKey,\n baseMint: new PublicKey(baseMintInfo.mint),\n quoteMint: new PublicKey(quoteMintInfo.mint),\n ...createPoolKeys,\n },\n }) as Promise<MakeMultiTxData<T, { address: CreatePoolAddress & MarketExtInfo[\"address\"] }>>;\n\n return txBuilder.sizeCheckBuild({\n computeBudgetConfig,\n splitIns,\n address: {\n requestQueue: requestQueue.publicKey,\n eventQueue: eventQueue.publicKey,\n bids: bids.publicKey,\n asks: asks.publicKey,\n baseVault: baseVault.publicKey,\n quoteVault: quoteVault.publicKey,\n baseMint: new PublicKey(baseMintInfo.mint),\n quoteMint: new PublicKey(quoteMintInfo.mint),\n ...createPoolKeys,\n },\n }) as Promise<MakeMultiTxData<T, { address: CreatePoolAddress & MarketExtInfo[\"address\"] }>>;\n }\n\n public async getCreatePoolFee({ programId }: { programId: PublicKey }): Promise<BN> {\n const configId = getAssociatedConfigId({ programId });\n\n const account = await this.scope.connection.getAccountInfo(configId, { dataSlice: { offset: 536, length: 8 } });\n if (account === null) throw Error(\"get config account error\");\n\n return createPoolFeeLayout.decode(account.data).fee;\n }\n\n public computeAmountOut({\n poolInfo,\n amountIn,\n mintIn: propMintIn,\n mintOut: propMintOut,\n slippage,\n }: ComputeAmountOutParam): {\n amountOut: BN;\n minAmountOut: BN;\n currentPrice: Decimal;\n executionPrice: Decimal;\n priceImpact: Decimal;\n fee: BN;\n } {\n const [mintIn, mintOut] = [propMintIn.toString(), propMintOut.toString()];\n if (mintIn !== poolInfo.mintA.address && mintIn !== poolInfo.mintB.address) throw new Error(\"toke not match\");\n if (mintOut !== poolInfo.mintA.address && mintOut !== poolInfo.mintB.address) throw new Error(\"toke not match\");\n\n const { baseReserve, quoteReserve } = poolInfo;\n\n const reserves = [baseReserve, quoteReserve];\n const mintDecimals = [poolInfo.mintA.decimals, poolInfo.mintB.decimals];\n\n // input is fixed\n const input = mintIn == poolInfo.mintA.address ? \"base\" : \"quote\";\n if (input === \"quote\") {\n reserves.reverse();\n mintDecimals.reverse();\n }\n\n const [reserveIn, reserveOut] = reserves;\n const [mintInDecimals, mintOutDecimals] = mintDecimals;\n const isVersion4 = poolInfo.version === 4;\n let currentPrice: Decimal;\n if (isVersion4) {\n currentPrice = new Decimal(reserveOut.toString())\n .div(10 ** mintOutDecimals)\n .div(new Decimal(reserveIn.toString()).div(10 ** mintInDecimals));\n } else {\n const p = getStablePrice(\n this.stableLayout.stableModelData,\n baseReserve.toNumber(),\n quoteReserve.toNumber(),\n false,\n );\n if (input === \"quote\") currentPrice = new Decimal(1e6).div(p * 1e6);\n else currentPrice = new Decimal(p * 1e6).div(1e6);\n }\n\n const amountInRaw = amountIn;\n let amountOutRaw = new BN(0);\n let feeRaw = new BN(0);\n\n if (!amountInRaw.isZero()) {\n if (isVersion4) {\n feeRaw = BNDivCeil(amountInRaw.mul(LIQUIDITY_FEES_NUMERATOR), LIQUIDITY_FEES_DENOMINATOR);\n const amountInWithFee = amountInRaw.sub(feeRaw);\n\n const denominator = reserveIn.add(amountInWithFee);\n amountOutRaw = reserveOut.mul(amountInWithFee).div(denominator);\n } else {\n feeRaw = amountInRaw.mul(new BN(2)).div(new BN(10000));\n const amountInWithFee = amountInRaw.sub(feeRaw);\n if (input === \"quote\")\n amountOutRaw = new BN(\n getDyByDxBaseIn(\n this.stableLayout.stableModelData,\n quoteReserve.toNumber(),\n baseReserve.toNumber(),\n amountInWithFee.toNumber(),\n ),\n );\n else {\n amountOutRaw = new BN(\n getDxByDyBaseIn(\n this.stableLayout.stableModelData,\n quoteReserve.toNumber(),\n baseReserve.toNumber(),\n amountInWithFee.toNumber(),\n ),\n );\n }\n }\n }\n\n const minAmountOutRaw = new BN(new Decimal(amountOutRaw.toString()).mul(1 - slippage).toFixed(0));\n\n const amountOut = amountOutRaw;\n const minAmountOut = minAmountOutRaw;\n\n let executionPrice = new Decimal(amountOutRaw.toString()).div(\n new Decimal(amountInRaw.sub(feeRaw).toString()).toFixed(0),\n );\n if (!amountInRaw.isZero() && !amountOutRaw.isZero()) {\n executionPrice = new Decimal(amountOutRaw.toString())\n .div(10 ** mintOutDecimals)\n .div(new Decimal(amountInRaw.sub(feeRaw).toString()).div(10 ** mintInDecimals));\n }\n\n const priceImpact = currentPrice.sub(executionPrice).div(currentPrice).mul(100);\n\n const fee = feeRaw;\n\n return {\n amountOut,\n minAmountOut,\n currentPrice,\n executionPrice,\n priceImpact,\n fee,\n };\n }\n\n public computeAmountIn({ poolInfo, amountOut, mintIn, mintOut, slippage }: ComputeAmountInParam): {\n amountIn: BN;\n maxAmountIn: BN;\n currentPrice: Decimal;\n executionPrice: Decimal | null;\n priceImpact: Decimal;\n fee: BN;\n } {\n const { baseReserve, quoteReserve } = poolInfo;\n if (mintIn.toString() !== poolInfo.mintA.address && mintIn.toString() !== poolInfo.mintB.address)\n this.logAndCreateError(\"mintIn does not match pool\");\n if (mintOut.toString() !== poolInfo.mintA.address && mintOut.toString() !== poolInfo.mintB.address)\n this.logAndCreateError(\"mintOut does not match pool\");\n this.logDebug(\"baseReserve:\", baseReserve.toString());\n this.logDebug(\"quoteReserve:\", quoteReserve.toString());\n\n const baseIn = mintIn.toString() === poolInfo.mintA.address;\n const [tokenIn, tokenOut] = baseIn ? [poolInfo.mintA, poolInfo.mintB] : [poolInfo.mintB, poolInfo.mintA];\n\n this.logDebug(\"currencyOut:\", tokenOut.symbol || tokenOut.address);\n this.logDebug(\n \"amountOut:\",\n new Decimal(amountOut.toString())\n .div(10 ** tokenOut.decimals)\n .toDecimalPlaces(tokenOut.decimals)\n .toString(),\n tokenIn.symbol || tokenIn.address,\n );\n this.logDebug(\"slippage:\", `${slippage * 100}%`);\n\n const reserves = [baseReserve, quoteReserve];\n\n // output is fixed\n const output = !baseIn ? \"base\" : \"quote\";\n if (output === \"base\") {\n reserves.reverse();\n }\n this.logDebug(\"output side:\", output);\n\n const [reserveIn, reserveOut] = reserves;\n\n const currentPrice = new Decimal(reserveOut.toString())\n .div(10 ** poolInfo[baseIn ? \"mintB\" : \"mintA\"].decimals)\n .div(new Decimal(reserveIn.toString()).div(10 ** poolInfo[baseIn ? \"mintA\" : \"mintB\"].decimals));\n this.logDebug(\n \"currentPrice:\",\n `1 ${tokenIn.symbol || tokenIn.address} ≈ ${currentPrice.toString()} ${tokenOut.symbol || tokenOut.address}`,\n );\n this.logDebug(\n \"currentPrice invert:\",\n `1 ${tokenOut.symbol || tokenOut.address} ≈ ${new Decimal(1).div(currentPrice).toString()} ${\n tokenIn.symbol || tokenIn.address\n }`,\n );\n\n let amountInRaw = new BN(0);\n let amountOutRaw = amountOut;\n let fee = new BN(0);\n if (!amountOutRaw.isZero()) {\n // if out > reserve, out = reserve - 1\n if (amountOutRaw.gt(reserveOut)) {\n amountOutRaw = reserveOut.sub(new BN(1));\n }\n\n const denominator = reserveOut.sub(amountOutRaw);\n const amountInWithoutFee = reserveIn.mul(amountOutRaw).div(denominator);\n\n amountInRaw = amountInWithoutFee\n .mul(LIQUIDITY_FEES_DENOMINATOR)\n .div(LIQUIDITY_FEES_DENOMINATOR.sub(LIQUIDITY_FEES_NUMERATOR));\n\n fee = amountInRaw.sub(amountInWithoutFee);\n }\n\n const maxAmountInRaw = new BN(new Decimal(amountInRaw.toString()).mul(1 + slippage).toFixed(0));\n\n const amountIn = amountInRaw;\n const maxAmountIn = maxAmountInRaw;\n this.logDebug(\n \"amountIn:\",\n new Decimal(amountIn.toString())\n .div(10 ** tokenIn.decimals)\n .toDecimalPlaces(tokenIn.decimals)\n .toString(),\n );\n this.logDebug(\n \"maxAmountIn:\",\n new Decimal(maxAmountIn.toString())\n .div(10 ** tokenIn.decimals)\n .toDecimalPlaces(tokenIn.decimals)\n .toString(),\n );\n\n let executionPrice: Decimal | null = null;\n if (!amountInRaw.isZero() && !amountOutRaw.isZero()) {\n executionPrice = new Decimal(amountOutRaw.toString())\n .div(10 ** tokenOut.decimals)\n .div(new Decimal(amountInRaw.toString()).div(10 ** tokenIn.decimals));\n this.logDebug(\n \"executionPrice:\",\n `1 ${tokenOut.symbol || tokenOut.address} ≈ ${executionPrice\n .toDecimalPlaces(Math.max(poolInfo.mintA.decimals, poolInfo.mintB.decimals))\n .toString()} ${tokenIn.symbol || tokenIn.address}`,\n );\n this.logDebug(\n \"executionPrice invert:\",\n `1 ${tokenOut.symbol || tokenOut.address} ≈ ${new Decimal(1)\n .div(executionPrice)\n .toDecimalPlaces(Math.max(poolInfo.mintA.decimals, poolInfo.mintB.decimals))\n .toString()} ${tokenIn.symbol || tokenIn.address}`,\n );\n }\n\n const exactQuote = currentPrice.mul(amountIn.toString());\n const priceImpact = exactQuote.sub(amountOut.toString()).abs().div(exactQuote);\n this.logDebug(\"priceImpact:\", `${priceImpact.toString()}%`);\n\n return {\n amountIn,\n maxAmountIn,\n currentPrice,\n executionPrice,\n priceImpact,\n fee,\n };\n }\n\n public async swap<T extends TxVersion>({\n poolInfo,\n poolKeys: propPoolKeys,\n amountIn,\n amountOut,\n inputMint,\n fixedSide,\n txVersion,\n config,\n computeBudgetConfig,\n txTipConfig,\n feePayer,\n }: SwapParam<T>): Promise<MakeTxData<T>> {\n const txBuilder = this.createTxBuilder(feePayer);\n const { associatedOnly = true, inputUseSolBalance = true, outputUseSolBalance = true } = config || {};\n\n const [tokenIn, tokenOut] =\n inputMint === poolInfo.mintA.address ? [poolInfo.mintA, poolInfo.mintB] : [poolInfo.mintB, poolInfo.mintA];\n\n const inputTokenUseSolBalance = inputUseSolBalance && tokenIn.address === WSOLMint.toBase58();\n const outputTokenUseSolBalance = outputUseSolBalance && tokenOut.address === WSOLMint.toBase58();\n\n const { account: _tokenAccountIn, instructionParams: ownerTokenAccountBaseInstruction } =\n await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: TOKEN_PROGRAM_ID,\n mint: new PublicKey(tokenIn.address),\n owner: this.scope.ownerPubKey,\n\n createInfo: inputTokenUseSolBalance\n ? {\n payer: this.scope.ownerPubKey,\n amount: amountIn,\n }\n : undefined,\n skipCloseAccount: !inputTokenUseSolBalance,\n notUseTokenAccount: inputTokenUseSolBalance,\n associatedOnly,\n });\n txBuilder.addInstruction(ownerTokenAccountBaseInstruction || {});\n\n if (!_tokenAccountIn)\n this.logAndCreateError(\"input token account not found\", {\n token: tokenIn.symbol || tokenIn.address,\n tokenAccountIn: _tokenAccountIn,\n inputTokenUseSolBalance,\n associatedOnly,\n });\n\n const { account: _tokenAccountOut, instructionParams: ownerTokenAccountQuoteInstruction } =\n await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: TOKEN_PROGRAM_ID,\n mint: new PublicKey(tokenOut.address),\n owner: this.scope.ownerPubKey,\n createInfo: {\n payer: this.scope.ownerPubKey!,\n amount: 0,\n },\n skipCloseAccount: !outputTokenUseSolBalance,\n notUseTokenAccount: outputTokenUseSolBalance,\n associatedOnly: outputTokenUseSolBalance ? false : associatedOnly,\n });\n txBuilder.addInstruction(ownerTokenAccountQuoteInstruction || {});\n if (_tokenAccountOut === undefined)\n this.logAndCreateError(\"output token account not found\", {\n token: tokenOut.symbol || tokenOut.address,\n tokenAccountOut: _tokenAccountOut,\n outputTokenUseSolBalance,\n associatedOnly,\n });\n\n const poolKeys = propPoolKeys || (await this.getAmmPoolKeys(poolInfo.id));\n let version = 4;\n if (poolInfo.pooltype.includes(\"StablePool\")) version = 5;\n\n txBuilder.addInstruction({\n instructions: [\n version === 4\n ? makeAMMSwapV2Instruction({\n version,\n poolKeys,\n userKeys: {\n tokenAccountIn: _tokenAccountIn!,\n tokenAccountOut: _tokenAccountOut!,\n owner: this.scope.ownerPubKey,\n },\n amountIn,\n amountOut,\n fixedSide,\n })\n : makeAMMSwapInstruction({\n version,\n poolKeys,\n userKeys: {\n tokenAccountIn: _tokenAccountIn!,\n tokenAccountOut: _tokenAccountOut!,\n owner: this.scope.ownerPubKey,\n },\n amountIn,\n amountOut,\n fixedSide,\n }),\n ],\n instructionTypes: [version === 4 ? InstructionType.AmmV4SwapBaseIn : InstructionType.AmmV5SwapBaseIn],\n });\n\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n return txBuilder.versionBuild({\n txVersion,\n }) as Promise<MakeTxData<T>>;\n }\n\n public async getRpcPoolInfo(poolId: string): Promise<AmmRpcData> {\n return (await this.getRpcPoolInfos([poolId]))[poolId];\n }\n\n public async getRpcPoolInfos(\n poolIds: (string | PublicKey)[],\n config?: { batchRequest?: boolean; chunkCount?: number },\n ): Promise<{\n [poolId: string]: AmmRpcData;\n }> {\n const accounts = await getMultipleAccountsInfoWithCustomFlags(\n this.scope.connection,\n poolIds.map((i) => ({ pubkey: new PublicKey(i) })),\n config,\n );\n const poolInfos: { [poolId: string]: ReturnType<typeof liquidityStateV4Layout.decode> & { programId: PublicKey } } =\n {};\n\n const needFetchVaults: PublicKey[] = [];\n\n for (let i = 0; i < poolIds.length; i++) {\n const item = accounts[i];\n if (item === null || !item.accountInfo) throw Error(\"fetch pool info error: \" + String(poolIds[i]));\n const rpc = liquidityStateV4Layout.decode(item.accountInfo.data);\n poolInfos[String(poolIds[i])] = {\n ...rpc,\n programId: item.accountInfo.owner,\n };\n\n needFetchVaults.push(rpc.baseVault, rpc.quoteVault);\n }\n\n const vaultInfo: { [vaultId: string]: BN } = {};\n const vaultAccountInfo = await getMultipleAccountsInfoWithCustomFlags(\n this.scope.connection,\n needFetchVaults.map((i) => ({ pubkey: new PublicKey(i) })),\n config,\n );\n for (let i = 0; i < needFetchVaults.length; i++) {\n const vaultItemInfo = vaultAccountInfo[i].accountInfo;\n if (vaultItemInfo === null) throw Error(\"fetch vault info error: \" + needFetchVaults[i]);\n // eslint-disable-next-line\n // @ts-ignore\n vaultInfo[String(needFetchVaults[i])] = new BN(AccountLayout.decode(vaultItemInfo.data).amount.toString());\n }\n\n const returnData: { [poolId: string]: AmmRpcData } = {};\n\n for (const [id, info] of Object.entries(poolInfos)) {\n const baseReserve = vaultInfo[info.baseVault.toString()].sub(info.baseNeedTakePnl);\n const quoteReserve = vaultInfo[info.quoteVault.toString()].sub(info.quoteNeedTakePnl);\n returnData[id] = {\n ...info,\n baseReserve,\n mintAAmount: vaultInfo[info.baseVault.toString()],\n mintBAmount: vaultInfo[info.quoteVault.toString()],\n quoteReserve,\n poolPrice: new Decimal(quoteReserve.toString())\n .div(new Decimal(10).pow(info.quoteDecimal.toString()))\n .div(new Decimal(baseReserve.toString()).div(new Decimal(10).pow(info.baseDecimal.toString()))),\n };\n }\n\n return returnData;\n }\n\n public async getPoolInfoFromRpc({ poolId }: { poolId: string }): Promise<{\n poolRpcData: AmmRpcData;\n poolInfo: ComputeAmountOutParam[\"poolInfo\"];\n poolKeys: AmmV4Keys | AmmV5Keys;\n }> {\n const rpcData = await this.getRpcPoolInfo(poolId);\n const computeData = toAmmComputePoolInfo({ [poolId]: rpcData });\n const poolInfo = computeData[poolId];\n const allKeys = await this.scope.tradeV2.computePoolToPoolKeys({\n pools: [computeData[poolId]],\n ammRpcData: { [poolId]: rpcData },\n });\n return {\n poolRpcData: rpcData,\n poolInfo,\n poolKeys: allKeys[0] as AmmV4Keys | AmmV5Keys,\n };\n }\n\n public async fetchPoolBalances(): Promise<LpBalanceInfo[]> {\n await this.scope.account.fetchWalletTokenAccounts({ forceUpdate: true });\n const readyFetchMints = this.scope.account.tokenAccounts\n .filter((p) => !p.mint.equals(PublicKey.default) && !p.amount.isZero())\n .map((t) => t.mint);\n\n const r = await getMultipleAccountsInfo(this.scope.connection, readyFetchMints);\n const mints = r.map((data, idx) => {\n return data && data.data.length === MintLayout.span\n ? {\n ...MintLayout.decode(data.data as any),\n address: readyFetchMints[idx],\n }\n : undefined;\n });\n const balanceMints = mints\n .filter(Boolean)\n .filter((m) =>\n this.scope.cluster === \"devnet\" ? m : poolLpAuthority.has(m!.mintAuthority.toString()),\n ) as (RawMint & { address: PublicKey })[];\n\n const poolList = await this.scope.api.fetchPoolByLpMints({\n ids: balanceMints.map((m) => m.address.toBase58()).join(\",\"),\n });\n\n return balanceMints.map((b, idx) => ({\n mintData: b,\n address: b.address,\n poolInfo: poolList[idx] as ApiV3PoolInfoStandardItem,\n balance: this.scope.account.tokenAccounts.find((a) => a.mint.equals(b.address))?.amount ?? new BN(0),\n }));\n }\n}\n","import { PublicKey } from \"@solana/web3.js\";\n\nimport { TOKEN_PROGRAM_ID } from \"@solana/spl-token\";\nimport { findProgramAddress } from \"./txTool/txUtils\";\n\nexport function getATAAddress(\n owner: PublicKey,\n mint: PublicKey,\n programId?: PublicKey,\n): {\n publicKey: PublicKey;\n nonce: number;\n} {\n return findProgramAddress(\n [owner.toBuffer(), (programId ?? TOKEN_PROGRAM_ID).toBuffer(), mint.toBuffer()],\n new PublicKey(\"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL\"),\n );\n}\n","import { EpochInfo } from \"@solana/web3.js\";\nimport BN from \"bn.js\";\nimport { TransferFee, TransferFeeConfig } from \"@solana/spl-token\";\n\nimport { TransferFeeDataBaseType } from \"../api/type\";\nimport { GetTransferAmountFee } from \"../raydium/type\";\n\nconst POINT = 10_000;\nexport function getTransferAmountFee(\n amount: BN,\n feeConfig: TransferFeeConfig | undefined,\n epochInfo: EpochInfo,\n addFee: boolean,\n): GetTransferAmountFee {\n if (feeConfig === undefined) {\n return {\n amount,\n fee: undefined,\n expirationTime: undefined,\n };\n }\n\n const nowFeeConfig: TransferFee =\n epochInfo.epoch < feeConfig.newerTransferFee.epoch ? feeConfig.olderTransferFee : feeConfig.newerTransferFee;\n const maxFee = new BN(nowFeeConfig.maximumFee.toString());\n const expirationTime: number | undefined =\n epochInfo.epoch < feeConfig.newerTransferFee.epoch\n ? ((Number(feeConfig.newerTransferFee.epoch) * epochInfo.slotsInEpoch - epochInfo.absoluteSlot) * 400) / 1000\n : undefined;\n\n if (addFee) {\n if (nowFeeConfig.transferFeeBasisPoints === POINT) {\n const nowMaxFee = new BN(nowFeeConfig.maximumFee.toString());\n return {\n amount: amount.add(nowMaxFee),\n fee: nowMaxFee,\n expirationTime,\n };\n } else {\n const _TAmount = BNDivCeil(amount.mul(new BN(POINT)), new BN(POINT - nowFeeConfig.transferFeeBasisPoints));\n\n const nowMaxFee = new BN(nowFeeConfig.maximumFee.toString());\n const TAmount = _TAmount.sub(amount).gt(nowMaxFee) ? amount.add(nowMaxFee) : _TAmount;\n\n const _fee = BNDivCeil(TAmount.mul(new BN(nowFeeConfig.transferFeeBasisPoints)), new BN(POINT));\n const fee = _fee.gt(maxFee) ? maxFee : _fee;\n return {\n amount: TAmount,\n fee,\n expirationTime,\n };\n }\n } else {\n const _fee = BNDivCeil(amount.mul(new BN(nowFeeConfig.transferFeeBasisPoints)), new BN(POINT));\n const fee = _fee.gt(maxFee) ? maxFee : _fee;\n\n return {\n amount,\n fee,\n expirationTime,\n };\n }\n}\n\nexport function getTransferAmountFeeV2(\n amount: BN,\n _feeConfig: TransferFeeDataBaseType | undefined,\n epochInfo: EpochInfo,\n addFee: boolean,\n): GetTransferAmountFee {\n if (_feeConfig === undefined) {\n return {\n amount,\n fee: undefined,\n expirationTime: undefined,\n };\n }\n const feeConfig = {\n ..._feeConfig,\n olderTransferFee: {\n epoch: BigInt(_feeConfig.olderTransferFee.epoch),\n maximumFee: BigInt(_feeConfig.olderTransferFee.maximumFee),\n transferFeeBasisPoints: _feeConfig.olderTransferFee.transferFeeBasisPoints,\n },\n newerTransferFee: {\n epoch: BigInt(_feeConfig.newerTransferFee.epoch),\n maximumFee: BigInt(_feeConfig.newerTransferFee.maximumFee),\n transferFeeBasisPoints: _feeConfig.newerTransferFee.transferFeeBasisPoints,\n },\n };\n\n const nowFeeConfig: TransferFee =\n epochInfo.epoch < feeConfig.newerTransferFee.epoch ? feeConfig.olderTransferFee : feeConfig.newerTransferFee;\n const maxFee = new BN(nowFeeConfig.maximumFee.toString());\n const expirationTime: number | undefined =\n epochInfo.epoch < feeConfig.newerTransferFee.epoch\n ? ((Number(feeConfig.newerTransferFee.epoch) * epochInfo.slotsInEpoch - epochInfo.absoluteSlot) * 400) / 1000\n : undefined;\n\n if (addFee) {\n if (nowFeeConfig.transferFeeBasisPoints === POINT) {\n const nowMaxFee = new BN(nowFeeConfig.maximumFee.toString());\n return {\n amount: amount.add(nowMaxFee),\n fee: nowMaxFee,\n expirationTime,\n };\n } else {\n const _TAmount = BNDivCeil(amount.mul(new BN(POINT)), new BN(POINT - nowFeeConfig.transferFeeBasisPoints));\n\n const nowMaxFee = new BN(nowFeeConfig.maximumFee.toString());\n const TAmount = _TAmount.sub(amount).gt(nowMaxFee) ? amount.add(nowMaxFee) : _TAmount;\n\n const _fee = BNDivCeil(TAmount.mul(new BN(nowFeeConfig.transferFeeBasisPoints)), new BN(POINT));\n const fee = _fee.gt(maxFee) ? maxFee : _fee;\n return {\n amount: TAmount,\n fee,\n expirationTime,\n };\n }\n } else {\n const _fee = BNDivCeil(amount.mul(new BN(nowFeeConfig.transferFeeBasisPoints)), new BN(POINT));\n const fee = _fee.gt(maxFee) ? maxFee : _fee;\n\n return {\n amount,\n fee,\n expirationTime,\n };\n }\n}\n\nexport function minExpirationTime(\n expirationTime1: number | undefined,\n expirationTime2: number | undefined,\n): number | undefined {\n if (expirationTime1 === undefined) return expirationTime2;\n if (expirationTime2 === undefined) return expirationTime1;\n\n return Math.min(expirationTime1, expirationTime2);\n}\n\nexport function BNDivCeil(bn1: BN, bn2: BN): BN {\n const { div, mod } = bn1.divmod(bn2);\n\n if (mod.gt(new BN(0))) {\n return div.add(new BN(1));\n } else {\n return div;\n }\n}\n\nexport function ceilDivBN(amountA: BN, amountB: BN): BN {\n if (amountA.isZero()) return new BN(0);\n\n const quotient = amountA.div(amountB);\n\n if (quotient.isZero()) return new BN(1);\n\n const remainder = amountA.mod(amountB);\n if (remainder.gt(new BN(0))) {\n return quotient.add(new BN(1));\n }\n return quotient;\n}\n\nexport function getTransferAmountFeeFromPre(\n amount: BN,\n feeConfig: TransferFeeConfig | undefined,\n slot: number,\n): GetTransferAmountFee {\n if (feeConfig === undefined) {\n return {\n amount,\n fee: undefined,\n expirationTime: undefined,\n };\n }\n const epoch = Math.floor(slot / 432000);\n const nowFeeConfig: TransferFee =\n epoch < feeConfig.newerTransferFee.epoch ? feeConfig.olderTransferFee : feeConfig.newerTransferFee;\n const maxFee = new BN(nowFeeConfig.maximumFee.toString());\n const expirationTime: number | undefined =\n epoch < feeConfig.newerTransferFee.epoch\n ? ((Number(feeConfig.newerTransferFee.epoch) * 432000 - slot) * 400) / 1000\n : undefined;\n const _fee = BNDivCeil(amount.mul(new BN(nowFeeConfig.transferFeeBasisPoints)), new BN(POINT));\n const fee = _fee.gt(maxFee) ? maxFee : _fee;\n return {\n amount,\n fee,\n expirationTime,\n };\n}\nexport function getTransferAmountFeeFromPost(\n amount: BN,\n feeConfig: TransferFeeConfig | undefined,\n slot: number,\n): GetTransferAmountFee {\n if (feeConfig === undefined) {\n return {\n amount,\n fee: undefined,\n expirationTime: undefined,\n };\n }\n const epoch = Math.floor(slot / 432000);\n const nowFeeConfig: TransferFee =\n epoch < feeConfig.newerTransferFee.epoch ? feeConfig.olderTransferFee : feeConfig.newerTransferFee;\n const maxFee = new BN(nowFeeConfig.maximumFee.toString());\n const expirationTime: number | undefined =\n epoch < feeConfig.newerTransferFee.epoch\n ? ((Number(feeConfig.newerTransferFee.epoch) * 432000 - slot) * 400) / 1000\n : undefined;\n if (nowFeeConfig.transferFeeBasisPoints === POINT) {\n const nowMaxFee = new BN(nowFeeConfig.maximumFee.toString());\n return {\n amount: amount.add(nowMaxFee),\n fee: nowMaxFee,\n expirationTime,\n };\n } else {\n const _TAmount = BNDivCeil(amount.mul(new BN(POINT)), new BN(POINT - nowFeeConfig.transferFeeBasisPoints));\n const nowMaxFee = new BN(nowFeeConfig.maximumFee.toString());\n const TAmount = _TAmount.sub(amount).gt(nowMaxFee) ? amount.add(nowMaxFee) : _TAmount;\n const _fee = BNDivCeil(TAmount.mul(new BN(nowFeeConfig.transferFeeBasisPoints)), new BN(POINT));\n const fee = _fee.gt(maxFee) ? maxFee : _fee;\n return {\n amount: TAmount,\n fee,\n expirationTime,\n };\n }\n}\n","import { PublicKey } from \"@solana/web3.js\";\n\nimport { ApiV3Token } from \"../../api/type\";\nimport { createLogger } from \"../../common/logger\";\nimport {\n DEVNET_PROGRAM_ID,\n FARM_PROGRAM_ID_V3,\n FARM_PROGRAM_ID_V4,\n FARM_PROGRAM_ID_V5,\n FARM_PROGRAM_ID_V6,\n} from \"../../common/programId\";\n\nimport {\n FarmLedgerLayout,\n farmLedgerLayoutV3_2,\n farmLedgerLayoutV5_2,\n farmLedgerLayoutV6_1,\n FarmStateLayout,\n farmStateV3Layout,\n farmStateV5Layout,\n farmStateV6Layout,\n} from \"./layout\";\nimport { NATIVE_MINT } from \"@solana/spl-token\";\n\nconst logger = createLogger(\"Raydium_farm_config\");\n\nexport type FarmVersion = 3 | 4 | 5 | 6;\nexport const FARM_LOCK_MINT = new PublicKey(\"4k3Dyjzvzp8eMZWUXbBCjEvwSkkk59S5iCNLY3QrkX6R\");\nexport const FARM_LOCK_VAULT = new PublicKey(\"FrspKwj8i3pNmKwXreTveC4fu7KL5ZbGeXdZBe2XViu1\");\n\nexport const DEV_FARM_LOCK_MINT = NATIVE_MINT;\nexport const DEV_FARM_LOCK_VAULT = new PublicKey(\"3TRTX4dXUpp2eqxi3tvQDFYUV7SdDJjcPE3Y4mbtftaX\");\n\n/* ================= index ================= */\n// version => farm state layout\nexport const FARM_VERSION_TO_STATE_LAYOUT: {\n [version in FarmVersion]?: FarmStateLayout;\n} = {\n 3: farmStateV3Layout,\n 5: farmStateV5Layout,\n 6: farmStateV6Layout,\n};\n\n// version => farm ledger layout\nexport const FARM_VERSION_TO_LEDGER_LAYOUT: {\n [version in FarmVersion]?: FarmLedgerLayout;\n} = {\n 3: farmLedgerLayoutV3_2,\n 5: farmLedgerLayoutV5_2,\n 6: farmLedgerLayoutV6_1,\n};\n\nexport const isValidFarmVersion = (version: number): boolean => [3, 4, 5, 6].indexOf(version) !== -1;\n\nexport const validateFarmRewards = (params: {\n version: number;\n rewardInfos: { mint: ApiV3Token }[];\n rewardTokenAccountsPublicKeys: PublicKey[];\n}): (() => string | undefined) => {\n const { version, rewardInfos, rewardTokenAccountsPublicKeys } = params;\n\n const infoMsg = `rewardInfo:${JSON.stringify(rewardInfos)}, rewardAccount:${JSON.stringify(\n rewardTokenAccountsPublicKeys,\n )}`;\n\n const validator = {\n 3: (): string | undefined => {\n if (rewardInfos.length !== 1 || rewardTokenAccountsPublicKeys.length !== 1) {\n return `rewardInfos or rewardTokenAccounts lengths not equal 1: ${infoMsg}`;\n }\n },\n 5: (): string | undefined => {\n if (rewardInfos.length !== rewardTokenAccountsPublicKeys.length) {\n return `rewardInfos and rewardTokenAccounts lengths not equal: ${infoMsg}`;\n }\n },\n 6: (): string | undefined => {\n if (!rewardTokenAccountsPublicKeys.length || rewardInfos.length !== rewardTokenAccountsPublicKeys.length) {\n return `no rewardTokenAccounts or rewardInfos and rewardTokenAccounts lengths not equal: ${infoMsg}`;\n }\n },\n };\n\n return validator[version]?.();\n};\n\nexport const poolTypeV6 = { \"Standard SPL\": 0, \"Option tokens\": 1 };\n\nexport const FARM_PROGRAM_TO_VERSION: Record<string, 3 | 4 | 5 | 6> = {\n [FARM_PROGRAM_ID_V3.toString()]: 3,\n [FARM_PROGRAM_ID_V4.toString()]: 4,\n [FARM_PROGRAM_ID_V5.toString()]: 5,\n [FARM_PROGRAM_ID_V6.toString()]: 6,\n [DEVNET_PROGRAM_ID.FARM_PROGRAM_ID_V3.toString()]: 3,\n [DEVNET_PROGRAM_ID.FARM_PROGRAM_ID_V4.toString()]: 4,\n [DEVNET_PROGRAM_ID.FARM_PROGRAM_ID_V5.toString()]: 5,\n [DEVNET_PROGRAM_ID.FARM_PROGRAM_ID_V6.toString()]: 6,\n};\n","import { PublicKey } from \"@solana/web3.js\";\n\n// raydium\nexport const FARM_PROGRAM_ID_V3 = new PublicKey(\"EhhTKczWMGQt46ynNeRX1WfeagwwJd7ufHvCDjRxjo5Q\");\n// temp fusion\nexport const FARM_PROGRAM_ID_V4 = new PublicKey(\"CBuCnLe26faBpcBP2fktp4rp8abpcAnTWft6ZrP5Q4T\");\n// \"fusion\"\nexport const FARM_PROGRAM_ID_V5 = new PublicKey(\"9KEPoZmtHUrBbhWN1v1KWLMkkvwY6WLtAVUCPRtRjP4z\");\n// echosystem\nexport const FARM_PROGRAM_ID_V6 = new PublicKey(\"FarmqiPv5eAj3j1GMdMCMUGXqPUvmquZtMy86QH6rzhG\");\n\nexport const UTIL1216 = new PublicKey(\"CLaimxFqjHzgTJtAGHU47NPhg6qrc5sCnpC4tBLyABQS\");\n\nexport const OPEN_BOOK_PROGRAM = new PublicKey(\"srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX\");\nexport const SERUM_PROGRAM_ID_V3 = new PublicKey(\"9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin\");\n\nexport const AMM_V4 = new PublicKey(\"675kPX9MHTjS2zt1qfr1NYHuzeLXfQM9H24wFSUt1Mp8\");\nexport const AMM_STABLE = new PublicKey(\"5quBtoiQqxF9Jv6KYKctB59NT3gtJD2Y65kdnB1Uev3h\");\nexport const LIQUIDITY_POOL_PROGRAM_ID_V5_MODEL = new PublicKey(\"CDSr3ssLcRB6XYPJwAfFt18MZvEZp4LjHcvzBVZ45duo\");\nexport const CLMM_PROGRAM_ID = new PublicKey(\"CAMMCzo5YL8w4VFF8KVHrK22GGUsp5VTaW7grrKgrWqK\");\nexport const CLMM_LOCK_PROGRAM_ID = new PublicKey(\"LockrWmn6K5twhz3y9w1dQERbmgSaRkfnTeTKbpofwE\");\nexport const CLMM_LOCK_AUTH_ID = new PublicKey(\"kN1kEznaF5Xbd8LYuqtEFcxzWSBk5Fv6ygX6SqEGJVy\");\n\nexport const MODEL_DATA_PUBKEY = new PublicKey(\"CDSr3ssLcRB6XYPJwAfFt18MZvEZp4LjHcvzBVZ45duo\");\n\nexport const Router = new PublicKey(\"routeUGWgWzqBWFcrCfv8tritsqukccJPu3q5GPP3xS\");\nexport const FEE_DESTINATION_ID = new PublicKey(\"7YttLkHDoNj9wyDur5pM1ejNaAvT9X4eqaYcHQqtj2G5\");\n\nexport const CREATE_CPMM_POOL_PROGRAM = new PublicKey(\"CPMMoo8L3F4NbTegBCKVNunggL7H1ZpdTHKxQB5qKP1C\");\nexport const CREATE_CPMM_POOL_AUTH = new PublicKey(\"GpMZbSM2GgvTKHJirzeGfMFoaZ8UR2X7F4v8vHTvxFbL\");\nexport const CREATE_CPMM_POOL_FEE_ACC = new PublicKey(\"DNXgeM9EiiaAbaWvwjHj9fQQLAX5ZsfHyvmYUNRAdNC8\");\n\nexport const LOCK_CPMM_PROGRAM = new PublicKey(\"LockrWmn6K5twhz3y9w1dQERbmgSaRkfnTeTKbpofwE\");\n\nexport const LOCK_CPMM_AUTH = new PublicKey(\"3f7GcQFG397GAaEnv51zR6tsTVihYRydnydDD1cXekxH\");\n\nexport const LAUNCHPAD_PROGRAM = new PublicKey(\"LanMV9sAd7wArD4vJFi2qDdfnVhFxYSUg6eADduJ3uj\");\nexport const LAUNCHPAD_AUTH = new PublicKey(\"WLHv2UAZm6z4KyaaELi5pjdbJh6RESMva1Rnn8pJVVh\");\n\nexport const DEV_LAUNCHPAD_PROGRAM = new PublicKey(\"DRay6fNdQ5J82H7xV6uq2aV3mNrUZ1J4PgSKsWgptcm6\");\nexport const DEV_LAUNCHPAD_AUTH = new PublicKey(\"5xqNaZXX5eUi4p5HU4oz9i5QnwRNT2y6oN7yyn4qENeq\");\n\nexport const LAUNCHPAD_PLATFORM = new PublicKey(\"4Bu96XjU84XjPDSpveTVf6LYGCkfW5FK7SNkREWcEfV4\");\n\nexport const LAUNCHPAD_CONFIG = new PublicKey(\"6s1xP3hpbAfFoNtUNF8mfHsjr2Bd97JxFJRWLbL6aHuX\");\n\nexport const ALL_PROGRAM_ID = {\n AMM_V4,\n AMM_STABLE,\n\n CLMM_PROGRAM_ID,\n CLMM_LOCK_PROGRAM_ID,\n CLMM_LOCK_AUTH_ID,\n\n FARM_PROGRAM_ID_V3,\n FARM_PROGRAM_ID_V4,\n FARM_PROGRAM_ID_V5,\n FARM_PROGRAM_ID_V6,\n\n OPEN_BOOK_PROGRAM,\n SERUM_PROGRAM_ID_V3,\n\n UTIL1216,\n\n Router,\n\n CREATE_CPMM_POOL_PROGRAM,\n CREATE_CPMM_POOL_AUTH,\n CREATE_CPMM_POOL_FEE_ACC,\n\n LOCK_CPMM_PROGRAM,\n LOCK_CPMM_AUTH,\n\n LAUNCHPAD_PROGRAM,\n LAUNCHPAD_AUTH,\n\n LAUNCHPAD_PLATFORM,\n LAUNCHPAD_CONFIG,\n\n FEE_DESTINATION_ID,\n\n MODEL_DATA_PUBKEY,\n};\n\nexport type ProgramIdConfig = Partial<typeof ALL_PROGRAM_ID>;\n\nexport const DEVNET_PROGRAM_ID: typeof ALL_PROGRAM_ID = {\n OPEN_BOOK_PROGRAM: new PublicKey(\"EoTcMgcDRTJVZDMZWBoU6rhYHZfkNTVEAfz3uUJRcYGj\"),\n SERUM_PROGRAM_ID_V3: new PublicKey(\"Ray1111111111111111111111111111111111111111\"),\n AMM_V4: new PublicKey(\"DRaya7Kj3aMWQSy19kSjvmuwq9docCHofyP9kanQGaav\"),\n AMM_STABLE: new PublicKey(\"DRayDdXc1NZQ9C3hRWmoSf8zK4iapgMnjdNZWrfwsP8m\"),\n\n CLMM_PROGRAM_ID: new PublicKey(\"DRayAUgENGQBKVaX8owNhgzkEDyoHTGVEGHVJT1E9pfH\"),\n CLMM_LOCK_PROGRAM_ID: new PublicKey(\"DRay25Usp3YJAi7beckgpGUC7mGJ2cR1AVPxhYfwVCUX\"),\n CLMM_LOCK_AUTH_ID: new PublicKey(\"6Aoh8h2Lw2m5UGxYR8AdAL87jTWYeKoxM52mJRzfYwN\"),\n\n CREATE_CPMM_POOL_PROGRAM: new PublicKey(\"DRaycpLY18LhpbydsBWbVJtxpNv9oXPgjRSfpF2bWpYb\"),\n CREATE_CPMM_POOL_AUTH: new PublicKey(\"CXniRufdq5xL8t8jZAPxsPZDpuudwuJSPWnbcD5Y5Nxq\"),\n CREATE_CPMM_POOL_FEE_ACC: new PublicKey(\"3oE58BKVt8KuYkGxx8zBojugnymWmBiyafWgMrnb6eYy\"),\n\n LOCK_CPMM_PROGRAM: new PublicKey(\"DRay25Usp3YJAi7beckgpGUC7mGJ2cR1AVPxhYfwVCUX\"),\n LOCK_CPMM_AUTH: new PublicKey(\"7qWVV8UY2bRJfDLP4s37YzBPKUkVB46DStYJBpYbQzu3\"),\n\n UTIL1216: PublicKey.default,\n\n Router: new PublicKey(\"DRaybByLpbUL57LJARs3j8BitTxVfzBg351EaMr5UTCd\"),\n\n FARM_PROGRAM_ID_V3: new PublicKey(\"DRayWyrLmEW5KEeqs8kdTMMaBabapqagaBC7KWpGtJeZ\"),\n FARM_PROGRAM_ID_V4: new PublicKey(\"Ray1111111111111111111111111111111111111111\"),\n FARM_PROGRAM_ID_V5: new PublicKey(\"DRayiCGSZgku1GTK6rXD6mVDdingXy6APAH1R6R5L2LC\"),\n FARM_PROGRAM_ID_V6: new PublicKey(\"DRayzbYakXs45ELHkzH6vC3fuhQqTAnv5A68gdFuvZyZ\"),\n\n LAUNCHPAD_PROGRAM: new PublicKey(\"DRay6fNdQ5J82H7xV6uq2aV3mNrUZ1J4PgSKsWgptcm6\"),\n LAUNCHPAD_AUTH: new PublicKey(\"5xqNaZXX5eUi4p5HU4oz9i5QnwRNT2y6oN7yyn4qENeq\"),\n\n LAUNCHPAD_PLATFORM: new PublicKey(\"2Jx4KTDrVSdWNazuGpcA8n3ZLTRGGBDxAWhuKe2Xcj2a\"),\n LAUNCHPAD_CONFIG: new PublicKey(\"7ZR4zD7PYfY2XxoG1Gxcy2EgEeGYrpxrwzPuwdUBssEt\"),\n\n FEE_DESTINATION_ID: new PublicKey(\"9y8ENuuZ3b19quffx9hQvRVygG5ky6snHfRvGpuSfeJy\"),\n\n MODEL_DATA_PUBKEY: new PublicKey(\"Ray1111111111111111111111111111111111111111\"),\n};\n","import { PublicKey } from \"@solana/web3.js\";\nimport BN from \"bn.js\";\n\nimport {\n blob,\n bool,\n GetLayoutSchemaFromStructure,\n GetStructureFromLayoutSchema,\n GetStructureSchema,\n i64,\n i8,\n publicKey,\n seq,\n struct,\n u128,\n u64,\n u8,\n} from \"../../marshmallow\";\n\nimport { poolTypeV6 } from \"./config\";\nimport { RewardType } from \"./type\";\n\nexport const associatedLedgerAccountLayout = struct([u8(\"instruction\")]);\nexport const withdrawRewardLayout = struct([u8(\"instruction\")]);\n\nconst farmStateRewardInfoV6Layout = struct([\n u64(\"rewardState\"),\n u64(\"rewardOpenTime\"),\n u64(\"rewardEndTime\"),\n u64(\"rewardLastUpdateTime\"),\n u64(\"totalReward\"),\n u64(\"totalRewardEmissioned\"),\n u64(\"rewardClaimed\"),\n u64(\"rewardPerSecond\"),\n u128(\"accRewardPerShare\"),\n publicKey(\"rewardVault\"),\n publicKey(\"rewardMint\"),\n publicKey(\"rewardSender\"),\n u64(\"rewardType\"),\n seq(u64(), 15, \"padding\"),\n]);\n\nexport const realFarmStateV3Layout = struct([\n u64(\"state\"),\n u64(\"nonce\"),\n publicKey(\"lpVault\"),\n publicKey(\"rewardVault\"),\n publicKey(),\n publicKey(),\n u64(),\n u64(),\n u64(\"totalReward\"),\n u128(\"perShareReward\"),\n u64(\"lastSlot\"),\n u64(\"perSlotReward\"),\n]);\n\nexport const realFarmStateV5Layout = struct([\n u64(\"state\"),\n u64(\"nonce\"),\n publicKey(\"lpVault\"),\n publicKey(\"rewardVaultA\"),\n u64(\"totalRewardA\"),\n u128(\"perShareRewardA\"),\n u64(\"perSlotRewardA\"),\n u8(\"option\"),\n publicKey(\"rewardVaultB\"),\n blob(7),\n u64(\"totalRewardB\"),\n u128(\"perShareRewardB\"),\n u64(\"perSlotRewardB\"),\n u64(\"lastSlot\"),\n publicKey(),\n]);\n\nexport const realFarmV6Layout = struct([\n u64(),\n u64(\"state\"),\n u64(\"nonce\"),\n u64(\"validRewardTokenNum\"),\n u128(\"rewardMultiplier\"),\n u64(\"rewardPeriodMax\"),\n u64(\"rewardPeriodMin\"),\n u64(\"rewardPeriodExtend\"),\n publicKey(\"lpMint\"),\n publicKey(\"lpVault\"),\n seq(farmStateRewardInfoV6Layout, 5, \"rewardInfos\"),\n publicKey(\"creator\"),\n publicKey(),\n seq(u64(), 32, \"padding\"),\n]);\n\nexport const farmStateV3Layout = new Proxy(\n realFarmStateV3Layout as GetStructureFromLayoutSchema<\n {\n version: 3;\n rewardInfos: {\n rewardVault: PublicKey;\n totalReward: BN;\n perSlotReward: BN;\n perShareReward: BN;\n }[];\n } & GetLayoutSchemaFromStructure<typeof realFarmStateV3Layout>\n >,\n {\n get(target, p, receiver): any {\n if (p === \"decode\")\n return (...decodeParams: Parameters<typeof target[\"decode\"]>) => {\n const originalResult = target.decode(...decodeParams);\n return {\n ...originalResult,\n version: 3,\n rewardInfos: [\n {\n rewardVault: originalResult.rewardVault,\n totalReward: originalResult.totalReward,\n perSlotReward: originalResult.perSlotReward,\n perShareReward: originalResult.perShareReward,\n },\n ],\n };\n };\n else return Reflect.get(target, p, receiver);\n },\n },\n);\n\nexport const farmStateV5Layout = new Proxy(\n realFarmStateV5Layout as GetStructureFromLayoutSchema<\n {\n version: 5;\n rewardInfos: {\n rewardVault: PublicKey;\n totalReward: BN;\n perSlotReward: BN;\n perShareReward: BN;\n }[];\n } & GetLayoutSchemaFromStructure<typeof realFarmStateV5Layout>\n >,\n {\n get(target, p, receiver): any {\n if (p === \"decode\")\n return (...decodeParams: Parameters<typeof target[\"decode\"]>) => {\n const originalResult = target.decode(...decodeParams);\n return {\n ...originalResult,\n version: 5,\n rewardInfos: [\n {\n rewardVault: originalResult.rewardVaultA,\n totalReward: originalResult.totalRewardA,\n perSlotReward: originalResult.perSlotRewardA,\n perShareReward: originalResult.perShareRewardA,\n },\n {\n rewardVault: originalResult.rewardVaultB,\n totalReward: originalResult.totalRewardB,\n perSlotReward: originalResult.perSlotRewardB,\n perShareReward: originalResult.perShareRewardB,\n },\n ],\n };\n };\n else return Reflect.get(target, p, receiver);\n },\n },\n);\n\nexport const farmStateV6Layout = new Proxy(\n realFarmV6Layout as GetStructureFromLayoutSchema<\n {\n version: 6;\n rewardInfos: {\n rewardState: BN;\n rewardOpenTime: BN;\n rewardEndTime: BN;\n rewardLastUpdateTime: BN;\n totalReward: BN;\n totalRewardEmissioned: BN;\n rewardClaimed: BN;\n rewardPerSecond: BN;\n accRewardPerShare: BN;\n rewardVault: PublicKey;\n rewardMint: PublicKey;\n rewardSender: PublicKey;\n rewardType: RewardType;\n }[];\n } & GetLayoutSchemaFromStructure<typeof realFarmV6Layout>\n >,\n {\n get(target, p, receiver): any {\n if (p === \"decode\")\n return (...decodeParams: Parameters<typeof target[\"decode\"]>) => {\n const originalResult = target.decode(...decodeParams);\n return {\n ...originalResult,\n version: 6,\n rewardInfos: originalResult.rewardInfos.map((item) => ({\n ...item,\n rewardType: (Object.entries(poolTypeV6).find((i) => String(i[1]) === item.rewardType.toString()) ?? [\n \"Standard SPL\",\n ])[0],\n })),\n };\n };\n else return Reflect.get(target, p, receiver);\n },\n },\n);\n\nexport const farmRewardTimeInfoLayout = struct([\n u64(\"isSet\"),\n u64(\"rewardPerSecond\"),\n u64(\"rewardOpenTime\"),\n u64(\"rewardEndTime\"),\n u64(\"rewardType\"),\n]);\n\nexport const farmRewardLayout = struct([\n u8(\"instruction\"),\n u64(\"nonce\"),\n seq(farmRewardTimeInfoLayout, 5, \"rewardTimeInfo\"),\n]);\n\nexport const farmRewardRestartLayout = struct([\n u8(\"instruction\"),\n u64(\"rewardReopenTime\"),\n u64(\"rewardEndTime\"),\n u64(\"rewardPerSecond\"),\n]);\n\nexport const farmAddRewardLayout = struct([\n u8(\"instruction\"),\n u64(\"isSet\"),\n u64(\"rewardPerSecond\"),\n u64(\"rewardOpenTime\"),\n u64(\"rewardEndTime\"),\n u64(\"rewardType\"),\n]);\n\nexport type FarmStateLayoutV3 = typeof farmStateV3Layout;\nexport type FarmStateLayoutV5 = typeof farmStateV5Layout;\nexport type FarmStateLayoutV6 = typeof farmStateV6Layout;\n\nexport type FarmStateV3 = GetStructureSchema<FarmStateLayoutV3>;\nexport type FarmStateV5 = GetStructureSchema<FarmStateLayoutV5>;\nexport type FarmStateV6 = GetStructureSchema<FarmStateLayoutV6>;\n\nexport type FarmState = FarmStateV3 | FarmStateV5 | FarmStateV6;\n// farmStateLayoutV3\nexport type FarmStateLayout = FarmStateLayoutV3 | FarmStateLayoutV5 | FarmStateLayoutV6;\n\n/* ================= ledger layouts ================= */\nexport const farmLedgerLayoutV3_1 = struct([\n u64(\"state\"),\n publicKey(\"id\"),\n publicKey(\"owner\"),\n u64(\"deposited\"),\n seq(u64(), 1, \"rewardDebts\"),\n]);\n\nexport const farmLedgerLayoutV3_2 = struct([\n u64(\"state\"),\n publicKey(\"id\"),\n publicKey(\"owner\"),\n u64(\"deposited\"),\n seq(u128(), 1, \"rewardDebts\"),\n u64(\"\"),\n u64(\"voteLockedBalance\"),\n seq(u64(), 15),\n]);\n\nexport const farmLedgerLayoutV5_1 = struct([\n u64(\"state\"),\n publicKey(\"id\"),\n publicKey(\"owner\"),\n u64(\"deposited\"),\n seq(u64(), 2, \"rewardDebts\"),\n]);\n\nexport const farmLedgerLayoutV5_2 = struct([\n u64(\"state\"),\n publicKey(\"id\"),\n publicKey(\"owner\"),\n u64(\"deposited\"),\n seq(u128(), 2, \"rewardDebts\"),\n seq(u64(), 17),\n]);\n\nexport const farmLedgerLayoutV6_1 = struct([\n u64(),\n u64(\"state\"),\n publicKey(\"id\"),\n publicKey(\"owner\"),\n u64(\"deposited\"),\n seq(u128(), 5, \"rewardDebts\"),\n seq(u64(), 16),\n]);\n\nexport type FarmLedgerLayoutV3_1 = typeof farmLedgerLayoutV3_1;\nexport type FarmLedgerLayoutV3_2 = typeof farmLedgerLayoutV3_2;\nexport type FarmLedgerLayoutV5_1 = typeof farmLedgerLayoutV5_1;\nexport type FarmLedgerLayoutV5_2 = typeof farmLedgerLayoutV5_2;\nexport type FarmLedgerLayoutV6_1 = typeof farmLedgerLayoutV6_1;\nexport type FarmLedgerLayout =\n | FarmLedgerLayoutV3_1\n | FarmLedgerLayoutV3_2\n | FarmLedgerLayoutV5_1\n | FarmLedgerLayoutV5_2\n | FarmLedgerLayoutV6_1;\n\nexport type FarmLedgerV3_1 = GetStructureSchema<FarmLedgerLayoutV3_1>;\nexport type FarmLedgerV3_2 = GetStructureSchema<FarmLedgerLayoutV3_2>;\nexport type FarmLedgerV5_1 = GetStructureSchema<FarmLedgerLayoutV5_1>;\nexport type FarmLedgerV5_2 = GetStructureSchema<FarmLedgerLayoutV5_2>;\nexport type FarmLedgerV6_1 = GetStructureSchema<FarmLedgerLayoutV6_1>;\nexport type FarmLedger = FarmLedgerV3_1 | FarmLedgerV3_2 | FarmLedgerV5_1 | FarmLedgerV5_2 | FarmLedgerV6_1;\n\nexport const dwLayout = struct([u8(\"instruction\"), u64(\"amount\")]);\n\nexport const VoterVotingMintConfig = struct([\n publicKey(\"mint\"),\n publicKey(\"grantAuthority\"),\n u64(\"baselineVoteWeightScaledFactor\"),\n u64(\"maxExtraLockupVoteWeightScaledFactor\"),\n u64(\"lockupSaturationSecs\"),\n\n i8(\"digitShift\"), // TODO\n seq(u8(), 7, \"reserved1\"),\n seq(u64(), 7, \"reserved2\"),\n]);\n\nexport const VoterRegistrar = struct([\n blob(8),\n publicKey(\"governanceProgramId\"),\n publicKey(\"realm\"),\n publicKey(\"realmGoverningTokenMint\"),\n publicKey(\"realmAuthority\"),\n\n seq(u8(), 32, \"reserved1\"),\n seq(VoterVotingMintConfig, 4, \"votingMints\"),\n\n i64(\"timeOffset\"),\n u8(\"bump\"),\n seq(u8(), 7, \"reserved2\"),\n seq(u64(), 11, \"reserved3\"),\n]);\n\nexport const VoterLockup = struct([i64(\"startTime\"), i64(\"endTime\"), u8(\"kind\"), seq(u8(), 15, \"reserved\")]);\n\nexport const VoterDepositEntry = struct([\n seq(VoterLockup, 1, \"lockup\"),\n u64(\"amountDeposited_native\"),\n u64(\"amountInitiallyLockedNative\"),\n bool(\"isUsed\"),\n bool(\"allowClawback\"),\n u8(\"votingMintConfigIdx\"),\n seq(u8(), 29, \"reserved\"),\n]);\n\nexport const Voter = struct([\n blob(8),\n publicKey(\"voterAuthority\"),\n publicKey(\"registrar\"),\n\n seq(VoterDepositEntry, 32, \"deposits\"),\n\n u8(\"voterBump\"),\n u8(\"voterWweightRecordBump\"),\n seq(u8(), 94, \"reserved\"),\n]);\n","import { Connection, PublicKey } from \"@solana/web3.js\";\nimport BN from \"bn.js\";\n\nimport { RewardInfoV6 } from \"../../api/type\";\nimport { parseBigNumberish } from \"../../common\";\nimport { GetMultipleAccountsInfoConfig, getMultipleAccountsInfoWithCustomFlags } from \"../../common/accountInfo\";\nimport { DateParam, isDateAfter, isDateBefore } from \"../../common/date\";\nimport { createLogger } from \"../../common/logger\";\nimport { findProgramAddress, ProgramAddress } from \"../../common/txTool/txUtils\";\nimport { jsonInfo2PoolKeys } from \"../../common/utility\";\n\nimport { splAccountLayout } from \"../account/layout\";\nimport { SplAccount } from \"../account/types\";\nimport { FARM_VERSION_TO_LEDGER_LAYOUT, FARM_VERSION_TO_STATE_LAYOUT, poolTypeV6 } from \"./config\";\nimport { FarmLedger, FarmLedgerLayout, FarmState, FarmStateLayout } from \"./layout\";\nimport { FarmRewardInfo, FarmRewardInfoConfig } from \"./type\";\n\nimport { Voter, VoterRegistrar } from \"./layout\";\n\nconst logger = createLogger(\"Raydium.farm.util\");\ninterface AssociatedLedgerPoolAccount {\n programId: PublicKey;\n poolId: PublicKey;\n mint: PublicKey;\n type: \"lpVault\" | \"rewardVault\";\n}\n\nexport function getAssociatedLedgerPoolAccount({\n programId,\n poolId,\n mint,\n type,\n}: AssociatedLedgerPoolAccount): PublicKey {\n const { publicKey } = findProgramAddress(\n [\n poolId.toBuffer(),\n mint.toBuffer(),\n Buffer.from(\n type === \"lpVault\" ? \"lp_vault_associated_seed\" : type === \"rewardVault\" ? \"reward_vault_associated_seed\" : \"\",\n \"utf-8\",\n ),\n ],\n programId,\n );\n return publicKey;\n}\n\nexport function getAssociatedLedgerAccount({\n programId,\n poolId,\n owner,\n version,\n}: {\n programId: PublicKey;\n poolId: PublicKey;\n owner: PublicKey;\n version: 6 | 5 | 3;\n}): PublicKey {\n const { publicKey } = findProgramAddress(\n [\n poolId.toBuffer(),\n owner.toBuffer(),\n Buffer.from(version === 6 ? \"farmer_info_associated_seed\" : \"staker_info_v2_associated_seed\", \"utf-8\"),\n ],\n programId,\n );\n return publicKey;\n}\n\nexport const getAssociatedAuthority = ({\n programId,\n poolId,\n}: {\n programId: PublicKey;\n poolId: PublicKey;\n}): ProgramAddress => findProgramAddress([poolId.toBuffer()], programId);\n\nexport function farmRewardInfoToConfig(data: FarmRewardInfo): FarmRewardInfoConfig {\n return {\n isSet: new BN(1),\n rewardPerSecond: parseBigNumberish(data.perSecond),\n rewardOpenTime: parseBigNumberish(data.openTime),\n rewardEndTime: parseBigNumberish(data.endTime),\n rewardType: parseBigNumberish(poolTypeV6[data.rewardType]),\n };\n}\n\nexport function calFarmRewardAmount(data: Pick<RewardInfoV6, \"openTime\" | \"endTime\"> & { perSecond: string }): BN {\n return parseBigNumberish(data.endTime).sub(parseBigNumberish(data.openTime)).mul(parseBigNumberish(data.perSecond));\n}\n\nexport function getFarmLedgerLayout(version: number): FarmLedgerLayout | undefined {\n const ledgerLayout = FARM_VERSION_TO_LEDGER_LAYOUT[version];\n if (!ledgerLayout) logger.logWithError(\"invalid version\", version);\n return ledgerLayout;\n}\n\nexport function getFarmStateLayout(version: number): FarmStateLayout | undefined {\n const stateLayout = FARM_VERSION_TO_STATE_LAYOUT[version];\n if (!stateLayout) logger.logWithError(\"invalid version\", version);\n return stateLayout;\n}\n\nexport function updateFarmPoolInfo(\n poolInfo: FarmState,\n lpVault: SplAccount,\n slot: number,\n chainTime: number,\n): FarmState {\n if (poolInfo.version === 3 || poolInfo.version === 5) {\n if (poolInfo.lastSlot.gte(new BN(slot))) return poolInfo;\n\n const spread = new BN(slot).sub(poolInfo.lastSlot);\n poolInfo.lastSlot = new BN(slot);\n\n for (const itemRewardInfo of poolInfo.rewardInfos) {\n if (lpVault.amount.eq(new BN(0))) continue;\n\n const reward = itemRewardInfo.perSlotReward.mul(spread);\n itemRewardInfo.perShareReward = itemRewardInfo.perShareReward.add(\n reward.mul(new BN(10).pow(new BN(poolInfo.version === 3 ? 9 : 15))).div(lpVault.amount),\n );\n itemRewardInfo.totalReward = itemRewardInfo.totalReward.add(reward);\n }\n } else if (poolInfo.version === 6) {\n for (const itemRewardInfo of poolInfo.rewardInfos) {\n if (itemRewardInfo.rewardState.eq(new BN(0))) continue;\n const updateTime = BN.min(new BN(chainTime), itemRewardInfo.rewardEndTime);\n if (itemRewardInfo.rewardOpenTime.gte(updateTime)) continue;\n const spread = updateTime.sub(itemRewardInfo.rewardLastUpdateTime);\n let reward = spread.mul(itemRewardInfo.rewardPerSecond);\n const leftReward = itemRewardInfo.totalReward.sub(itemRewardInfo.totalRewardEmissioned);\n if (leftReward.lt(reward)) {\n reward = leftReward;\n itemRewardInfo.rewardLastUpdateTime = itemRewardInfo.rewardLastUpdateTime.add(\n leftReward.div(itemRewardInfo.rewardPerSecond),\n );\n } else {\n itemRewardInfo.rewardLastUpdateTime = updateTime;\n }\n if (lpVault.amount.eq(new BN(0))) continue;\n itemRewardInfo.accRewardPerShare = itemRewardInfo.accRewardPerShare.add(\n reward.mul(poolInfo.rewardMultiplier).div(lpVault.amount),\n );\n itemRewardInfo.totalRewardEmissioned = itemRewardInfo.totalRewardEmissioned.add(reward);\n }\n }\n return poolInfo;\n}\n\ninterface FarmPoolsInfo {\n [id: string]: {\n state: FarmState;\n lpVault: SplAccount;\n ledger?: FarmLedger;\n wrapped?: { pendingRewards: BN[] };\n };\n}\n\nexport interface FarmFetchMultipleInfoParams {\n connection: Connection;\n farmPools: any[];\n owner?: PublicKey;\n config?: GetMultipleAccountsInfoConfig;\n chainTime: number;\n}\n\nexport async function fetchMultipleFarmInfoAndUpdate({\n connection,\n farmPools,\n owner,\n config,\n chainTime,\n}: FarmFetchMultipleInfoParams): Promise<FarmPoolsInfo> {\n let hasNotV6Pool = false;\n let hasV6Pool = false;\n const tenBN = new BN(10);\n\n const publicKeys: {\n pubkey: PublicKey;\n version: number;\n key: \"state\" | \"lpVault\" | \"ledger\";\n poolId: PublicKey;\n }[] = [];\n\n for (const poolInfo of farmPools) {\n const pool = jsonInfo2PoolKeys(poolInfo);\n if (pool.version === 6) hasV6Pool = true;\n else hasNotV6Pool = true;\n\n publicKeys.push(\n {\n pubkey: pool.id,\n version: pool.version,\n key: \"state\",\n poolId: pool.id,\n },\n {\n pubkey: pool.lpVault,\n version: pool.version,\n key: \"lpVault\",\n poolId: pool.id,\n },\n );\n\n if (owner) {\n publicKeys.push({\n pubkey: getAssociatedLedgerAccount({\n programId: pool.programId,\n poolId: pool.id,\n owner,\n version: poolInfo.version as 6 | 5 | 3,\n }),\n version: pool.version,\n key: \"ledger\",\n poolId: pool.id,\n });\n }\n }\n\n const poolsInfo: FarmPoolsInfo = {};\n const accountsInfo = await getMultipleAccountsInfoWithCustomFlags(connection, publicKeys, config);\n for (const { pubkey, version, key, poolId, accountInfo } of accountsInfo) {\n const _poolId = poolId.toBase58();\n poolsInfo[_poolId] = { ...poolsInfo[_poolId] };\n if (key === \"state\") {\n const stateLayout = getFarmStateLayout(version);\n if (!accountInfo || !accountInfo.data || accountInfo.data.length !== stateLayout!.span)\n logger.logWithError(`invalid farm state account info, pools.id, ${pubkey}`);\n poolsInfo[_poolId].state = stateLayout!.decode(accountInfo!.data);\n } else if (key === \"lpVault\") {\n if (!accountInfo || !accountInfo.data || accountInfo.data.length !== splAccountLayout.span)\n logger.logWithError(`invalid farm lp vault account info, pools.lpVault, ${pubkey}`);\n poolsInfo[_poolId].lpVault = splAccountLayout.decode(accountInfo!.data);\n } else if (key === \"ledger\") {\n const legerLayout = getFarmLedgerLayout(version)!;\n if (accountInfo && accountInfo.data) {\n if (accountInfo.data.length !== legerLayout.span)\n logger.logWithError(`invalid farm ledger account info, ledger, ${pubkey}`);\n poolsInfo[_poolId].ledger = legerLayout.decode(accountInfo.data);\n }\n }\n }\n\n const slot = hasV6Pool || hasNotV6Pool ? await connection.getSlot() : 0;\n\n for (const poolId of Object.keys(poolsInfo)) {\n if (poolsInfo[poolId] === undefined) continue;\n poolsInfo[poolId].state = updateFarmPoolInfo(poolsInfo[poolId].state, poolsInfo[poolId].lpVault, slot, chainTime);\n }\n\n for (const [poolId, { state, ledger }] of Object.entries(poolsInfo)) {\n if (ledger) {\n const multiplier =\n state.version === 6\n ? state.rewardMultiplier\n : state.rewardInfos.length === 1\n ? tenBN.pow(new BN(9))\n : tenBN.pow(new BN(15));\n\n const pendingRewards = state.rewardInfos.map((rewardInfo, index) => {\n const rewardDebt = ledger.rewardDebts[index];\n const pendingReward = ledger.deposited\n .mul(state.version === 6 ? rewardInfo.accRewardPerShare : rewardInfo.perShareReward)\n .div(multiplier)\n .sub(rewardDebt);\n\n return pendingReward;\n });\n\n poolsInfo[poolId].wrapped = {\n ...poolsInfo[poolId].wrapped,\n pendingRewards,\n };\n }\n }\n\n return poolsInfo;\n}\n/** deprecated */\nexport function judgeFarmType(\n info: any,\n currentTime: DateParam = Date.now(),\n): \"closed pool\" | \"normal fusion pool\" | \"dual fusion pool\" | undefined | \"upcoming pool\" {\n if (info.version === 6) {\n const rewardInfos = info.state.rewardInfos;\n if (rewardInfos.every(({ rewardOpenTime }) => isDateBefore(currentTime, rewardOpenTime.toNumber(), { unit: \"s\" })))\n return \"upcoming pool\";\n if (rewardInfos.every(({ rewardEndTime }) => isDateAfter(currentTime, rewardEndTime.toNumber(), { unit: \"s\" })))\n return \"closed pool\";\n } else {\n const perSlotRewards = info.state.rewardInfos.map(({ perSlotReward }) => perSlotReward);\n if (perSlotRewards.length === 2) {\n // v5\n if (String(perSlotRewards[0]) === \"0\" && String(perSlotRewards[1]) !== \"0\") {\n return \"normal fusion pool\"; // reward xxx token\n }\n if (String(perSlotRewards[0]) !== \"0\" && String(perSlotRewards[1]) !== \"0\") {\n return \"dual fusion pool\"; // reward ray and xxx token\n }\n if (String(perSlotRewards[0]) === \"0\" && String(perSlotRewards[1]) === \"0\") {\n return \"closed pool\";\n }\n } else if (perSlotRewards.length === 1) {\n // v3\n if (String(perSlotRewards[0]) === \"0\") {\n return \"closed pool\";\n }\n }\n }\n}\n\nexport async function getDepositEntryIndex(\n connection: Connection,\n registrar: PublicKey,\n voter: PublicKey,\n voterMint: PublicKey,\n): Promise<{ index: number; isInit: boolean }> {\n const registrarAccountData = await connection.getAccountInfo(registrar);\n if (registrarAccountData === null) throw Error(\"registrar info check error\");\n const registrarData = VoterRegistrar.decode(registrarAccountData.data);\n\n const votingMintConfigIndex = registrarData.votingMints.findIndex((i) => i.mint.equals(voterMint));\n\n if (votingMintConfigIndex === -1) throw Error(\"find voter mint error\");\n\n const voterAccountData = await connection.getAccountInfo(voter);\n if (voterAccountData === null) return { index: votingMintConfigIndex, isInit: false }; // throw Error('voter info check error')\n\n const voterData = Voter.decode(voterAccountData.data);\n\n const depositEntryIndex = voterData.deposits.findIndex(\n (i) => i.isUsed && i.votingMintConfigIdx === votingMintConfigIndex,\n );\n if (depositEntryIndex === -1) return { index: votingMintConfigIndex, isInit: false };\n else return { index: depositEntryIndex, isInit: true };\n}\n","import { PublicKey } from \"@solana/web3.js\";\nimport BN from \"bn.js\";\n\nimport { Fraction, Percent, Price, Token, TokenAmount } from \"../module\";\nimport { ReplaceType } from \"../raydium/type\";\n\nimport { tryParsePublicKey } from \"./pubKey\";\n\nexport async function sleep(ms: number): Promise<void> {\n new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport function getTimestamp(): number {\n return new Date().getTime();\n}\n\nexport function notInnerObject(v: unknown): v is Record<string, any> {\n return (\n typeof v === \"object\" &&\n v !== null &&\n ![Token, TokenAmount, PublicKey, Fraction, BN, Price, Percent].some((o) => typeof o === \"object\" && v instanceof o)\n );\n}\n\nexport function jsonInfo2PoolKeys<T>(jsonInfo: T): ReplaceType<T, string, PublicKey> {\n // @ts-expect-error no need type for inner code\n return typeof jsonInfo === \"string\"\n ? tryParsePublicKey(jsonInfo)\n : Array.isArray(jsonInfo)\n ? jsonInfo.map((k) => jsonInfo2PoolKeys(k))\n : notInnerObject(jsonInfo)\n ? Object.fromEntries(Object.entries(jsonInfo).map(([k, v]) => [k, jsonInfo2PoolKeys(v)]))\n : jsonInfo;\n}\n","import {\n Connection,\n PublicKey,\n SystemProgram,\n SYSVAR_CLOCK_PUBKEY,\n SYSVAR_RENT_PUBKEY,\n TransactionInstruction,\n} from \"@solana/web3.js\";\nimport BN from \"bn.js\";\nimport {\n ASSOCIATED_TOKEN_PROGRAM_ID,\n createAssociatedTokenAccountIdempotentInstruction,\n TOKEN_PROGRAM_ID,\n} from \"@solana/spl-token\";\n\nimport { FormatFarmKeyOut } from \"@/api/type\";\nimport { parseBigNumberish } from \"@/common\";\nimport { createLogger } from \"@/common/logger\";\nimport { getATAAddress } from \"@/common/pda\";\nimport {\n accountMeta,\n commonSystemAccountMeta,\n INSTRUCTION_PROGRAM_ID,\n RENT_PROGRAM_ID,\n SOLMint,\n} from \"@/common/pubKey\";\nimport { InstructionType } from \"@/common/txTool/txType\";\nimport { bool, struct, u32, u64, u8 } from \"../../marshmallow\";\nimport { InstructionReturn } from \"../type\";\nimport { poolTypeV6 } from \"./config\";\nimport {\n associatedLedgerAccountLayout,\n dwLayout,\n farmAddRewardLayout,\n farmLedgerLayoutV3_2,\n farmRewardLayout,\n farmRewardRestartLayout,\n withdrawRewardLayout,\n} from \"./layout\";\nimport {\n getRegistrarAddress,\n getTokenOwnerRecordAddress,\n getVoterAddress,\n getVoterWeightRecordAddress,\n getVotingMintAuthority,\n getVotingTokenMint,\n} from \"./pda\";\nimport { FarmRewardInfoConfig, RewardInfoKey, RewardType } from \"./type\";\nimport { getAssociatedLedgerAccount, getDepositEntryIndex } from \"./util\";\n\nconst logger = createLogger(\"Raydium_farm_instruction\");\n\nconst anchorDataBuf = {\n voterStakeRegistryCreateVoter: Buffer.from([6, 24, 245, 52, 243, 255, 148, 25]), // CreateVoter\n voterStakeRegistryCreateDepositEntry: Buffer.from([185, 131, 167, 186, 159, 125, 19, 67]), // CreateDepositEntry\n voterStakeRegistryDeposit: Buffer.from([242, 35, 198, 137, 82, 225, 242, 182]), // Deposit\n voterStakeRegistryWithdraw: Buffer.from([183, 18, 70, 156, 148, 109, 161, 34]), // Withdraw\n voterStakeRegistryUpdateVoterWeightRecord: Buffer.from([45, 185, 3, 36, 109, 190, 115, 169]), // UpdateVoterWeightRecord\n};\n\nexport function createAssociatedLedgerAccountInstruction(params: {\n version: number;\n id: PublicKey;\n programId: PublicKey;\n ledger: PublicKey;\n owner: PublicKey;\n}): InstructionReturn {\n const { version, id, ledger, programId, owner } = params;\n const instruction = { 3: 9, 5: 10 }[version];\n if (!instruction) logger.logWithError(`invalid farm pool version: ${version}`);\n\n const data = Buffer.alloc(associatedLedgerAccountLayout.span);\n associatedLedgerAccountLayout.encode(\n {\n instruction: instruction!,\n },\n data,\n );\n\n const keys = [\n accountMeta({ pubkey: id }),\n accountMeta({ pubkey: ledger }),\n accountMeta({ pubkey: owner, isWritable: false }),\n accountMeta({ pubkey: SystemProgram.programId, isWritable: false }),\n accountMeta({ pubkey: SYSVAR_RENT_PUBKEY, isWritable: false }),\n ];\n\n return {\n instruction: new TransactionInstruction({\n programId,\n keys,\n data,\n }),\n instructionType: InstructionType.FarmV3CreateLedger,\n };\n}\n\ninterface CreateFarmInstruction {\n farmId: PublicKey;\n farmAuthority: PublicKey;\n lpVault: PublicKey;\n lpMint: PublicKey;\n lockVault: PublicKey;\n lockMint: PublicKey;\n lockUserAccount?: PublicKey;\n programId: PublicKey;\n owner: PublicKey;\n rewardInfo: RewardInfoKey[];\n rewardInfoConfig: FarmRewardInfoConfig[];\n nonce: number;\n}\nexport function makeCreateFarmInstruction(params: CreateFarmInstruction): InstructionReturn {\n const data = Buffer.alloc(farmRewardLayout.span);\n farmRewardLayout.encode(\n {\n instruction: 0,\n nonce: new BN(params.nonce),\n rewardTimeInfo: params.rewardInfoConfig,\n },\n data,\n );\n\n const keys = [\n ...commonSystemAccountMeta,\n accountMeta({ pubkey: params.farmId }),\n accountMeta({ pubkey: params.farmAuthority, isWritable: false }),\n accountMeta({ pubkey: params.lpVault }),\n accountMeta({ pubkey: params.lpMint, isWritable: false }),\n accountMeta({ pubkey: params.lockVault }),\n accountMeta({ pubkey: params.lockMint, isWritable: false }),\n accountMeta({ pubkey: params.lockUserAccount ?? SOLMint }),\n accountMeta({ pubkey: params.owner, isWritable: false, isSigner: true }),\n ];\n\n for (const item of params.rewardInfo) {\n keys.push(\n ...[\n accountMeta({ pubkey: item.rewardMint, isWritable: false }),\n accountMeta({ pubkey: item.rewardVault }),\n accountMeta({ pubkey: item.userRewardToken }),\n ],\n );\n }\n\n return {\n instruction: new TransactionInstruction({ programId: params.programId, keys, data }),\n instructionType: InstructionType.FarmV6Create,\n };\n}\n\ninterface CreatorWithdrawFarmRewardInstruction {\n id: PublicKey;\n programId: PublicKey;\n authority: PublicKey;\n lpVault: PublicKey;\n rewardVault: PublicKey;\n userRewardToken: PublicKey;\n owner: PublicKey;\n}\n\nexport function makeCreatorWithdrawFarmRewardInstruction(\n params: CreatorWithdrawFarmRewardInstruction,\n): InstructionReturn {\n const data = Buffer.alloc(withdrawRewardLayout.span);\n withdrawRewardLayout.encode({ instruction: 5 }, data);\n\n const keys = [\n accountMeta({ pubkey: TOKEN_PROGRAM_ID, isWritable: false }),\n accountMeta({ pubkey: params.id }),\n accountMeta({ pubkey: params.authority, isWritable: false }),\n accountMeta({ pubkey: params.lpVault, isWritable: false }),\n accountMeta({ pubkey: params.rewardVault }),\n accountMeta({ pubkey: params.userRewardToken }),\n accountMeta({ pubkey: params.owner, isWritable: false, isSigner: true }),\n ];\n\n return {\n instruction: new TransactionInstruction({ programId: params.programId, keys, data }),\n instructionType: InstructionType.FarmV6CreatorWithdraw,\n };\n}\n\nexport function voterStakeRegistryDeposit(\n programId: PublicKey,\n registrar: PublicKey,\n voter: PublicKey,\n voterVault: PublicKey,\n depositToken: PublicKey,\n depositAuthority: PublicKey,\n\n userStakerInfoV2: PublicKey,\n pool: PublicKey,\n votingMint: PublicKey,\n votingMintAuthority: PublicKey,\n stakeProgramId: PublicKey,\n\n depositEntryIndex: number,\n amount: BN,\n): TransactionInstruction {\n const dataLayout = struct([u8(\"depositEntryIndex\"), u64(\"amount\")]);\n\n const keys = [\n { pubkey: registrar, isSigner: false, isWritable: false },\n { pubkey: voter, isSigner: false, isWritable: true },\n { pubkey: voterVault, isSigner: false, isWritable: true },\n { pubkey: depositToken, isSigner: false, isWritable: true },\n { pubkey: depositAuthority, isSigner: false, isWritable: false },\n { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n\n { pubkey: userStakerInfoV2, isSigner: false, isWritable: true },\n { pubkey: pool, isSigner: false, isWritable: false },\n { pubkey: votingMint, isSigner: false, isWritable: true },\n\n { pubkey: votingMintAuthority, isSigner: false, isWritable: false },\n { pubkey: stakeProgramId, isSigner: false, isWritable: false },\n { pubkey: INSTRUCTION_PROGRAM_ID, isSigner: false, isWritable: false },\n ];\n\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode(\n {\n depositEntryIndex,\n amount,\n },\n data,\n );\n const aData = Buffer.from([...anchorDataBuf.voterStakeRegistryDeposit, ...data]);\n\n return new TransactionInstruction({\n keys,\n programId,\n data: aData,\n });\n}\n\nexport function voterStakeRegistryUpdateVoterWeightRecord(\n programId: PublicKey,\n registrar: PublicKey,\n voter: PublicKey,\n voterWeightRecord: PublicKey,\n): TransactionInstruction {\n const dataLayout = struct([]);\n\n const keys = [\n { pubkey: registrar, isSigner: false, isWritable: false },\n { pubkey: voter, isSigner: false, isWritable: false },\n { pubkey: voterWeightRecord, isSigner: false, isWritable: true },\n { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },\n ];\n\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode({}, data);\n const aData = Buffer.from([...anchorDataBuf.voterStakeRegistryUpdateVoterWeightRecord, ...data]);\n\n return new TransactionInstruction({\n keys,\n programId,\n data: aData,\n });\n}\n\nexport function voterStakeRegistryWithdraw(\n programId: PublicKey,\n registrar: PublicKey,\n voter: PublicKey,\n voterAuthority: PublicKey,\n tokenOwnerRecord: PublicKey,\n voterWeightRecord: PublicKey,\n vault: PublicKey,\n destination: PublicKey,\n\n userStakerInfoV2: PublicKey,\n pool: PublicKey,\n votingMint: PublicKey,\n votingMintAuthority: PublicKey,\n stakeProgramId: PublicKey,\n\n depositEntryIndex: number,\n amount: BN,\n): TransactionInstruction {\n const dataLayout = struct([u8(\"depositEntryIndex\"), u64(\"amount\")]);\n\n const keys = [\n { pubkey: registrar, isSigner: false, isWritable: false },\n { pubkey: voter, isSigner: false, isWritable: true },\n { pubkey: voterAuthority, isSigner: true, isWritable: false },\n { pubkey: tokenOwnerRecord, isSigner: false, isWritable: false },\n\n { pubkey: voterWeightRecord, isSigner: false, isWritable: true },\n { pubkey: vault, isSigner: false, isWritable: true },\n { pubkey: destination, isSigner: false, isWritable: true },\n { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n\n { pubkey: userStakerInfoV2, isSigner: false, isWritable: true },\n { pubkey: pool, isSigner: false, isWritable: false },\n { pubkey: votingMint, isSigner: false, isWritable: true },\n\n { pubkey: votingMintAuthority, isSigner: false, isWritable: false },\n { pubkey: stakeProgramId, isSigner: false, isWritable: false },\n { pubkey: INSTRUCTION_PROGRAM_ID, isSigner: false, isWritable: false },\n ];\n\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode(\n {\n depositEntryIndex,\n amount,\n },\n data,\n );\n const aData = Buffer.from([...anchorDataBuf.voterStakeRegistryWithdraw, ...data]);\n\n return new TransactionInstruction({\n keys,\n programId,\n data: aData,\n });\n}\n\nexport function governanceCreateTokenOwnerRecord(\n programId: PublicKey,\n realm: PublicKey,\n governingTokenOwner: PublicKey,\n governingTokenMint: PublicKey,\n payer: PublicKey,\n tokenOwnerRecordAddress: PublicKey,\n): TransactionInstruction {\n const dataLayout = struct([u8(\"ins\")]);\n\n const keys = [\n { pubkey: realm, isSigner: false, isWritable: false },\n { pubkey: governingTokenOwner, isSigner: false, isWritable: false },\n\n { pubkey: tokenOwnerRecordAddress, isSigner: false, isWritable: true },\n\n { pubkey: governingTokenMint, isSigner: false, isWritable: false },\n\n { pubkey: payer, isSigner: true, isWritable: true },\n\n { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },\n ];\n\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode({ ins: 23 }, data);\n\n return new TransactionInstruction({\n keys,\n programId,\n data,\n });\n}\n\nexport function voterStakeRegistryCreateVoter(\n programId: PublicKey,\n registrar: PublicKey,\n voter: PublicKey,\n voterWeightRecord: PublicKey,\n voterAuthority: PublicKey,\n payer: PublicKey,\n\n voterBump: number,\n voterWeightRecordBump: number,\n): TransactionInstruction {\n const dataLayout = struct([u8(\"voterBump\"), u8(\"voterWeightRecordBump\")]);\n\n const keys = [\n { pubkey: registrar, isSigner: false, isWritable: false },\n { pubkey: voter, isSigner: false, isWritable: true },\n { pubkey: voterAuthority, isSigner: true, isWritable: false },\n { pubkey: voterWeightRecord, isSigner: false, isWritable: true },\n { pubkey: payer, isSigner: true, isWritable: true },\n { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },\n { pubkey: RENT_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: INSTRUCTION_PROGRAM_ID, isSigner: false, isWritable: false },\n ];\n\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode({ voterBump, voterWeightRecordBump }, data);\n const aData = Buffer.from([...anchorDataBuf.voterStakeRegistryCreateVoter, ...data]);\n\n return new TransactionInstruction({\n keys,\n programId,\n data: aData,\n });\n}\n\nexport function voterStakeRegistryCreateDepositEntry(\n programId: PublicKey,\n registrar: PublicKey,\n voter: PublicKey,\n voterVault: PublicKey,\n voterAuthority: PublicKey,\n payer: PublicKey,\n depositMint: PublicKey,\n\n depositEntryIndex: number,\n kind: number,\n startTs: BN | undefined,\n periods: number,\n allowClawback: boolean,\n): TransactionInstruction {\n const dataLayout = struct([\n u8(\"depositEntryIndex\"),\n u8(\"kind\"),\n u8(\"option\"),\n u64(\"startTs\"),\n u32(\"periods\"),\n bool(\"allowClawback\"),\n ]);\n\n const keys = [\n { pubkey: registrar, isSigner: false, isWritable: false },\n { pubkey: voter, isSigner: false, isWritable: true },\n { pubkey: voterVault, isSigner: false, isWritable: true },\n { pubkey: voterAuthority, isSigner: true, isWritable: false },\n { pubkey: payer, isSigner: true, isWritable: true },\n { pubkey: depositMint, isSigner: false, isWritable: false },\n { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },\n { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: RENT_PROGRAM_ID, isSigner: false, isWritable: false },\n ];\n\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode(\n {\n depositEntryIndex,\n kind,\n option: startTs === undefined ? 0 : 1,\n startTs: startTs!,\n periods,\n allowClawback,\n },\n data,\n );\n const aData = Buffer.from([...anchorDataBuf.voterStakeRegistryCreateDepositEntry, ...data]);\n\n return new TransactionInstruction({\n keys,\n programId,\n data: aData,\n });\n}\n\nexport async function makeDepositTokenInstruction({\n connection,\n programId,\n governanceProgramId,\n voteWeightAddinProgramId,\n realm,\n communityTokenMint,\n owner,\n poolId,\n tokenProgram,\n}: {\n connection: Connection;\n programId: PublicKey;\n governanceProgramId: PublicKey;\n voteWeightAddinProgramId: PublicKey;\n realm: PublicKey;\n communityTokenMint: PublicKey;\n owner: PublicKey;\n poolId: PublicKey;\n tokenProgram?: PublicKey;\n}): Promise<TransactionInstruction[]> {\n const registrar = getRegistrarAddress(voteWeightAddinProgramId, realm, communityTokenMint).publicKey;\n const ownerPda = getAssociatedLedgerAccount({ programId, poolId, owner, version: 3 });\n const ownerAccountInfo = await connection.getAccountInfo(ownerPda);\n if (ownerAccountInfo === null) {\n throw Error(\"user is not staker\");\n }\n const ownerInfo = farmLedgerLayoutV3_2.decode(ownerAccountInfo.data);\n const mintAmount = ownerInfo.deposited.sub(ownerInfo.voteLockedBalance);\n console.log(\"amount\", mintAmount.toString());\n if (mintAmount.eq(new BN(0))) {\n throw Error(\"user do not has new stake amount\");\n }\n\n const votingMint = getVotingTokenMint(programId, poolId).publicKey;\n const votingMintAuthority = getVotingMintAuthority(programId, poolId).publicKey;\n const { publicKey: voter, nonce: voterBump } = getVoterAddress(voteWeightAddinProgramId, registrar, owner);\n const voterVault = getATAAddress(voter, votingMint, tokenProgram).publicKey;\n\n const { publicKey: voterWeightRecord, nonce: voterWeightRecordBump } = getVoterWeightRecordAddress(\n voteWeightAddinProgramId,\n registrar,\n owner,\n );\n\n const tokenOwnerRecordAddress = getTokenOwnerRecordAddress(\n governanceProgramId,\n realm,\n communityTokenMint,\n owner,\n ).publicKey;\n\n const instructions: TransactionInstruction[] = [];\n\n const depositToken = getATAAddress(owner, votingMint, tokenProgram).publicKey;\n const depositTokenAccountInfo = await connection.getAccountInfo(depositToken);\n if (depositTokenAccountInfo === null) {\n instructions.push(createAssociatedTokenAccountIdempotentInstruction(owner, depositToken, owner, votingMint));\n }\n const voterAccountInfo = await connection.getAccountInfo(voter);\n if (voterAccountInfo === null) {\n const createTokenOwnerRecodeIns = governanceCreateTokenOwnerRecord(\n governanceProgramId,\n realm,\n owner,\n communityTokenMint,\n owner,\n tokenOwnerRecordAddress,\n );\n\n instructions.push(\n createTokenOwnerRecodeIns,\n voterStakeRegistryCreateVoter(\n voteWeightAddinProgramId,\n registrar,\n voter,\n voterWeightRecord,\n owner,\n owner,\n voterBump,\n voterWeightRecordBump,\n ),\n );\n }\n\n const { index: depositEntryIndex, isInit: depositEntryInit } = await getDepositEntryIndex(\n connection,\n registrar,\n voter,\n votingMint,\n );\n if (!depositEntryInit) {\n instructions.push(\n voterStakeRegistryCreateDepositEntry(\n voteWeightAddinProgramId,\n registrar,\n voter,\n voterVault,\n owner,\n owner,\n votingMint,\n\n depositEntryIndex,\n 0,\n undefined,\n 0,\n false,\n ),\n );\n }\n\n instructions.push(\n voterStakeRegistryDeposit(\n voteWeightAddinProgramId,\n registrar,\n voter,\n voterVault,\n depositToken,\n owner,\n\n ownerPda,\n poolId,\n votingMint,\n votingMintAuthority,\n programId,\n\n depositEntryIndex,\n mintAmount,\n ),\n voterStakeRegistryUpdateVoterWeightRecord(voteWeightAddinProgramId, registrar, voter, voterWeightRecord),\n );\n\n return instructions;\n}\n\nexport async function makeWithdrawTokenInstruction({\n connection,\n programId,\n governanceProgramId,\n voteWeightAddinProgramId,\n realm,\n communityTokenMint,\n owner,\n poolId,\n tokenProgram,\n}: {\n connection: Connection;\n programId: PublicKey;\n\n governanceProgramId: PublicKey;\n voteWeightAddinProgramId: PublicKey;\n realm: PublicKey;\n communityTokenMint: PublicKey;\n owner: PublicKey;\n poolId: PublicKey;\n tokenProgram?: PublicKey;\n}): Promise<TransactionInstruction[]> {\n const registrar = getRegistrarAddress(voteWeightAddinProgramId, realm, communityTokenMint).publicKey;\n const ownerPda = getAssociatedLedgerAccount({ programId, poolId, owner, version: 3 });\n const ownerAccountInfo = await connection.getAccountInfo(ownerPda);\n if (ownerAccountInfo === null) {\n throw Error(\"user is not staker\");\n }\n const ownerInfo = farmLedgerLayoutV3_2.decode(ownerAccountInfo.data);\n if (ownerInfo.voteLockedBalance.eq(new BN(0))) {\n throw Error(\"user has vote locked balance = 0\");\n }\n\n const votingMint = getVotingTokenMint(programId, poolId).publicKey;\n const votingMintAuthority = getVotingMintAuthority(programId, poolId).publicKey;\n const { publicKey: voter } = getVoterAddress(voteWeightAddinProgramId, registrar, owner);\n const voterVault = getATAAddress(voter, votingMint, tokenProgram).publicKey;\n const { publicKey: voterWeightRecord } = getVoterWeightRecordAddress(voteWeightAddinProgramId, registrar, owner);\n\n const tokenOwnerRecordAddress = getTokenOwnerRecordAddress(\n governanceProgramId,\n realm,\n communityTokenMint,\n owner,\n ).publicKey;\n\n const instructions: TransactionInstruction[] = [];\n\n const { index: depositEntryIndex, isInit: depositEntryInit } = await getDepositEntryIndex(\n connection,\n registrar,\n voter,\n votingMint,\n );\n if (!depositEntryInit) throw Error(\"deposit entry index check error\");\n\n instructions.push(\n voterStakeRegistryWithdraw(\n voteWeightAddinProgramId,\n registrar,\n voter,\n owner,\n tokenOwnerRecordAddress,\n voterWeightRecord,\n voterVault,\n getATAAddress(owner, votingMint, tokenProgram).publicKey,\n ownerPda,\n poolId,\n votingMint,\n votingMintAuthority,\n programId,\n\n depositEntryIndex,\n ownerInfo.voteLockedBalance,\n ),\n );\n\n return instructions;\n}\n\nexport function makeRestartRewardInstruction({\n payer,\n rewardVault,\n userRewardTokenPub,\n farmKeys,\n rewardInfo,\n}: {\n payer: PublicKey;\n rewardVault: PublicKey;\n userRewardTokenPub: PublicKey;\n farmKeys: {\n id: PublicKey;\n programId: PublicKey;\n lpVault: PublicKey;\n };\n rewardInfo: {\n openTime: number;\n endTime: number;\n perSecond: string;\n };\n}): TransactionInstruction {\n const data = Buffer.alloc(farmRewardRestartLayout.span);\n farmRewardRestartLayout.encode(\n {\n instruction: 3,\n rewardReopenTime: parseBigNumberish(rewardInfo.openTime),\n rewardEndTime: parseBigNumberish(rewardInfo.endTime),\n rewardPerSecond: parseBigNumberish(rewardInfo.perSecond),\n },\n data,\n );\n\n const keys = [\n accountMeta({ pubkey: TOKEN_PROGRAM_ID, isWritable: false }),\n accountMeta({ pubkey: farmKeys.id }),\n accountMeta({ pubkey: farmKeys.lpVault, isWritable: false }),\n accountMeta({ pubkey: rewardVault }),\n accountMeta({ pubkey: userRewardTokenPub! }),\n accountMeta({ pubkey: payer, isWritable: false, isSigner: true }),\n ];\n\n return new TransactionInstruction({ programId: farmKeys.programId, keys, data });\n}\n\nexport function makeAddNewRewardInstruction({\n payer,\n userRewardTokenPub,\n farmKeys,\n rewardVault,\n rewardInfo,\n}: {\n payer: PublicKey;\n userRewardTokenPub: PublicKey;\n rewardVault: PublicKey;\n farmKeys: {\n id: PublicKey;\n programId: PublicKey;\n authority: PublicKey;\n };\n rewardInfo: {\n mint: PublicKey;\n openTime: number;\n endTime: number;\n perSecond: string;\n rewardType: RewardType;\n };\n}): TransactionInstruction {\n const data = Buffer.alloc(farmAddRewardLayout.span);\n farmAddRewardLayout.encode(\n {\n instruction: 4,\n isSet: new BN(1),\n rewardPerSecond: parseBigNumberish(rewardInfo.perSecond),\n rewardOpenTime: parseBigNumberish(rewardInfo.openTime),\n rewardEndTime: parseBigNumberish(rewardInfo.endTime),\n rewardType: parseBigNumberish(poolTypeV6[rewardInfo.rewardType]),\n },\n data,\n );\n\n const keys = [\n ...commonSystemAccountMeta,\n accountMeta({ pubkey: farmKeys.id }),\n accountMeta({ pubkey: farmKeys.authority, isWritable: false }),\n accountMeta({ pubkey: rewardInfo.mint, isWritable: false }),\n accountMeta({ pubkey: rewardVault }),\n accountMeta({ pubkey: userRewardTokenPub! }),\n accountMeta({ pubkey: payer, isWritable: false, isSigner: true }),\n ];\n\n return new TransactionInstruction({ programId: farmKeys.programId, keys, data });\n}\n\nexport function makeDepositWithdrawInstruction(params: {\n instruction: number;\n amount: BN;\n farmInfo: { id: string; programId: string };\n farmKeys: FormatFarmKeyOut;\n lpAccount: PublicKey;\n owner: PublicKey;\n rewardAccounts: PublicKey[];\n deposit?: boolean;\n version: 3 | 5 | 6;\n}): TransactionInstruction {\n const { farmInfo, farmKeys, version, lpAccount, rewardAccounts, owner, instruction, amount, deposit } = params;\n\n const [programId, id] = [new PublicKey(farmInfo.programId), new PublicKey(farmInfo.id)];\n\n const ledgerAddress = getAssociatedLedgerAccount({\n programId,\n poolId: id,\n owner,\n version,\n });\n\n const data = Buffer.alloc(dwLayout.span);\n dwLayout.encode(\n {\n instruction,\n amount,\n },\n data,\n );\n\n const keys =\n version === 6\n ? [\n accountMeta({ pubkey: TOKEN_PROGRAM_ID, isWritable: false }),\n ...(deposit ? [accountMeta({ pubkey: SystemProgram.programId, isWritable: false })] : []),\n accountMeta({ pubkey: id }),\n accountMeta({ pubkey: new PublicKey(farmKeys.authority), isWritable: false }),\n accountMeta({ pubkey: new PublicKey(farmKeys.lpVault) }),\n accountMeta({ pubkey: ledgerAddress }),\n accountMeta({ pubkey: owner, isWritable: false, isSigner: true }),\n accountMeta({ pubkey: lpAccount }),\n ]\n : [\n accountMeta({ pubkey: id }),\n accountMeta({ pubkey: new PublicKey(farmKeys.authority), isWritable: false }),\n accountMeta({ pubkey: ledgerAddress }),\n accountMeta({ pubkey: owner, isWritable: false, isSigner: true }),\n accountMeta({ pubkey: lpAccount }),\n accountMeta({ pubkey: new PublicKey(farmKeys.lpVault) }),\n accountMeta({ pubkey: rewardAccounts[0] }),\n accountMeta({ pubkey: new PublicKey(farmKeys.rewardInfos[0].vault) }),\n // system\n accountMeta({ pubkey: SYSVAR_CLOCK_PUBKEY, isWritable: false }),\n accountMeta({ pubkey: TOKEN_PROGRAM_ID, isWritable: false }),\n ];\n\n if (version === 5) {\n for (let index = 1; index < farmKeys.rewardInfos.length; index++) {\n keys.push(accountMeta({ pubkey: rewardAccounts[index] }));\n keys.push(accountMeta({ pubkey: new PublicKey(farmKeys.rewardInfos[index].vault) }));\n }\n }\n\n if (version === 6) {\n for (let index = 0; index < farmKeys.rewardInfos.length; index++) {\n keys.push(accountMeta({ pubkey: new PublicKey(farmKeys.rewardInfos[index].vault) }));\n keys.push(accountMeta({ pubkey: rewardAccounts[index] }));\n }\n }\n\n return new TransactionInstruction({ programId, keys, data });\n}\n\ninterface DepositWithdrawParams {\n amount: BN;\n farmInfo: { id: string; programId: string };\n farmKeys: FormatFarmKeyOut;\n lpAccount: PublicKey;\n owner: PublicKey;\n rewardAccounts: PublicKey[];\n userAuxiliaryLedgers?: PublicKey[];\n}\n\nexport function makeWithdrawInstructionV6(params: DepositWithdrawParams): TransactionInstruction {\n const { farmInfo, farmKeys, lpAccount, rewardAccounts, owner, amount } = params;\n const [programId, id] = [new PublicKey(farmInfo.programId), new PublicKey(farmInfo.id)];\n\n const ledgerAddress = getAssociatedLedgerAccount({\n programId,\n poolId: id,\n owner,\n version: 6,\n });\n\n const data = Buffer.alloc(dwLayout.span);\n dwLayout.encode(\n {\n instruction: 2,\n amount: parseBigNumberish(amount),\n },\n data,\n );\n\n const keys = [\n accountMeta({ pubkey: TOKEN_PROGRAM_ID, isWritable: false }),\n\n accountMeta({ pubkey: id }),\n\n accountMeta({ pubkey: new PublicKey(farmKeys.authority), isWritable: false }),\n accountMeta({ pubkey: new PublicKey(farmKeys.lpVault) }),\n accountMeta({ pubkey: ledgerAddress }),\n accountMeta({ pubkey: owner, isWritable: false, isSigner: true }),\n accountMeta({ pubkey: lpAccount }),\n ];\n\n for (let index = 0; index < farmKeys.rewardInfos.length; index++) {\n keys.push(accountMeta({ pubkey: new PublicKey(farmKeys.rewardInfos[index].vault) }));\n keys.push(accountMeta({ pubkey: rewardAccounts[index] }));\n }\n\n return new TransactionInstruction({ programId, keys, data });\n}\n\nexport function makeWithdrawInstructionV5(params: DepositWithdrawParams): TransactionInstruction {\n const { farmInfo, farmKeys, lpAccount, rewardAccounts, owner, amount, userAuxiliaryLedgers } = params;\n const [programId, id] = [new PublicKey(farmInfo.programId), new PublicKey(farmInfo.id)];\n\n const ledgerAddress = getAssociatedLedgerAccount({\n programId,\n poolId: id,\n owner,\n version: 5,\n });\n\n const data = Buffer.alloc(dwLayout.span);\n dwLayout.encode(\n {\n instruction: 12,\n amount: parseBigNumberish(amount),\n },\n data,\n );\n\n const keys = [\n accountMeta({ pubkey: id }),\n accountMeta({ pubkey: new PublicKey(farmKeys.authority), isWritable: false }),\n accountMeta({ pubkey: ledgerAddress }),\n accountMeta({ pubkey: owner, isWritable: false, isSigner: true }),\n accountMeta({ pubkey: lpAccount }),\n accountMeta({ pubkey: new PublicKey(farmKeys.lpVault) }),\n accountMeta({ pubkey: rewardAccounts[0] }),\n accountMeta({ pubkey: new PublicKey(farmKeys.rewardInfos[0].vault) }),\n // system\n accountMeta({ pubkey: SYSVAR_CLOCK_PUBKEY, isWritable: false }),\n accountMeta({ pubkey: TOKEN_PROGRAM_ID, isWritable: false }),\n ];\n\n for (let index = 1; index < farmKeys.rewardInfos.length; index++) {\n keys.push(accountMeta({ pubkey: rewardAccounts[index] }));\n keys.push(accountMeta({ pubkey: new PublicKey(farmKeys.rewardInfos[index].vault) }));\n }\n\n if (userAuxiliaryLedgers) {\n for (const auxiliaryLedger of userAuxiliaryLedgers) {\n keys.push(accountMeta({ pubkey: auxiliaryLedger }));\n }\n }\n\n return new TransactionInstruction({ programId, keys, data });\n}\n\nexport function makeWithdrawInstructionV4(params: DepositWithdrawParams): TransactionInstruction {\n const { farmInfo, farmKeys, lpAccount, rewardAccounts, owner, amount, userAuxiliaryLedgers } = params;\n const [programId, id] = [new PublicKey(farmInfo.programId), new PublicKey(farmInfo.id)];\n\n const dataLayout = struct([u8('instruction'), u64('amount')])\n\n const keys = [\n accountMeta({ pubkey: id }),\n accountMeta({ pubkey: new PublicKey(farmKeys.authority), isWritable: false }),\n accountMeta({ pubkey: userAuxiliaryLedgers![0] }),\n accountMeta({ pubkey: owner, isSigner: true, isWritable: false }),\n accountMeta({ pubkey: lpAccount }),\n accountMeta({ pubkey: new PublicKey(farmKeys.lpVault) }),\n accountMeta({ pubkey: rewardAccounts[0] }),\n accountMeta({ pubkey: new PublicKey(farmKeys.rewardInfos[0].vault) }),\n accountMeta({ pubkey: SYSVAR_CLOCK_PUBKEY, isWritable: false }),\n accountMeta({ pubkey: TOKEN_PROGRAM_ID, isWritable: false }),\n accountMeta({ pubkey: rewardAccounts[1] }),\n accountMeta({ pubkey: new PublicKey(farmKeys.rewardInfos[1].vault) }),\n ]\n\n const data = Buffer.alloc(dataLayout.span)\n dataLayout.encode(\n {\n instruction: 2,\n amount\n },\n data\n )\n\n return new TransactionInstruction({\n keys,\n programId,\n data\n })\n}\n\nexport function makeWithdrawInstructionV3(params: DepositWithdrawParams): TransactionInstruction {\n const { farmInfo, farmKeys, lpAccount, rewardAccounts, owner, amount, userAuxiliaryLedgers } = params;\n const [programId, id] = [new PublicKey(farmInfo.programId), new PublicKey(farmInfo.id)];\n\n const ledgerAddress = getAssociatedLedgerAccount({\n programId,\n poolId: id,\n owner,\n version: 3,\n });\n\n const data = Buffer.alloc(dwLayout.span);\n dwLayout.encode(\n {\n instruction: 11,\n amount: parseBigNumberish(amount),\n },\n data,\n );\n\n const keys = [\n accountMeta({ pubkey: id }),\n accountMeta({ pubkey: new PublicKey(farmKeys.authority), isWritable: false }),\n accountMeta({ pubkey: ledgerAddress }),\n accountMeta({ pubkey: owner, isWritable: false, isSigner: true }),\n accountMeta({ pubkey: lpAccount }),\n accountMeta({ pubkey: new PublicKey(farmKeys.lpVault) }),\n accountMeta({ pubkey: rewardAccounts[0] }),\n accountMeta({ pubkey: new PublicKey(farmKeys.rewardInfos[0].vault) }),\n // system\n accountMeta({ pubkey: SYSVAR_CLOCK_PUBKEY, isWritable: false }),\n accountMeta({ pubkey: TOKEN_PROGRAM_ID, isWritable: false }),\n ];\n\n if (userAuxiliaryLedgers) {\n for (const auxiliaryLedger of userAuxiliaryLedgers) {\n keys.push(accountMeta({ pubkey: auxiliaryLedger }));\n }\n }\n\n return new TransactionInstruction({ programId, keys, data });\n}\n\nexport function makeDepositInstructionV3(params: DepositWithdrawParams): TransactionInstruction {\n const { farmInfo, farmKeys, lpAccount, rewardAccounts, owner, amount, userAuxiliaryLedgers } = params;\n const [programId, id] = [new PublicKey(farmInfo.programId), new PublicKey(farmInfo.id)];\n\n const ledgerAddress = getAssociatedLedgerAccount({\n programId,\n poolId: id,\n owner,\n version: 3,\n });\n\n const data = Buffer.alloc(dwLayout.span);\n dwLayout.encode(\n {\n instruction: 10,\n amount: parseBigNumberish(amount),\n },\n data,\n );\n\n const keys = [\n accountMeta({ pubkey: id }),\n accountMeta({ pubkey: new PublicKey(farmKeys.authority), isWritable: false }),\n accountMeta({ pubkey: ledgerAddress }),\n accountMeta({ pubkey: owner, isWritable: false, isSigner: true }),\n accountMeta({ pubkey: lpAccount }),\n accountMeta({ pubkey: new PublicKey(farmKeys.lpVault) }),\n accountMeta({ pubkey: rewardAccounts[0] }),\n accountMeta({ pubkey: new PublicKey(farmKeys.rewardInfos[0].vault) }),\n // system\n accountMeta({ pubkey: SYSVAR_CLOCK_PUBKEY, isWritable: false }),\n accountMeta({ pubkey: TOKEN_PROGRAM_ID, isWritable: false }),\n ];\n\n if (userAuxiliaryLedgers) {\n for (const auxiliaryLedger of userAuxiliaryLedgers) {\n keys.push(accountMeta({ pubkey: auxiliaryLedger }));\n }\n }\n\n return new TransactionInstruction({ programId, keys, data });\n}\n\nexport function makeDepositInstructionV5(params: DepositWithdrawParams): TransactionInstruction {\n const { farmInfo, farmKeys, lpAccount, rewardAccounts, owner, amount, userAuxiliaryLedgers } = params;\n const [programId, id] = [new PublicKey(farmInfo.programId), new PublicKey(farmInfo.id)];\n\n const ledgerAddress = getAssociatedLedgerAccount({\n programId,\n poolId: id,\n owner,\n version: 5,\n });\n\n const data = Buffer.alloc(dwLayout.span);\n dwLayout.encode(\n {\n instruction: 11,\n amount: parseBigNumberish(amount),\n },\n data,\n );\n\n const keys = [\n accountMeta({ pubkey: id }),\n accountMeta({ pubkey: new PublicKey(farmKeys.authority), isWritable: false }),\n accountMeta({ pubkey: ledgerAddress }),\n accountMeta({ pubkey: owner, isWritable: false, isSigner: true }),\n accountMeta({ pubkey: lpAccount }),\n accountMeta({ pubkey: new PublicKey(farmKeys.lpVault) }),\n accountMeta({ pubkey: rewardAccounts[0] }),\n accountMeta({ pubkey: new PublicKey(farmKeys.rewardInfos[0].vault) }),\n // system\n accountMeta({ pubkey: SYSVAR_CLOCK_PUBKEY, isWritable: false }),\n accountMeta({ pubkey: TOKEN_PROGRAM_ID, isWritable: false }),\n ];\n\n for (let index = 1; index < farmKeys.rewardInfos.length; index++) {\n keys.push(accountMeta({ pubkey: rewardAccounts[index] }));\n keys.push(accountMeta({ pubkey: new PublicKey(farmKeys.rewardInfos[index].vault) }));\n }\n\n if (userAuxiliaryLedgers) {\n for (const auxiliaryLedger of userAuxiliaryLedgers) {\n keys.push(accountMeta({ pubkey: auxiliaryLedger }));\n }\n }\n\n return new TransactionInstruction({ programId, keys, data });\n}\n\nexport function makeDepositInstructionV6(params: DepositWithdrawParams): TransactionInstruction {\n const { farmInfo, farmKeys, lpAccount, rewardAccounts, owner, amount } = params;\n const [programId, id] = [new PublicKey(farmInfo.programId), new PublicKey(farmInfo.id)];\n\n const ledgerAddress = getAssociatedLedgerAccount({\n programId,\n poolId: id,\n owner,\n version: 6,\n });\n\n const data = Buffer.alloc(dwLayout.span);\n dwLayout.encode(\n {\n instruction: 1,\n amount: parseBigNumberish(amount),\n },\n data,\n );\n\n const keys = [\n accountMeta({ pubkey: TOKEN_PROGRAM_ID, isWritable: false }),\n accountMeta({ pubkey: SystemProgram.programId, isWritable: false }),\n accountMeta({ pubkey: id }),\n accountMeta({ pubkey: new PublicKey(farmKeys.authority), isWritable: false }),\n accountMeta({ pubkey: new PublicKey(farmKeys.lpVault) }),\n accountMeta({ pubkey: ledgerAddress }),\n accountMeta({ pubkey: owner, isWritable: false, isSigner: true }),\n accountMeta({ pubkey: lpAccount }),\n ];\n\n for (let index = 0; index < farmKeys.rewardInfos.length; index++) {\n keys.push(accountMeta({ pubkey: new PublicKey(farmKeys.rewardInfos[index].vault) }));\n keys.push(accountMeta({ pubkey: rewardAccounts[index] }));\n }\n\n return new TransactionInstruction({ programId, keys, data });\n}\n","import { ApiV3PoolInfoConcentratedItem, ApiV3Token, ClmmKeys } from \"@/api/type\";\nimport { InstructionType, MEMO_PROGRAM_ID, METADATA_PROGRAM_ID, RENT_PROGRAM_ID, getATAAddress } from \"@/common\";\nimport { createLogger } from \"@/common/logger\";\nimport { bool, s32, struct, u128, u16, u64, u8 } from \"@/marshmallow\";\nimport { ReturnTypeMakeInstructions } from \"@/raydium/type\";\nimport { ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_2022_PROGRAM_ID, TOKEN_PROGRAM_ID } from \"@solana/spl-token\";\nimport { Connection, Keypair, PublicKey, Signer, SystemProgram, TransactionInstruction } from \"@solana/web3.js\";\nimport BN from \"bn.js\";\nimport { ObservationLayout, PersonalPositionLayout } from \"./layout\";\nimport {\n getPdaExBitmapAccount,\n getPdaLockClPositionIdV2,\n getPdaLockPositionId,\n getPdaMetadataKey,\n getPdaObservationAccount,\n getPdaOperationAccount,\n getPdaPermission,\n getPdaPermissionedPoolId,\n getPdaPersonalPositionAddress,\n getPdaPoolId,\n getPdaPoolRewardVaultId,\n getPdaPoolVaultId,\n getPdaProtocolPositionAddress,\n getPdaTickArrayAddress,\n} from \"./libraries/pda\";\nimport {\n ClmmLockAddress,\n ClmmPoolPersonalPosition,\n ClosePositionExtInfo,\n InitRewardExtInfo,\n ManipulateLiquidityExtInfo,\n OpenPositionFromBaseExtInfo,\n OpenPositionFromLiquidityExtInfo,\n SimpleClmmPoolInfo,\n} from \"./type\";\n\nimport { sha256 } from \"js-sha256\";\nimport { PoolUtil } from \"./libraries\";\nimport { BN_ZERO } from \"./libraries/constants\";\nimport { TickArrayUtil } from \"./libraries/tickArrayUtil\";\n\nfunction getAnchorByte(ixName: string): Buffer {\n const preimage = `global:${ixName}`;\n return Buffer.from(sha256.digest(preimage)).slice(0, 8);\n}\n\nObservationLayout.span; // do not delete this line\n\nconst logger = createLogger(\"Raydium_Clmm\");\n\nconst insId = {\n createPool: getAnchorByte(\"create_pool\"),\n createCustomizablePool: getAnchorByte(\"create_customizable_pool\"), // todo\n createPermissionedPool: getAnchorByte(\"create_permissioned_pool\"),\n\n openPositionV2: getAnchorByte(\"open_position_v2\"),\n openPositionWithToken22Nft: getAnchorByte(\"open_position_with_token22_nft\"),\n closePosition: getAnchorByte(\"close_position\"),\n increaseLiquidityV2: getAnchorByte(\"increase_liquidity_v2\"),\n decreaseLiquidityV2: getAnchorByte(\"decrease_liquidity_v2\"),\n\n initializeReward: getAnchorByte(\"initialize_reward\"),\n setRewardParams: getAnchorByte(\"set_reward_params\"),\n updateRewardInfos: getAnchorByte(\"update_reward_infos\"),\n collectRemainingRewards: getAnchorByte(\"collect_remaining_rewards\"),\n\n swapV2: getAnchorByte(\"swap_v2\"),\n\n openLimitOrder: getAnchorByte(\"open_limit_order\"), // todo\n increaseLimitOrder: getAnchorByte(\"increase_limit_order\"), // todo\n decreaseLimitOrder: getAnchorByte(\"decrease_limit_order\"), // todo\n settleLimitOrder: getAnchorByte(\"settle_limit_order\"), // todo\n closeLimitOrder: getAnchorByte(\"close_limit_order\"), // todo\n};\n\nconst lockInsDataBuf = [188, 37, 179, 131, 82, 150, 84, 73];\nconst lockHarvestInsDataBuf = [16, 72, 250, 198, 14, 162, 212, 19];\n\ninterface CreatePoolInstruction {\n connection: Connection;\n programId: PublicKey;\n owner: PublicKey;\n mintA: ApiV3Token;\n mintB: ApiV3Token;\n ammConfigId: PublicKey;\n initialPriceX64: BN;\n forerunCreate?: boolean;\n extendMintAccount?: PublicKey[];\n}\n\nexport class ClmmInstrument {\n static createPoolInstruction(\n programId: PublicKey,\n poolId: PublicKey,\n poolCreator: PublicKey,\n ammConfigId: PublicKey,\n observationId: PublicKey,\n mintA: PublicKey,\n vaultA: PublicKey,\n mintProgramIdA: PublicKey,\n mintB: PublicKey,\n vaultB: PublicKey,\n mintProgramIdB: PublicKey,\n tickArrayBitmap: PublicKey,\n sqrtPriceX64: BN,\n supperMintEx: PublicKey[] | undefined,\n ): TransactionInstruction {\n const dataLayout = struct([u128(\"sqrtPriceX64\"), u64(\"startTime\")]);\n\n const keys = [\n { pubkey: poolCreator, isSigner: true, isWritable: true },\n { pubkey: ammConfigId, isSigner: false, isWritable: false },\n { pubkey: poolId, isSigner: false, isWritable: true },\n { pubkey: mintA, isSigner: false, isWritable: false },\n { pubkey: mintB, isSigner: false, isWritable: false },\n { pubkey: vaultA, isSigner: false, isWritable: true },\n { pubkey: vaultB, isSigner: false, isWritable: true },\n { pubkey: observationId, isSigner: false, isWritable: true },\n { pubkey: tickArrayBitmap, isSigner: false, isWritable: true },\n { pubkey: mintProgramIdA, isSigner: false, isWritable: false },\n { pubkey: mintProgramIdB, isSigner: false, isWritable: false },\n { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },\n { pubkey: RENT_PROGRAM_ID, isSigner: false, isWritable: false },\n ...(supperMintEx ?? []).map((i) => ({ pubkey: i, isSigner: false, isWritable: false })),\n ];\n\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode({ sqrtPriceX64, startTime: BN_ZERO }, data);\n const aData = Buffer.from([...insId.createPool, ...data]);\n\n return new TransactionInstruction({\n keys,\n programId,\n data: aData,\n });\n }\n\n static createCustomizablePoolInstruction(\n programId: PublicKey,\n poolId: PublicKey,\n poolCreator: PublicKey,\n ammConfig: PublicKey,\n mintA: PublicKey,\n mintB: PublicKey,\n vaultA: PublicKey,\n vaultB: PublicKey,\n observationId: PublicKey,\n tickArrayBitmap: PublicKey,\n mintProgramIdA: PublicKey,\n mintProgramIdB: PublicKey,\n sqrtPriceX64: BN,\n collectFeeOn: number, // new\n supperMintEx: PublicKey[],\n dynamicFeeConfig?: PublicKey, // new\n ): TransactionInstruction {\n const dataLayout = struct([u128(\"sqrtPriceX64\"), u8(\"collectFeeOn\"), bool(\"enableDynamicFee\")]);\n\n const keys = [\n { pubkey: poolCreator, isSigner: true, isWritable: true },\n { pubkey: ammConfig, isSigner: false, isWritable: false },\n { pubkey: poolId, isSigner: false, isWritable: true },\n { pubkey: mintA, isSigner: false, isWritable: false },\n { pubkey: mintB, isSigner: false, isWritable: false },\n { pubkey: vaultA, isSigner: false, isWritable: true },\n { pubkey: vaultB, isSigner: false, isWritable: true },\n { pubkey: observationId, isSigner: false, isWritable: true },\n { pubkey: tickArrayBitmap, isSigner: false, isWritable: true },\n { pubkey: mintProgramIdA, isSigner: false, isWritable: false },\n { pubkey: mintProgramIdB, isSigner: false, isWritable: false },\n { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },\n { pubkey: RENT_PROGRAM_ID, isSigner: false, isWritable: false },\n ...supperMintEx.map((i) => ({ pubkey: i, isSigner: false, isWritable: false })),\n ...(dynamicFeeConfig ? [{ pubkey: dynamicFeeConfig, isSigner: false, isWritable: false }] : []),\n ];\n\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode({ sqrtPriceX64, collectFeeOn, enableDynamicFee: dynamicFeeConfig !== undefined }, data);\n const aData = Buffer.from([...insId.createCustomizablePool, ...data]);\n\n return new TransactionInstruction({\n keys,\n programId,\n data: aData,\n });\n }\n\n static createPermissionedPoolInstruction(\n programId: PublicKey,\n payer: PublicKey,\n poolCreator: PublicKey,\n permission: PublicKey,\n ammConfig: PublicKey,\n poolId: PublicKey,\n mintA: PublicKey,\n mintB: PublicKey,\n vaultA: PublicKey,\n vaultB: PublicKey,\n observationId: PublicKey,\n tickArrayBitmap: PublicKey,\n mintProgramIdA: PublicKey,\n mintProgramIdB: PublicKey,\n sqrtPriceX64: BN,\n collectFeeOn: number,\n seedIndex: number,\n supperMintEx: PublicKey[],\n dynamicFeeConfig?: PublicKey,\n ): TransactionInstruction {\n const dataLayout = struct([u128(\"sqrtPriceX64\"), u8(\"collectFeeOn\"), bool(\"enableDynamicFee\"), u16(\"seedIndex\")]);\n\n const keys = [\n { pubkey: payer, isSigner: true, isWritable: true },\n { pubkey: poolCreator, isSigner: false, isWritable: false },\n { pubkey: permission, isSigner: false, isWritable: false },\n { pubkey: ammConfig, isSigner: false, isWritable: false },\n { pubkey: poolId, isSigner: false, isWritable: true },\n { pubkey: mintA, isSigner: false, isWritable: false },\n { pubkey: mintB, isSigner: false, isWritable: false },\n { pubkey: vaultA, isSigner: false, isWritable: true },\n { pubkey: vaultB, isSigner: false, isWritable: true },\n { pubkey: observationId, isSigner: false, isWritable: true },\n { pubkey: tickArrayBitmap, isSigner: false, isWritable: true },\n { pubkey: mintProgramIdA, isSigner: false, isWritable: false },\n { pubkey: mintProgramIdB, isSigner: false, isWritable: false },\n { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },\n { pubkey: RENT_PROGRAM_ID, isSigner: false, isWritable: false },\n ...supperMintEx.map((i) => ({ pubkey: i, isSigner: false, isWritable: false })),\n ...(dynamicFeeConfig ? [{ pubkey: dynamicFeeConfig, isSigner: false, isWritable: false }] : []),\n ];\n\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode(\n { sqrtPriceX64, collectFeeOn, enableDynamicFee: dynamicFeeConfig !== undefined, seedIndex },\n data,\n );\n const aData = Buffer.from([...insId.createPermissionedPool, ...data]);\n\n return new TransactionInstruction({\n keys,\n programId,\n data: aData,\n });\n }\n\n static initializeRewardInstruction(\n programId: PublicKey,\n rewardFunder: PublicKey,\n poolId: PublicKey,\n operationId: PublicKey,\n ammConfigId: PublicKey,\n\n funderTokenAccount: PublicKey,\n tokenProgramId: PublicKey,\n rewardTokenMint: PublicKey,\n rewardTokenVault: PublicKey,\n\n openTime: BN,\n endTime: BN,\n emissionsPerSecondX64: BN,\n ): TransactionInstruction {\n const dataLayout = struct([u64(\"openTime\"), u64(\"endTime\"), u128(\"emissionsPerSecondX64\")]);\n\n const keys = [\n { pubkey: rewardFunder, isSigner: true, isWritable: true },\n { pubkey: funderTokenAccount, isSigner: false, isWritable: true },\n { pubkey: ammConfigId, isSigner: false, isWritable: false },\n\n { pubkey: poolId, isSigner: false, isWritable: true },\n { pubkey: operationId, isSigner: false, isWritable: false },\n { pubkey: rewardTokenMint, isSigner: false, isWritable: false },\n { pubkey: rewardTokenVault, isSigner: false, isWritable: true },\n\n { pubkey: tokenProgramId, isSigner: false, isWritable: false },\n { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },\n { pubkey: RENT_PROGRAM_ID, isSigner: false, isWritable: false },\n ];\n\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode({ openTime, endTime, emissionsPerSecondX64 }, data);\n const aData = Buffer.from([...insId.initializeReward, ...data]);\n\n return new TransactionInstruction({\n keys,\n programId,\n data: aData,\n });\n }\n\n static updateRewardInfosInstruction(programId: PublicKey, poolId: PublicKey): TransactionInstruction {\n const keys = [{ pubkey: poolId, isSigner: false, isWritable: true }];\n\n const aData = Buffer.from([...insId.updateRewardInfos]);\n\n return new TransactionInstruction({\n keys,\n programId,\n data: aData,\n });\n }\n\n static setRewardParamsInstruction(\n programId: PublicKey,\n authority: PublicKey,\n poolId: PublicKey,\n operationId: PublicKey,\n ammConfigId: PublicKey,\n\n ownerTokenAccount: PublicKey,\n rewardVault: PublicKey,\n rewardMint: PublicKey,\n\n rewardIndex: number,\n openTime: BN,\n endTime: BN,\n emissionsPerSecondX64: BN,\n ): TransactionInstruction {\n const dataLayout = struct([u8(\"rewardIndex\"), u128(\"emissionsPerSecondX64\"), u64(\"openTime\"), u64(\"endTime\")]);\n\n const keys = [\n { pubkey: authority, isSigner: true, isWritable: false },\n { pubkey: ammConfigId, isSigner: false, isWritable: false },\n { pubkey: poolId, isSigner: false, isWritable: true },\n { pubkey: operationId, isSigner: false, isWritable: false },\n { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: TOKEN_2022_PROGRAM_ID, isSigner: false, isWritable: false },\n\n { pubkey: rewardVault, isSigner: false, isWritable: true },\n { pubkey: ownerTokenAccount, isSigner: false, isWritable: true },\n { pubkey: rewardMint, isSigner: false, isWritable: true },\n ];\n\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode({ rewardIndex, emissionsPerSecondX64, openTime, endTime }, data);\n const aData = Buffer.from([...insId.setRewardParams, ...data]);\n\n return new TransactionInstruction({\n keys,\n programId,\n data: aData,\n });\n }\n\n static closePositionInstruction(\n programId: PublicKey,\n nftOwner: PublicKey,\n positionNftMint: PublicKey,\n positionNftAccount: PublicKey,\n personalPosition: PublicKey,\n nft2022: boolean,\n poolId?: PublicKey,\n ): TransactionInstruction {\n const keys = [\n { pubkey: nftOwner, isSigner: true, isWritable: true },\n { pubkey: positionNftMint, isSigner: false, isWritable: true },\n { pubkey: positionNftAccount, isSigner: false, isWritable: true },\n { pubkey: personalPosition, isSigner: false, isWritable: true },\n\n { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },\n { pubkey: nft2022 ? TOKEN_2022_PROGRAM_ID : TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n ];\n\n if (poolId) keys.push({ pubkey: poolId, isSigner: false, isWritable: true });\n\n const aData = Buffer.from([...insId.closePosition]);\n\n return new TransactionInstruction({\n keys,\n programId,\n data: aData,\n });\n }\n\n static openPositionV2Instruction(\n programId: PublicKey,\n payer: PublicKey,\n poolId: PublicKey,\n positionNftOwner: PublicKey,\n positionNftMint: PublicKey,\n positionNftAccount: PublicKey,\n metadataAccount: PublicKey,\n protocolPosition: PublicKey,\n tickArrayLower: PublicKey,\n tickArrayUpper: PublicKey,\n personalPosition: PublicKey,\n ownerVaultA: PublicKey,\n ownerVaultB: PublicKey,\n vaultA: PublicKey,\n vaultB: PublicKey,\n mintA: PublicKey,\n mintB: PublicKey,\n tickLower: number,\n tickUpper: number,\n tickArrayLowerStart: number,\n tickArrayUpperStart: number,\n liquidity: BN,\n amountMaxA: BN,\n amountMaxB: BN,\n withMetadata: boolean,\n baseFlag: boolean | null,\n\n exTickArrayBitmap?: PublicKey,\n ): TransactionInstruction {\n const dataLayout = struct([\n s32(\"tickLower\"),\n s32(\"tickUpper\"),\n s32(\"tickArrayLowerStart\"),\n s32(\"tickArrayUpperStart\"),\n u128(\"liquidity\"),\n u64(\"amountMaxA\"),\n u64(\"amountMaxB\"),\n bool(\"withMetadata\"),\n u8(\"optionBaseFlag\"),\n bool(\"baseFlag\"),\n ]);\n\n const keys = [\n { pubkey: payer, isSigner: true, isWritable: true },\n { pubkey: positionNftOwner, isSigner: false, isWritable: false },\n { pubkey: positionNftMint, isSigner: true, isWritable: true },\n { pubkey: positionNftAccount, isSigner: false, isWritable: true },\n { pubkey: metadataAccount, isSigner: false, isWritable: true },\n { pubkey: poolId, isSigner: false, isWritable: true },\n { pubkey: protocolPosition, isSigner: false, isWritable: false },\n { pubkey: tickArrayLower, isSigner: false, isWritable: true },\n { pubkey: tickArrayUpper, isSigner: false, isWritable: true },\n { pubkey: personalPosition, isSigner: false, isWritable: true },\n { pubkey: ownerVaultA, isSigner: false, isWritable: true },\n { pubkey: ownerVaultB, isSigner: false, isWritable: true },\n { pubkey: vaultA, isSigner: false, isWritable: true },\n { pubkey: vaultB, isSigner: false, isWritable: true },\n { pubkey: RENT_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },\n { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: METADATA_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: TOKEN_2022_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: mintA, isSigner: false, isWritable: false },\n { pubkey: mintB, isSigner: false, isWritable: false },\n\n ...(exTickArrayBitmap ? [{ pubkey: exTickArrayBitmap, isSigner: false, isWritable: true }] : []),\n ];\n\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode(\n {\n tickLower,\n tickUpper,\n tickArrayLowerStart,\n tickArrayUpperStart,\n liquidity,\n amountMaxA,\n amountMaxB,\n withMetadata,\n optionBaseFlag: baseFlag !== null ? 1 : 0,\n baseFlag: baseFlag ?? false,\n },\n data,\n );\n const aData = Buffer.from([...insId.openPositionV2, ...data]);\n\n return new TransactionInstruction({\n keys,\n programId,\n data: aData,\n });\n }\n\n static increaseLiquidityV2Instruction(\n programId: PublicKey,\n nftOwner: PublicKey,\n nftAccount: PublicKey,\n personalPosition: PublicKey,\n\n poolId: PublicKey,\n protocolPosition: PublicKey,\n tickArrayLower: PublicKey,\n tickArrayUpper: PublicKey,\n ownerVaultA: PublicKey,\n ownerVaultB: PublicKey,\n vaultA: PublicKey,\n vaultB: PublicKey,\n mintA: PublicKey,\n mintB: PublicKey,\n\n liquidity: BN,\n amountMaxA: BN,\n amountMaxB: BN,\n baseFlag: boolean | null,\n\n exTickArrayBitmap?: PublicKey,\n ): TransactionInstruction {\n const dataLayout = struct([\n u128(\"liquidity\"),\n u64(\"amountMaxA\"),\n u64(\"amountMaxB\"),\n u8(\"optionBaseFlag\"),\n bool(\"baseFlag\"),\n ]);\n\n const keys = [\n { pubkey: nftOwner, isSigner: true, isWritable: false },\n { pubkey: nftAccount, isSigner: false, isWritable: false },\n { pubkey: poolId, isSigner: false, isWritable: true },\n { pubkey: protocolPosition, isSigner: false, isWritable: false },\n { pubkey: personalPosition, isSigner: false, isWritable: true },\n { pubkey: tickArrayLower, isSigner: false, isWritable: true },\n { pubkey: tickArrayUpper, isSigner: false, isWritable: true },\n { pubkey: ownerVaultA, isSigner: false, isWritable: true },\n { pubkey: ownerVaultB, isSigner: false, isWritable: true },\n { pubkey: vaultA, isSigner: false, isWritable: true },\n { pubkey: vaultB, isSigner: false, isWritable: true },\n { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: TOKEN_2022_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: mintA, isSigner: false, isWritable: false },\n { pubkey: mintB, isSigner: false, isWritable: false },\n\n ...(exTickArrayBitmap ? [{ pubkey: exTickArrayBitmap, isSigner: false, isWritable: true }] : []),\n ];\n\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode(\n {\n liquidity,\n amountMaxA,\n amountMaxB,\n optionBaseFlag: baseFlag !== null ? 1 : 0,\n baseFlag: baseFlag ?? false,\n },\n data,\n );\n const aData = Buffer.from([...insId.increaseLiquidityV2, ...data]);\n\n return new TransactionInstruction({\n keys,\n programId,\n data: aData,\n });\n }\n\n static decreaseLiquidityV2Instruction(\n programId: PublicKey,\n nftOwner: PublicKey,\n nftAccount: PublicKey,\n personalPosition: PublicKey,\n\n poolId: PublicKey,\n protocolPosition: PublicKey,\n tickArrayLower: PublicKey,\n tickArrayUpper: PublicKey,\n ownerVaultA: PublicKey,\n ownerVaultB: PublicKey,\n vaultA: PublicKey,\n vaultB: PublicKey,\n mintA: PublicKey,\n mintB: PublicKey,\n rewardAccounts: {\n poolRewardVault: PublicKey;\n ownerRewardVault: PublicKey;\n rewardMint: PublicKey;\n }[],\n\n liquidity: BN,\n amountMinA: BN,\n amountMinB: BN,\n\n exTickArrayBitmap?: PublicKey,\n ): TransactionInstruction {\n const dataLayout = struct([u128(\"liquidity\"), u64(\"amountMinA\"), u64(\"amountMinB\")]);\n\n const keys = [\n { pubkey: nftOwner, isSigner: true, isWritable: false },\n { pubkey: nftAccount, isSigner: false, isWritable: false },\n { pubkey: personalPosition, isSigner: false, isWritable: true },\n { pubkey: poolId, isSigner: false, isWritable: true },\n { pubkey: protocolPosition, isSigner: false, isWritable: false },\n { pubkey: vaultA, isSigner: false, isWritable: true },\n { pubkey: vaultB, isSigner: false, isWritable: true },\n { pubkey: tickArrayLower, isSigner: false, isWritable: true },\n { pubkey: tickArrayUpper, isSigner: false, isWritable: true },\n { pubkey: ownerVaultA, isSigner: false, isWritable: true },\n { pubkey: ownerVaultB, isSigner: false, isWritable: true },\n { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: TOKEN_2022_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: MEMO_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: mintA, isSigner: false, isWritable: false },\n { pubkey: mintB, isSigner: false, isWritable: false },\n\n ...(exTickArrayBitmap ? [{ pubkey: exTickArrayBitmap, isSigner: false, isWritable: true }] : []),\n ...rewardAccounts\n .map((i) => [\n { pubkey: i.poolRewardVault, isSigner: false, isWritable: true },\n { pubkey: i.ownerRewardVault, isSigner: false, isWritable: true },\n { pubkey: i.rewardMint, isSigner: false, isWritable: false },\n ])\n .flat(),\n ];\n\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode({ liquidity, amountMinA, amountMinB }, data);\n const aData = Buffer.from([...insId.decreaseLiquidityV2, ...data]);\n\n return new TransactionInstruction({\n keys,\n programId,\n data: aData,\n });\n }\n\n static swapV2Instruction(\n programId: PublicKey,\n payer: PublicKey,\n poolId: PublicKey,\n ammConfig: PublicKey,\n inputTokenAccount: PublicKey,\n outputTokenAccount: PublicKey,\n inputVault: PublicKey,\n outputVault: PublicKey,\n inputTokenMint: PublicKey,\n outputTokenMint: PublicKey,\n tickArray: PublicKey[],\n observationId: PublicKey,\n amount: BN,\n otherAmountThreshold: BN,\n sqrtPriceLimitX64: BN,\n isBaseInput: boolean,\n\n tickArrayBitmapExtension?: PublicKey,\n ): TransactionInstruction {\n const dataLayout = struct([\n u64(\"amount\"),\n u64(\"otherAmountThreshold\"),\n u128(\"sqrtPriceLimitX64\"),\n bool(\"isBaseInput\"),\n ]);\n\n const keys = [\n { pubkey: payer, isSigner: true, isWritable: false },\n { pubkey: ammConfig, isSigner: false, isWritable: false },\n { pubkey: poolId, isSigner: false, isWritable: true },\n { pubkey: inputTokenAccount, isSigner: false, isWritable: true },\n { pubkey: outputTokenAccount, isSigner: false, isWritable: true },\n { pubkey: inputVault, isSigner: false, isWritable: true },\n { pubkey: outputVault, isSigner: false, isWritable: true },\n { pubkey: observationId, isSigner: false, isWritable: true },\n { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: TOKEN_2022_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: MEMO_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: inputTokenMint, isSigner: false, isWritable: false },\n { pubkey: outputTokenMint, isSigner: false, isWritable: false },\n\n ...(tickArrayBitmapExtension ? [{ pubkey: tickArrayBitmapExtension, isSigner: false, isWritable: true }] : []),\n ...tickArray.map((i) => ({ pubkey: i, isSigner: false, isWritable: true })),\n ];\n\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode({ amount, otherAmountThreshold, sqrtPriceLimitX64, isBaseInput }, data);\n const aData = Buffer.from([...insId.swapV2, ...data]);\n\n return new TransactionInstruction({\n keys,\n programId,\n data: aData,\n });\n }\n\n static collectRemainingRewardsInstruction(\n programId: PublicKey,\n rewardFunder: PublicKey,\n poolId: PublicKey,\n funderTokenAccount: PublicKey,\n rewardTokenVault: PublicKey,\n rewardMint: PublicKey,\n rewardIndex: number,\n ): TransactionInstruction {\n const dataLayout = struct([u8(\"rewardIndex\")]);\n\n const keys = [\n { pubkey: rewardFunder, isSigner: true, isWritable: false },\n { pubkey: funderTokenAccount, isSigner: false, isWritable: true },\n { pubkey: poolId, isSigner: false, isWritable: true },\n { pubkey: rewardTokenVault, isSigner: false, isWritable: true },\n { pubkey: rewardMint, isSigner: false, isWritable: false },\n\n { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: TOKEN_2022_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: MEMO_PROGRAM_ID, isSigner: false, isWritable: false },\n ];\n\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode({ rewardIndex }, data);\n const aData = Buffer.from([...insId.collectRemainingRewards, ...data]);\n\n return new TransactionInstruction({\n keys,\n programId,\n data: aData,\n });\n }\n\n static openPositionWithToken22NftInstruction(\n programId: PublicKey,\n payer: PublicKey,\n poolId: PublicKey,\n positionNftOwner: PublicKey,\n positionNftMint: PublicKey,\n positionNftAccount: PublicKey,\n protocolPosition: PublicKey,\n tickArrayLower: PublicKey,\n tickArrayUpper: PublicKey,\n personalPosition: PublicKey,\n ownerVaultA: PublicKey,\n ownerVaultB: PublicKey,\n vaultA: PublicKey,\n vaultB: PublicKey,\n mintA: PublicKey,\n mintB: PublicKey,\n tickLower: number,\n tickUpper: number,\n tickArrayLowerStart: number,\n tickArrayUpperStart: number,\n liquidity: BN,\n amountMaxA: BN,\n amountMaxB: BN,\n withMetadata: boolean,\n baseFlag: boolean | null,\n\n exTickArrayBitmap?: PublicKey,\n ): TransactionInstruction {\n const dataLayout = struct([\n s32(\"tickLower\"),\n s32(\"tickUpper\"),\n s32(\"tickArrayLowerStart\"),\n s32(\"tickArrayUpperStart\"),\n u128(\"liquidity\"),\n u64(\"amountMaxA\"),\n u64(\"amountMaxB\"),\n bool(\"withMetadata\"),\n u8(\"optionBaseFlag\"),\n bool(\"baseFlag\"),\n ]);\n\n const keys = [\n { pubkey: payer, isSigner: true, isWritable: true },\n { pubkey: positionNftOwner, isSigner: false, isWritable: false },\n { pubkey: positionNftMint, isSigner: true, isWritable: true },\n { pubkey: positionNftAccount, isSigner: false, isWritable: true },\n { pubkey: poolId, isSigner: false, isWritable: true },\n { pubkey: protocolPosition, isSigner: false, isWritable: false },\n { pubkey: tickArrayLower, isSigner: false, isWritable: true },\n { pubkey: tickArrayUpper, isSigner: false, isWritable: true },\n { pubkey: personalPosition, isSigner: false, isWritable: true },\n { pubkey: ownerVaultA, isSigner: false, isWritable: true },\n { pubkey: ownerVaultB, isSigner: false, isWritable: true },\n { pubkey: vaultA, isSigner: false, isWritable: true },\n { pubkey: vaultB, isSigner: false, isWritable: true },\n { pubkey: RENT_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },\n { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: TOKEN_2022_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: mintA, isSigner: false, isWritable: false },\n { pubkey: mintB, isSigner: false, isWritable: false },\n ...(exTickArrayBitmap ? [{ pubkey: exTickArrayBitmap, isSigner: false, isWritable: true }] : []),\n ];\n\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode(\n {\n tickLower,\n tickUpper,\n tickArrayLowerStart,\n tickArrayUpperStart,\n liquidity,\n amountMaxA,\n amountMaxB,\n withMetadata,\n optionBaseFlag: baseFlag !== null ? 1 : 0,\n baseFlag: baseFlag ?? false,\n },\n data,\n );\n const aData = Buffer.from([...insId.openPositionWithToken22Nft, ...data]);\n\n return new TransactionInstruction({\n keys,\n programId,\n data: aData,\n });\n }\n\n static openLimitOrderInstruction(\n programId: PublicKey,\n payer: PublicKey,\n poolId: PublicKey,\n tickArray: PublicKey,\n limitOrderNonce: PublicKey,\n limitOrder: PublicKey,\n inputTokenAccount: PublicKey,\n outputTokenAccount: PublicKey,\n inputVault: PublicKey,\n outputVault: PublicKey,\n inputVaultMint: PublicKey,\n outputVaultMint: PublicKey,\n inputTokenProgram: PublicKey,\n nonceIndex: number,\n zeroForOne: boolean,\n tickIndex: number,\n amount: BN,\n tickArrayBitmap?: PublicKey,\n ): TransactionInstruction {\n const dataLayout = struct([u8(\"nonceIndex\"), bool(\"zeroForOne\"), s32(\"tickIndex\"), u64(\"amount\")]);\n\n const keys = [\n { pubkey: payer, isSigner: true, isWritable: true },\n { pubkey: poolId, isSigner: false, isWritable: true },\n { pubkey: tickArray, isSigner: false, isWritable: true },\n { pubkey: limitOrderNonce, isSigner: false, isWritable: true },\n { pubkey: limitOrder, isSigner: false, isWritable: true },\n { pubkey: inputTokenAccount, isSigner: false, isWritable: true },\n { pubkey: outputTokenAccount, isSigner: false, isWritable: true },\n { pubkey: inputVault, isSigner: false, isWritable: true },\n { pubkey: outputVault, isSigner: false, isWritable: true },\n { pubkey: inputVaultMint, isSigner: false, isWritable: false },\n { pubkey: outputVaultMint, isSigner: false, isWritable: false },\n { pubkey: inputTokenProgram, isSigner: false, isWritable: false },\n { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },\n ...(tickArrayBitmap ? [{ pubkey: tickArrayBitmap, isSigner: false, isWritable: true }] : []),\n ];\n\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode({ nonceIndex, zeroForOne, tickIndex, amount }, data);\n const aData = Buffer.from([...insId.openLimitOrder, ...data]);\n\n return new TransactionInstruction({\n keys,\n programId,\n data: aData,\n });\n }\n\n static increaseLimitOrderInstruction(\n programId: PublicKey,\n owner: PublicKey,\n poolId: PublicKey,\n tickArray: PublicKey,\n limitOrder: PublicKey,\n inputTokenAccount: PublicKey,\n inputVault: PublicKey,\n inputVaultMint: PublicKey,\n inputTokenProgram: PublicKey,\n amount: BN,\n ): TransactionInstruction {\n const dataLayout = struct([u64(\"amount\")]);\n\n const keys = [\n { pubkey: owner, isSigner: true, isWritable: false },\n { pubkey: poolId, isSigner: false, isWritable: true },\n { pubkey: tickArray, isSigner: false, isWritable: true },\n { pubkey: limitOrder, isSigner: false, isWritable: true },\n { pubkey: inputTokenAccount, isSigner: false, isWritable: true },\n { pubkey: inputVault, isSigner: false, isWritable: true },\n { pubkey: inputVaultMint, isSigner: false, isWritable: false },\n { pubkey: inputTokenProgram, isSigner: false, isWritable: false },\n ];\n\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode({ amount }, data);\n const aData = Buffer.from([...insId.increaseLimitOrder, ...data]);\n\n return new TransactionInstruction({\n keys,\n programId,\n data: aData,\n });\n }\n\n static decreaseLimitOrderInstruction(\n programId: PublicKey,\n owner: PublicKey,\n poolId: PublicKey,\n tickArray: PublicKey,\n limitOrder: PublicKey,\n inputTokenAccount: PublicKey,\n outputTokenAccount: PublicKey,\n inputVault: PublicKey,\n outputVault: PublicKey,\n inputVaultMint: PublicKey,\n outputVaultMint: PublicKey,\n amount: BN,\n amountMin: BN,\n tickArrayBitmap?: PublicKey,\n ): TransactionInstruction {\n const dataLayout = struct([u64(\"amount\"), u64(\"amountMin\")]);\n\n const keys = [\n { pubkey: owner, isSigner: true, isWritable: false },\n { pubkey: poolId, isSigner: false, isWritable: true },\n { pubkey: tickArray, isSigner: false, isWritable: true },\n { pubkey: limitOrder, isSigner: false, isWritable: true },\n { pubkey: inputTokenAccount, isSigner: false, isWritable: true },\n { pubkey: outputTokenAccount, isSigner: false, isWritable: true },\n { pubkey: inputVault, isSigner: false, isWritable: true },\n { pubkey: outputVault, isSigner: false, isWritable: true },\n { pubkey: inputVaultMint, isSigner: false, isWritable: false },\n { pubkey: outputVaultMint, isSigner: false, isWritable: false },\n { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: TOKEN_2022_PROGRAM_ID, isSigner: false, isWritable: false },\n ...(tickArrayBitmap ? [{ pubkey: tickArrayBitmap, isSigner: false, isWritable: true }] : []),\n ];\n\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode({ amount, amountMin }, data);\n const aData = Buffer.from([...insId.decreaseLimitOrder, ...data]);\n\n return new TransactionInstruction({\n keys,\n programId,\n data: aData,\n });\n }\n\n static settleLimitOrderInstruction(\n programId: PublicKey,\n signer: PublicKey,\n poolId: PublicKey,\n tickArray: PublicKey,\n limitOrder: PublicKey,\n outputTokenAccount: PublicKey,\n outputVault: PublicKey,\n outputVaultMint: PublicKey,\n outputTokenProgram: PublicKey,\n ): TransactionInstruction {\n const keys = [\n { pubkey: signer, isSigner: true, isWritable: false },\n { pubkey: poolId, isSigner: false, isWritable: false },\n { pubkey: tickArray, isSigner: false, isWritable: true },\n { pubkey: limitOrder, isSigner: false, isWritable: true },\n { pubkey: outputTokenAccount, isSigner: false, isWritable: true },\n { pubkey: outputVault, isSigner: false, isWritable: true },\n { pubkey: outputVaultMint, isSigner: false, isWritable: false },\n { pubkey: outputTokenProgram, isSigner: false, isWritable: false },\n ];\n\n const aData = Buffer.from([...insId.settleLimitOrder]);\n\n return new TransactionInstruction({\n keys,\n programId,\n data: aData,\n });\n }\n\n static closeLimitOrderInstruction(\n programId: PublicKey,\n signer: PublicKey,\n rentReceiver: PublicKey,\n limitOrder: PublicKey,\n ): TransactionInstruction {\n const keys = [\n { pubkey: signer, isSigner: true, isWritable: false },\n { pubkey: rentReceiver, isSigner: false, isWritable: true },\n { pubkey: limitOrder, isSigner: false, isWritable: true },\n ];\n\n const aData = Buffer.from([...insId.closeLimitOrder]);\n\n return new TransactionInstruction({\n keys,\n programId,\n data: aData,\n });\n }\n\n static createPoolInstructions(props: CreatePoolInstruction): ReturnTypeMakeInstructions<{\n poolId: PublicKey;\n observationId: PublicKey;\n exBitmapAccount: PublicKey;\n mintA: PublicKey;\n mintB: PublicKey;\n mintAProgram: PublicKey;\n mintBProgram: PublicKey;\n mintAVault: PublicKey;\n mintBVault: PublicKey;\n }> {\n const { programId, owner, mintA, mintB, ammConfigId, initialPriceX64, extendMintAccount } = props;\n const [mintAAddress, mintBAddress] = [new PublicKey(mintA.address), new PublicKey(mintB.address)];\n const [mintAProgram, mintBProgram] = [\n new PublicKey(mintA.programId || TOKEN_PROGRAM_ID),\n new PublicKey(mintB.programId || TOKEN_PROGRAM_ID),\n ];\n\n const { publicKey: poolId } = getPdaPoolId(programId, ammConfigId, mintAAddress, mintBAddress);\n const { publicKey: observationId } = getPdaObservationAccount(programId, poolId);\n const { publicKey: mintAVault } = getPdaPoolVaultId(programId, poolId, mintAAddress);\n const { publicKey: mintBVault } = getPdaPoolVaultId(programId, poolId, mintBAddress);\n const exBitmapAccount = getPdaExBitmapAccount(programId, poolId).publicKey;\n\n const ins = [\n this.createPoolInstruction(\n programId,\n poolId,\n owner,\n ammConfigId,\n observationId,\n mintAAddress,\n mintAVault,\n mintAProgram,\n mintBAddress,\n mintBVault,\n mintBProgram,\n exBitmapAccount,\n initialPriceX64,\n extendMintAccount,\n ),\n ];\n\n return {\n signers: [],\n instructions: ins,\n instructionTypes: [InstructionType.CreateAccount, InstructionType.ClmmCreatePool],\n address: {\n poolId,\n observationId,\n exBitmapAccount,\n mintA: mintAAddress,\n mintB: mintBAddress,\n mintAProgram,\n mintBProgram,\n mintAVault,\n mintBVault,\n },\n lookupTableAddress: [],\n };\n }\n\n static createPermissionedPoolInstructions(\n props: CreatePoolInstruction & { payer: PublicKey; seedIndex: number },\n ): ReturnTypeMakeInstructions<{\n poolId: PublicKey;\n observationId: PublicKey;\n exBitmapAccount: PublicKey;\n mintA: PublicKey;\n mintB: PublicKey;\n mintAProgram: PublicKey;\n mintBProgram: PublicKey;\n mintAVault: PublicKey;\n mintBVault: PublicKey;\n permission: PublicKey;\n }> {\n const { programId, owner, mintA, mintB, ammConfigId, initialPriceX64, extendMintAccount, payer, seedIndex } = props;\n const [mintAAddress, mintBAddress] = [new PublicKey(mintA.address), new PublicKey(mintB.address)];\n const [mintAProgram, mintBProgram] = [\n new PublicKey(mintA.programId || TOKEN_PROGRAM_ID),\n new PublicKey(mintB.programId || TOKEN_PROGRAM_ID),\n ];\n\n const { publicKey: poolId } = getPdaPermissionedPoolId(\n programId,\n ammConfigId,\n mintAAddress,\n mintBAddress,\n seedIndex,\n );\n const { publicKey: permission } = getPdaPermission(programId, payer);\n const { publicKey: observationId } = getPdaObservationAccount(programId, poolId);\n const { publicKey: mintAVault } = getPdaPoolVaultId(programId, poolId, mintAAddress);\n const { publicKey: mintBVault } = getPdaPoolVaultId(programId, poolId, mintBAddress);\n const exBitmapAccount = getPdaExBitmapAccount(programId, poolId).publicKey;\n\n const ins = [\n this.createPoolInstruction(\n programId,\n poolId,\n owner,\n ammConfigId,\n observationId,\n mintAAddress,\n mintAVault,\n mintAProgram,\n mintBAddress,\n mintBVault,\n mintBProgram,\n exBitmapAccount,\n initialPriceX64,\n extendMintAccount,\n ),\n ];\n\n return {\n signers: [],\n instructions: ins,\n instructionTypes: [InstructionType.CreateAccount, InstructionType.ClmmCreatePool],\n address: {\n poolId,\n observationId,\n exBitmapAccount,\n mintA: mintAAddress,\n mintB: mintBAddress,\n mintAProgram,\n mintBProgram,\n mintAVault,\n mintBVault,\n permission,\n },\n lookupTableAddress: [],\n };\n }\n\n static async openPositionInstructions({\n poolInfo,\n poolKeys,\n ownerInfo,\n tickLower,\n tickUpper,\n liquidity,\n amountMaxA,\n amountMaxB,\n base,\n withMetadata,\n getEphemeralSigners,\n nft2022,\n }: {\n poolInfo: ApiV3PoolInfoConcentratedItem;\n poolKeys: ClmmKeys;\n ownerInfo: {\n feePayer: PublicKey;\n wallet: PublicKey;\n tokenAccountA: PublicKey;\n tokenAccountB: PublicKey;\n };\n\n tickLower: number;\n tickUpper: number;\n liquidity: BN;\n amountMaxA: BN;\n amountMaxB: BN;\n base: \"MintA\" | \"MintB\" | null;\n withMetadata: \"create\" | \"no-create\";\n getEphemeralSigners?: (k: number) => any;\n nft2022?: boolean;\n }): Promise<ReturnTypeMakeInstructions> {\n const signers: Signer[] = [];\n const [programId, id] = [new PublicKey(poolInfo.programId), new PublicKey(poolInfo.id)];\n\n let nftMintAccount;\n if (getEphemeralSigners) {\n nftMintAccount = new PublicKey((await getEphemeralSigners(1))[0]);\n } else {\n const _k = Keypair.generate();\n signers.push(_k);\n nftMintAccount = _k.publicKey;\n }\n\n const tickArrayLowerStartIndex = TickArrayUtil.getTickArrayStartIndex(tickLower, poolInfo.config.tickSpacing);\n const tickArrayUpperStartIndex = TickArrayUtil.getTickArrayStartIndex(tickUpper, poolInfo.config.tickSpacing);\n\n const { publicKey: tickArrayLower } = getPdaTickArrayAddress(programId, id, tickArrayLowerStartIndex);\n const { publicKey: tickArrayUpper } = getPdaTickArrayAddress(programId, id, tickArrayUpperStartIndex);\n\n const { publicKey: positionNftAccount } = nft2022\n ? getATAAddress(ownerInfo.wallet, nftMintAccount, TOKEN_2022_PROGRAM_ID)\n : getATAAddress(ownerInfo.wallet, nftMintAccount, TOKEN_PROGRAM_ID);\n const { publicKey: metadataAccount } = getPdaMetadataKey(nftMintAccount);\n const { publicKey: personalPosition } = getPdaPersonalPositionAddress(programId, nftMintAccount);\n const { publicKey: protocolPosition } = getPdaProtocolPositionAddress(programId, id, tickLower, tickUpper);\n\n const ins = nft2022\n ? this.openPositionWithToken22NftInstruction(\n programId,\n ownerInfo.feePayer,\n id,\n ownerInfo.wallet,\n nftMintAccount,\n positionNftAccount,\n protocolPosition,\n tickArrayLower,\n tickArrayUpper,\n personalPosition,\n ownerInfo.tokenAccountA,\n ownerInfo.tokenAccountB,\n new PublicKey(poolKeys.vault.A),\n new PublicKey(poolKeys.vault.B),\n new PublicKey(poolInfo.mintA.address),\n new PublicKey(poolInfo.mintB.address),\n\n tickLower,\n tickUpper,\n tickArrayLowerStartIndex,\n tickArrayUpperStartIndex,\n liquidity,\n amountMaxA,\n amountMaxB,\n withMetadata === \"create\",\n base ? base === \"MintA\" : base,\n PoolUtil.isOverflowDefaultTickarrayBitmap({\n tickSpacing: poolInfo.config.tickSpacing,\n tickIndexs: [tickArrayLowerStartIndex, tickArrayUpperStartIndex],\n })\n ? getPdaExBitmapAccount(programId, id).publicKey\n : undefined,\n )\n : this.openPositionV2Instruction(\n programId,\n ownerInfo.feePayer,\n id,\n ownerInfo.wallet,\n nftMintAccount,\n positionNftAccount,\n metadataAccount,\n protocolPosition,\n tickArrayLower,\n tickArrayUpper,\n personalPosition,\n ownerInfo.tokenAccountA,\n ownerInfo.tokenAccountB,\n new PublicKey(poolKeys.vault.A),\n new PublicKey(poolKeys.vault.B),\n new PublicKey(poolInfo.mintA.address),\n new PublicKey(poolInfo.mintB.address),\n\n tickLower,\n tickUpper,\n tickArrayLowerStartIndex,\n tickArrayUpperStartIndex,\n liquidity,\n amountMaxA,\n amountMaxB,\n withMetadata === \"create\",\n null,\n PoolUtil.isOverflowDefaultTickarrayBitmap({\n tickSpacing: poolInfo.config.tickSpacing,\n tickIndexs: [tickArrayLowerStartIndex, tickArrayUpperStartIndex],\n })\n ? getPdaExBitmapAccount(programId, id).publicKey\n : undefined,\n );\n\n return {\n signers,\n instructions: [ins],\n instructionTypes: [InstructionType.ClmmOpenPosition],\n lookupTableAddress: poolKeys.lookupTableAccount ? [poolKeys.lookupTableAccount] : [],\n address: {\n nftMint: nftMintAccount,\n tickArrayLower,\n tickArrayUpper,\n positionNftAccount,\n metadataAccount,\n personalPosition,\n protocolPosition,\n },\n };\n }\n\n static async openPositionFromBaseInstructions({\n poolInfo,\n poolKeys,\n ownerInfo,\n tickLower,\n tickUpper,\n base,\n baseAmount,\n otherAmountMax,\n liquidity,\n withMetadata,\n getEphemeralSigners,\n nft2022,\n }: {\n poolInfo: SimpleClmmPoolInfo;\n poolKeys: {\n vault: {\n A: string | PublicKey;\n B: string | PublicKey;\n };\n lookupTableAccount?: string;\n };\n ownerInfo: {\n feePayer: PublicKey;\n wallet: PublicKey;\n tokenAccountA: PublicKey;\n tokenAccountB: PublicKey;\n };\n\n tickLower: number;\n tickUpper: number;\n\n base: \"MintA\" | \"MintB\" | null;\n baseAmount: BN;\n\n otherAmountMax: BN;\n liquidity: BN;\n withMetadata: \"create\" | \"no-create\";\n getEphemeralSigners?: (k: number) => any;\n nft2022?: boolean;\n }): Promise<ReturnTypeMakeInstructions<OpenPositionFromBaseExtInfo>> {\n const signers: Signer[] = [];\n const [programId, id] = [new PublicKey(poolInfo.programId), new PublicKey(poolInfo.id)];\n\n let nftMintAccount: PublicKey;\n if (getEphemeralSigners) {\n nftMintAccount = new PublicKey((await getEphemeralSigners(1))[0]);\n } else {\n const _k = Keypair.generate();\n signers.push(_k);\n nftMintAccount = _k.publicKey;\n }\n\n const tickArrayLowerStartIndex = TickArrayUtil.getTickArrayStartIndex(tickLower, poolInfo.config.tickSpacing);\n const tickArrayUpperStartIndex = TickArrayUtil.getTickArrayStartIndex(tickUpper, poolInfo.config.tickSpacing);\n\n const { publicKey: tickArrayLower } = getPdaTickArrayAddress(programId, id, tickArrayLowerStartIndex);\n const { publicKey: tickArrayUpper } = getPdaTickArrayAddress(programId, id, tickArrayUpperStartIndex);\n\n const { publicKey: positionNftAccount } = nft2022\n ? getATAAddress(ownerInfo.wallet, nftMintAccount, TOKEN_2022_PROGRAM_ID)\n : getATAAddress(ownerInfo.wallet, nftMintAccount, TOKEN_PROGRAM_ID);\n const { publicKey: metadataAccount } = getPdaMetadataKey(nftMintAccount);\n const { publicKey: personalPosition } = getPdaPersonalPositionAddress(programId, nftMintAccount);\n const { publicKey: protocolPosition } = getPdaProtocolPositionAddress(programId, id, tickLower, tickUpper);\n\n const ins = nft2022\n ? this.openPositionWithToken22NftInstruction(\n programId,\n ownerInfo.feePayer,\n id,\n ownerInfo.wallet,\n nftMintAccount,\n positionNftAccount,\n protocolPosition,\n tickArrayLower,\n tickArrayUpper,\n personalPosition,\n ownerInfo.tokenAccountA,\n ownerInfo.tokenAccountB,\n new PublicKey(poolKeys.vault.A),\n new PublicKey(poolKeys.vault.B),\n new PublicKey(poolInfo.mintA.address),\n new PublicKey(poolInfo.mintB.address),\n\n tickLower,\n tickUpper,\n tickArrayLowerStartIndex,\n tickArrayUpperStartIndex,\n\n liquidity,\n !base || base === \"MintA\" ? baseAmount : otherAmountMax,\n !base || base === \"MintA\" ? otherAmountMax : baseAmount,\n\n withMetadata === \"create\",\n\n base ? base === \"MintA\" : base,\n\n PoolUtil.isOverflowDefaultTickarrayBitmap({\n tickSpacing: poolInfo.config.tickSpacing,\n tickIndexs: [tickArrayLowerStartIndex, tickArrayUpperStartIndex],\n })\n ? getPdaExBitmapAccount(programId, id).publicKey\n : undefined,\n )\n : this.openPositionV2Instruction(\n programId,\n ownerInfo.feePayer,\n id,\n ownerInfo.wallet,\n nftMintAccount,\n positionNftAccount,\n metadataAccount,\n protocolPosition,\n tickArrayLower,\n tickArrayUpper,\n personalPosition,\n ownerInfo.tokenAccountA,\n ownerInfo.tokenAccountB,\n new PublicKey(poolKeys.vault.A),\n new PublicKey(poolKeys.vault.B),\n new PublicKey(poolInfo.mintA.address),\n new PublicKey(poolInfo.mintB.address),\n\n tickLower,\n tickUpper,\n tickArrayLowerStartIndex,\n tickArrayUpperStartIndex,\n\n BN_ZERO,\n base === \"MintA\" ? baseAmount : otherAmountMax,\n base === \"MintA\" ? otherAmountMax : baseAmount,\n\n withMetadata === \"create\",\n\n base === \"MintA\",\n\n PoolUtil.isOverflowDefaultTickarrayBitmap({\n tickSpacing: poolInfo.config.tickSpacing,\n tickIndexs: [tickArrayLowerStartIndex, tickArrayUpperStartIndex],\n })\n ? getPdaExBitmapAccount(programId, id).publicKey\n : undefined,\n );\n\n return {\n address: {\n nftMint: nftMintAccount,\n tickArrayLower,\n tickArrayUpper,\n positionNftAccount,\n metadataAccount,\n personalPosition,\n protocolPosition,\n },\n instructions: [ins],\n signers,\n instructionTypes: [InstructionType.ClmmOpenPosition],\n lookupTableAddress: poolKeys.lookupTableAccount ? [poolKeys.lookupTableAccount] : [],\n };\n }\n\n static async openPositionFromLiquidityInstructions({\n poolInfo,\n poolKeys,\n ownerInfo,\n tickLower,\n tickUpper,\n liquidity,\n amountMaxA,\n amountMaxB,\n base,\n withMetadata,\n getEphemeralSigners,\n nft2022,\n }: {\n poolInfo: SimpleClmmPoolInfo;\n poolKeys: ClmmKeys;\n ownerInfo: {\n wallet: PublicKey;\n tokenAccountA: PublicKey;\n tokenAccountB: PublicKey;\n };\n\n tickLower: number;\n tickUpper: number;\n liquidity: BN;\n amountMaxA: BN;\n amountMaxB: BN;\n base: \"MintA\" | \"MintB\" | null;\n withMetadata: \"create\" | \"no-create\";\n getEphemeralSigners?: (k: number) => any;\n nft2022?: boolean;\n }): Promise<ReturnTypeMakeInstructions<OpenPositionFromLiquidityExtInfo[\"address\"]>> {\n let nftMintAccount: PublicKey;\n const signers: Keypair[] = [];\n if (getEphemeralSigners) {\n nftMintAccount = new PublicKey((await getEphemeralSigners(1))[0]);\n } else {\n const _k = Keypair.generate();\n signers.push(_k);\n nftMintAccount = _k.publicKey;\n }\n\n const [programId, id] = [new PublicKey(poolInfo.programId), new PublicKey(poolInfo.id)];\n\n const tickArrayLowerStartIndex = TickArrayUtil.getTickArrayStartIndex(tickLower, poolInfo.config.tickSpacing);\n const tickArrayUpperStartIndex = TickArrayUtil.getTickArrayStartIndex(tickUpper, poolInfo.config.tickSpacing);\n\n const { publicKey: tickArrayLower } = getPdaTickArrayAddress(programId, id, tickArrayLowerStartIndex);\n const { publicKey: tickArrayUpper } = getPdaTickArrayAddress(programId, id, tickArrayUpperStartIndex);\n\n const { publicKey: positionNftAccount } = nft2022\n ? getATAAddress(ownerInfo.wallet, nftMintAccount, TOKEN_2022_PROGRAM_ID)\n : getATAAddress(ownerInfo.wallet, nftMintAccount, TOKEN_PROGRAM_ID);\n const { publicKey: metadataAccount } = getPdaMetadataKey(nftMintAccount);\n const { publicKey: personalPosition } = getPdaPersonalPositionAddress(programId, nftMintAccount);\n const { publicKey: protocolPosition } = getPdaProtocolPositionAddress(programId, id, tickLower, tickUpper);\n\n const ins = nft2022\n ? this.openPositionWithToken22NftInstruction(\n programId,\n ownerInfo.wallet,\n id,\n ownerInfo.wallet,\n nftMintAccount,\n positionNftAccount,\n protocolPosition,\n tickArrayLower,\n tickArrayUpper,\n personalPosition,\n ownerInfo.tokenAccountA,\n ownerInfo.tokenAccountB,\n new PublicKey(poolKeys.vault.A),\n new PublicKey(poolKeys.vault.B),\n new PublicKey(poolKeys.mintA.address),\n new PublicKey(poolKeys.mintB.address),\n\n tickLower,\n tickUpper,\n tickArrayLowerStartIndex,\n tickArrayUpperStartIndex,\n liquidity,\n amountMaxA,\n amountMaxB,\n withMetadata === \"create\",\n base ? base === \"MintA\" : base,\n PoolUtil.isOverflowDefaultTickarrayBitmap({\n tickSpacing: poolInfo.config.tickSpacing,\n tickIndexs: [tickArrayLowerStartIndex, tickArrayUpperStartIndex],\n })\n ? getPdaExBitmapAccount(programId, id).publicKey\n : undefined,\n )\n : this.openPositionV2Instruction(\n programId,\n ownerInfo.wallet,\n id,\n ownerInfo.wallet,\n nftMintAccount,\n positionNftAccount,\n metadataAccount,\n protocolPosition,\n tickArrayLower,\n tickArrayUpper,\n personalPosition,\n ownerInfo.tokenAccountA,\n ownerInfo.tokenAccountB,\n new PublicKey(poolKeys.vault.A),\n new PublicKey(poolKeys.vault.B),\n new PublicKey(poolKeys.mintA.address),\n new PublicKey(poolKeys.mintB.address),\n\n tickLower,\n tickUpper,\n tickArrayLowerStartIndex,\n tickArrayUpperStartIndex,\n liquidity,\n amountMaxA,\n amountMaxB,\n withMetadata === \"create\",\n null,\n PoolUtil.isOverflowDefaultTickarrayBitmap({\n tickSpacing: poolInfo.config.tickSpacing,\n tickIndexs: [tickArrayLowerStartIndex, tickArrayUpperStartIndex],\n })\n ? getPdaExBitmapAccount(programId, id).publicKey\n : undefined,\n );\n\n return {\n address: {\n nftMint: nftMintAccount,\n tickArrayLower,\n tickArrayUpper,\n positionNftAccount,\n metadataAccount,\n personalPosition,\n protocolPosition,\n },\n instructions: [ins],\n signers,\n instructionTypes: [InstructionType.ClmmOpenPosition],\n lookupTableAddress: poolKeys.lookupTableAccount ? [poolKeys.lookupTableAccount] : [],\n };\n }\n\n static closePositionInstructions({\n poolInfo,\n poolKeys,\n ownerInfo,\n ownerPosition,\n nft2022,\n }: {\n poolInfo: ApiV3PoolInfoConcentratedItem;\n poolKeys: ClmmKeys;\n ownerPosition: ReturnType<typeof PersonalPositionLayout.decode>;\n ownerInfo: {\n wallet: PublicKey;\n };\n nft2022?: boolean;\n }): ReturnTypeMakeInstructions<ClosePositionExtInfo[\"address\"]> {\n const programId = new PublicKey(poolInfo.programId);\n // const { publicKey: positionNftAccount } = getATAAddress(ownerInfo.wallet, ownerPosition.nftMint, TOKEN_PROGRAM_ID);\n const positionNftAccount = nft2022\n ? getATAAddress(ownerInfo.wallet, ownerPosition.nftMint, TOKEN_2022_PROGRAM_ID).publicKey\n : getATAAddress(ownerInfo.wallet, ownerPosition.nftMint, TOKEN_PROGRAM_ID).publicKey;\n const { publicKey: personalPosition } = getPdaPersonalPositionAddress(programId, ownerPosition.nftMint);\n\n const ins: TransactionInstruction[] = [];\n ins.push(\n this.closePositionInstruction(\n programId,\n ownerInfo.wallet,\n ownerPosition.nftMint,\n positionNftAccount,\n personalPosition,\n !!nft2022,\n new PublicKey(poolInfo.id),\n ),\n );\n\n return {\n address: {\n positionNftAccount,\n personalPosition,\n },\n signers: [],\n instructions: ins,\n instructionTypes: [InstructionType.ClmmClosePosition],\n lookupTableAddress: poolKeys.lookupTableAccount ? [poolKeys.lookupTableAccount] : [],\n };\n }\n\n static increasePositionFromLiquidityInstructions({\n poolInfo,\n poolKeys,\n ownerPosition,\n ownerInfo,\n liquidity,\n amountMaxA,\n amountMaxB,\n nft2022,\n }: {\n poolInfo: ApiV3PoolInfoConcentratedItem;\n poolKeys: ClmmKeys;\n ownerPosition: ReturnType<typeof PersonalPositionLayout.decode>;\n\n ownerInfo: {\n wallet: PublicKey;\n tokenAccountA: PublicKey;\n tokenAccountB: PublicKey;\n };\n\n liquidity: BN;\n amountMaxA: BN;\n amountMaxB: BN;\n nft2022?: boolean;\n }): ReturnTypeMakeInstructions<ManipulateLiquidityExtInfo[\"address\"]> {\n const [programId, id] = [new PublicKey(poolInfo.programId), new PublicKey(poolInfo.id)];\n const tickArrayLowerStartIndex = TickArrayUtil.getTickArrayStartIndex(\n ownerPosition.tickLower,\n poolInfo.config.tickSpacing,\n );\n const tickArrayUpperStartIndex = TickArrayUtil.getTickArrayStartIndex(\n ownerPosition.tickUpper,\n poolInfo.config.tickSpacing,\n );\n\n const { publicKey: tickArrayLower } = getPdaTickArrayAddress(programId, id, tickArrayLowerStartIndex);\n const { publicKey: tickArrayUpper } = getPdaTickArrayAddress(programId, id, tickArrayUpperStartIndex);\n\n const { publicKey: positionNftAccount } = nft2022\n ? getATAAddress(ownerInfo.wallet, ownerPosition.nftMint, TOKEN_2022_PROGRAM_ID)\n : getATAAddress(ownerInfo.wallet, ownerPosition.nftMint, TOKEN_PROGRAM_ID);\n\n const { publicKey: personalPosition } = getPdaPersonalPositionAddress(programId, ownerPosition.nftMint);\n const { publicKey: protocolPosition } = getPdaProtocolPositionAddress(\n programId,\n id,\n ownerPosition.tickLower,\n ownerPosition.tickUpper,\n );\n\n const ins = this.increaseLiquidityV2Instruction(\n programId,\n ownerInfo.wallet,\n positionNftAccount,\n personalPosition,\n id,\n protocolPosition,\n tickArrayLower,\n tickArrayUpper,\n ownerInfo.tokenAccountA,\n ownerInfo.tokenAccountB,\n new PublicKey(poolKeys.vault.A),\n new PublicKey(poolKeys.vault.B),\n new PublicKey(poolInfo.mintA.address),\n new PublicKey(poolInfo.mintB.address),\n\n liquidity,\n amountMaxA,\n amountMaxB,\n\n null,\n PoolUtil.isOverflowDefaultTickarrayBitmap({\n tickSpacing: poolInfo.config.tickSpacing,\n tickIndexs: [tickArrayLowerStartIndex, tickArrayUpperStartIndex],\n })\n ? getPdaExBitmapAccount(programId, id).publicKey\n : undefined,\n );\n\n return {\n address: {\n tickArrayLower,\n tickArrayUpper,\n positionNftAccount,\n personalPosition,\n protocolPosition,\n },\n signers: [],\n instructions: [ins],\n instructionTypes: [InstructionType.ClmmIncreasePosition],\n lookupTableAddress: poolKeys.lookupTableAccount ? [poolKeys.lookupTableAccount] : [],\n };\n }\n\n static increasePositionFromBaseInstructions({\n poolInfo,\n poolKeys,\n ownerPosition,\n ownerInfo,\n base,\n baseAmount,\n otherAmountMax,\n nft2022,\n }: {\n poolInfo: ApiV3PoolInfoConcentratedItem;\n poolKeys: ClmmKeys;\n ownerPosition: ClmmPoolPersonalPosition;\n\n ownerInfo: {\n wallet: PublicKey;\n tokenAccountA: PublicKey;\n tokenAccountB: PublicKey;\n };\n\n base: \"MintA\" | \"MintB\";\n baseAmount: BN;\n\n otherAmountMax: BN;\n nft2022?: boolean;\n }): ReturnTypeMakeInstructions<ManipulateLiquidityExtInfo[\"address\"]> {\n const [programId, id] = [new PublicKey(poolInfo.programId), new PublicKey(poolInfo.id)];\n const tickArrayLowerStartIndex = TickArrayUtil.getTickArrayStartIndex(\n ownerPosition.tickLower,\n poolInfo.config.tickSpacing,\n );\n const tickArrayUpperStartIndex = TickArrayUtil.getTickArrayStartIndex(\n ownerPosition.tickUpper,\n poolInfo.config.tickSpacing,\n );\n\n const { publicKey: tickArrayLower } = getPdaTickArrayAddress(programId, id, tickArrayLowerStartIndex);\n const { publicKey: tickArrayUpper } = getPdaTickArrayAddress(programId, id, tickArrayUpperStartIndex);\n\n const { publicKey: positionNftAccount } = nft2022\n ? getATAAddress(ownerInfo.wallet, ownerPosition.nftMint, TOKEN_2022_PROGRAM_ID)\n : getATAAddress(ownerInfo.wallet, ownerPosition.nftMint, TOKEN_PROGRAM_ID);\n\n const { publicKey: personalPosition } = getPdaPersonalPositionAddress(programId, ownerPosition.nftMint);\n const { publicKey: protocolPosition } = getPdaProtocolPositionAddress(\n programId,\n id,\n ownerPosition.tickLower,\n ownerPosition.tickUpper,\n );\n\n return {\n address: {\n tickArrayLower,\n tickArrayUpper,\n positionNftAccount,\n personalPosition,\n protocolPosition,\n },\n instructions: [\n this.increaseLiquidityV2Instruction(\n programId,\n ownerInfo.wallet,\n positionNftAccount,\n personalPosition,\n id,\n protocolPosition,\n tickArrayLower,\n tickArrayUpper,\n ownerInfo.tokenAccountA,\n ownerInfo.tokenAccountB,\n new PublicKey(poolKeys.vault.A),\n new PublicKey(poolKeys.vault.B),\n new PublicKey(poolInfo.mintA.address),\n new PublicKey(poolInfo.mintB.address),\n\n BN_ZERO,\n base === \"MintA\" ? baseAmount : otherAmountMax,\n base === \"MintA\" ? otherAmountMax : baseAmount,\n\n base === \"MintA\",\n\n PoolUtil.isOverflowDefaultTickarrayBitmap({\n tickSpacing: poolInfo.config.tickSpacing,\n tickIndexs: [tickArrayLowerStartIndex, tickArrayUpperStartIndex],\n })\n ? getPdaExBitmapAccount(programId, id).publicKey\n : undefined,\n ),\n ],\n signers: [],\n instructionTypes: [InstructionType.ClmmIncreasePosition],\n lookupTableAddress: poolKeys.lookupTableAccount ? [poolKeys.lookupTableAccount] : [],\n };\n }\n\n static decreaseLiquidityInstructions({\n poolInfo,\n poolKeys,\n ownerPosition,\n ownerInfo,\n liquidity,\n amountMinA,\n amountMinB,\n programId,\n nft2022,\n }: {\n poolInfo: ApiV3PoolInfoConcentratedItem;\n poolKeys: ClmmKeys;\n ownerPosition: ReturnType<typeof PersonalPositionLayout.decode>;\n ownerInfo: {\n wallet: PublicKey;\n tokenAccountA: PublicKey;\n tokenAccountB: PublicKey;\n rewardAccounts: PublicKey[];\n };\n\n liquidity: BN;\n amountMinA: BN;\n amountMinB: BN;\n programId?: PublicKey;\n nft2022?: boolean;\n }): ReturnTypeMakeInstructions<ManipulateLiquidityExtInfo[\"address\"]> {\n const [poolProgramId, id] = [new PublicKey(poolInfo.programId), new PublicKey(poolInfo.id)];\n const tickArrayLowerStartIndex = TickArrayUtil.getTickArrayStartIndex(\n ownerPosition.tickLower,\n poolInfo.config.tickSpacing,\n );\n const tickArrayUpperStartIndex = TickArrayUtil.getTickArrayStartIndex(\n ownerPosition.tickUpper,\n poolInfo.config.tickSpacing,\n );\n\n const { publicKey: tickArrayLower } = getPdaTickArrayAddress(poolProgramId, id, tickArrayLowerStartIndex);\n const { publicKey: tickArrayUpper } = getPdaTickArrayAddress(poolProgramId, id, tickArrayUpperStartIndex);\n const { publicKey: positionNftAccount } = nft2022\n ? getATAAddress(ownerInfo.wallet, ownerPosition.nftMint, TOKEN_2022_PROGRAM_ID)\n : getATAAddress(ownerInfo.wallet, ownerPosition.nftMint, programId);\n const { publicKey: personalPosition } = getPdaPersonalPositionAddress(poolProgramId, ownerPosition.nftMint);\n const { publicKey: protocolPosition } = getPdaProtocolPositionAddress(\n poolProgramId,\n id,\n ownerPosition.tickLower,\n ownerPosition.tickUpper,\n );\n\n // Match by mint: rewardDefaultInfos and rewardInfos can differ in length/order\n const ownerMintToAccount = new Map<string, PublicKey>();\n for (let i = 0; i < poolKeys.rewardInfos.length; i++) {\n ownerMintToAccount.set(poolKeys.rewardInfos[i].mint.address, ownerInfo.rewardAccounts[i]);\n }\n const rewardAccounts: {\n poolRewardVault: PublicKey;\n ownerRewardVault: PublicKey;\n rewardMint: PublicKey;\n }[] = [];\n for (let i = 0; i < poolKeys.rewardInfos.length; i++) {\n const mint = poolKeys.rewardInfos[i].mint.address;\n const ownerRewardVault = ownerMintToAccount.get(mint);\n if (ownerRewardVault) {\n rewardAccounts.push({\n poolRewardVault: new PublicKey(poolKeys.rewardInfos[i].vault),\n ownerRewardVault,\n rewardMint: new PublicKey(mint),\n });\n }\n }\n\n const ins: TransactionInstruction[] = [];\n const decreaseIns = this.decreaseLiquidityV2Instruction(\n poolProgramId,\n ownerInfo.wallet,\n positionNftAccount,\n personalPosition,\n id,\n protocolPosition,\n tickArrayLower,\n tickArrayUpper,\n ownerInfo.tokenAccountA,\n ownerInfo.tokenAccountB,\n new PublicKey(poolKeys.vault.A),\n new PublicKey(poolKeys.vault.B),\n new PublicKey(poolInfo.mintA.address),\n new PublicKey(poolInfo.mintB.address),\n rewardAccounts,\n\n liquidity,\n amountMinA,\n amountMinB,\n PoolUtil.isOverflowDefaultTickarrayBitmap({\n tickSpacing: poolInfo.config.tickSpacing,\n tickIndexs: [tickArrayLowerStartIndex, tickArrayUpperStartIndex],\n })\n ? getPdaExBitmapAccount(poolProgramId, id).publicKey\n : undefined,\n );\n ins.push(decreaseIns);\n\n return {\n address: {\n tickArrayLower,\n tickArrayUpper,\n positionNftAccount,\n personalPosition,\n protocolPosition,\n },\n signers: [],\n instructions: ins,\n instructionTypes: [InstructionType.ClmmDecreasePosition],\n lookupTableAddress: poolKeys.lookupTableAccount ? [poolKeys.lookupTableAccount] : [],\n };\n }\n\n static makeSwapBaseInInstructions({\n poolInfo,\n poolKeys,\n observationId,\n ownerInfo,\n inputMint,\n amountIn,\n amountOutMin,\n sqrtPriceLimitX64,\n remainingAccounts,\n }: {\n poolInfo: SimpleClmmPoolInfo;\n poolKeys: Pick<ClmmKeys, \"vault\" | \"lookupTableAccount\">;\n observationId: PublicKey;\n ownerInfo: {\n wallet: PublicKey;\n tokenAccountA: PublicKey;\n tokenAccountB: PublicKey;\n };\n\n inputMint: PublicKey;\n amountIn: BN;\n amountOutMin: BN;\n sqrtPriceLimitX64: BN;\n\n remainingAccounts: PublicKey[];\n }): ReturnTypeMakeInstructions {\n const [programId, id] = [new PublicKey(poolInfo.programId), new PublicKey(poolInfo.id)];\n const [mintAVault, mintBVault] = [new PublicKey(poolKeys.vault.A), new PublicKey(poolKeys.vault.B)];\n const [mintA, mintB] = [new PublicKey(poolInfo.mintA.address), new PublicKey(poolInfo.mintB.address)];\n\n const isInputMintA = poolInfo.mintA.address.toString() === inputMint.toString();\n\n const ins = [\n this.swapV2Instruction(\n programId,\n ownerInfo.wallet,\n\n id,\n new PublicKey(poolInfo.config.id),\n\n isInputMintA ? ownerInfo.tokenAccountA : ownerInfo.tokenAccountB,\n isInputMintA ? ownerInfo.tokenAccountB : ownerInfo.tokenAccountA,\n\n isInputMintA ? mintAVault : mintBVault,\n isInputMintA ? mintBVault : mintAVault,\n\n isInputMintA ? mintA : mintB,\n isInputMintA ? mintB : mintA,\n\n remainingAccounts,\n observationId,\n amountIn,\n amountOutMin,\n sqrtPriceLimitX64,\n true,\n getPdaExBitmapAccount(programId, id).publicKey,\n ),\n ];\n return {\n signers: [],\n instructions: ins,\n instructionTypes: [InstructionType.ClmmSwapBaseIn],\n lookupTableAddress: poolKeys.lookupTableAccount ? [poolKeys.lookupTableAccount] : [],\n address: {},\n };\n }\n\n static makeSwapBaseOutInstructions({\n poolInfo,\n poolKeys,\n observationId,\n ownerInfo,\n outputMint,\n amountOut,\n amountInMax,\n sqrtPriceLimitX64,\n remainingAccounts,\n }: {\n poolInfo: SimpleClmmPoolInfo;\n poolKeys: Pick<ClmmKeys, \"vault\" | \"lookupTableAccount\">;\n observationId: PublicKey;\n\n ownerInfo: {\n wallet: PublicKey;\n tokenAccountA: PublicKey;\n tokenAccountB: PublicKey;\n };\n\n outputMint: PublicKey;\n\n amountOut: BN;\n amountInMax: BN;\n sqrtPriceLimitX64: BN;\n\n remainingAccounts: PublicKey[];\n }): ReturnTypeMakeInstructions {\n const [programId, id] = [new PublicKey(poolInfo.programId), new PublicKey(poolInfo.id)];\n const [mintAVault, mintBVault] = [new PublicKey(poolKeys.vault.A), new PublicKey(poolKeys.vault.B)];\n const [mintA, mintB] = [new PublicKey(poolInfo.mintA.address), new PublicKey(poolInfo.mintB.address)];\n const isInputMintA = poolInfo.mintB.address.toString() === outputMint.toBase58();\n\n const ins = [\n this.swapV2Instruction(\n programId,\n ownerInfo.wallet,\n\n id,\n new PublicKey(poolInfo.config.id),\n\n isInputMintA ? ownerInfo.tokenAccountA : ownerInfo.tokenAccountB,\n isInputMintA ? ownerInfo.tokenAccountB : ownerInfo.tokenAccountA,\n\n isInputMintA ? mintAVault : mintBVault,\n isInputMintA ? mintBVault : mintAVault,\n\n isInputMintA ? mintA : mintB,\n isInputMintA ? mintB : mintA,\n\n remainingAccounts,\n observationId,\n amountOut,\n amountInMax,\n sqrtPriceLimitX64,\n false,\n getPdaExBitmapAccount(programId, id).publicKey,\n ),\n ];\n return {\n signers: [],\n instructions: ins,\n instructionTypes: [InstructionType.ClmmSwapBaseOut],\n lookupTableAddress: poolKeys.lookupTableAccount ? [poolKeys.lookupTableAccount] : [],\n address: {},\n };\n }\n\n static initRewardInstructions({\n poolInfo,\n poolKeys,\n ownerInfo,\n rewardInfo,\n }: {\n poolInfo: ApiV3PoolInfoConcentratedItem;\n poolKeys: ClmmKeys;\n ownerInfo: {\n wallet: PublicKey;\n tokenAccount: PublicKey;\n };\n rewardInfo: {\n programId: PublicKey;\n mint: PublicKey;\n openTime: number;\n endTime: number;\n emissionsPerSecondX64: BN;\n };\n }): ReturnTypeMakeInstructions<InitRewardExtInfo[\"address\"]> {\n const [programId, id] = [new PublicKey(poolInfo.programId), new PublicKey(poolInfo.id)];\n const poolRewardVault = getPdaPoolRewardVaultId(programId, id, rewardInfo.mint).publicKey;\n const operationId = getPdaOperationAccount(programId).publicKey;\n const ins = [\n this.initializeRewardInstruction(\n programId,\n ownerInfo.wallet,\n id,\n operationId,\n new PublicKey(poolInfo.config.id),\n\n ownerInfo.tokenAccount,\n rewardInfo.programId,\n rewardInfo.mint,\n poolRewardVault,\n\n new BN(rewardInfo.openTime),\n new BN(rewardInfo.endTime),\n rewardInfo.emissionsPerSecondX64,\n ),\n ];\n return {\n address: { poolRewardVault, operationId },\n signers: [],\n instructions: ins,\n instructionTypes: [InstructionType.ClmmInitReward],\n lookupTableAddress: poolKeys.lookupTableAccount ? [poolKeys.lookupTableAccount] : [],\n };\n }\n\n static setRewardInstructions({\n poolInfo,\n poolKeys,\n ownerInfo,\n rewardInfo,\n }: {\n poolInfo: ApiV3PoolInfoConcentratedItem;\n poolKeys: ClmmKeys;\n ownerInfo: {\n wallet: PublicKey;\n tokenAccount: PublicKey;\n };\n rewardInfo: {\n mint: PublicKey;\n openTime: number;\n endTime: number;\n emissionsPerSecondX64: BN;\n };\n }): ReturnTypeMakeInstructions {\n const [programId, id] = [new PublicKey(poolInfo.programId), new PublicKey(poolInfo.id)];\n\n let rewardIndex: number | undefined;\n let rewardVault: PublicKey | undefined;\n let rewardMint: PublicKey | undefined;\n for (let index = 0; index < poolInfo.rewardDefaultInfos.length; index++)\n if (poolInfo.rewardDefaultInfos[index].mint.address === rewardInfo.mint.toString()) {\n rewardIndex = index;\n rewardVault = new PublicKey(poolKeys.rewardInfos[index].vault);\n rewardMint = new PublicKey(poolKeys.rewardInfos[index].mint.address);\n }\n\n if (rewardIndex === undefined || rewardVault === undefined)\n logger.logWithError(\"reward mint check error\", \"no reward mint\", poolInfo.rewardDefaultInfos);\n\n const operationId = getPdaOperationAccount(programId).publicKey;\n\n const ins = [\n this.setRewardParamsInstruction(\n programId,\n ownerInfo.wallet,\n id,\n operationId,\n new PublicKey(poolInfo.config.id),\n\n ownerInfo.tokenAccount,\n rewardVault!,\n rewardMint!,\n\n rewardIndex!,\n new BN(rewardInfo.openTime),\n new BN(rewardInfo.endTime),\n rewardInfo.emissionsPerSecondX64,\n ),\n ];\n return {\n address: { rewardVault: rewardVault!, operationId },\n signers: [],\n instructions: ins,\n instructionTypes: [InstructionType.ClmmSetReward],\n lookupTableAddress: poolKeys.lookupTableAccount ? [poolKeys.lookupTableAccount] : [],\n };\n }\n\n static collectRewardInstructions({\n poolInfo,\n poolKeys,\n ownerInfo,\n rewardMint,\n }: {\n poolInfo: ApiV3PoolInfoConcentratedItem;\n poolKeys: ClmmKeys;\n ownerInfo: {\n wallet: PublicKey;\n tokenAccount: PublicKey;\n };\n rewardMint: PublicKey;\n }): ReturnTypeMakeInstructions {\n const [programId, id] = [new PublicKey(poolInfo.programId), new PublicKey(poolInfo.id)];\n let rewardIndex: number | undefined;\n let rewardVault: PublicKey | undefined;\n for (let index = 0; index < poolInfo.rewardDefaultInfos.length; index++)\n if (poolInfo.rewardDefaultInfos[index].mint.address === rewardMint.toString()) {\n rewardIndex = index;\n rewardVault = new PublicKey(poolKeys.rewardInfos[index].vault);\n }\n\n if (rewardIndex === undefined || rewardVault === undefined)\n logger.logWithError(\"reward mint check error\", \"no reward mint\", poolInfo.rewardDefaultInfos);\n\n const ins = [\n this.collectRemainingRewardsInstruction(\n programId,\n ownerInfo.wallet,\n id,\n\n ownerInfo.tokenAccount,\n rewardVault!,\n rewardMint,\n\n rewardIndex!,\n ),\n ];\n return {\n address: { rewardVault: rewardVault! },\n signers: [],\n instructions: ins,\n instructionTypes: [InstructionType.ClmmCollectReward],\n lookupTableAddress: poolKeys.lookupTableAccount ? [poolKeys.lookupTableAccount] : [],\n };\n }\n\n static async makeLockPositions({\n programId,\n authProgramId,\n poolProgramId,\n payer,\n wallet,\n nftMint,\n nft2022,\n getEphemeralSigners,\n }: {\n programId: PublicKey;\n authProgramId: PublicKey;\n poolProgramId: PublicKey;\n wallet: PublicKey;\n payer: PublicKey;\n nftMint: PublicKey;\n nft2022?: boolean;\n getEphemeralSigners?: (k: number) => any;\n }): Promise<ReturnTypeMakeInstructions<ClmmLockAddress>> {\n const signers: Signer[] = [];\n let lockNftMint: PublicKey;\n if (getEphemeralSigners) {\n lockNftMint = new PublicKey((await getEphemeralSigners(1))[0]);\n } else {\n const _k = Keypair.generate();\n signers.push(_k);\n lockNftMint = _k.publicKey;\n }\n\n const positionNftAccount = nft2022\n ? getATAAddress(wallet, nftMint, TOKEN_2022_PROGRAM_ID).publicKey\n : getATAAddress(wallet, nftMint, TOKEN_PROGRAM_ID).publicKey;\n const { publicKey: positionId } = getPdaPersonalPositionAddress(poolProgramId, nftMint);\n const lockPositionId = getPdaLockClPositionIdV2(programId, lockNftMint).publicKey;\n const lockNftAccount = getATAAddress(wallet, lockNftMint, TOKEN_PROGRAM_ID).publicKey;\n const metadataAccount = getPdaMetadataKey(lockNftMint).publicKey;\n\n const ins = ClmmInstrument.lockPositionInstructionV2({\n programId,\n auth: authProgramId,\n payer,\n positionOwner: wallet,\n lockOwner: wallet,\n positionNftAccount,\n positionId,\n lockPositionId,\n lockNftMint,\n lockNftAccount,\n metadataAccount,\n withMetadata: true,\n nft2022,\n\n positionNftMint: nftMint,\n authPositionNftAccount: getATAAddress(authProgramId, nftMint, nft2022 ? TOKEN_2022_PROGRAM_ID : TOKEN_PROGRAM_ID)\n .publicKey,\n positionNftProgram: nft2022 ? TOKEN_2022_PROGRAM_ID : TOKEN_PROGRAM_ID,\n });\n\n return {\n address: {\n positionId,\n lockPositionId,\n lockNftAccount,\n lockNftMint,\n positionNftAccount,\n metadataAccount,\n },\n instructions: [ins],\n signers,\n instructionTypes: [InstructionType.ClmmLockPosition],\n lookupTableAddress: [],\n };\n }\n\n static lockPositionInstructionV2({\n programId,\n auth,\n payer,\n positionOwner,\n lockOwner,\n positionNftAccount,\n positionId,\n positionNftMint,\n authPositionNftAccount,\n positionNftProgram,\n lockPositionId,\n lockNftMint,\n lockNftAccount,\n metadataAccount,\n withMetadata,\n }: {\n programId: PublicKey;\n auth: PublicKey;\n payer: PublicKey;\n positionOwner: PublicKey;\n lockOwner: PublicKey;\n positionNftAccount: PublicKey;\n positionId: PublicKey;\n positionNftMint: PublicKey;\n authPositionNftAccount: PublicKey;\n positionNftProgram: PublicKey;\n lockPositionId: PublicKey;\n lockNftMint: PublicKey;\n lockNftAccount: PublicKey;\n metadataAccount: PublicKey;\n withMetadata: boolean;\n nft2022?: boolean;\n }): TransactionInstruction {\n const keys = [\n { pubkey: auth, isSigner: false, isWritable: false },\n { pubkey: payer, isSigner: true, isWritable: true },\n { pubkey: positionOwner, isSigner: true, isWritable: true },\n { pubkey: lockOwner, isSigner: false, isWritable: false },\n { pubkey: positionNftAccount, isSigner: false, isWritable: true },\n { pubkey: positionId, isSigner: false, isWritable: false },\n { pubkey: positionNftMint, isSigner: false, isWritable: true },\n { pubkey: authPositionNftAccount, isSigner: false, isWritable: true },\n { pubkey: lockPositionId, isSigner: false, isWritable: true },\n { pubkey: lockNftMint, isSigner: true, isWritable: true },\n { pubkey: lockNftAccount, isSigner: false, isWritable: true },\n { pubkey: metadataAccount, isSigner: false, isWritable: true },\n { pubkey: METADATA_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: RENT_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: positionNftProgram, isSigner: false, isWritable: false },\n { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },\n ];\n const dataLayout = struct([bool(\"withMetadata\")]);\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode(\n {\n withMetadata,\n },\n data,\n );\n const aData = Buffer.from([...lockInsDataBuf, ...data]);\n return new TransactionInstruction({\n keys,\n programId,\n data: aData,\n });\n }\n\n static lockPositionInstruction({\n programId,\n authProgramId,\n poolProgramId,\n owner,\n positionNft,\n }: {\n programId: PublicKey;\n authProgramId: PublicKey;\n poolProgramId: PublicKey;\n owner: PublicKey;\n positionNft: PublicKey;\n }): TransactionInstruction {\n const { publicKey: nftAccount } = getATAAddress(owner, positionNft, TOKEN_PROGRAM_ID);\n const { publicKey: positionId } = getPdaPersonalPositionAddress(poolProgramId, positionNft);\n\n const keys = [\n { pubkey: authProgramId, isSigner: false, isWritable: false },\n { pubkey: owner, isSigner: true, isWritable: false },\n { pubkey: nftAccount, isSigner: false, isWritable: true },\n { pubkey: positionId, isSigner: false, isWritable: false },\n { pubkey: getPdaLockPositionId(programId, positionId).publicKey, isSigner: false, isWritable: true },\n { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },\n ];\n return new TransactionInstruction({\n keys,\n programId,\n data: Buffer.from(lockInsDataBuf),\n });\n }\n\n static harvestLockPositionInstruction(props: {\n poolKeys: ClmmKeys;\n programId: PublicKey;\n authProgramId: PublicKey;\n ownerPosition: ReturnType<typeof PersonalPositionLayout.decode>;\n owner: PublicKey;\n ownerRewardAccounts: PublicKey[];\n userVaultA: PublicKey;\n userVaultB: PublicKey;\n }): TransactionInstruction {\n const [poolProgramId, poolId] = [new PublicKey(props.poolKeys.programId), new PublicKey(props.poolKeys.id)];\n\n const tickArrayLowerStartIndex = TickArrayUtil.getTickArrayStartIndex(\n props.ownerPosition.tickLower,\n props.poolKeys.config.tickSpacing,\n );\n const tickArrayUpperStartIndex = TickArrayUtil.getTickArrayStartIndex(\n props.ownerPosition.tickUpper,\n props.poolKeys.config.tickSpacing,\n );\n const { publicKey: tickArrayLower } = getPdaTickArrayAddress(poolProgramId, poolId, tickArrayLowerStartIndex);\n const { publicKey: tickArrayUpper } = getPdaTickArrayAddress(poolProgramId, poolId, tickArrayUpperStartIndex);\n const { publicKey: nftAccount } = getATAAddress(props.owner, props.ownerPosition.nftMint, TOKEN_PROGRAM_ID);\n const { publicKey: positionId } = getPdaPersonalPositionAddress(poolProgramId, props.ownerPosition.nftMint);\n const { publicKey: protocolPosition } = getPdaProtocolPositionAddress(\n poolProgramId,\n poolId,\n props.ownerPosition.tickLower,\n props.ownerPosition.tickUpper,\n );\n\n const rewardAccounts: {\n poolRewardVault: PublicKey;\n ownerRewardVault: PublicKey;\n rewardMint: PublicKey;\n }[] = [];\n\n for (let i = 0; i < props.poolKeys.rewardInfos.length; i++) {\n rewardAccounts.push({\n poolRewardVault: new PublicKey(props.poolKeys.rewardInfos[i].vault),\n ownerRewardVault: props.ownerRewardAccounts[i],\n rewardMint: new PublicKey(props.poolKeys.rewardInfos[i].mint.address),\n });\n }\n\n const remainingAccounts = [\n ...rewardAccounts\n .map((i) => [\n { pubkey: i.poolRewardVault, isSigner: false, isWritable: true },\n { pubkey: i.ownerRewardVault, isSigner: false, isWritable: true },\n { pubkey: i.rewardMint, isSigner: false, isWritable: false },\n ])\n .flat(),\n ];\n\n const keys = [\n { pubkey: props.authProgramId, isSigner: false, isWritable: false },\n { pubkey: getPdaLockPositionId(props.programId, positionId).publicKey, isSigner: false, isWritable: false },\n { pubkey: poolProgramId, isSigner: false, isWritable: false },\n { pubkey: props.owner, isSigner: true, isWritable: false },\n { pubkey: nftAccount, isSigner: false, isWritable: true },\n { pubkey: positionId, isSigner: false, isWritable: true },\n { pubkey: poolId, isSigner: false, isWritable: true },\n { pubkey: protocolPosition, isSigner: false, isWritable: true },\n { pubkey: new PublicKey(props.poolKeys.vault.A), isSigner: false, isWritable: true },\n { pubkey: new PublicKey(props.poolKeys.vault.B), isSigner: false, isWritable: true },\n { pubkey: tickArrayLower, isSigner: false, isWritable: true },\n { pubkey: tickArrayUpper, isSigner: false, isWritable: true },\n { pubkey: props.userVaultA, isSigner: false, isWritable: true },\n { pubkey: props.userVaultB, isSigner: false, isWritable: true },\n { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: TOKEN_2022_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: MEMO_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: new PublicKey(props.poolKeys.mintA.address), isSigner: false, isWritable: false },\n { pubkey: new PublicKey(props.poolKeys.mintB.address), isSigner: false, isWritable: false },\n ...remainingAccounts,\n ];\n\n return new TransactionInstruction({\n keys,\n programId: props.programId,\n data: Buffer.from(lockHarvestInsDataBuf),\n });\n }\n\n static harvestLockPositionInstructionV2({\n programId,\n auth,\n lockPositionId,\n clmmProgram,\n lockOwner,\n lockNftMint,\n lockNftAccount,\n positionNftAccount,\n positionId,\n poolId,\n protocolPosition,\n vaultA,\n vaultB,\n tickArrayLower,\n tickArrayUpper,\n userVaultA,\n userVaultB,\n mintA,\n mintB,\n rewardAccounts,\n exTickArrayBitmap,\n }: {\n programId: PublicKey;\n auth: PublicKey;\n lockPositionId: PublicKey;\n clmmProgram: PublicKey;\n lockOwner: PublicKey;\n lockNftMint: PublicKey;\n lockNftAccount: PublicKey;\n positionNftAccount: PublicKey;\n positionId: PublicKey;\n poolId: PublicKey;\n protocolPosition: PublicKey;\n vaultA: PublicKey;\n vaultB: PublicKey;\n tickArrayLower: PublicKey;\n tickArrayUpper: PublicKey;\n userVaultA: PublicKey;\n userVaultB: PublicKey;\n mintA: PublicKey;\n mintB: PublicKey;\n rewardAccounts: {\n poolRewardVault: PublicKey;\n ownerRewardVault: PublicKey;\n rewardMint: PublicKey;\n }[];\n\n exTickArrayBitmap?: PublicKey;\n }): TransactionInstruction {\n const remainingAccounts = [\n ...(exTickArrayBitmap ? [{ pubkey: exTickArrayBitmap, isSigner: false, isWritable: true }] : []),\n ...rewardAccounts\n .map((i) => [\n { pubkey: i.poolRewardVault, isSigner: false, isWritable: true },\n { pubkey: i.ownerRewardVault, isSigner: false, isWritable: true },\n { pubkey: i.rewardMint, isSigner: false, isWritable: false },\n ])\n .flat(),\n ];\n\n const keys = [\n { pubkey: auth, isSigner: false, isWritable: false },\n { pubkey: lockOwner, isSigner: true, isWritable: false },\n // { pubkey: lockNftMint, isSigner: false, isWritable: false },\n { pubkey: lockNftAccount, isSigner: false, isWritable: true },\n { pubkey: lockPositionId, isSigner: false, isWritable: false },\n { pubkey: clmmProgram, isSigner: false, isWritable: false },\n { pubkey: positionNftAccount, isSigner: false, isWritable: true },\n { pubkey: positionId, isSigner: false, isWritable: true },\n { pubkey: poolId, isSigner: false, isWritable: true },\n { pubkey: protocolPosition, isSigner: false, isWritable: true },\n { pubkey: vaultA, isSigner: false, isWritable: true },\n { pubkey: vaultB, isSigner: false, isWritable: true },\n { pubkey: tickArrayLower, isSigner: false, isWritable: true },\n { pubkey: tickArrayUpper, isSigner: false, isWritable: true },\n { pubkey: userVaultA, isSigner: false, isWritable: true },\n { pubkey: userVaultB, isSigner: false, isWritable: true },\n { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: TOKEN_2022_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: MEMO_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: mintA, isSigner: false, isWritable: false },\n { pubkey: mintB, isSigner: false, isWritable: false },\n ...remainingAccounts,\n ];\n\n return new TransactionInstruction({\n keys,\n programId,\n data: Buffer.from(lockHarvestInsDataBuf),\n });\n }\n}\n","import BN from \"bn.js\";\n\nexport const Q64 = new BN(1).shln(64);\n\nexport const RESOLUTION = 64;\n\nexport const Q128 = new BN(1).shln(128);\n\nexport const U64_MAX = new BN(1).shln(64).subn(1);\n\nexport const U128_MAX = new BN(1).shln(128).subn(1);\n\nexport const MIN_TICK = -443636;\n\nexport const MAX_TICK = 443636;\n\nexport const MIN_SQRT_PRICE_X64 = new BN(\"4295048016\");\n\nexport const MAX_SQRT_PRICE_X64 = new BN(\"79226673521066979257578248091\");\n\nexport const LOG_B_2_X32 = new BN(\"59543866431248\");\n\nexport const LOG_B_P_ERR_MARGIN_LOWER_X64 = new BN(\"184467440737095516\");\n\nexport const LOG_B_P_ERR_MARGIN_UPPER_X64 = new BN(\"15793534762490258745\");\n\nexport const BIT_PRECISION = 16;\n\nexport const TICK_ARRAY_BITMAP_SIZE = 512;\n\nexport const TICK_ARRAY_SIZE = 60;\n\nexport const MAGIC_SQRT_10001 = new BN(\"18446743708227953217\");\n\nexport const TICK_TO_SQRT_PRICE_FACTORS: { bit: number; factor: BN }[] = [\n { bit: 0, factor: new BN(\"fffcb933bd6fb800\", 16) }, // i=0\n { bit: 1, factor: new BN(\"fff97272373d4000\", 16) }, // i=1\n { bit: 2, factor: new BN(\"fff2e50f5f657000\", 16) }, // i=2\n { bit: 3, factor: new BN(\"ffe5caca7e10f000\", 16) }, // i=3\n { bit: 4, factor: new BN(\"ffcb9843d60f7000\", 16) }, // i=4\n { bit: 5, factor: new BN(\"ff973b41fa98e800\", 16) }, // i=5\n { bit: 6, factor: new BN(\"ff2ea16466c9b000\", 16) }, // i=6\n { bit: 7, factor: new BN(\"fe5dee046a9a3800\", 16) }, // i=7\n { bit: 8, factor: new BN(\"fcbe86c7900bb000\", 16) }, // i=8\n { bit: 9, factor: new BN(\"f987a7253ac65800\", 16) }, // i=9\n { bit: 10, factor: new BN(\"f3392b0822bb6000\", 16) }, // i=10\n { bit: 11, factor: new BN(\"e7159475a2caf000\", 16) }, // i=11\n { bit: 12, factor: new BN(\"d097f3bdfd2f2000\", 16) }, // i=12\n { bit: 13, factor: new BN(\"a9f746462d9f8000\", 16) }, // i=13\n { bit: 14, factor: new BN(\"70d869a156f31c00\", 16) }, // i=14\n { bit: 15, factor: new BN(\"31be135f97ed3200\", 16) }, // i=15\n { bit: 16, factor: new BN(\"9aa508b5b85a500\", 16) }, // i=16\n { bit: 17, factor: new BN(\"5d6af8dedc582c\", 16) }, // i=17\n { bit: 18, factor: new BN(\"2216e584f5fa\", 16) }, // i=18\n];\n\nexport const FEE_RATE_DENOMINATOR = 1_000_000;\n\nexport const MAX_FEE_RATE = 100_000;\n\nexport enum CollectFeeOn {\n FromInput = 0,\n TokenOnlyA = 1,\n TokenOnlyB = 2,\n}\n\n// export const FEE_RATE_DENOMINATOR_VALUE = 1_000_000;\n\nexport const MAX_TICK_SPACING = 1000;\n\nexport const MAX_FEE_RATE_NUMERATOR = 100_000;\nexport const VOLATILITY_ACCUMULATOR_SCALE = 10_000;\nexport const REDUCTION_FACTOR_DENOMINATOR = 10_000;\nexport const DYNAMIC_FEE_CONTROL_DENOMINATOR = 100_000;\n\nexport const TICK_ARRAY_SIZE_USIZE = 60;\n\nexport const REWARD_NUM = 3;\n\nexport const OBSERVATION_NUM = 100;\nexport const OBSERVATION_UPDATE_DURATION_DEFAULT = 15;\n\nexport const OPERATION_SIZE_USIZE = 10;\nexport const WHITE_MINT_SIZE_USIZE = 100;\n\nexport const EXTENSION_TICKARRAY_BITMAP_SIZE = 14;\n\nexport enum PoolStatusBitIndex {\n OpenPositionOrIncreaseLiquidity = 0,\n DecreaseLiquidity = 1,\n CollectFee = 2,\n CollectReward = 3,\n Swap = 4,\n LimitOrder = 5,\n}\n\nexport enum PoolStatusBitFlag {\n Enable = 0,\n Disable = 1,\n}\n\nexport enum RewardState {\n Uninitialized = 0,\n Initialized = 1,\n Opening = 2,\n Ended = 3,\n}\n\nexport enum UpdateAmmConfigParam {\n TradeFeeRate = 0,\n ProtocolFeeRate = 1,\n FundFeeRate = 2,\n NewOwner = 3,\n NewFundOwner = 4,\n}\n\nexport enum UpdateOperationAccountParam {\n UpdateOperationOwner = 0,\n RemoveOperationOwner = 1,\n UpdateWhitelistMint = 2,\n RemoveWhitelistMint = 3,\n}\n\nexport const BN_ZERO = new BN(0);\nexport const BN_ONE = new BN(1);\nexport const BN_NEGATIVE_ONE = new BN(-1);\n\nexport const mockV3CreatePoolInfo = {\n tvl: 0,\n volumeQuote: 0,\n mintAmountA: 0,\n mintAmountB: 0,\n rewardDefaultInfos: [],\n farmUpcomingCount: 0,\n farmOngoingCount: 0,\n farmFinishedCount: 0,\n\n day: {\n volume: 0,\n volumeQuote: 0,\n volumeFee: 0,\n apr: 0,\n feeApr: 0,\n priceMin: 0,\n priceMax: 0,\n rewardApr: [0],\n },\n week: {\n volume: 0,\n volumeQuote: 0,\n volumeFee: 0,\n apr: 0,\n feeApr: 0,\n priceMin: 0,\n priceMax: 0,\n rewardApr: [0],\n },\n month: {\n volume: 0,\n volumeQuote: 0,\n volumeFee: 0,\n apr: 0,\n feeApr: 0,\n priceMin: 0,\n priceMax: 0,\n rewardApr: [0],\n },\n pooltype: [],\n};\n\n/**\n * Get human-readable description for collectFeeOn value\n * CollectFeeOn enum values:\n * 0 = FromInput - fee collected from input token during swap\n * 1 = Token0Only - fee collected from token0\n * 2 = Token1Only - fee collected from token1\n */\nexport function getCollectFeeOnDescription(value: number): string {\n switch (value) {\n case 0:\n return \"0 (FromInput - fee from input token)\";\n case 1:\n return \"1 (Token0Only - fee from token0)\";\n case 2:\n return \"2 (Token1Only - fee from token1)\";\n default:\n return `${value} (unknown)`;\n }\n}\n\nexport const DYNAMIC_CONFIG_INDEX = 2;\nexport const U64_IGNORE_RANGE = new BN(\"18446744073700000000\");\n","import { blob, bool, i128, i64, publicKey, s32, seq, struct, u128, u16, u32, u64, u8 } from \"../../marshmallow\";\nimport {\n EXTENSION_TICKARRAY_BITMAP_SIZE,\n OBSERVATION_NUM,\n OPERATION_SIZE_USIZE,\n REWARD_NUM,\n TICK_ARRAY_SIZE,\n WHITE_MINT_SIZE_USIZE,\n} from \"./libraries/constants\";\n\nexport const ClmmConfigLayout = struct([\n blob(8),\n u8(\"bump\"),\n u16(\"index\"),\n publicKey(\"owner\"),\n u32(\"protocolFeeRate\"),\n u32(\"tradeFeeRate\"),\n u16(\"tickSpacing\"),\n u32(\"fundFeeRate\"),\n seq(u32(), 1),\n publicKey(\"fundOwner\"),\n seq(u64(), 3),\n]);\n\nexport const ObservationItemLayout = struct([u32(\"blockTimestamp\"), i64(\"tickCumulative\"), seq(u64(), 4)]);\n\nexport const ObservationLayout = struct([\n blob(8),\n bool(\"initialized\"),\n u64(\"recentEpoch\"),\n u16(\"observationIndex\"),\n publicKey(\"poolId\"),\n seq(ObservationItemLayout, OBSERVATION_NUM, \"observations\"),\n seq(u64(), 4),\n]);\n\nexport const DynamicFeeInfoLayout = struct([\n u16(\"filterPeriod\"),\n u16(\"decayPeriod\"),\n u16(\"reductionFactor\"),\n u32(\"dynamicFeeControl\"),\n u32(\"maxVolatilityAccumulator\"),\n s32(\"tickSpacingIndexReference\"),\n u32(\"volatilityReference\"),\n u32(\"volatilityAccumulator\"),\n u64(\"lastUpdateTimestamp\"),\n seq(u8(), 46),\n]);\n\nexport const RewardInfoLayout = struct([\n u8(\"state\"),\n u64(\"openTime\"),\n u64(\"endTime\"),\n u64(\"lastUpdateTime\"),\n u128(\"emissionsPerSecondX64\"),\n u64(\"totalEmissioned\"),\n u64(\"claimed\"),\n publicKey(\"mint\"),\n publicKey(\"vault\"),\n publicKey(\"creator\"),\n u128(\"growthGlobalX64\"),\n]);\n\nexport const PoolInfoLayout = struct([\n blob(8),\n u8(\"bump\"),\n publicKey(\"configId\"),\n publicKey(\"creator\"),\n publicKey(\"mintA\"),\n publicKey(\"mintB\"),\n publicKey(\"vaultA\"),\n publicKey(\"vaultB\"),\n publicKey(\"observationId\"),\n\n u8(\"mintDecimalsA\"),\n u8(\"mintDecimalsB\"),\n u16(\"tickSpacing\"),\n u128(\"liquidity\"),\n u128(\"sqrtPriceX64\"),\n s32(\"tickCurrent\"),\n\n u32(),\n\n u128(\"feeGrowthGlobalX64A\"),\n u128(\"feeGrowthGlobalX64B\"),\n u64(\"protocolFeesTokenA\"),\n u64(\"protocolFeesTokenB\"),\n\n seq(u128(), 4),\n // u128(\"swapInAmountTokenA\"),\n // u128(\"swapOutAmountTokenB\"),\n // u128(\"swapInAmountTokenB\"),\n // u128(\"swapOutAmountTokenA\"),\n\n u8(\"status\"),\n u8(\"feeOn\"),\n blob(6),\n\n seq(RewardInfoLayout, REWARD_NUM, \"rewardInfos\"),\n\n blob(8 * 16, \"tickArrayBitmap\"),\n\n seq(u64(), 4),\n // u64(\"totalFeesTokenA\"),\n // u64(\"totalFeesClaimedTokenA\"),\n // u64(\"totalFeesTokenB\"),\n // u64(\"totalFeesClaimedTokenB\"),\n\n u64(\"fundFeesTokenA\"),\n u64(\"fundFeesTokenB\"),\n\n u64(\"startTime\"),\n u64(\"recentEpoch\"),\n\n DynamicFeeInfoLayout.replicate(\"dynamicFeeInfo\"),\n seq(u64(), 46),\n]);\n\nexport const PositionRewardInfoLayout = struct([u128(\"growthInsideLastX64\"), u64(\"rewardAmountOwed\")]);\nexport const PersonalPositionLayout = struct([\n blob(8),\n u8(\"bump\"),\n publicKey(\"nftMint\"),\n publicKey(\"poolId\"),\n\n s32(\"tickLower\"),\n s32(\"tickUpper\"),\n u128(\"liquidity\"),\n u128(\"feeGrowthInsideLastX64A\"),\n u128(\"feeGrowthInsideLastX64B\"),\n u64(\"tokenFeesOwedA\"),\n u64(\"tokenFeesOwedB\"),\n\n seq(PositionRewardInfoLayout, REWARD_NUM, \"rewardInfos\"),\n u64(\"recentEpoch\"),\n seq(u64(), 7),\n]);\n\nexport const ProtocolPositionLayout = struct([\n blob(8),\n u8(\"bump\"),\n publicKey(\"poolId\"),\n s32(\"tickLower\"),\n s32(\"tickUpper\"),\n u128(\"liquidity\"),\n u128(\"feeGrowthInsideLastX64A\"),\n u128(\"feeGrowthInsideLastX64B\"),\n u64(\"tokenFeesOwedA\"),\n u64(\"tokenFeesOwedB\"),\n seq(u128(), REWARD_NUM, \"rewardGrowthInside\"),\n u64(\"recentEpoch\"),\n seq(u64(), 7),\n]);\n\nexport const TickLayout = struct([\n s32(\"tick\"),\n i128(\"liquidityNet\"),\n u128(\"liquidityGross\"),\n u128(\"feeGrowthOutsideX64A\"),\n u128(\"feeGrowthOutsideX64B\"),\n seq(u128(), REWARD_NUM, \"rewardGrowthsOutsideX64\"),\n\n u64(\"orderPhase\"),\n u64(\"ordersAmount\"),\n u64(\"partFilledOrdersRemaining\"),\n u128(\"unfilledRatioX64\"),\n seq(u32(), 3),\n]);\n\nexport const TickArrayLayout = struct([\n blob(8),\n publicKey(\"poolId\"),\n s32(\"startTickIndex\"),\n seq(TickLayout, TICK_ARRAY_SIZE, \"ticks\"),\n u8(\"initializedTickCount\"),\n u64(\"recentEpoch\"),\n seq(u8(), 107),\n]);\n\nexport const OperationLayout = struct([\n blob(8),\n u8(\"bump\"),\n seq(publicKey(), OPERATION_SIZE_USIZE, \"operationOwners\"),\n seq(publicKey(), WHITE_MINT_SIZE_USIZE, \"whitelistMints\"),\n]);\n\nexport const LimitOrderLayout = struct([\n blob(8),\n publicKey(\"poolId\"),\n publicKey(\"owner\"),\n s32(\"tick\"),\n bool(\"zeroForOne\"),\n u64(\"orderPhase\"),\n u64(\"totalAmount\"),\n u64(\"filledAmount\"),\n u64(\"settleBase\"),\n u64(\"settleOutput\"),\n u64(\"openTime\"),\n u128(\"unfilledRatioX64\"),\n seq(u64(), 4),\n]);\n\nexport const TickArrayBitmapExtensionLayout = struct([\n blob(8),\n publicKey(\"poolId\"),\n\n blob(8 * 8 * EXTENSION_TICKARRAY_BITMAP_SIZE, \"positiveTickArrayBitmap\"),\n blob(8 * 8 * EXTENSION_TICKARRAY_BITMAP_SIZE, \"negativeTickArrayBitmap\"),\n]);\n\nexport const DynamicFeeConfigLayout = struct([\n blob(8),\n u16(\"index\"),\n u16(\"filterPeriod\"),\n u16(\"decayPeriod\"),\n u16(\"reductionFactor\"),\n u32(\"dynamicFeeControl\"),\n u32(\"maxVolatilityAccumulator\"),\n seq(u64(), 8),\n]);\n\nexport const LimitOrderNonceLayout = struct([\n blob(8),\n publicKey(\"wallet\"),\n u8(\"nonceIndex\"),\n u64(\"orderNonce\"),\n seq(u64(), 4),\n]);\n\nexport const LockPositionLayout = struct([\n u64(),\n u8(\"bump\"),\n publicKey(\"owner\"),\n publicKey(\"poolId\"),\n publicKey(\"positionId\"),\n publicKey(\"nftAccount\"),\n seq(u64(), 8),\n]);\n\nexport const LockClPositionLayoutV2 = struct([\n blob(8),\n u8(\"bump\"),\n publicKey(\"lockOwner\"),\n publicKey(\"poolId\"),\n publicKey(\"positionId\"),\n publicKey(\"nftAccount\"),\n publicKey(\"lockNftMint\"),\n u64(\"recentEpoch\"),\n seq(u64(), 8),\n]);\n\nexport type ClmmPositionLayout = ReturnType<typeof PersonalPositionLayout.decode>;\n","import {\n CLMM_LOCK_AUTH_ID,\n CLMM_LOCK_PROGRAM_ID,\n CLMM_PROGRAM_ID,\n fetchMultipleMintInfos,\n getATAAddress,\n getMultipleAccountsInfo,\n getMultipleAccountsInfoWithCustomFlags,\n InstructionType,\n WSOLMint,\n} from \"@/common\";\nimport { MakeMultiTxData, MakeTxData } from \"@/common/txTool/txTool\";\nimport { TxVersion } from \"@/common/txTool/txType\";\nimport {\n createAssociatedTokenAccountIdempotentInstruction,\n TOKEN_2022_PROGRAM_ID,\n TOKEN_PROGRAM_ID,\n} from \"@solana/spl-token\";\nimport { PublicKey } from \"@solana/web3.js\";\nimport BN from \"bn.js\";\nimport Decimal from \"decimal.js\";\nimport { ApiV3PoolInfoConcentratedItem, ClmmKeys } from \"../../api/type\";\nimport { toApiV3Token, toFeeConfig } from \"../../raydium/token/utils\";\nimport { ComputeBudgetConfig, ReturnTypeFetchMultipleMintInfos, TxTipConfig } from \"../../raydium/type\";\nimport { splAccountLayout } from \"../account\";\nimport ModuleBase, { ModuleBaseProps } from \"../moduleBase\";\nimport { MakeTransaction } from \"../type\";\nimport { ClmmInstrument } from \"./instrument\";\nimport {\n ClmmConfigLayout,\n LimitOrderLayout,\n LimitOrderNonceLayout,\n LockClPositionLayoutV2,\n OperationLayout,\n PersonalPositionLayout,\n PoolInfoLayout,\n TickArrayBitmapExtensionLayout,\n TickArrayLayout,\n} from \"./layout\";\nimport { clmmComputeInfoToApiInfo, decimalToX64, LimitOrderMath, PoolUtils } from \"./libraries\";\nimport {\n BN_ZERO,\n CollectFeeOn,\n DYNAMIC_CONFIG_INDEX,\n MAX_SQRT_PRICE_X64,\n MIN_SQRT_PRICE_X64,\n mockV3CreatePoolInfo,\n} from \"./libraries/constants\";\nimport {\n getPdaDynamicFeeConfigAddress,\n getPdaExBitmapAccount,\n getPdaLimitOrderAddress,\n getPdaLimitOrderNonceAddress,\n getPdaLockClPositionIdV2,\n getPdaMintExAccount,\n getPdaOperationAccount,\n getPdaPersonalPositionAddress,\n getPdaPoolVaultId,\n getPdaProtocolPositionAddress,\n getPdaTickArrayAddress,\n} from \"./libraries/pda\";\nimport { fetchTickArrays, TickArrayBitmapUtil, TickArrayUtil, TickUtil } from \"./libraries/tickArrayUtil\";\nimport {\n ClmmLockAddress,\n ClmmParsedRpcData,\n CloseAllLimitOrder,\n CloseLimitOrder,\n ClosePositionExtInfo,\n CollectRewardParams,\n CollectRewardsParams,\n ComputeClmmPoolInfo,\n CreateConcentratedPool,\n CreateCustomizablePool,\n DecreaseLimitOrder,\n DecreaseLiquidity,\n HarvestAllRewardsParams,\n HarvestLockPosition,\n IncreaseLimitOrder,\n IncreasePositionFromBase,\n IncreasePositionFromLiquidity,\n InitRewardExtInfo,\n InitRewardParams,\n InitRewardsParams,\n LockPosition,\n ManipulateLiquidityExtInfo,\n OpenLimitOrder,\n OpenPositionFromBase,\n OpenPositionFromBaseExtInfo,\n OpenPositionFromLiquidity,\n OpenPositionFromLiquidityExtInfo,\n ReturnTypeFetchMultiplePoolTickArrays,\n SetRewardParams,\n SetRewardsParams,\n SettleAllLimitOrders,\n SettleLimitOrder,\n SimpleClmmPoolInfo,\n} from \"./type\";\n\nexport class Clmm extends ModuleBase {\n constructor(params: ModuleBaseProps) {\n super(params);\n }\n\n public async getClmmPoolKeys(poolId: string): Promise<ClmmKeys> {\n return ((await this.scope.api.fetchPoolKeysById({ idList: [poolId] })) as ClmmKeys[])[0];\n }\n\n public async createPool<T extends TxVersion>(\n props: CreateConcentratedPool<T>,\n ): Promise<MakeTxData<T, { mockPoolInfo: ApiV3PoolInfoConcentratedItem; address: ClmmKeys }>> {\n const {\n programId,\n owner = this.scope.owner?.publicKey || PublicKey.default,\n mint1,\n mint2,\n ammConfig,\n initialPrice,\n computeBudgetConfig,\n txVersion,\n txTipConfig,\n feePayer,\n } = props;\n const txBuilder = this.createTxBuilder(feePayer);\n const [mintA, mintB, initPrice] = new BN(new PublicKey(mint1.address).toBuffer()).gt(\n new BN(new PublicKey(mint2.address).toBuffer()),\n )\n ? [mint2, mint1, new Decimal(1).div(initialPrice)]\n : [mint1, mint2, initialPrice];\n\n const initialPriceX64 = TickUtil.priceToSqrtPriceX64(initPrice, mintA.decimals, mintB.decimals);\n\n const extendMintAccount: PublicKey[] = [];\n const fetchAccounts: PublicKey[] = [];\n if (mintA.programId === TOKEN_2022_PROGRAM_ID.toBase58())\n fetchAccounts.push(getPdaMintExAccount(programId, new PublicKey(mintA.address)).publicKey);\n if (mintB.programId === TOKEN_2022_PROGRAM_ID.toBase58())\n fetchAccounts.push(getPdaMintExAccount(programId, new PublicKey(mintB.address)).publicKey);\n const extMintRes = await this.scope.connection.getMultipleAccountsInfo(fetchAccounts);\n\n extMintRes.forEach((r, idx) => {\n if (r) extendMintAccount.push(fetchAccounts[idx]);\n });\n\n const insInfo = await ClmmInstrument.createPoolInstructions({\n connection: this.scope.connection,\n programId,\n owner,\n mintA,\n mintB,\n ammConfigId: ammConfig.id,\n initialPriceX64,\n extendMintAccount,\n });\n\n txBuilder.addInstruction(insInfo);\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n\n return txBuilder.versionBuild<{\n mockPoolInfo: ApiV3PoolInfoConcentratedItem;\n address: ClmmKeys;\n }>({\n txVersion,\n extInfo: {\n address: {\n ...insInfo.address,\n observationId: insInfo.address.observationId.toBase58(),\n exBitmapAccount: insInfo.address.exBitmapAccount.toBase58(),\n programId: programId.toString(),\n id: insInfo.address.poolId.toString(),\n mintA,\n mintB,\n openTime: \"0\",\n vault: { A: insInfo.address.mintAVault.toString(), B: insInfo.address.mintBVault.toString() },\n rewardInfos: [],\n config: {\n id: ammConfig.id.toString(),\n index: ammConfig.index,\n protocolFeeRate: ammConfig.protocolFeeRate,\n tradeFeeRate: ammConfig.tradeFeeRate,\n tickSpacing: ammConfig.tickSpacing,\n fundFeeRate: ammConfig.fundFeeRate,\n description: ammConfig.description,\n defaultRange: 0,\n defaultRangePoint: [],\n },\n },\n mockPoolInfo: {\n type: \"Concentrated\",\n rewardDefaultPoolInfos: \"Clmm\",\n id: insInfo.address.poolId.toString(),\n mintA,\n mintB,\n feeRate: ammConfig.tradeFeeRate,\n openTime: \"0\",\n programId: programId.toString(),\n price: initPrice.toNumber(),\n config: {\n id: ammConfig.id.toString(),\n index: ammConfig.index,\n protocolFeeRate: ammConfig.protocolFeeRate,\n tradeFeeRate: ammConfig.tradeFeeRate,\n tickSpacing: ammConfig.tickSpacing,\n fundFeeRate: ammConfig.fundFeeRate,\n description: ammConfig.description,\n defaultRange: 0,\n defaultRangePoint: [],\n },\n feeOn: \"Both\",\n hasDynamicFee: false,\n launchMigratePool: false,\n burnPercent: 0,\n tips: [],\n ...mockV3CreatePoolInfo,\n },\n },\n }) as Promise<MakeTxData<T, { mockPoolInfo: ApiV3PoolInfoConcentratedItem; address: ClmmKeys }>>;\n }\n\n public async createCustomizablePool<T extends TxVersion>(\n props: CreateCustomizablePool<T>,\n ): Promise<MakeTxData<T, { mockPoolInfo: ApiV3PoolInfoConcentratedItem; address: ClmmKeys }>> {\n const {\n programId,\n owner = this.scope.owner?.publicKey || PublicKey.default,\n mint1,\n mint2,\n initialPrice,\n ammConfig,\n collectFeeOn = CollectFeeOn.FromInput,\n dynamicFeeConfig,\n computeBudgetConfig,\n txVersion,\n txTipConfig,\n feePayer,\n addSupportMintExt,\n } = props;\n const txBuilder = this.createTxBuilder(feePayer);\n const [mintA, mintB, initPrice] = new BN(new PublicKey(mint1.address).toBuffer()).gt(\n new BN(new PublicKey(mint2.address).toBuffer()),\n )\n ? [mint2, mint1, new Decimal(1).div(initialPrice)]\n : [mint1, mint2, initialPrice];\n\n const initialPriceX64 = TickUtil.priceToSqrtPriceX64(initPrice, mintA.decimals, mintB.decimals);\n\n const extendMintAccount: PublicKey[] = [];\n const fetchAccounts: PublicKey[] = [];\n if (addSupportMintExt) {\n if (mintA.programId === TOKEN_2022_PROGRAM_ID.toBase58())\n fetchAccounts.push(getPdaMintExAccount(programId, new PublicKey(mintA.address)).publicKey);\n if (mintB.programId === TOKEN_2022_PROGRAM_ID.toBase58())\n fetchAccounts.push(getPdaMintExAccount(programId, new PublicKey(mintB.address)).publicKey);\n const extMintRes = await this.scope.connection.getMultipleAccountsInfo(fetchAccounts);\n\n extMintRes.forEach((r, idx) => {\n if (r) extendMintAccount.push(fetchAccounts[idx]);\n });\n }\n\n const { address } = await ClmmInstrument.createPoolInstructions({\n connection: this.scope.connection,\n programId,\n owner,\n mintA,\n mintB,\n ammConfigId: ammConfig.id,\n initialPriceX64,\n extendMintAccount,\n });\n\n // const desc = getCollectFeeOnDescription(collectFeeOn);\n const remainingAccounts: { pubkey: PublicKey; isSigner: boolean; isWritable: boolean }[] = [];\n\n if (dynamicFeeConfig) {\n // Check if dynamic fee config exists\n const dynamicFeeData = await this.scope.connection.getAccountInfo(dynamicFeeConfig);\n if (!dynamicFeeData)\n throw new Error(\"Dynamic Fee Config not found. Run 03_admin_create_dynamic_fee_config.ts first.\");\n console.log(\"Dynamic Fee Config\", dynamicFeeConfig.toBase58());\n\n // Add dynamic fee config as remaining account\n remainingAccounts.push({\n pubkey: dynamicFeeConfig,\n isSigner: false,\n isWritable: false,\n });\n }\n\n const ins = ClmmInstrument.createCustomizablePoolInstruction(\n programId,\n address.poolId,\n this.scope.ownerPubKey,\n ammConfig.id,\n address.mintA,\n address.mintB,\n address.mintAVault,\n address.mintBVault,\n address.observationId,\n address.exBitmapAccount,\n address.mintAProgram,\n address.mintBProgram,\n initialPriceX64,\n collectFeeOn,\n [...extendMintAccount, ...remainingAccounts.map((d) => d.pubkey)],\n dynamicFeeConfig,\n );\n\n txBuilder.addInstruction({ instructions: [ins] });\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n\n return txBuilder.versionBuild<{\n mockPoolInfo: ApiV3PoolInfoConcentratedItem;\n address: ClmmKeys;\n }>({\n txVersion,\n extInfo: {\n address: {\n ...address,\n observationId: address.observationId.toBase58(),\n exBitmapAccount: address.exBitmapAccount.toBase58(),\n programId: programId.toString(),\n id: address.poolId.toString(),\n mintA,\n mintB,\n openTime: \"0\",\n vault: { A: address.mintAVault.toString(), B: address.mintBVault.toString() },\n rewardInfos: [],\n config: {\n id: ammConfig.id.toString(),\n index: ammConfig.index,\n protocolFeeRate: ammConfig.protocolFeeRate,\n tradeFeeRate: ammConfig.tradeFeeRate,\n tickSpacing: ammConfig.tickSpacing,\n fundFeeRate: ammConfig.fundFeeRate,\n description: ammConfig.description,\n defaultRange: 0,\n defaultRangePoint: [],\n },\n },\n mockPoolInfo: {\n type: \"Concentrated\",\n rewardDefaultPoolInfos: \"Clmm\",\n id: address.poolId.toString(),\n mintA,\n mintB,\n feeRate: ammConfig.tradeFeeRate,\n openTime: \"0\",\n programId: programId.toString(),\n price: initPrice.toNumber(),\n config: {\n id: ammConfig.id.toString(),\n index: ammConfig.index,\n protocolFeeRate: ammConfig.protocolFeeRate,\n tradeFeeRate: ammConfig.tradeFeeRate,\n tickSpacing: ammConfig.tickSpacing,\n fundFeeRate: ammConfig.fundFeeRate,\n description: ammConfig.description,\n defaultRange: 0,\n defaultRangePoint: [],\n },\n burnPercent: 0,\n collectFeeOn,\n feeOn:\n collectFeeOn === CollectFeeOn.FromInput\n ? \"Both\"\n : collectFeeOn === CollectFeeOn.TokenOnlyA\n ? \"TokenA\"\n : \"TokenB\",\n hasDynamicFee: !!dynamicFeeConfig,\n tips: [],\n launchMigratePool: false,\n ...mockV3CreatePoolInfo,\n } as ApiV3PoolInfoConcentratedItem,\n },\n }) as Promise<MakeTxData<T, { mockPoolInfo: ApiV3PoolInfoConcentratedItem; address: ClmmKeys }>>;\n }\n\n public async createPermissionedPool<T extends TxVersion>(\n props: CreateCustomizablePool<T>,\n ): Promise<MakeTxData<T, { mockPoolInfo: ApiV3PoolInfoConcentratedItem; address: ClmmKeys }>> {\n const {\n programId,\n owner = this.scope.owner?.publicKey || PublicKey.default,\n mint1,\n mint2,\n initialPrice,\n ammConfig,\n collectFeeOn = CollectFeeOn.FromInput,\n dynamicFeeConfig,\n computeBudgetConfig,\n txVersion,\n txTipConfig,\n feePayer,\n addSupportMintExt,\n } = props;\n const txBuilder = this.createTxBuilder(feePayer);\n const [mintA, mintB, initPrice] = new BN(new PublicKey(mint1.address).toBuffer()).gt(\n new BN(new PublicKey(mint2.address).toBuffer()),\n )\n ? [mint2, mint1, new Decimal(1).div(initialPrice)]\n : [mint1, mint2, initialPrice];\n\n const initialPriceX64 = TickUtil.priceToSqrtPriceX64(initPrice, mintA.decimals, mintB.decimals);\n\n const extendMintAccount: PublicKey[] = [];\n const fetchAccounts: PublicKey[] = [];\n if (addSupportMintExt) {\n if (mintA.programId === TOKEN_2022_PROGRAM_ID.toBase58())\n fetchAccounts.push(getPdaMintExAccount(programId, new PublicKey(mintA.address)).publicKey);\n if (mintB.programId === TOKEN_2022_PROGRAM_ID.toBase58())\n fetchAccounts.push(getPdaMintExAccount(programId, new PublicKey(mintB.address)).publicKey);\n const extMintRes = await this.scope.connection.getMultipleAccountsInfo(fetchAccounts);\n\n extMintRes.forEach((r, idx) => {\n if (r) extendMintAccount.push(fetchAccounts[idx]);\n });\n }\n\n const payer = feePayer ?? this.scope.ownerPubKey;\n const seedIndex = Math.floor(Math.random() * Math.pow(2, 16)) + 1;\n\n const { address } = await ClmmInstrument.createPermissionedPoolInstructions({\n connection: this.scope.connection,\n programId,\n owner,\n mintA,\n mintB,\n ammConfigId: ammConfig.id,\n initialPriceX64,\n extendMintAccount,\n payer,\n seedIndex,\n });\n\n // const desc = getCollectFeeOnDescription(collectFeeOn);\n const remainingAccounts: { pubkey: PublicKey; isSigner: boolean; isWritable: boolean }[] = [];\n\n if (dynamicFeeConfig) {\n // Check if dynamic fee config exists\n const dynamicFeeData = await this.scope.connection.getAccountInfo(dynamicFeeConfig);\n if (!dynamicFeeData)\n throw new Error(\"Dynamic Fee Config not found. Run 03_admin_create_dynamic_fee_config.ts first.\");\n console.log(\"Dynamic Fee Config\", dynamicFeeConfig.toBase58());\n\n // Add dynamic fee config as remaining account\n remainingAccounts.push({\n pubkey: dynamicFeeConfig,\n isSigner: false,\n isWritable: false,\n });\n }\n\n const ins = ClmmInstrument.createPermissionedPoolInstruction(\n programId,\n payer,\n payer,\n address.permission,\n ammConfig.id,\n address.poolId,\n address.mintA,\n address.mintB,\n address.mintAVault,\n address.mintBVault,\n address.observationId,\n address.exBitmapAccount,\n address.mintAProgram,\n address.mintBProgram,\n initialPriceX64,\n collectFeeOn,\n seedIndex,\n [...extendMintAccount, ...remainingAccounts.map((d) => d.pubkey)],\n dynamicFeeConfig,\n );\n\n txBuilder.addInstruction({ instructions: [ins] });\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n\n return txBuilder.versionBuild<{\n mockPoolInfo: ApiV3PoolInfoConcentratedItem;\n address: ClmmKeys;\n }>({\n txVersion,\n extInfo: {\n address: {\n ...address,\n observationId: address.observationId.toBase58(),\n exBitmapAccount: address.exBitmapAccount.toBase58(),\n programId: programId.toString(),\n id: address.poolId.toString(),\n mintA,\n mintB,\n openTime: \"0\",\n vault: { A: address.mintAVault.toString(), B: address.mintBVault.toString() },\n rewardInfos: [],\n config: {\n id: ammConfig.id.toString(),\n index: ammConfig.index,\n protocolFeeRate: ammConfig.protocolFeeRate,\n tradeFeeRate: ammConfig.tradeFeeRate,\n tickSpacing: ammConfig.tickSpacing,\n fundFeeRate: ammConfig.fundFeeRate,\n description: ammConfig.description,\n defaultRange: 0,\n defaultRangePoint: [],\n },\n },\n mockPoolInfo: {\n type: \"Concentrated\",\n rewardDefaultPoolInfos: \"Clmm\",\n id: address.poolId.toString(),\n mintA,\n mintB,\n feeRate: ammConfig.tradeFeeRate,\n openTime: \"0\",\n programId: programId.toString(),\n price: initPrice.toNumber(),\n config: {\n id: ammConfig.id.toString(),\n index: ammConfig.index,\n protocolFeeRate: ammConfig.protocolFeeRate,\n tradeFeeRate: ammConfig.tradeFeeRate,\n tickSpacing: ammConfig.tickSpacing,\n fundFeeRate: ammConfig.fundFeeRate,\n description: ammConfig.description,\n defaultRange: 0,\n defaultRangePoint: [],\n },\n burnPercent: 0,\n collectFeeOn,\n feeOn:\n collectFeeOn === CollectFeeOn.FromInput\n ? \"Both\"\n : collectFeeOn === CollectFeeOn.TokenOnlyA\n ? \"TokenA\"\n : \"TokenB\",\n hasDynamicFee: !!dynamicFeeConfig,\n tips: [],\n launchMigratePool: false,\n ...mockV3CreatePoolInfo,\n } as ApiV3PoolInfoConcentratedItem,\n },\n }) as Promise<MakeTxData<T, { mockPoolInfo: ApiV3PoolInfoConcentratedItem; address: ClmmKeys }>>;\n }\n\n public async openPositionFromBase<T extends TxVersion>({\n poolInfo,\n poolKeys: propsPoolKeys,\n ownerInfo,\n tickLower,\n tickUpper,\n base = null,\n baseAmount,\n otherAmountMax,\n liquidity = new BN(0),\n nft2022,\n associatedOnly = true,\n checkCreateATAOwner = false,\n withMetadata = \"create\",\n getEphemeralSigners,\n computeBudgetConfig,\n txTipConfig,\n txVersion,\n feePayer,\n }: OpenPositionFromBase<T>): Promise<MakeTxData<T, OpenPositionFromBaseExtInfo>> {\n if (this.scope.availability.addConcentratedPosition === false)\n this.logAndCreateError(\"add position feature disabled in your region\");\n\n this.scope.checkOwner();\n const txBuilder = this.createTxBuilder(feePayer);\n\n let ownerTokenAccountA: PublicKey | null = null;\n let ownerTokenAccountB: PublicKey | null = null;\n const mintAUseSOLBalance = ownerInfo.useSOLBalance && poolInfo.mintA.address === WSOLMint.toString();\n const mintBUseSOLBalance = ownerInfo.useSOLBalance && poolInfo.mintB.address === WSOLMint.toString();\n const [amountA, amountB] = base === \"MintA\" ? [baseAmount, otherAmountMax] : [otherAmountMax, baseAmount];\n\n const { account: _ownerTokenAccountA, instructionParams: _tokenAccountAInstruction } =\n await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: poolInfo.mintA.programId,\n mint: new PublicKey(poolInfo.mintA.address),\n owner: this.scope.ownerPubKey,\n\n createInfo:\n mintAUseSOLBalance || amountA.isZero()\n ? {\n payer: this.scope.ownerPubKey,\n amount: amountA,\n }\n : undefined,\n skipCloseAccount: !mintAUseSOLBalance,\n notUseTokenAccount: mintAUseSOLBalance,\n associatedOnly: mintAUseSOLBalance ? false : associatedOnly,\n checkCreateATAOwner,\n });\n if (_ownerTokenAccountA) ownerTokenAccountA = _ownerTokenAccountA;\n txBuilder.addInstruction(_tokenAccountAInstruction || {});\n\n const { account: _ownerTokenAccountB, instructionParams: _tokenAccountBInstruction } =\n await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: poolInfo.mintB.programId,\n mint: new PublicKey(poolInfo.mintB.address),\n owner: this.scope.ownerPubKey,\n\n createInfo:\n mintBUseSOLBalance || amountB.isZero()\n ? {\n payer: this.scope.ownerPubKey!,\n amount: amountB,\n }\n : undefined,\n skipCloseAccount: !mintBUseSOLBalance,\n notUseTokenAccount: mintBUseSOLBalance,\n associatedOnly: mintBUseSOLBalance ? false : associatedOnly,\n checkCreateATAOwner,\n });\n if (_ownerTokenAccountB) ownerTokenAccountB = _ownerTokenAccountB;\n txBuilder.addInstruction(_tokenAccountBInstruction || {});\n\n if (!ownerTokenAccountA || !ownerTokenAccountB)\n this.logAndCreateError(\"cannot found target token accounts\", \"tokenAccounts\", {\n ownerTokenAccountA: ownerTokenAccountA?.toBase58(),\n ownerTokenAccountB: ownerTokenAccountB?.toBase58(),\n });\n const poolKeys = propsPoolKeys ?? (await this.getClmmPoolKeys(poolInfo.id.toString()))!;\n\n const insInfo = await ClmmInstrument.openPositionFromBaseInstructions({\n poolInfo,\n poolKeys,\n ownerInfo: {\n ...ownerInfo,\n feePayer: this.scope.ownerPubKey,\n wallet: this.scope.ownerPubKey,\n tokenAccountA: ownerTokenAccountA!,\n tokenAccountB: ownerTokenAccountB!,\n },\n tickLower,\n tickUpper,\n base,\n baseAmount,\n otherAmountMax,\n liquidity,\n withMetadata,\n getEphemeralSigners,\n nft2022,\n });\n\n txBuilder.addInstruction(insInfo);\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n return txBuilder.versionBuild<OpenPositionFromBaseExtInfo>({\n txVersion,\n extInfo: { ...insInfo.address },\n }) as Promise<MakeTxData<T, OpenPositionFromBaseExtInfo>>;\n }\n\n public async openPositionFromLiquidity<T extends TxVersion>({\n poolInfo,\n poolKeys: propPoolKeys,\n ownerInfo,\n amountMaxA,\n amountMaxB,\n base = null,\n tickLower,\n tickUpper,\n liquidity,\n associatedOnly = true,\n checkCreateATAOwner = false,\n withMetadata = \"create\",\n txVersion,\n computeBudgetConfig,\n txTipConfig,\n getEphemeralSigners,\n nft2022,\n feePayer,\n }: OpenPositionFromLiquidity<T>): Promise<MakeTxData<T, OpenPositionFromLiquidityExtInfo>> {\n if (this.scope.availability.createConcentratedPosition === false)\n this.logAndCreateError(\"open position feature disabled in your region\");\n const txBuilder = this.createTxBuilder(feePayer);\n\n let ownerTokenAccountA: PublicKey | null = null;\n let ownerTokenAccountB: PublicKey | null = null;\n const mintAUseSOLBalance = ownerInfo.useSOLBalance && poolInfo.mintA.address === WSOLMint.toBase58();\n const mintBUseSOLBalance = ownerInfo.useSOLBalance && poolInfo.mintB.address === WSOLMint.toBase58();\n\n const { account: _ownerTokenAccountA, instructionParams: _tokenAccountAInstruction } =\n await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: poolInfo.mintA.programId,\n mint: new PublicKey(poolInfo.mintA.address),\n owner: this.scope.ownerPubKey,\n\n createInfo:\n mintAUseSOLBalance || amountMaxA.isZero()\n ? {\n payer: this.scope.ownerPubKey,\n amount: amountMaxA,\n }\n : undefined,\n\n skipCloseAccount: !mintAUseSOLBalance,\n notUseTokenAccount: mintAUseSOLBalance,\n associatedOnly: mintAUseSOLBalance ? false : associatedOnly,\n checkCreateATAOwner,\n });\n if (_ownerTokenAccountA) ownerTokenAccountA = _ownerTokenAccountA;\n txBuilder.addInstruction(_tokenAccountAInstruction || {});\n\n const { account: _ownerTokenAccountB, instructionParams: _tokenAccountBInstruction } =\n await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: poolInfo.mintB.programId,\n mint: new PublicKey(poolInfo.mintB.address),\n owner: this.scope.ownerPubKey,\n\n createInfo:\n mintBUseSOLBalance || amountMaxB.isZero()\n ? {\n payer: this.scope.ownerPubKey!,\n amount: amountMaxB,\n }\n : undefined,\n skipCloseAccount: !mintBUseSOLBalance,\n notUseTokenAccount: mintBUseSOLBalance,\n associatedOnly: mintBUseSOLBalance ? false : associatedOnly,\n checkCreateATAOwner,\n });\n if (_ownerTokenAccountB) ownerTokenAccountB = _ownerTokenAccountB;\n txBuilder.addInstruction(_tokenAccountBInstruction || {});\n\n if (ownerTokenAccountA === undefined || ownerTokenAccountB === undefined)\n this.logAndCreateError(\"cannot found target token accounts\", \"tokenAccounts\", this.scope.account.tokenAccounts);\n\n const poolKeys = propPoolKeys || (await this.getClmmPoolKeys(poolInfo.id.toString()));\n\n const makeOpenPositionInstructions = await ClmmInstrument.openPositionFromLiquidityInstructions({\n poolInfo,\n poolKeys,\n ownerInfo: {\n wallet: this.scope.ownerPubKey,\n tokenAccountA: ownerTokenAccountA!,\n tokenAccountB: ownerTokenAccountB!,\n },\n tickLower,\n tickUpper,\n liquidity,\n amountMaxA,\n amountMaxB,\n base,\n withMetadata,\n getEphemeralSigners,\n nft2022,\n });\n txBuilder.addInstruction(makeOpenPositionInstructions);\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n return txBuilder.versionBuild<OpenPositionFromLiquidityExtInfo>({\n txVersion,\n extInfo: { address: makeOpenPositionInstructions.address },\n }) as Promise<MakeTxData<T, OpenPositionFromLiquidityExtInfo>>;\n }\n\n public async increasePositionFromLiquidity<T extends TxVersion>(\n props: IncreasePositionFromLiquidity<T>,\n ): Promise<MakeTxData<T, ManipulateLiquidityExtInfo>> {\n const {\n poolInfo,\n poolKeys: propPoolKeys,\n ownerPosition,\n amountMaxA,\n amountMaxB,\n liquidity,\n ownerInfo,\n associatedOnly = true,\n checkCreateATAOwner = false,\n computeBudgetConfig,\n txTipConfig,\n txVersion,\n feePayer,\n } = props;\n const txBuilder = this.createTxBuilder(feePayer);\n\n let ownerTokenAccountA: PublicKey | undefined = undefined;\n let ownerTokenAccountB: PublicKey | undefined = undefined;\n\n const mintAUseSOLBalance = ownerInfo.useSOLBalance && poolInfo.mintA.address === WSOLMint.toString();\n const mintBUseSOLBalance = ownerInfo.useSOLBalance && poolInfo.mintB.address === WSOLMint.toString();\n const { account: _ownerTokenAccountA, instructionParams: _tokenAccountAInstruction } =\n await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: poolInfo.mintA.programId,\n mint: new PublicKey(poolInfo.mintA.address),\n notUseTokenAccount: mintAUseSOLBalance,\n owner: this.scope.ownerPubKey,\n\n createInfo:\n mintAUseSOLBalance || amountMaxA.isZero()\n ? {\n payer: this.scope.ownerPubKey,\n amount: amountMaxA,\n }\n : undefined,\n skipCloseAccount: !mintAUseSOLBalance,\n associatedOnly: mintAUseSOLBalance ? false : associatedOnly,\n checkCreateATAOwner,\n });\n if (_ownerTokenAccountA) ownerTokenAccountA = _ownerTokenAccountA;\n txBuilder.addInstruction(_tokenAccountAInstruction || {});\n const { account: _ownerTokenAccountB, instructionParams: _tokenAccountBInstruction } =\n await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: poolInfo.mintB.programId,\n mint: new PublicKey(poolInfo.mintB.address),\n owner: this.scope.ownerPubKey,\n\n createInfo:\n mintBUseSOLBalance || amountMaxB.isZero()\n ? {\n payer: this.scope.ownerPubKey!,\n amount: amountMaxB,\n }\n : undefined,\n notUseTokenAccount: mintBUseSOLBalance,\n skipCloseAccount: !mintBUseSOLBalance,\n associatedOnly: mintBUseSOLBalance ? false : associatedOnly,\n checkCreateATAOwner,\n });\n if (_ownerTokenAccountB) ownerTokenAccountB = _ownerTokenAccountB;\n txBuilder.addInstruction(_tokenAccountBInstruction || {});\n\n if (!ownerTokenAccountA && !ownerTokenAccountB)\n this.logAndCreateError(\"cannot found target token accounts\", \"tokenAccounts\", this.scope.account.tokenAccounts);\n const poolKeys = propPoolKeys ?? (await this.getClmmPoolKeys(poolInfo.id));\n const ins = ClmmInstrument.increasePositionFromLiquidityInstructions({\n poolInfo,\n poolKeys,\n ownerPosition,\n ownerInfo: {\n wallet: this.scope.ownerPubKey,\n tokenAccountA: ownerTokenAccountA!,\n tokenAccountB: ownerTokenAccountB!,\n },\n liquidity,\n amountMaxA,\n amountMaxB,\n nft2022: (await this.scope.connection.getAccountInfo(ownerPosition.nftMint))?.owner.equals(TOKEN_2022_PROGRAM_ID),\n });\n txBuilder.addInstruction(ins);\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n return txBuilder.versionBuild<ManipulateLiquidityExtInfo>({\n txVersion,\n extInfo: { address: ins.address },\n }) as Promise<MakeTxData<T, ManipulateLiquidityExtInfo>>;\n }\n\n public async increasePositionFromBase<T extends TxVersion>(\n props: IncreasePositionFromBase<T>,\n ): Promise<MakeTxData<T, ManipulateLiquidityExtInfo>> {\n const {\n poolInfo,\n ownerPosition,\n base,\n baseAmount,\n otherAmountMax,\n ownerInfo,\n associatedOnly = true,\n checkCreateATAOwner = false,\n computeBudgetConfig,\n txTipConfig,\n txVersion,\n feePayer,\n } = props;\n const txBuilder = this.createTxBuilder(feePayer);\n\n let ownerTokenAccountA: PublicKey | undefined = undefined;\n let ownerTokenAccountB: PublicKey | undefined = undefined;\n const mintAUseSOLBalance = ownerInfo.useSOLBalance && poolInfo.mintA.address === WSOLMint.toString();\n const mintBUseSOLBalance = ownerInfo.useSOLBalance && poolInfo.mintB.address === WSOLMint.toString();\n\n const { account: _ownerTokenAccountA, instructionParams: _tokenAccountAInstruction } =\n await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: poolInfo.mintA.programId,\n mint: new PublicKey(poolInfo.mintA.address),\n notUseTokenAccount: mintAUseSOLBalance,\n owner: this.scope.ownerPubKey,\n\n createInfo:\n mintAUseSOLBalance || (base === \"MintA\" ? baseAmount : otherAmountMax).isZero()\n ? {\n payer: this.scope.ownerPubKey,\n amount: base === \"MintA\" ? baseAmount : otherAmountMax,\n }\n : undefined,\n skipCloseAccount: !mintAUseSOLBalance,\n associatedOnly: mintAUseSOLBalance ? false : associatedOnly,\n checkCreateATAOwner,\n });\n if (_ownerTokenAccountA) ownerTokenAccountA = _ownerTokenAccountA;\n txBuilder.addInstruction(_tokenAccountAInstruction || {});\n\n const { account: _ownerTokenAccountB, instructionParams: _tokenAccountBInstruction } =\n await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: poolInfo.mintB.programId,\n mint: new PublicKey(poolInfo.mintB.address),\n owner: this.scope.ownerPubKey,\n\n createInfo:\n mintBUseSOLBalance || (base === \"MintA\" ? otherAmountMax : baseAmount).isZero()\n ? {\n payer: this.scope.ownerPubKey!,\n amount: base === \"MintA\" ? otherAmountMax : baseAmount,\n }\n : undefined,\n notUseTokenAccount: mintBUseSOLBalance,\n skipCloseAccount: !mintBUseSOLBalance,\n associatedOnly: mintBUseSOLBalance ? false : associatedOnly,\n checkCreateATAOwner,\n });\n if (_ownerTokenAccountB) ownerTokenAccountB = _ownerTokenAccountB;\n txBuilder.addInstruction(_tokenAccountBInstruction || {});\n if (!ownerTokenAccountA && !ownerTokenAccountB)\n this.logAndCreateError(\"cannot found target token accounts\", \"tokenAccounts\", this.scope.account.tokenAccounts);\n\n const poolKeys = await this.getClmmPoolKeys(poolInfo.id);\n const ins = ClmmInstrument.increasePositionFromBaseInstructions({\n poolInfo,\n poolKeys,\n ownerPosition,\n ownerInfo: {\n wallet: this.scope.ownerPubKey,\n tokenAccountA: ownerTokenAccountA!,\n tokenAccountB: ownerTokenAccountB!,\n },\n base,\n baseAmount,\n otherAmountMax,\n nft2022: (await this.scope.connection.getAccountInfo(ownerPosition.nftMint))?.owner.equals(TOKEN_2022_PROGRAM_ID),\n });\n txBuilder.addInstruction(ins);\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n return txBuilder.versionBuild<ManipulateLiquidityExtInfo>({\n txVersion,\n extInfo: { address: ins.address },\n }) as Promise<MakeTxData<T, ManipulateLiquidityExtInfo>>;\n }\n\n public async decreaseLiquidity<T extends TxVersion>(\n props: DecreaseLiquidity<T>,\n ): Promise<MakeTxData<T, ManipulateLiquidityExtInfo & Partial<ClosePositionExtInfo>>> {\n const {\n poolInfo,\n poolKeys: propPoolKeys,\n ownerPosition,\n ownerInfo,\n amountMinA,\n amountMinB,\n liquidity,\n associatedOnly = true,\n checkCreateATAOwner = false,\n computeBudgetConfig,\n txTipConfig,\n txVersion,\n feePayer,\n } = props;\n if (this.scope.availability.removeConcentratedPosition === false)\n this.logAndCreateError(\"remove position feature disabled in your region\");\n const txBuilder = this.createTxBuilder(feePayer);\n\n const mintAUseSOLBalance = ownerInfo.useSOLBalance && poolInfo.mintA.address === WSOLMint.toString();\n const mintBUseSOLBalance = ownerInfo.useSOLBalance && poolInfo.mintB.address === WSOLMint.toString();\n\n let ownerTokenAccountA: PublicKey | undefined = undefined;\n let ownerTokenAccountB: PublicKey | undefined = undefined;\n const { account: _ownerTokenAccountA, instructionParams: accountAInstructions } =\n await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: poolInfo.mintA.programId,\n mint: new PublicKey(poolInfo.mintA.address),\n notUseTokenAccount: mintAUseSOLBalance,\n owner: this.scope.ownerPubKey,\n createInfo: {\n payer: this.scope.ownerPubKey,\n amount: 0,\n },\n skipCloseAccount: !mintAUseSOLBalance,\n associatedOnly: mintAUseSOLBalance ? false : associatedOnly,\n checkCreateATAOwner,\n });\n ownerTokenAccountA = _ownerTokenAccountA;\n accountAInstructions && txBuilder.addInstruction(accountAInstructions);\n\n const { account: _ownerTokenAccountB, instructionParams: accountBInstructions } =\n await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: poolInfo.mintB.programId,\n mint: new PublicKey(poolInfo.mintB.address),\n notUseTokenAccount: mintBUseSOLBalance,\n owner: this.scope.ownerPubKey,\n createInfo: {\n payer: this.scope.ownerPubKey,\n amount: 0,\n },\n skipCloseAccount: !mintBUseSOLBalance,\n associatedOnly: mintBUseSOLBalance ? false : associatedOnly,\n checkCreateATAOwner,\n });\n ownerTokenAccountB = _ownerTokenAccountB;\n accountBInstructions && txBuilder.addInstruction(accountBInstructions);\n\n const poolKeys = propPoolKeys ?? (await this.getClmmPoolKeys(poolInfo.id));\n const rewardAccounts: PublicKey[] = [];\n for (const itemReward of poolKeys.rewardInfos) {\n const rewardUseSOLBalance = ownerInfo.useSOLBalance && itemReward.mint.address === WSOLMint.toString();\n\n let ownerRewardAccount: PublicKey | undefined;\n\n if (itemReward.mint.address === poolInfo.mintA.address) ownerRewardAccount = ownerTokenAccountA;\n else if (itemReward.mint.address === poolInfo.mintB.address) ownerRewardAccount = ownerTokenAccountB;\n else {\n const { account: _ownerRewardAccount, instructionParams: ownerRewardAccountInstructions } =\n await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: new PublicKey(itemReward.mint.programId),\n mint: new PublicKey(itemReward.mint.address),\n notUseTokenAccount: rewardUseSOLBalance,\n owner: this.scope.ownerPubKey,\n createInfo: {\n payer: this.scope.ownerPubKey,\n amount: 0,\n },\n skipCloseAccount: !rewardUseSOLBalance,\n associatedOnly: rewardUseSOLBalance ? false : associatedOnly,\n checkCreateATAOwner,\n });\n ownerRewardAccount = _ownerRewardAccount;\n ownerRewardAccountInstructions && txBuilder.addInstruction(ownerRewardAccountInstructions);\n }\n\n rewardAccounts.push(ownerRewardAccount!);\n }\n\n if (!ownerTokenAccountA && !ownerTokenAccountB)\n this.logAndCreateError(\n \"cannot found target token accounts\",\n \"tokenAccounts\",\n this.scope.account.tokenAccountRawInfos,\n );\n\n const nft2022 = (await this.scope.connection.getAccountInfo(ownerPosition.nftMint))?.owner.equals(\n TOKEN_2022_PROGRAM_ID,\n );\n\n const decreaseInsInfo = await ClmmInstrument.decreaseLiquidityInstructions({\n poolInfo,\n poolKeys,\n ownerPosition,\n ownerInfo: {\n wallet: this.scope.ownerPubKey,\n tokenAccountA: ownerTokenAccountA!,\n tokenAccountB: ownerTokenAccountB!,\n rewardAccounts,\n },\n liquidity,\n amountMinA,\n amountMinB,\n nft2022,\n });\n\n txBuilder.addInstruction({\n instructions: decreaseInsInfo.instructions,\n instructionTypes: [InstructionType.ClmmDecreasePosition],\n });\n\n let extInfo = { ...decreaseInsInfo.address };\n if (ownerInfo.closePosition) {\n const closeInsInfo = await ClmmInstrument.closePositionInstructions({\n poolInfo,\n poolKeys,\n ownerInfo: { wallet: this.scope.ownerPubKey },\n ownerPosition,\n nft2022,\n });\n txBuilder.addInstruction({\n endInstructions: closeInsInfo.instructions,\n endInstructionTypes: closeInsInfo.instructionTypes,\n });\n extInfo = { ...extInfo, ...closeInsInfo.address };\n }\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n return txBuilder.versionBuild<ManipulateLiquidityExtInfo>({\n txVersion,\n extInfo: { address: extInfo },\n }) as Promise<MakeTxData<T, ManipulateLiquidityExtInfo>>;\n }\n\n public async lockPosition<T extends TxVersion>(props: LockPosition<T>): Promise<MakeTxData<ClmmLockAddress>> {\n const {\n programId = CLMM_LOCK_PROGRAM_ID,\n authProgramId = CLMM_LOCK_AUTH_ID,\n poolProgramId = CLMM_PROGRAM_ID,\n ownerPosition,\n payer,\n computeBudgetConfig,\n txTipConfig,\n txVersion,\n getEphemeralSigners,\n feePayer,\n } = props;\n const txBuilder = this.createTxBuilder(feePayer);\n const lockIns = await ClmmInstrument.makeLockPositions({\n programId,\n authProgramId,\n poolProgramId,\n wallet: this.scope.ownerPubKey,\n payer: payer ?? this.scope.ownerPubKey,\n nftMint: ownerPosition.nftMint,\n getEphemeralSigners,\n nft2022: (await this.scope.connection.getAccountInfo(ownerPosition.nftMint))?.owner.equals(TOKEN_2022_PROGRAM_ID),\n });\n\n txBuilder.addInstruction(lockIns);\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n return txBuilder.versionBuild({\n txVersion,\n extInfo: lockIns.address,\n }) as Promise<MakeTxData<ClmmLockAddress>>;\n }\n\n public async harvestLockPosition<T extends TxVersion>(props: HarvestLockPosition<T>): Promise<MakeTxData<T>> {\n const {\n programId = CLMM_LOCK_PROGRAM_ID,\n authProgramId = CLMM_LOCK_AUTH_ID,\n clmmProgram = CLMM_PROGRAM_ID,\n poolKeys: propPoolKeys,\n lockData,\n ownerInfo = { useSOLBalance: true },\n associatedOnly = true,\n checkCreateATAOwner = false,\n computeBudgetConfig,\n txTipConfig,\n txVersion,\n feePayer,\n } = props;\n\n const poolKeys = propPoolKeys || (await this.getClmmPoolKeys(lockData.poolId.toString()));\n const txBuilder = this.createTxBuilder(feePayer);\n\n const positionData = await this.scope.connection.getAccountInfo(lockData.positionId);\n if (!positionData) this.logger.logWithError(\"position not found\", lockData.positionId);\n const position = PersonalPositionLayout.decode(positionData!.data);\n\n const mintAUseSOLBalance = ownerInfo.useSOLBalance && poolKeys.mintA.address === WSOLMint.toString();\n const mintBUseSOLBalance = ownerInfo.useSOLBalance && poolKeys.mintB.address === WSOLMint.toString();\n\n let ownerTokenAccountA: PublicKey | undefined = undefined;\n let ownerTokenAccountB: PublicKey | undefined = undefined;\n const { account: _ownerTokenAccountA, instructionParams: accountAInstructions } =\n await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: poolKeys.mintA.programId,\n mint: new PublicKey(poolKeys.mintA.address),\n notUseTokenAccount: mintAUseSOLBalance,\n owner: this.scope.ownerPubKey,\n createInfo: {\n payer: this.scope.ownerPubKey,\n amount: 0,\n },\n skipCloseAccount: !mintAUseSOLBalance,\n associatedOnly: mintAUseSOLBalance ? false : associatedOnly,\n checkCreateATAOwner,\n });\n ownerTokenAccountA = _ownerTokenAccountA;\n accountAInstructions && txBuilder.addInstruction(accountAInstructions);\n\n const { account: _ownerTokenAccountB, instructionParams: accountBInstructions } =\n await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: poolKeys.mintB.programId,\n mint: new PublicKey(poolKeys.mintB.address),\n notUseTokenAccount: mintBUseSOLBalance,\n owner: this.scope.ownerPubKey,\n createInfo: {\n payer: this.scope.ownerPubKey,\n amount: 0,\n },\n skipCloseAccount: !mintBUseSOLBalance,\n associatedOnly: mintBUseSOLBalance ? false : associatedOnly,\n checkCreateATAOwner,\n });\n ownerTokenAccountB = _ownerTokenAccountB;\n accountBInstructions && txBuilder.addInstruction(accountBInstructions);\n\n const ownerMintToAccount: { [mint: string]: PublicKey } = {};\n const rewardAccounts: PublicKey[] = [];\n for (const itemReward of poolKeys.rewardInfos) {\n const rewardUseSOLBalance = ownerInfo.useSOLBalance && itemReward.mint.address === WSOLMint.toString();\n let ownerRewardAccount = ownerMintToAccount[itemReward.mint.address];\n if (!ownerRewardAccount) {\n const { account, instructionParams } = await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: new PublicKey(itemReward.mint.programId),\n mint: new PublicKey(itemReward.mint.address),\n notUseTokenAccount: rewardUseSOLBalance,\n owner: this.scope.ownerPubKey,\n skipCloseAccount: !rewardUseSOLBalance,\n createInfo: {\n payer: this.scope.ownerPubKey,\n amount: 0,\n },\n associatedOnly: rewardUseSOLBalance ? false : associatedOnly,\n });\n ownerRewardAccount = account!;\n instructionParams && txBuilder.addInstruction(instructionParams);\n }\n\n ownerMintToAccount[itemReward.mint.address] = ownerRewardAccount;\n rewardAccounts.push(ownerRewardAccount!);\n }\n const lockPositionId = getPdaLockClPositionIdV2(programId, lockData.lockNftMint).publicKey;\n const lockNftAccount = getATAAddress(this.scope.ownerPubKey, lockData.lockNftMint, TOKEN_PROGRAM_ID).publicKey;\n\n const tickArrayLowerStartIndex = TickArrayUtil.getTickArrayStartIndex(\n position.tickLower,\n poolKeys.config.tickSpacing,\n );\n const tickArrayUpperStartIndex = TickArrayUtil.getTickArrayStartIndex(\n position.tickUpper,\n poolKeys.config.tickSpacing,\n );\n const { publicKey: tickArrayLower } = getPdaTickArrayAddress(\n new PublicKey(poolKeys.programId),\n lockData.poolId,\n tickArrayLowerStartIndex,\n );\n const { publicKey: tickArrayUpper } = getPdaTickArrayAddress(\n new PublicKey(poolKeys.programId),\n lockData.poolId,\n tickArrayUpperStartIndex,\n );\n const { publicKey: protocolPosition } = getPdaProtocolPositionAddress(\n new PublicKey(poolKeys.programId),\n lockData.poolId,\n position.tickLower,\n position.tickUpper,\n );\n\n const rewardAccountsFullInfo: {\n poolRewardVault: PublicKey;\n ownerRewardVault: PublicKey;\n rewardMint: PublicKey;\n }[] = [];\n for (let i = 0; i < poolKeys.rewardInfos.length; i++) {\n const mint = poolKeys.rewardInfos[i].mint.address;\n const ownerRewardVault = ownerMintToAccount[mint];\n if (ownerRewardVault) {\n rewardAccountsFullInfo.push({\n poolRewardVault: new PublicKey(poolKeys.rewardInfos[i].vault),\n ownerRewardVault,\n rewardMint: new PublicKey(mint),\n });\n }\n }\n\n const harvestLockIns = await ClmmInstrument.harvestLockPositionInstructionV2({\n programId,\n auth: authProgramId,\n lockPositionId,\n clmmProgram,\n lockOwner: this.scope.ownerPubKey,\n lockNftMint: lockData.lockNftMint,\n lockNftAccount,\n positionNftAccount: lockData.nftAccount,\n positionId: lockData.positionId,\n poolId: lockData.poolId,\n protocolPosition,\n vaultA: new PublicKey(poolKeys.vault.A),\n vaultB: new PublicKey(poolKeys.vault.B),\n tickArrayLower,\n tickArrayUpper,\n userVaultA: ownerTokenAccountA!,\n userVaultB: ownerTokenAccountB!,\n mintA: new PublicKey(poolKeys.mintA.address),\n mintB: new PublicKey(poolKeys.mintB.address),\n rewardAccounts: rewardAccountsFullInfo,\n exTickArrayBitmap: getPdaExBitmapAccount(clmmProgram, lockData.poolId).publicKey,\n });\n\n txBuilder.addInstruction({\n instructions: [harvestLockIns],\n instructionTypes: [InstructionType.ClmmHarvestLockPosition],\n });\n\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n return txBuilder.versionBuild({\n txVersion,\n }) as Promise<MakeTxData<T>>;\n }\n\n public async closePosition<T extends TxVersion>({\n poolInfo,\n poolKeys: propPoolKeys,\n ownerPosition,\n txVersion,\n computeBudgetConfig,\n txTipConfig,\n feePayer,\n }: {\n poolInfo: ApiV3PoolInfoConcentratedItem;\n poolKeys?: ClmmKeys;\n ownerPosition: ReturnType<typeof PersonalPositionLayout.decode>;\n computeBudgetConfig?: ComputeBudgetConfig;\n txTipConfig?: TxTipConfig;\n txVersion: T;\n feePayer?: PublicKey;\n }): Promise<MakeTxData<T, ClosePositionExtInfo>> {\n if (this.scope.availability.removeConcentratedPosition === false)\n this.logAndCreateError(\"remove position feature disabled in your region\");\n const txBuilder = this.createTxBuilder(feePayer);\n const poolKeys = propPoolKeys ?? (await this.getClmmPoolKeys(poolInfo.id));\n const ins = ClmmInstrument.closePositionInstructions({\n poolInfo,\n poolKeys,\n ownerInfo: { wallet: this.scope.ownerPubKey },\n ownerPosition,\n nft2022: (await this.scope.connection.getAccountInfo(ownerPosition.nftMint))?.owner.equals(TOKEN_2022_PROGRAM_ID),\n });\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n return txBuilder.addInstruction(ins).versionBuild<ClosePositionExtInfo>({\n txVersion,\n extInfo: { address: ins.address },\n }) as Promise<MakeTxData<T, ClosePositionExtInfo>>;\n }\n\n public async initReward<T extends TxVersion>({\n poolInfo,\n ownerInfo,\n rewardInfo,\n associatedOnly = true,\n checkCreateATAOwner = false,\n computeBudgetConfig,\n txVersion,\n feePayer,\n }: InitRewardParams<T>): Promise<MakeTxData<T, InitRewardExtInfo>> {\n if (rewardInfo.endTime <= rewardInfo.openTime)\n this.logAndCreateError(\"reward time error\", \"rewardInfo\", rewardInfo);\n\n const txBuilder = this.createTxBuilder(feePayer);\n\n const rewardMintUseSOLBalance =\n ownerInfo.useSOLBalance && rewardInfo.mint.address.toString() === WSOLMint.toString();\n const _baseRewardAmount = rewardInfo.perSecond.mul(rewardInfo.endTime - rewardInfo.openTime);\n\n const { account: ownerRewardAccount, instructionParams: ownerRewardAccountIns } =\n await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: new PublicKey(rewardInfo.mint.programId),\n mint: new PublicKey(rewardInfo.mint.address),\n notUseTokenAccount: !!rewardMintUseSOLBalance,\n skipCloseAccount: !rewardMintUseSOLBalance,\n owner: this.scope.ownerPubKey,\n createInfo: rewardMintUseSOLBalance\n ? {\n payer: ownerInfo.feePayer || this.scope.ownerPubKey,\n amount: new BN(\n new Decimal(_baseRewardAmount.toFixed(0)).gte(_baseRewardAmount)\n ? _baseRewardAmount.toFixed(0)\n : _baseRewardAmount.add(1).toFixed(0),\n ),\n }\n : undefined,\n associatedOnly: rewardMintUseSOLBalance ? false : associatedOnly,\n checkCreateATAOwner,\n });\n ownerRewardAccountIns && txBuilder.addInstruction(ownerRewardAccountIns);\n\n if (!ownerRewardAccount)\n this.logAndCreateError(\"no money\", \"ownerRewardAccount\", this.scope.account.tokenAccountRawInfos);\n const poolKeys = await this.getClmmPoolKeys(poolInfo.id);\n const insInfo = ClmmInstrument.initRewardInstructions({\n poolInfo,\n poolKeys,\n ownerInfo: {\n wallet: this.scope.ownerPubKey,\n tokenAccount: ownerRewardAccount!,\n },\n rewardInfo: {\n programId: new PublicKey(rewardInfo.mint.programId),\n mint: new PublicKey(rewardInfo.mint.address),\n openTime: rewardInfo.openTime,\n endTime: rewardInfo.endTime,\n emissionsPerSecondX64: decimalToX64(rewardInfo.perSecond),\n },\n });\n txBuilder.addInstruction(insInfo);\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n return txBuilder.versionBuild<InitRewardExtInfo>({\n txVersion,\n extInfo: { address: insInfo.address },\n }) as Promise<MakeTxData<T, InitRewardExtInfo>>;\n }\n\n public async initRewards<T extends TxVersion>({\n poolInfo,\n poolKeys: propPoolKeys,\n ownerInfo,\n rewardInfos,\n associatedOnly = true,\n checkCreateATAOwner = false,\n computeBudgetConfig,\n txTipConfig,\n txVersion,\n feePayer,\n }: InitRewardsParams<T>): Promise<MakeTxData<T, { address: Record<string, PublicKey> }>> {\n for (const rewardInfo of rewardInfos) {\n if (rewardInfo.endTime <= rewardInfo.openTime)\n this.logAndCreateError(\"reward time error\", \"rewardInfo\", rewardInfo);\n }\n\n const txBuilder = this.createTxBuilder(feePayer);\n let address: Record<string, PublicKey> = {};\n\n for (const rewardInfo of rewardInfos) {\n const rewardMintUseSOLBalance = ownerInfo.useSOLBalance && rewardInfo.mint.address === WSOLMint.toString();\n const _baseRewardAmount = rewardInfo.perSecond.mul(rewardInfo.endTime - rewardInfo.openTime);\n\n const { account: ownerRewardAccount, instructionParams: ownerRewardAccountIns } =\n await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: new PublicKey(rewardInfo.mint.programId),\n mint: new PublicKey(rewardInfo.mint.address),\n notUseTokenAccount: !!rewardMintUseSOLBalance,\n skipCloseAccount: !rewardMintUseSOLBalance,\n owner: this.scope.ownerPubKey,\n createInfo: rewardMintUseSOLBalance\n ? {\n payer: ownerInfo.feePayer || this.scope.ownerPubKey,\n amount: new BN(\n new Decimal(_baseRewardAmount.toFixed(0)).gte(_baseRewardAmount)\n ? _baseRewardAmount.toFixed(0)\n : _baseRewardAmount.add(1).toFixed(0),\n ),\n }\n : undefined,\n associatedOnly: rewardMintUseSOLBalance ? false : associatedOnly,\n checkCreateATAOwner,\n });\n ownerRewardAccountIns && txBuilder.addInstruction(ownerRewardAccountIns);\n\n if (!ownerRewardAccount)\n this.logAndCreateError(\"no money\", \"ownerRewardAccount\", this.scope.account.tokenAccountRawInfos);\n\n const poolKeys = propPoolKeys ?? (await this.getClmmPoolKeys(poolInfo.id));\n const insInfo = ClmmInstrument.initRewardInstructions({\n poolInfo,\n poolKeys,\n ownerInfo: {\n wallet: this.scope.ownerPubKey,\n tokenAccount: ownerRewardAccount!,\n },\n rewardInfo: {\n programId: new PublicKey(rewardInfo.mint.programId),\n mint: new PublicKey(rewardInfo.mint.address),\n openTime: rewardInfo.openTime,\n endTime: rewardInfo.endTime,\n emissionsPerSecondX64: decimalToX64(rewardInfo.perSecond),\n },\n });\n address = {\n ...address,\n ...insInfo.address,\n };\n txBuilder.addInstruction(insInfo);\n }\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n return txBuilder.versionBuild({\n txVersion,\n extInfo: { address },\n }) as Promise<MakeTxData<T, { address: Record<string, PublicKey> }>>;\n }\n\n public async setReward<T extends TxVersion>({\n poolInfo,\n ownerInfo,\n rewardInfo,\n associatedOnly = true,\n checkCreateATAOwner = false,\n computeBudgetConfig,\n txTipConfig,\n txVersion,\n feePayer,\n }: SetRewardParams<T>): Promise<MakeTxData<T, { address: Record<string, PublicKey> }>> {\n if (rewardInfo.endTime <= rewardInfo.openTime)\n this.logAndCreateError(\"reward time error\", \"rewardInfo\", rewardInfo);\n\n const txBuilder = this.createTxBuilder(feePayer);\n const rewardMintUseSOLBalance = ownerInfo.useSOLBalance && rewardInfo.mint.equals(WSOLMint);\n const { account: ownerRewardAccount, instructionParams: ownerRewardIns } =\n await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: rewardInfo.programId,\n mint: rewardInfo.mint,\n notUseTokenAccount: rewardMintUseSOLBalance,\n owner: this.scope.ownerPubKey,\n createInfo: rewardMintUseSOLBalance\n ? {\n payer: ownerInfo.feePayer || this.scope.ownerPubKey,\n amount: new BN(\n new Decimal(rewardInfo.perSecond.mul(rewardInfo.endTime - rewardInfo.openTime).toFixed(0)).gte(\n rewardInfo.perSecond.mul(rewardInfo.endTime - rewardInfo.openTime),\n )\n ? rewardInfo.perSecond.mul(rewardInfo.endTime - rewardInfo.openTime).toFixed(0)\n : rewardInfo.perSecond\n .mul(rewardInfo.endTime - rewardInfo.openTime)\n .add(1)\n .toFixed(0),\n ),\n }\n : undefined,\n\n associatedOnly: rewardMintUseSOLBalance ? false : associatedOnly,\n checkCreateATAOwner,\n });\n ownerRewardIns && txBuilder.addInstruction(ownerRewardIns);\n if (!ownerRewardAccount)\n this.logAndCreateError(\"no money\", \"ownerRewardAccount\", this.scope.account.tokenAccountRawInfos);\n const poolKeys = await this.getClmmPoolKeys(poolInfo.id);\n const insInfo = ClmmInstrument.setRewardInstructions({\n poolInfo,\n poolKeys,\n ownerInfo: {\n wallet: this.scope.ownerPubKey,\n tokenAccount: ownerRewardAccount!,\n },\n rewardInfo: {\n mint: rewardInfo.mint,\n openTime: rewardInfo.openTime,\n endTime: rewardInfo.endTime,\n emissionsPerSecondX64: decimalToX64(rewardInfo.perSecond),\n },\n });\n\n txBuilder.addInstruction(insInfo);\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n return txBuilder.versionBuild<{ address: Record<string, PublicKey> }>({\n txVersion,\n extInfo: { address: insInfo.address },\n }) as Promise<MakeTxData<T, { address: Record<string, PublicKey> }>>;\n }\n\n public async setRewards<T extends TxVersion>({\n poolInfo,\n poolKeys: propPoolKeys,\n ownerInfo,\n rewardInfos,\n associatedOnly = true,\n checkCreateATAOwner = false,\n computeBudgetConfig,\n txTipConfig,\n txVersion,\n feePayer,\n }: SetRewardsParams<T>): Promise<MakeTxData<T, { address: Record<string, PublicKey> }>> {\n const txBuilder = this.createTxBuilder(feePayer);\n let address: Record<string, PublicKey> = {};\n for (const rewardInfo of rewardInfos) {\n if (rewardInfo.endTime <= rewardInfo.openTime)\n this.logAndCreateError(\"reward time error\", \"rewardInfo\", rewardInfo);\n\n const rewardMintUseSOLBalance = ownerInfo.useSOLBalance && rewardInfo.mint.address === WSOLMint.toString();\n const { account: ownerRewardAccount, instructionParams: ownerRewardIns } =\n await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: new PublicKey(rewardInfo.mint.programId),\n mint: new PublicKey(rewardInfo.mint.address),\n notUseTokenAccount: rewardMintUseSOLBalance,\n owner: this.scope.ownerPubKey,\n createInfo: rewardMintUseSOLBalance\n ? {\n payer: ownerInfo.feePayer || this.scope.ownerPubKey,\n amount: new BN(\n new Decimal(rewardInfo.perSecond.mul(rewardInfo.endTime - rewardInfo.openTime).toFixed(0)).gte(\n rewardInfo.perSecond.mul(rewardInfo.endTime - rewardInfo.openTime),\n )\n ? rewardInfo.perSecond.mul(rewardInfo.endTime - rewardInfo.openTime).toFixed(0)\n : rewardInfo.perSecond\n .mul(rewardInfo.endTime - rewardInfo.openTime)\n .add(1)\n .toFixed(0),\n ),\n }\n : undefined,\n associatedOnly: rewardMintUseSOLBalance ? false : associatedOnly,\n checkCreateATAOwner,\n });\n ownerRewardIns && txBuilder.addInstruction(ownerRewardIns);\n if (!ownerRewardAccount)\n this.logAndCreateError(\"no money\", \"ownerRewardAccount\", this.scope.account.tokenAccountRawInfos);\n const poolKeys = propPoolKeys ?? (await this.getClmmPoolKeys(poolInfo.id));\n const insInfo = ClmmInstrument.setRewardInstructions({\n poolInfo,\n poolKeys,\n ownerInfo: {\n wallet: this.scope.ownerPubKey,\n tokenAccount: ownerRewardAccount!,\n },\n rewardInfo: {\n mint: new PublicKey(rewardInfo.mint.address),\n openTime: rewardInfo.openTime,\n endTime: rewardInfo.endTime,\n emissionsPerSecondX64: decimalToX64(rewardInfo.perSecond),\n },\n });\n txBuilder.addInstruction(insInfo);\n address = {\n ...address,\n ...insInfo.address,\n };\n }\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n return txBuilder.versionBuild<{ address: Record<string, PublicKey> }>({\n txVersion,\n extInfo: { address },\n }) as Promise<MakeTxData<T, { address: Record<string, PublicKey> }>>;\n }\n\n public async collectReward<T extends TxVersion>({\n poolInfo,\n ownerInfo,\n rewardMint,\n associatedOnly = true,\n checkCreateATAOwner = false,\n computeBudgetConfig,\n txTipConfig,\n txVersion,\n feePayer,\n }: CollectRewardParams<T>): Promise<MakeTxData<{ address: Record<string, PublicKey> }>> {\n const rewardInfo = poolInfo!.rewardDefaultInfos.find((i) => i.mint.address === rewardMint.toString());\n if (!rewardInfo) this.logAndCreateError(\"reward mint error\", \"not found reward mint\", rewardMint);\n\n const txBuilder = this.createTxBuilder(feePayer);\n const rewardMintUseSOLBalance = ownerInfo.useSOLBalance && rewardMint.equals(WSOLMint);\n const { account: ownerRewardAccount, instructionParams: ownerRewardIns } =\n await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: new PublicKey(rewardInfo!.mint.programId),\n mint: rewardMint,\n notUseTokenAccount: rewardMintUseSOLBalance,\n owner: this.scope.ownerPubKey,\n skipCloseAccount: !rewardMintUseSOLBalance,\n createInfo: {\n payer: ownerInfo.feePayer || this.scope.ownerPubKey,\n amount: 0,\n },\n associatedOnly: rewardMintUseSOLBalance ? false : associatedOnly,\n checkCreateATAOwner,\n });\n ownerRewardIns && txBuilder.addInstruction(ownerRewardIns);\n\n if (!ownerRewardAccount)\n this.logAndCreateError(\"no money\", \"ownerRewardAccount\", this.scope.account.tokenAccountRawInfos);\n const poolKeys = await this.getClmmPoolKeys(poolInfo.id);\n const insInfo = ClmmInstrument.collectRewardInstructions({\n poolInfo,\n poolKeys,\n ownerInfo: {\n wallet: this.scope.ownerPubKey,\n tokenAccount: ownerRewardAccount!,\n },\n rewardMint,\n });\n txBuilder.addInstruction(insInfo);\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n return txBuilder.versionBuild<{ address: Record<string, PublicKey> }>({\n txVersion,\n extInfo: { address: insInfo.address },\n }) as Promise<MakeTxData<{ address: Record<string, PublicKey> }>>;\n }\n\n public async collectRewards({\n poolInfo,\n ownerInfo,\n rewardMints,\n associatedOnly = true,\n checkCreateATAOwner = false,\n computeBudgetConfig,\n txTipConfig,\n feePayer,\n }: CollectRewardsParams): Promise<MakeTransaction> {\n const txBuilder = this.createTxBuilder(feePayer);\n let address: Record<string, PublicKey> = {};\n\n for (const rewardMint of rewardMints) {\n const rewardInfo = poolInfo!.rewardDefaultInfos.find((i) => i.mint.address === rewardMint.toString());\n if (!rewardInfo) {\n this.logAndCreateError(\"reward mint error\", \"not found reward mint\", rewardMint);\n continue;\n }\n\n const rewardMintUseSOLBalance = ownerInfo.useSOLBalance && rewardMint.equals(WSOLMint);\n const { account: ownerRewardAccount, instructionParams: ownerRewardIns } =\n await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: new PublicKey(rewardInfo.mint.programId),\n mint: rewardMint,\n notUseTokenAccount: rewardMintUseSOLBalance,\n owner: this.scope.ownerPubKey,\n skipCloseAccount: !rewardMintUseSOLBalance,\n createInfo: {\n payer: ownerInfo.feePayer || this.scope.ownerPubKey,\n amount: 0,\n },\n associatedOnly: rewardMintUseSOLBalance ? false : associatedOnly,\n checkCreateATAOwner,\n });\n if (!ownerRewardAccount)\n this.logAndCreateError(\"no money\", \"ownerRewardAccount\", this.scope.account.tokenAccountRawInfos);\n ownerRewardIns && txBuilder.addInstruction(ownerRewardIns);\n const poolKeys = await this.getClmmPoolKeys(poolInfo.id);\n const insInfo = ClmmInstrument.collectRewardInstructions({\n poolInfo,\n poolKeys,\n ownerInfo: {\n wallet: this.scope.ownerPubKey,\n tokenAccount: ownerRewardAccount!,\n },\n\n rewardMint,\n });\n txBuilder.addInstruction(insInfo);\n address = { ...address, ...insInfo.address };\n }\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n return txBuilder.build<{ address: Record<string, PublicKey> }>({ address });\n }\n\n public async openLimitOrder<T extends TxVersion>({\n poolInfo,\n baseIn = true,\n orderTick,\n amount,\n noneIndex = 0,\n tickArrayBitmap,\n ownerInfo = {\n useSOLBalance: true,\n },\n associatedOnly = true,\n feePayer,\n computeBudgetConfig,\n txTipConfig,\n txVersion,\n }: OpenLimitOrder<T>): Promise<MakeTxData<T, { limitOrder: PublicKey }>> {\n const poolId = new PublicKey(poolInfo.id);\n const programId = new PublicKey(poolInfo.programId);\n const inputMint = baseIn ? new PublicKey(poolInfo.mintA.address) : new PublicKey(poolInfo.mintB.address);\n const outputMint = baseIn ? new PublicKey(poolInfo.mintB.address) : new PublicKey(poolInfo.mintA.address);\n const inputMintProgram = new PublicKey(poolInfo[baseIn ? \"mintA\" : \"mintB\"].programId);\n const outputMintProgram = new PublicKey(poolInfo[baseIn ? \"mintB\" : \"mintA\"].programId);\n const isInputSol = inputMint.equals(WSOLMint);\n const isOutputSol = outputMint.equals(WSOLMint);\n const inputUseSolBalance = ownerInfo.useSOLBalance && isInputSol;\n const outputUseSolBalance = ownerInfo.useSOLBalance && isOutputSol;\n\n const txBuilder = this.createTxBuilder();\n\n let ownerInputTokenAccount: PublicKey | undefined =\n inputUseSolBalance || !associatedOnly\n ? undefined\n : getATAAddress(this.scope.ownerPubKey, inputMint, inputMintProgram).publicKey;\n\n if (!ownerInputTokenAccount) {\n const { account, instructionParams } = await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: inputMintProgram,\n mint: inputMint,\n notUseTokenAccount: inputUseSolBalance,\n owner: this.scope.ownerPubKey,\n skipCloseAccount: !inputUseSolBalance,\n createInfo: {\n payer: ownerInfo.feePayer || this.scope.ownerPubKey,\n amount,\n },\n associatedOnly: !inputUseSolBalance,\n });\n ownerInputTokenAccount = account!;\n instructionParams && txBuilder.addInstruction(instructionParams);\n } else {\n txBuilder.addInstruction({\n instructions: [\n createAssociatedTokenAccountIdempotentInstruction(\n this.scope.ownerPubKey,\n ownerInputTokenAccount,\n this.scope.ownerPubKey,\n inputMint,\n inputMintProgram,\n ),\n ],\n });\n }\n\n let ownerOutputTokenAccount: PublicKey | undefined =\n outputUseSolBalance || !associatedOnly\n ? undefined\n : getATAAddress(this.scope.ownerPubKey, outputMint, outputMintProgram).publicKey;\n\n if (!ownerOutputTokenAccount) {\n const { account, instructionParams } = await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: outputMintProgram,\n mint: outputMint,\n notUseTokenAccount: outputUseSolBalance,\n owner: this.scope.ownerPubKey,\n skipCloseAccount: !outputUseSolBalance,\n createInfo: {\n payer: ownerInfo.feePayer || this.scope.ownerPubKey,\n amount,\n },\n associatedOnly: !outputUseSolBalance,\n });\n ownerOutputTokenAccount = account!;\n instructionParams && txBuilder.addInstruction(instructionParams);\n } else {\n txBuilder.addInstruction({\n instructions: [\n createAssociatedTokenAccountIdempotentInstruction(\n this.scope.ownerPubKey,\n ownerOutputTokenAccount,\n this.scope.ownerPubKey,\n outputMint,\n outputMintProgram,\n ),\n ],\n });\n }\n\n const limitOrderNonce = getPdaLimitOrderNonceAddress(programId, this.scope.ownerPubKey, noneIndex).publicKey;\n const res = await this.scope.connection.getAccountInfo(limitOrderNonce);\n\n const orderNonce = res ? LimitOrderNonceLayout.decode(res.data).orderNonce : new BN(0);\n\n const limitOrder = getPdaLimitOrderAddress(\n programId,\n feePayer || this.scope.ownerPubKey,\n limitOrderNonce,\n orderNonce,\n ).publicKey;\n const tickArrayStart = TickArrayUtil.getTickArrayStartIndex(orderTick, poolInfo.config.tickSpacing);\n const tickArray = getPdaTickArrayAddress(programId, poolId, tickArrayStart).publicKey;\n const inputVault = getPdaPoolVaultId(\n programId,\n poolId,\n new PublicKey(poolInfo[baseIn ? \"mintA\" : \"mintB\"].address),\n ).publicKey;\n const outputVault = getPdaPoolVaultId(\n programId,\n poolId,\n new PublicKey(poolInfo[baseIn ? \"mintB\" : \"mintA\"].address),\n ).publicKey;\n\n txBuilder.addInstruction({\n instructions: [\n ClmmInstrument.openLimitOrderInstruction(\n programId,\n feePayer || this.scope.ownerPubKey,\n poolId,\n tickArray,\n limitOrderNonce,\n limitOrder,\n ownerInputTokenAccount,\n ownerOutputTokenAccount,\n inputVault,\n outputVault,\n inputMint,\n outputMint,\n inputMintProgram,\n noneIndex,\n baseIn,\n orderTick,\n amount,\n tickArrayBitmap,\n ),\n ],\n });\n\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n return txBuilder.versionBuild({\n txVersion,\n extInfo: {\n limitOrder,\n },\n }) as Promise<MakeTxData<T, { limitOrder: PublicKey }>>;\n }\n\n public async increaseLimitOrder<T extends TxVersion>({\n poolInfo,\n limitOrder,\n amount,\n ownerInfo = {\n useSOLBalance: true,\n },\n associatedOnly = true,\n feePayer,\n computeBudgetConfig,\n txTipConfig,\n txVersion,\n }: IncreaseLimitOrder<T>): Promise<MakeTxData<T>> {\n const poolId = new PublicKey(poolInfo.id);\n const programId = new PublicKey(poolInfo.programId);\n const data = await this.scope.connection.getAccountInfo(limitOrder);\n if (!data) this.logAndCreateError(`limit order ${limitOrder.toBase58()} not exist`);\n const limitOrderData = LimitOrderLayout.decode(data!.data);\n const inputMint = limitOrderData.zeroForOne\n ? new PublicKey(poolInfo.mintA.address)\n : new PublicKey(poolInfo.mintB.address);\n const inputMintProgram = new PublicKey(poolInfo[limitOrderData.zeroForOne ? \"mintA\" : \"mintB\"].programId);\n const isInputSol = inputMint.equals(WSOLMint);\n const inputUseSolBalance = ownerInfo.useSOLBalance && isInputSol;\n\n const txBuilder = this.createTxBuilder();\n\n let ownerInputTokenAccount: PublicKey | undefined =\n inputUseSolBalance || !associatedOnly\n ? undefined\n : getATAAddress(this.scope.ownerPubKey, inputMint, inputMintProgram).publicKey;\n\n if (!ownerInputTokenAccount) {\n const { account, instructionParams } = await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: inputMintProgram,\n mint: inputMint,\n notUseTokenAccount: inputUseSolBalance,\n owner: this.scope.ownerPubKey,\n skipCloseAccount: !inputUseSolBalance,\n createInfo: {\n payer: ownerInfo.feePayer || this.scope.ownerPubKey,\n amount,\n },\n associatedOnly: !inputUseSolBalance,\n });\n ownerInputTokenAccount = account!;\n instructionParams && txBuilder.addInstruction(instructionParams);\n } else {\n txBuilder.addInstruction({\n instructions: [\n createAssociatedTokenAccountIdempotentInstruction(\n this.scope.ownerPubKey,\n ownerInputTokenAccount,\n this.scope.ownerPubKey,\n inputMint,\n inputMintProgram,\n ),\n ],\n });\n }\n\n const inputVault = getPdaPoolVaultId(\n programId,\n poolId,\n new PublicKey(poolInfo[limitOrderData.zeroForOne ? \"mintA\" : \"mintB\"].address),\n ).publicKey;\n\n const tickArrayStart = TickArrayUtil.getTickArrayStartIndex(limitOrderData.tick, poolInfo.config.tickSpacing);\n const tickArray = getPdaTickArrayAddress(programId, poolId, tickArrayStart).publicKey;\n\n txBuilder.addInstruction({\n instructions: [\n ClmmInstrument.increaseLimitOrderInstruction(\n programId,\n feePayer || this.scope.ownerPubKey,\n limitOrderData.poolId,\n tickArray,\n limitOrder,\n ownerInputTokenAccount,\n inputVault,\n inputMint,\n inputMintProgram,\n amount,\n ),\n ],\n });\n\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n return txBuilder.versionBuild({\n txVersion,\n }) as Promise<MakeTxData<T>>;\n }\n\n public async decreaseLimitOrder<T extends TxVersion>({\n poolInfo,\n limitOrder,\n limitOrderInfo: defaultLimitOrderInfo,\n amount,\n slippage = 1000,\n tickArrayBitmap,\n ownerInfo = {\n useSOLBalance: true,\n },\n associatedOnly = true,\n feePayer,\n computeBudgetConfig,\n txTipConfig,\n txVersion,\n forerunCreate,\n }: DecreaseLimitOrder<T>): Promise<MakeTxData<T>> {\n const poolId = new PublicKey(poolInfo.id);\n const programId = new PublicKey(poolInfo.programId);\n let limitOrderData = defaultLimitOrderInfo;\n if (!limitOrderData) {\n const data = await this.scope.connection.getAccountInfo(limitOrder);\n if (!data) this.logAndCreateError(`limit order ${limitOrder.toBase58()} not exist`);\n limitOrderData = LimitOrderLayout.decode(data!.data);\n }\n\n const amountMin = amount.muln(10000 - slippage).divn(10000);\n const unfulfilledAmount = LimitOrderMath.getUnFilledAmount({ orderInfo: limitOrderData });\n if (unfulfilledAmount.isZero() || amount.gt(unfulfilledAmount))\n this.logAndCreateError(\n `amount should be less than unfulfilled amount: ${unfulfilledAmount.toString()}, amount: ${amount.toString()}`,\n );\n\n const [inputMint, outputMint] = limitOrderData.zeroForOne\n ? [new PublicKey(poolInfo.mintA.address), new PublicKey(poolInfo.mintB.address)]\n : [new PublicKey(poolInfo.mintB.address), new PublicKey(poolInfo.mintA.address)];\n const [inputMintProgram, outputMintProgram] = limitOrderData.zeroForOne\n ? [new PublicKey(poolInfo.mintA.programId), new PublicKey(poolInfo.mintB.programId)]\n : [new PublicKey(poolInfo.mintB.programId), new PublicKey(poolInfo.mintA.programId)];\n const [isInputSol, isOutputSol] = [inputMint.equals(WSOLMint), outputMint.equals(WSOLMint)];\n const [inputUseSolBalance, outputUseSolBalance] = [\n ownerInfo.useSOLBalance && isInputSol,\n ownerInfo.useSOLBalance && isOutputSol,\n ];\n\n const txBuilder = this.createTxBuilder();\n\n let ownerInputTokenAccount: PublicKey | undefined =\n inputUseSolBalance || !associatedOnly\n ? undefined\n : getATAAddress(this.scope.ownerPubKey, inputMint, inputMintProgram).publicKey;\n\n let ownerOutputTokenAccount: PublicKey | undefined =\n outputUseSolBalance || !associatedOnly\n ? undefined\n : getATAAddress(this.scope.ownerPubKey, outputMint, outputMintProgram).publicKey;\n\n if (!ownerInputTokenAccount) {\n const { account, instructionParams } = await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: inputMintProgram,\n mint: inputMint,\n notUseTokenAccount: inputUseSolBalance,\n owner: this.scope.ownerPubKey,\n skipCloseAccount: !inputUseSolBalance,\n createInfo: {\n payer: ownerInfo.feePayer || this.scope.ownerPubKey,\n amount: 0,\n },\n associatedOnly: !inputUseSolBalance,\n });\n ownerInputTokenAccount = account!;\n instructionParams && txBuilder.addInstruction(instructionParams);\n } else {\n txBuilder.addInstruction({\n instructions: [\n createAssociatedTokenAccountIdempotentInstruction(\n this.scope.ownerPubKey,\n ownerInputTokenAccount,\n this.scope.ownerPubKey,\n inputMint,\n inputMintProgram,\n ),\n ],\n });\n }\n\n if (!ownerOutputTokenAccount) {\n const { account, instructionParams } = await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: outputMintProgram,\n mint: outputMint,\n notUseTokenAccount: outputUseSolBalance,\n owner: this.scope.ownerPubKey,\n skipCloseAccount: !outputUseSolBalance,\n createInfo: {\n payer: ownerInfo.feePayer || this.scope.ownerPubKey,\n amount: 0,\n },\n associatedOnly: !outputUseSolBalance,\n });\n ownerOutputTokenAccount = account!;\n instructionParams && txBuilder.addInstruction(instructionParams);\n } else {\n txBuilder.addInstruction({\n instructions: [\n createAssociatedTokenAccountIdempotentInstruction(\n this.scope.ownerPubKey,\n ownerOutputTokenAccount,\n this.scope.ownerPubKey,\n outputMint,\n outputMintProgram,\n ),\n ],\n });\n }\n\n const [inputVault, outputVault] = [\n getPdaPoolVaultId(programId, poolId, inputMint).publicKey,\n getPdaPoolVaultId(programId, poolId, outputMint).publicKey,\n ];\n\n const tickArrayStart = TickArrayUtil.getTickArrayStartIndex(limitOrderData.tick, poolInfo.config.tickSpacing);\n const tickArray = getPdaTickArrayAddress(programId, poolId, tickArrayStart).publicKey;\n\n txBuilder.addInstruction({\n instructions: [\n ClmmInstrument.decreaseLimitOrderInstruction(\n programId,\n feePayer || this.scope.ownerPubKey,\n poolId,\n tickArray,\n limitOrder,\n ownerInputTokenAccount,\n ownerOutputTokenAccount,\n inputVault,\n outputVault,\n inputMint,\n outputMint,\n amount,\n amountMin,\n tickArrayBitmap,\n ),\n ],\n });\n\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n return txBuilder.versionBuild<{ forerunCreate?: boolean }>({\n txVersion,\n extInfo: { forerunCreate },\n }) as Promise<MakeTxData<T>>;\n }\n\n public async closeLimitOrder<T extends TxVersion>({\n programId = CLMM_PROGRAM_ID,\n limitOrder,\n autoWithdraw = true,\n tickArrayBitmap,\n slippage = 0,\n feePayer,\n computeBudgetConfig,\n txTipConfig,\n txVersion,\n }: CloseLimitOrder<T>): Promise<MakeTxData<T>> {\n const data = await this.scope.connection.getAccountInfo(limitOrder);\n if (!data) this.logAndCreateError(`limit order ${limitOrder.toBase58()} not exist`);\n const limitOrderData = LimitOrderLayout.decode(data!.data);\n const unfulfilledAmount = LimitOrderMath.getUnFilledAmount({ orderInfo: limitOrderData });\n if (!autoWithdraw && !unfulfilledAmount.isZero())\n this.logAndCreateError(\n `unfulfilled amount should be 0, (${unfulfilledAmount.toString()} remaining), please withdraw first or set autoWithdraw: true`,\n );\n\n const txBuilder = this.createTxBuilder();\n\n let poolInfo: SimpleClmmPoolInfo = (\n await this.scope.api.fetchPoolById({ ids: limitOrderData.poolId.toBase58() })\n )[0] as ApiV3PoolInfoConcentratedItem;\n if (!poolInfo) poolInfo = (await this.getSimplePoolInfo(limitOrderData.poolId)).poolInfo;\n\n const tickArrayInfo = await PoolUtils.fetchTickArrayInfo({\n connection: this.scope.connection,\n programId,\n poolId: limitOrderData.poolId,\n tick: limitOrderData.tick,\n tickSpacing: poolInfo.config.tickSpacing,\n });\n const limitOrderSettle = LimitOrderMath.settleFilledOrder({\n orderInfo: limitOrderData,\n tickInfo: tickArrayInfo.ticks.find((i) => i.tick === limitOrderData.tick)!,\n });\n\n if (!unfulfilledAmount.isZero()) {\n const { builder } = await this.decreaseLimitOrder({\n poolInfo,\n limitOrder,\n limitOrderInfo: limitOrderData,\n amount: unfulfilledAmount,\n tickArrayBitmap,\n slippage,\n txVersion: TxVersion.V0,\n });\n\n txBuilder.addInstruction({\n instructions: builder.allInstructions,\n });\n } else if (!limitOrderSettle.isZero()) {\n const settleBuilData = await this.settleLimitOrder({ limitOrder });\n txBuilder.addInstruction({ ...settleBuilData.builder.AllTxData });\n }\n\n txBuilder.addInstruction({\n instructions: [\n ClmmInstrument.closeLimitOrderInstruction(\n programId,\n feePayer || this.scope.ownerPubKey,\n this.scope.ownerPubKey,\n limitOrder,\n ),\n ],\n });\n\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n return txBuilder.versionBuild({\n txVersion,\n }) as Promise<MakeTxData<T>>;\n }\n\n public async closeAllLimitOrder<T extends TxVersion>({\n programId = CLMM_PROGRAM_ID,\n limitOrders,\n autoWithdraw = true,\n slippage = 10000,\n feePayer,\n computeBudgetConfig,\n txVersion,\n }: CloseAllLimitOrder<T>): Promise<MakeMultiTxData<T>> {\n const txBuilder = this.createTxBuilder();\n const ordersRes = await getMultipleAccountsInfo(this.scope.connection, limitOrders);\n const allLimitOrderData = ordersRes.map((o, idx) =>\n o ? { ...LimitOrderLayout.decode(o.data), pda: limitOrders[idx] } : null,\n );\n const noneNullLimitOrder = allLimitOrderData.filter(Boolean) as (ReturnType<typeof LimitOrderLayout.decode> & {\n pda: PublicKey;\n })[];\n const poolIdList = noneNullLimitOrder.map((o) => o.poolId.toBase58());\n\n const allPoolInfo = (\n await this.scope.api.fetchPoolById({\n ids: poolIdList.join(\",\"),\n })\n ).filter(Boolean) as ApiV3PoolInfoConcentratedItem[];\n const poolInfoMap: Record<string, SimpleClmmPoolInfo> = {};\n allPoolInfo.forEach((p) => (poolInfoMap[p.id] = p as SimpleClmmPoolInfo));\n\n const tickArrayInfos = await PoolUtils.fetchMultipleTickArrayInfo({\n connection: this.scope.connection,\n tickInfoList: noneNullLimitOrder.map((o) => ({\n programId,\n poolId: o!.poolId,\n tick: o!.tick,\n tickSpacing: poolInfoMap[o!.poolId.toString()].config.tickSpacing,\n })),\n });\n const tickArrayInfoMap: Record<string, ReturnType<typeof TickArrayLayout.decode>> = {};\n tickArrayInfos.forEach((info, idx) => {\n if (!info) return;\n tickArrayInfoMap[noneNullLimitOrder[idx].pda.toBase58()] = info;\n });\n\n let idx = 0;\n for (const limitOrder of limitOrders) {\n const limitOrderData = allLimitOrderData[idx];\n if (!limitOrderData) {\n idx++;\n continue;\n }\n const unfulfilledAmount = LimitOrderMath.getUnFilledAmount({ orderInfo: limitOrderData });\n if (!autoWithdraw && !unfulfilledAmount.isZero())\n this.logAndCreateError(\n `${limitOrder.toBase58()} order unfulfilled amount should be 0 (${unfulfilledAmount.toString()} remaining), please withdraw first or set autoWithdraw: true`,\n );\n\n const poolInfo = poolInfoMap[limitOrderData.poolId.toBase58()];\n const tickArrayInfo = tickArrayInfoMap[limitOrder.toBase58()];\n const limitOrderSettle = LimitOrderMath.settleFilledOrder({\n orderInfo: limitOrderData,\n tickInfo: tickArrayInfo.ticks.find((i) => i.tick === limitOrderData.tick)!,\n });\n\n if (!unfulfilledAmount.isZero()) {\n const { builder } = await this.decreaseLimitOrder({\n poolInfo,\n limitOrder,\n limitOrderInfo: limitOrderData,\n amount: unfulfilledAmount,\n slippage,\n txVersion: TxVersion.V0,\n forerunCreate: true,\n });\n\n txBuilder.addInstruction({\n instructions: builder.allInstructions,\n });\n } else if (!limitOrderSettle.isZero()) {\n const settleBuilData = await this.settleLimitOrder({ limitOrder, forerunCreate: true });\n txBuilder.addInstruction({ ...settleBuilData.builder.AllTxData });\n }\n\n txBuilder.addInstruction({\n instructions: [\n ClmmInstrument.closeLimitOrderInstruction(\n programId,\n feePayer || this.scope.ownerPubKey,\n this.scope.ownerPubKey,\n limitOrder,\n ),\n ],\n });\n idx++;\n }\n\n if (txVersion === TxVersion.V0)\n return txBuilder.sizeCheckBuildV0({ computeBudgetConfig }) as Promise<MakeMultiTxData<T>>;\n return txBuilder.sizeCheckBuild({ computeBudgetConfig }) as Promise<MakeMultiTxData<T>>;\n }\n\n public async settleLimitOrder<T extends TxVersion>({\n limitOrder,\n feePayer,\n ownerInfo = {\n useSOLBalance: true,\n },\n associatedOnly = true,\n computeBudgetConfig,\n txTipConfig,\n txVersion,\n forerunCreate,\n }: SettleLimitOrder<T>): Promise<MakeTxData<T>> {\n const data = await this.scope.connection.getAccountInfo(limitOrder);\n if (!data) this.logAndCreateError(`limit order ${limitOrder.toBase58()} not exist`);\n const limitOrderData = LimitOrderLayout.decode(data!.data);\n\n let poolInfo: SimpleClmmPoolInfo = (\n await this.scope.api.fetchPoolById({ ids: limitOrderData.poolId.toBase58() })\n )[0] as ApiV3PoolInfoConcentratedItem;\n if (!poolInfo) poolInfo = (await this.getSimplePoolInfo(limitOrderData.poolId)).poolInfo;\n\n const outputMintInfo = limitOrderData.zeroForOne ? poolInfo.mintB : poolInfo.mintA;\n const [outputMint, outputMintProgram] = [\n new PublicKey(outputMintInfo.address),\n new PublicKey(outputMintInfo.programId),\n ];\n const programId = new PublicKey(poolInfo.programId);\n\n const txBuilder = this.createTxBuilder();\n const isOutputSol = outputMint.equals(WSOLMint);\n const outputUseSolBalance = ownerInfo.useSOLBalance && isOutputSol;\n\n let ownerOutputTokenAccount: PublicKey | undefined =\n outputUseSolBalance || !associatedOnly\n ? undefined\n : getATAAddress(this.scope.ownerPubKey, outputMint, outputMintProgram).publicKey;\n\n if (!ownerOutputTokenAccount) {\n const { account, instructionParams } = await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: outputMintProgram,\n mint: outputMint,\n notUseTokenAccount: outputUseSolBalance,\n owner: this.scope.ownerPubKey,\n skipCloseAccount: !outputUseSolBalance,\n createInfo: {\n payer: ownerInfo.feePayer || this.scope.ownerPubKey,\n amount: 0,\n },\n associatedOnly: !outputUseSolBalance,\n });\n ownerOutputTokenAccount = account!;\n instructionParams && txBuilder.addInstruction(instructionParams);\n } else {\n txBuilder.addInstruction({\n instructions: [\n createAssociatedTokenAccountIdempotentInstruction(\n this.scope.ownerPubKey,\n ownerOutputTokenAccount,\n this.scope.ownerPubKey,\n outputMint,\n outputMintProgram,\n ),\n ],\n });\n }\n\n const tickArrayStart = TickArrayUtil.getTickArrayStartIndex(limitOrderData.tick, poolInfo.config.tickSpacing);\n txBuilder.addInstruction({\n instructions: [\n ClmmInstrument.settleLimitOrderInstruction(\n programId,\n feePayer || this.scope.ownerPubKey,\n limitOrderData.poolId,\n getPdaTickArrayAddress(programId, limitOrderData.poolId, tickArrayStart).publicKey,\n limitOrder,\n ownerOutputTokenAccount,\n getPdaPoolVaultId(programId, limitOrderData.poolId, outputMint).publicKey,\n outputMint,\n outputMintProgram,\n ),\n ],\n });\n\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n return txBuilder.versionBuild<{ forerunCreate?: boolean }>({\n txVersion,\n extInfo: { forerunCreate },\n }) as Promise<MakeTxData<T>>;\n }\n\n public async settleAllLimitOrder<T extends TxVersion>({\n limitOrders,\n feePayer,\n ownerInfo = {\n useSOLBalance: true,\n },\n associatedOnly = true,\n computeBudgetConfig,\n txVersion,\n }: SettleAllLimitOrders<T>): Promise<MakeMultiTxData<T>> {\n const res = await getMultipleAccountsInfo(this.scope.connection, limitOrders);\n const allPoolId: string[] = [];\n const allLimitOrderData = res.map((r, idx) => {\n if (!r) return;\n const data = LimitOrderLayout.decode(r!.data);\n allPoolId.push(data.poolId.toString());\n return {\n ...data,\n pda: limitOrders[idx],\n };\n });\n\n let poolInfo: SimpleClmmPoolInfo[] = (await this.scope.api.fetchPoolById({\n ids: allPoolId.join(\",\"),\n })) as ApiV3PoolInfoConcentratedItem[];\n\n if (!poolInfo.filter(Boolean).length) {\n const res = await Promise.all(allPoolId.map((p) => this.getSimplePoolInfo(p)));\n poolInfo = res.map((r) => r.poolInfo);\n }\n\n const txBuilder = this.createTxBuilder();\n\n const ataMap: Record<string, PublicKey> = {};\n\n for (const limitOrder of allLimitOrderData) {\n if (!limitOrder) continue;\n const pool = poolInfo.find((p) => p.id === limitOrder.poolId.toBase58());\n if (!pool) continue;\n const programId = new PublicKey(pool.programId);\n const outputMint = new PublicKey(limitOrder.zeroForOne ? pool.mintB.address : pool.mintA.address);\n const isOutputSol = outputMint.equals(WSOLMint);\n const outputUseSolBalance = ownerInfo.useSOLBalance && isOutputSol;\n const outputMintProgram = new PublicKey(\n isOutputSol ? TOKEN_PROGRAM_ID : (await this.scope.token.getTokenInfo(outputMint)).programId,\n );\n\n const preCreatedAta = ataMap[outputMint.toBase58()];\n\n let ownerOutputTokenAccount: PublicKey | undefined =\n outputUseSolBalance || !associatedOnly\n ? undefined\n : getATAAddress(this.scope.ownerPubKey, outputMint, outputMintProgram).publicKey;\n\n if (!preCreatedAta) {\n if (!ownerOutputTokenAccount) {\n const { account, instructionParams } = await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: outputMintProgram,\n mint: outputMint,\n notUseTokenAccount: outputUseSolBalance,\n owner: this.scope.ownerPubKey,\n skipCloseAccount: !outputUseSolBalance,\n createInfo: {\n payer: ownerInfo.feePayer || this.scope.ownerPubKey,\n amount: 0,\n },\n associatedOnly: !outputUseSolBalance,\n });\n ownerOutputTokenAccount = account!;\n instructionParams && txBuilder.addInstruction(instructionParams);\n } else {\n txBuilder.addInstruction({\n instructions: [\n createAssociatedTokenAccountIdempotentInstruction(\n this.scope.ownerPubKey,\n ownerOutputTokenAccount,\n this.scope.ownerPubKey,\n outputMint,\n outputMintProgram,\n ),\n ],\n });\n }\n ataMap[outputMint.toBase58()] = ownerOutputTokenAccount;\n } else {\n ownerOutputTokenAccount = preCreatedAta;\n }\n\n const tickArrayStart = TickArrayUtil.getTickArrayStartIndex(limitOrder.tick, pool.config.tickSpacing);\n txBuilder.addInstruction({\n instructions: [\n ClmmInstrument.settleLimitOrderInstruction(\n programId,\n feePayer || this.scope.ownerPubKey,\n limitOrder.poolId,\n getPdaTickArrayAddress(programId, limitOrder.poolId, tickArrayStart).publicKey,\n limitOrder.pda,\n ownerOutputTokenAccount,\n getPdaPoolVaultId(programId, limitOrder.poolId, outputMint).publicKey,\n outputMint,\n outputMintProgram,\n ),\n ],\n });\n }\n\n if (txVersion === TxVersion.V0)\n return txBuilder.sizeCheckBuildV0({ computeBudgetConfig }) as Promise<MakeMultiTxData<T>>;\n return txBuilder.sizeCheckBuild({ computeBudgetConfig }) as Promise<MakeMultiTxData<T>>;\n }\n\n public async swap<T extends TxVersion>({\n poolInfo,\n poolKeys: propPoolKeys,\n inputMint,\n amountIn,\n amountOutMin,\n priceLimit,\n observationId,\n ownerInfo,\n remainingAccounts,\n associatedOnly = true,\n checkCreateATAOwner = false,\n txVersion,\n computeBudgetConfig,\n txTipConfig,\n feePayer,\n }: {\n poolInfo: SimpleClmmPoolInfo;\n poolKeys?: Pick<ClmmKeys, \"vault\" | \"lookupTableAccount\">;\n inputMint: string | PublicKey;\n amountIn: BN;\n amountOutMin: BN;\n priceLimit?: Decimal;\n observationId: PublicKey;\n ownerInfo: {\n useSOLBalance?: boolean;\n feePayer?: PublicKey;\n };\n remainingAccounts: PublicKey[];\n associatedOnly?: boolean;\n checkCreateATAOwner?: boolean;\n txVersion?: T;\n computeBudgetConfig?: ComputeBudgetConfig;\n txTipConfig?: TxTipConfig;\n feePayer?: PublicKey;\n }): Promise<MakeTxData<T>> {\n const txBuilder = this.createTxBuilder(feePayer);\n const baseIn = inputMint.toString() === poolInfo.mintA.address.toString();\n const mintAUseSOLBalance = ownerInfo.useSOLBalance && poolInfo.mintA.address.toString() === WSOLMint.toBase58();\n const mintBUseSOLBalance = ownerInfo.useSOLBalance && poolInfo.mintB.address.toString() === WSOLMint.toBase58();\n\n let sqrtPriceLimitX64: BN;\n if (!priceLimit || priceLimit.equals(new Decimal(0))) {\n sqrtPriceLimitX64 = baseIn ? MIN_SQRT_PRICE_X64.add(new BN(1)) : MAX_SQRT_PRICE_X64.sub(new BN(1));\n } else {\n sqrtPriceLimitX64 = TickUtil.priceToSqrtPriceX64(priceLimit, poolInfo.mintA.decimals, poolInfo.mintB.decimals);\n }\n\n let ownerTokenAccountA: PublicKey | undefined;\n if (!ownerTokenAccountA) {\n const { account, instructionParams } = await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: poolInfo.mintA.programId,\n mint: new PublicKey(poolInfo.mintA.address),\n notUseTokenAccount: mintAUseSOLBalance,\n owner: this.scope.ownerPubKey,\n skipCloseAccount: !mintAUseSOLBalance,\n createInfo:\n mintAUseSOLBalance || !baseIn\n ? {\n payer: ownerInfo.feePayer || this.scope.ownerPubKey,\n amount: baseIn ? amountIn : 0,\n }\n : undefined,\n associatedOnly: mintAUseSOLBalance ? false : associatedOnly,\n checkCreateATAOwner,\n });\n ownerTokenAccountA = account!;\n instructionParams && txBuilder.addInstruction(instructionParams);\n }\n\n let ownerTokenAccountB: PublicKey | undefined;\n if (!ownerTokenAccountB) {\n const { account, instructionParams } = await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: poolInfo.mintB.programId,\n mint: new PublicKey(poolInfo.mintB.address),\n notUseTokenAccount: mintBUseSOLBalance,\n owner: this.scope.ownerPubKey,\n skipCloseAccount: !mintBUseSOLBalance,\n createInfo:\n mintBUseSOLBalance || baseIn\n ? {\n payer: ownerInfo.feePayer || this.scope.ownerPubKey,\n amount: baseIn ? 0 : amountIn,\n }\n : undefined,\n associatedOnly: mintBUseSOLBalance ? false : associatedOnly,\n checkCreateATAOwner,\n });\n ownerTokenAccountB = account!;\n instructionParams && txBuilder.addInstruction(instructionParams);\n }\n\n if (!ownerTokenAccountA || !ownerTokenAccountB)\n this.logAndCreateError(\"user do not have token account\", {\n tokenA: poolInfo.mintA.address,\n tokenB: poolInfo.mintB.address,\n ownerTokenAccountA,\n ownerTokenAccountB,\n mintAUseSOLBalance,\n mintBUseSOLBalance,\n associatedOnly,\n });\n\n const poolKeys = propPoolKeys ?? (await this.getClmmPoolKeys(poolInfo.id.toString()));\n txBuilder.addInstruction(\n ClmmInstrument.makeSwapBaseInInstructions({\n poolInfo: {\n ...poolInfo,\n id: poolInfo.id.toString(),\n programId: poolInfo.programId.toString(),\n },\n poolKeys,\n observationId,\n ownerInfo: {\n wallet: this.scope.ownerPubKey,\n tokenAccountA: ownerTokenAccountA!,\n tokenAccountB: ownerTokenAccountB!,\n },\n inputMint: new PublicKey(inputMint),\n amountIn,\n amountOutMin,\n sqrtPriceLimitX64: BN_ZERO,\n remainingAccounts,\n }),\n );\n\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n return txBuilder.versionBuild({ txVersion }) as Promise<MakeTxData<T>>;\n }\n\n public async swapBaseOut<T extends TxVersion>({\n poolInfo,\n poolKeys: propPoolKeys,\n outputMint,\n amountOut,\n amountInMax,\n priceLimit,\n observationId,\n ownerInfo,\n remainingAccounts,\n associatedOnly = true,\n checkCreateATAOwner = false,\n txVersion,\n computeBudgetConfig,\n txTipConfig,\n feePayer,\n }: {\n poolInfo: SimpleClmmPoolInfo;\n poolKeys?: Pick<ClmmKeys, \"vault\" | \"lookupTableAccount\">;\n outputMint: string | PublicKey;\n amountOut: BN;\n amountInMax: BN;\n priceLimit?: Decimal;\n observationId: PublicKey;\n ownerInfo: {\n useSOLBalance?: boolean;\n feePayer?: PublicKey;\n };\n remainingAccounts: PublicKey[];\n associatedOnly?: boolean;\n checkCreateATAOwner?: boolean;\n txVersion?: T;\n computeBudgetConfig?: ComputeBudgetConfig;\n txTipConfig?: TxTipConfig;\n feePayer?: PublicKey;\n }): Promise<MakeTxData<T>> {\n const txBuilder = this.createTxBuilder(feePayer);\n const baseIn = outputMint.toString() === poolInfo.mintB.address.toString();\n const mintAUseSOLBalance = ownerInfo.useSOLBalance && poolInfo.mintA.address.toString() === WSOLMint.toBase58();\n const mintBUseSOLBalance = ownerInfo.useSOLBalance && poolInfo.mintB.address.toString() === WSOLMint.toBase58();\n let sqrtPriceLimitX64: BN;\n if (!priceLimit || priceLimit.equals(new Decimal(0))) {\n sqrtPriceLimitX64 = baseIn ? MIN_SQRT_PRICE_X64.add(new BN(1)) : MAX_SQRT_PRICE_X64.sub(new BN(1));\n } else {\n sqrtPriceLimitX64 = TickUtil.priceToSqrtPriceX64(priceLimit, poolInfo.mintA.decimals, poolInfo.mintB.decimals);\n }\n\n let ownerTokenAccountA: PublicKey | undefined;\n if (!ownerTokenAccountA) {\n const { account, instructionParams } = await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: poolInfo.mintA.programId,\n mint: new PublicKey(poolInfo.mintA.address),\n notUseTokenAccount: mintAUseSOLBalance,\n owner: this.scope.ownerPubKey,\n skipCloseAccount: !mintAUseSOLBalance,\n createInfo:\n mintAUseSOLBalance || !baseIn\n ? {\n payer: ownerInfo.feePayer || this.scope.ownerPubKey,\n amount: baseIn ? amountInMax : 0,\n }\n : undefined,\n associatedOnly: mintAUseSOLBalance ? false : associatedOnly,\n checkCreateATAOwner,\n });\n ownerTokenAccountA = account!;\n instructionParams && txBuilder.addInstruction(instructionParams);\n }\n\n let ownerTokenAccountB: PublicKey | undefined;\n if (!ownerTokenAccountB) {\n const { account, instructionParams } = await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: poolInfo.mintB.programId,\n mint: new PublicKey(poolInfo.mintB.address),\n notUseTokenAccount: mintBUseSOLBalance,\n owner: this.scope.ownerPubKey,\n skipCloseAccount: !mintBUseSOLBalance,\n createInfo:\n mintBUseSOLBalance || baseIn\n ? {\n payer: ownerInfo.feePayer || this.scope.ownerPubKey,\n amount: baseIn ? 0 : amountInMax,\n }\n : undefined,\n associatedOnly: mintBUseSOLBalance ? false : associatedOnly,\n checkCreateATAOwner,\n });\n ownerTokenAccountB = account!;\n instructionParams && txBuilder.addInstruction(instructionParams);\n }\n\n if (!ownerTokenAccountA || !ownerTokenAccountB)\n this.logAndCreateError(\"user do not have token account\", {\n tokenA: poolInfo.mintA.address,\n tokenB: poolInfo.mintB.address,\n ownerTokenAccountA,\n ownerTokenAccountB,\n mintAUseSOLBalance,\n mintBUseSOLBalance,\n associatedOnly,\n });\n\n const poolKeys = propPoolKeys ?? (await this.getClmmPoolKeys(poolInfo.id.toString()));\n txBuilder.addInstruction(\n ClmmInstrument.makeSwapBaseOutInstructions({\n poolInfo: {\n ...poolInfo,\n id: poolInfo.id.toString(),\n programId: poolInfo.programId.toString(),\n },\n poolKeys,\n observationId,\n ownerInfo: {\n wallet: this.scope.ownerPubKey,\n tokenAccountA: ownerTokenAccountA!,\n tokenAccountB: ownerTokenAccountB!,\n },\n outputMint: new PublicKey(outputMint),\n amountOut,\n amountInMax,\n sqrtPriceLimitX64: BN_ZERO,\n remainingAccounts,\n }),\n );\n\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n return txBuilder.versionBuild({ txVersion }) as Promise<MakeTxData<T>>;\n }\n\n public async harvestAllRewards<T extends TxVersion = TxVersion.LEGACY>({\n allPoolInfo,\n allPositions,\n lockInfo,\n ownerInfo,\n associatedOnly = true,\n checkCreateATAOwner = false,\n programId,\n txVersion,\n computeBudgetConfig,\n feePayer,\n lockProgram = CLMM_LOCK_PROGRAM_ID,\n lockAuth = CLMM_LOCK_AUTH_ID,\n clmmProgram = CLMM_PROGRAM_ID,\n }: HarvestAllRewardsParams<T>): Promise<MakeMultiTxData<T>> {\n const ownerMintToAccount: { [mint: string]: PublicKey } = {};\n for (const item of this.scope.account.tokenAccountRawInfos) {\n if (associatedOnly) {\n const ata = getATAAddress(this.scope.ownerPubKey, item.accountInfo.mint, programId).publicKey;\n if (ata.equals(item.pubkey)) ownerMintToAccount[item.accountInfo.mint.toString()] = item.pubkey;\n } else {\n ownerMintToAccount[item.accountInfo.mint.toString()] = item.pubkey;\n }\n }\n const allNftMints = Object.values(allPositions)\n .flat()\n .map((p) => p.nftMint);\n\n const mintData = await getMultipleAccountsInfoWithCustomFlags(\n this.scope.connection,\n allNftMints.map((n) => ({ pubkey: n })),\n );\n const record: Record<string, PublicKey | null> = {};\n mintData.forEach((data) => {\n record[data.pubkey.toBase58()] = data?.accountInfo?.owner ?? null;\n });\n\n const txBuilder = this.createTxBuilder(feePayer);\n for (const itemInfo of Object.values(allPoolInfo)) {\n if (allPositions[itemInfo.id] === undefined) continue;\n if (\n !allPositions[itemInfo.id].find(\n (i) => !i.liquidity.isZero() || i.rewardInfos.find((ii) => !ii.rewardAmountOwed.isZero()),\n )\n )\n continue;\n\n const poolInfo = itemInfo;\n const mintAUseSOLBalance = ownerInfo.useSOLBalance && poolInfo.mintA.address === WSOLMint.toString();\n const mintBUseSOLBalance = ownerInfo.useSOLBalance && poolInfo.mintB.address === WSOLMint.toString();\n\n let ownerTokenAccountA = ownerMintToAccount[poolInfo.mintA.address];\n if (!ownerTokenAccountA) {\n if (mintAUseSOLBalance) {\n const { account, instructionParams } = await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: poolInfo.mintA.programId,\n mint: new PublicKey(poolInfo.mintA.address),\n notUseTokenAccount: mintAUseSOLBalance,\n owner: this.scope.ownerPubKey,\n skipCloseAccount: !mintAUseSOLBalance,\n createInfo: {\n payer: ownerInfo.feePayer || this.scope.ownerPubKey,\n amount: 0,\n },\n associatedOnly: mintAUseSOLBalance ? false : associatedOnly,\n checkCreateATAOwner,\n });\n ownerTokenAccountA = account!;\n instructionParams && txBuilder.addInstruction(instructionParams);\n } else {\n const mint = new PublicKey(poolInfo.mintA.address);\n ownerTokenAccountA = this.scope.account.getAssociatedTokenAccount(\n mint,\n new PublicKey(poolInfo.mintA.programId),\n );\n txBuilder.addInstruction({\n instructions: [\n createAssociatedTokenAccountIdempotentInstruction(\n this.scope.ownerPubKey,\n ownerTokenAccountA,\n this.scope.ownerPubKey,\n mint,\n new PublicKey(poolInfo.mintA.programId),\n ),\n ],\n });\n }\n }\n\n let ownerTokenAccountB = ownerMintToAccount[poolInfo.mintB.address];\n if (!ownerTokenAccountB) {\n if (mintBUseSOLBalance) {\n const { account, instructionParams } = await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: poolInfo.mintB.programId,\n mint: new PublicKey(poolInfo.mintB.address),\n notUseTokenAccount: mintBUseSOLBalance,\n owner: this.scope.ownerPubKey,\n skipCloseAccount: !mintBUseSOLBalance,\n createInfo: {\n payer: ownerInfo.feePayer || this.scope.ownerPubKey,\n amount: 0,\n },\n associatedOnly: mintBUseSOLBalance ? false : associatedOnly,\n checkCreateATAOwner,\n });\n ownerTokenAccountB = account!;\n instructionParams && txBuilder.addInstruction(instructionParams);\n } else {\n const mint = new PublicKey(poolInfo.mintB.address);\n ownerTokenAccountB = this.scope.account.getAssociatedTokenAccount(\n mint,\n new PublicKey(poolInfo.mintB.programId),\n );\n txBuilder.addInstruction({\n instructions: [\n createAssociatedTokenAccountIdempotentInstruction(\n this.scope.ownerPubKey,\n ownerTokenAccountB,\n this.scope.ownerPubKey,\n mint,\n new PublicKey(poolInfo.mintB.programId),\n ),\n ],\n });\n }\n }\n\n ownerMintToAccount[poolInfo.mintA.address] = ownerTokenAccountA;\n ownerMintToAccount[poolInfo.mintB.address] = ownerTokenAccountB;\n\n const rewardAccounts: PublicKey[] = [];\n\n for (const itemReward of poolInfo.rewardDefaultInfos) {\n const rewardUseSOLBalance = ownerInfo.useSOLBalance && itemReward.mint.address === WSOLMint.toString();\n let ownerRewardAccount = ownerMintToAccount[itemReward.mint.address];\n if (!ownerRewardAccount) {\n const { account, instructionParams } = await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: new PublicKey(itemReward.mint.programId),\n mint: new PublicKey(itemReward.mint.address),\n notUseTokenAccount: rewardUseSOLBalance,\n owner: this.scope.ownerPubKey,\n skipCloseAccount: !rewardUseSOLBalance,\n createInfo: {\n payer: ownerInfo.feePayer || this.scope.ownerPubKey,\n amount: 0,\n },\n associatedOnly: rewardUseSOLBalance ? false : associatedOnly,\n });\n ownerRewardAccount = account!;\n instructionParams && txBuilder.addInstruction(instructionParams);\n }\n\n ownerMintToAccount[itemReward.mint.address] = ownerRewardAccount;\n rewardAccounts.push(ownerRewardAccount!);\n }\n\n const poolKeys = await this.getClmmPoolKeys(poolInfo.id);\n\n const rewardAccountsFullInfo: {\n poolRewardVault: PublicKey;\n ownerRewardVault: PublicKey;\n rewardMint: PublicKey;\n }[] = [];\n for (let i = 0; i < poolKeys.rewardInfos.length; i++) {\n rewardAccountsFullInfo.push({\n poolRewardVault: new PublicKey(poolKeys.rewardInfos[i].vault),\n ownerRewardVault: rewardAccounts[i],\n rewardMint: new PublicKey(poolKeys.rewardInfos[i].mint.address),\n });\n }\n\n for (const itemPosition of allPositions[itemInfo.id]) {\n const lockData = lockInfo?.[itemInfo.id]?.[itemPosition.nftMint.toBase58()];\n if (lockData) {\n const lockNftAccount = getATAAddress(\n this.scope.ownerPubKey,\n lockData.lockNftMint,\n TOKEN_PROGRAM_ID,\n ).publicKey;\n\n const tickArrayLowerStartIndex = TickArrayUtil.getTickArrayStartIndex(\n itemPosition.tickLower,\n poolKeys.config.tickSpacing,\n );\n const tickArrayUpperStartIndex = TickArrayUtil.getTickArrayStartIndex(\n itemPosition.tickUpper,\n poolKeys.config.tickSpacing,\n );\n const { publicKey: tickArrayLower } = getPdaTickArrayAddress(\n new PublicKey(poolKeys.programId),\n lockData.poolId,\n tickArrayLowerStartIndex,\n );\n const { publicKey: tickArrayUpper } = getPdaTickArrayAddress(\n new PublicKey(poolKeys.programId),\n lockData.poolId,\n tickArrayUpperStartIndex,\n );\n const { publicKey: protocolPosition } = getPdaProtocolPositionAddress(\n new PublicKey(poolKeys.programId),\n lockData.poolId,\n itemPosition.tickLower,\n itemPosition.tickUpper,\n );\n const lockPositionId = getPdaLockClPositionIdV2(lockProgram, lockData.lockNftMint).publicKey;\n const harvestLockIns = ClmmInstrument.harvestLockPositionInstructionV2({\n programId: lockProgram,\n auth: lockAuth,\n lockPositionId,\n clmmProgram,\n lockOwner: this.scope.ownerPubKey,\n lockNftMint: lockData.lockNftMint,\n lockNftAccount,\n positionNftAccount: lockData.nftAccount,\n positionId: lockData.positionId,\n poolId: lockData.poolId,\n protocolPosition,\n vaultA: new PublicKey(poolKeys.vault.A),\n vaultB: new PublicKey(poolKeys.vault.B),\n tickArrayLower,\n tickArrayUpper,\n userVaultA: ownerTokenAccountA!,\n userVaultB: ownerTokenAccountB!,\n mintA: new PublicKey(poolKeys.mintA.address),\n mintB: new PublicKey(poolKeys.mintB.address),\n rewardAccounts: rewardAccountsFullInfo,\n exTickArrayBitmap: getPdaExBitmapAccount(clmmProgram, lockData.poolId).publicKey,\n });\n txBuilder.addInstruction({\n instructions: [harvestLockIns],\n instructionTypes: [InstructionType.ClmmHarvestLockPosition],\n lookupTableAddress: poolKeys.lookupTableAccount ? [poolKeys.lookupTableAccount] : [],\n });\n } else {\n const insData = ClmmInstrument.decreaseLiquidityInstructions({\n poolInfo,\n poolKeys,\n ownerPosition: itemPosition,\n ownerInfo: {\n wallet: this.scope.ownerPubKey,\n tokenAccountA: ownerTokenAccountA,\n tokenAccountB: ownerTokenAccountB,\n rewardAccounts,\n },\n liquidity: new BN(0),\n amountMinA: new BN(0),\n amountMinB: new BN(0),\n nft2022: record[itemPosition.nftMint.toBase58()]?.equals(TOKEN_2022_PROGRAM_ID),\n });\n txBuilder.addInstruction(insData);\n }\n }\n }\n\n if (txVersion === TxVersion.V0)\n return txBuilder.sizeCheckBuildV0({ computeBudgetConfig }) as Promise<MakeMultiTxData<T>>;\n return txBuilder.sizeCheckBuild({ computeBudgetConfig }) as Promise<MakeMultiTxData<T>>;\n }\n\n public async getWhiteListMint({ programId }: { programId: PublicKey }): Promise<PublicKey[]> {\n const accountInfo = await this.scope.connection.getAccountInfo(getPdaOperationAccount(programId).publicKey);\n if (!accountInfo) return [];\n const whitelistMintsInfo = OperationLayout.decode(accountInfo.data);\n return whitelistMintsInfo.whitelistMints.filter((i) => !i.equals(PublicKey.default));\n }\n\n public async getOwnerPositionInfo({\n programId = CLMM_PROGRAM_ID,\n }: {\n programId?: string | PublicKey;\n }): Promise<ReturnType<typeof PersonalPositionLayout.decode>[]> {\n await this.scope.account.fetchWalletTokenAccounts();\n const balanceMints = this.scope.account.tokenAccountRawInfos.filter((acc) => acc.accountInfo.amount.eq(new BN(1)));\n const allPositionKey = balanceMints.map(\n (acc) => getPdaPersonalPositionAddress(new PublicKey(programId), acc.accountInfo.mint).publicKey,\n );\n\n const accountInfo = await this.scope.connection.getMultipleAccountsInfo(allPositionKey);\n const allPosition: ReturnType<typeof PersonalPositionLayout.decode>[] = [];\n accountInfo.forEach((positionRes) => {\n if (!positionRes) return;\n const position = PersonalPositionLayout.decode(positionRes.data);\n allPosition.push(position);\n });\n\n return allPosition;\n }\n\n public async getOwnerLockedPositionInfo({\n programId = CLMM_LOCK_PROGRAM_ID,\n }: {\n programId?: string | PublicKey;\n }): Promise<\n {\n position: ReturnType<typeof PersonalPositionLayout.decode>;\n lockInfo: ReturnType<typeof LockClPositionLayoutV2.decode>;\n }[]\n > {\n await this.scope.account.fetchWalletTokenAccounts();\n const balanceMints = this.scope.account.tokenAccountRawInfos.filter((acc) => acc.accountInfo.amount.eq(new BN(1)));\n const allPositionKey = balanceMints.map(\n (acc) => getPdaLockClPositionIdV2(new PublicKey(programId), acc.accountInfo.mint).publicKey,\n );\n\n const lockAccountInfo = await this.scope.connection.getMultipleAccountsInfo(allPositionKey);\n const allLockPosition: ReturnType<typeof LockClPositionLayoutV2.decode>[] = [];\n lockAccountInfo.forEach((positionRes) => {\n if (!positionRes) return;\n const position = LockClPositionLayoutV2.decode(positionRes.data);\n allLockPosition.push(position);\n });\n\n const accountInfo = await this.scope.connection.getMultipleAccountsInfo(allLockPosition.map((p) => p.positionId));\n const allPosition: ReturnType<typeof PersonalPositionLayout.decode>[] = [];\n accountInfo.forEach((positionRes) => {\n if (!positionRes) return;\n const position = PersonalPositionLayout.decode(positionRes.data);\n allPosition.push(position);\n });\n\n return allLockPosition.map((data, idx) => ({\n position: allPosition[idx],\n lockInfo: data,\n }));\n }\n\n public async getRpcClmmPoolInfo({ poolId }: { poolId: string | PublicKey }): Promise<ClmmParsedRpcData> {\n return (await this.getRpcClmmPoolInfos({ poolIds: [poolId] }))[String(poolId)];\n }\n\n public async getRpcClmmPoolInfos({\n poolIds,\n config,\n }: {\n poolIds: (string | PublicKey)[];\n config?: { batchRequest?: boolean; chunkCount?: number };\n }): Promise<{\n [poolId: string]: ClmmParsedRpcData;\n }> {\n const accounts = await getMultipleAccountsInfoWithCustomFlags(\n this.scope.connection,\n poolIds.map((i) => ({ pubkey: new PublicKey(i) })),\n config,\n );\n const returnData: {\n [poolId: string]: ClmmParsedRpcData;\n } = {};\n for (let i = 0; i < poolIds.length; i++) {\n const item = accounts[i];\n if (item === null || !item.accountInfo) throw Error(\"fetch pool info error: \" + String(poolIds[i]));\n const rpc = PoolInfoLayout.decode(item.accountInfo.data);\n const currentPrice = TickUtil.sqrtPriceX64ToPrice(\n rpc.sqrtPriceX64,\n rpc.mintDecimalsA,\n rpc.mintDecimalsB,\n ).toNumber();\n\n returnData[String(poolIds[i])] = {\n ...rpc,\n currentPrice,\n programId: item.accountInfo.owner,\n };\n }\n return returnData;\n }\n\n public async getComputeClmmPoolInfos({\n clmmPoolsRpcInfo,\n mintInfos,\n }: {\n clmmPoolsRpcInfo: Record<\n string,\n ReturnType<typeof PoolInfoLayout.decode> & { currentPrice: number; programId: PublicKey }\n >;\n mintInfos: ReturnTypeFetchMultipleMintInfos;\n }): Promise<{\n computeClmmPoolInfo: Record<string, ComputeClmmPoolInfo>;\n computePoolTickData: ReturnTypeFetchMultiplePoolTickArrays;\n }> {\n const configSet = new Set(Object.keys(clmmPoolsRpcInfo).map((p) => clmmPoolsRpcInfo[p].configId.toBase58()));\n const res = await getMultipleAccountsInfoWithCustomFlags(\n this.scope.connection,\n Array.from(configSet).map((s) => ({ pubkey: new PublicKey(s) })),\n );\n const clmmConfigs: Record<string, ReturnType<typeof ClmmConfigLayout.decode>> = {};\n res.forEach((acc) => {\n if (!acc.accountInfo) return;\n clmmConfigs[acc.pubkey.toBase58()] = ClmmConfigLayout.decode(acc.accountInfo.data);\n });\n const computeClmmPoolInfo = await PoolUtils.fetchComputeMultipleClmmInfo({\n connection: this.scope.connection,\n rpcDataMap: clmmPoolsRpcInfo,\n poolList: Object.keys(clmmPoolsRpcInfo).map((poolId) => {\n const [mintA, mintB] = [clmmPoolsRpcInfo[poolId].mintA.toBase58(), clmmPoolsRpcInfo[poolId].mintB.toBase58()];\n return {\n id: poolId,\n programId: clmmPoolsRpcInfo[poolId].programId.toBase58(),\n mintA: toApiV3Token({\n address: mintA,\n decimals: clmmPoolsRpcInfo[poolId].mintDecimalsA,\n programId: mintInfos[mintA].programId.toBase58() || TOKEN_PROGRAM_ID.toBase58(),\n extensions: {\n feeConfig: mintInfos[mintA]?.feeConfig ? toFeeConfig(mintInfos[mintA]?.feeConfig) : undefined,\n },\n }),\n mintB: toApiV3Token({\n address: mintB,\n decimals: clmmPoolsRpcInfo[poolId].mintDecimalsB,\n programId: mintInfos[mintB].programId.toBase58() || TOKEN_PROGRAM_ID.toBase58(),\n extensions: {\n feeConfig: mintInfos[mintB]?.feeConfig ? toFeeConfig(mintInfos[mintB]?.feeConfig) : undefined,\n },\n }),\n price: clmmPoolsRpcInfo[poolId].currentPrice,\n config: {\n ...clmmConfigs[clmmPoolsRpcInfo[poolId].configId.toBase58()],\n id: clmmPoolsRpcInfo[poolId].configId.toBase58(),\n\n fundFeeRate: 0,\n description: \"\",\n defaultRange: 0,\n defaultRangePoint: [],\n },\n };\n }),\n });\n\n const computePoolTickData = await PoolUtils.fetchMultiplePoolTickArrays({\n connection: this.scope.connection,\n poolKeys: Object.values(computeClmmPoolInfo),\n });\n\n return {\n computeClmmPoolInfo,\n computePoolTickData,\n };\n }\n\n public async getPoolInfoFromRpc(poolId: string): Promise<{\n rpcPoolInfo: ClmmParsedRpcData;\n poolInfo: ApiV3PoolInfoConcentratedItem;\n poolKeys: ClmmKeys;\n computePoolInfo: ComputeClmmPoolInfo;\n tickData: ReturnTypeFetchMultiplePoolTickArrays;\n tickArrays: (ReturnType<typeof TickArrayLayout.decode> & { address: PublicKey })[];\n }> {\n const rpcData = await this.getRpcClmmPoolInfo({ poolId });\n const mintSet = new Set([\n rpcData.mintA.toBase58(),\n rpcData.mintB.toBase58(),\n ...rpcData.rewardInfos.filter((r) => !r.mint.equals(PublicKey.default)).map((r) => r.mint.toBase58()),\n ]);\n\n const mintInfos = await fetchMultipleMintInfos({\n connection: this.scope.connection,\n mints: Array.from(mintSet).map((m) => new PublicKey(m)),\n });\n\n const { computeClmmPoolInfo, computePoolTickData } = await this.scope.clmm.getComputeClmmPoolInfos({\n clmmPoolsRpcInfo: { [poolId]: rpcData },\n mintInfos,\n });\n const vaultData = await getMultipleAccountsInfoWithCustomFlags(this.scope.connection, [\n { pubkey: rpcData.vaultA },\n { pubkey: rpcData.vaultB },\n ]);\n\n const poolInfo = clmmComputeInfoToApiInfo(computeClmmPoolInfo[poolId], mintInfos);\n\n if (!vaultData[0].accountInfo || !vaultData[1].accountInfo) throw new Error(\"pool vault data not found\");\n poolInfo.mintAmountA = Number(splAccountLayout.decode(vaultData[0].accountInfo.data).amount.toString());\n poolInfo.mintAmountB = Number(splAccountLayout.decode(vaultData[1].accountInfo.data).amount.toString());\n const poolKeys: ClmmKeys = {\n ...computeClmmPoolInfo[poolId],\n exBitmapAccount: computeClmmPoolInfo[poolId].exBitmapAccount.toBase58(),\n observationId: computeClmmPoolInfo[poolId].observationId.toBase58(),\n id: poolId,\n programId: rpcData.programId.toBase58(),\n openTime: rpcData.startTime.toString(),\n vault: {\n A: rpcData.vaultA.toBase58(),\n B: rpcData.vaultB.toBase58(),\n },\n config: poolInfo.config,\n rewardInfos: computeClmmPoolInfo[poolId].rewardInfos\n .filter((r) => !r.vault.equals(PublicKey.default))\n .map((r) => ({\n mint: toApiV3Token({\n address: r.mint.toBase58(),\n programId: TOKEN_PROGRAM_ID.toBase58(),\n decimals: mintInfos[r.mint.toBase58()].decimals ?? 6,\n }),\n vault: r.vault.toBase58(),\n })),\n };\n\n return {\n poolInfo,\n poolKeys,\n computePoolInfo: computeClmmPoolInfo[poolId],\n tickData: computePoolTickData,\n rpcPoolInfo: rpcData,\n tickArrays: Object.values(computePoolTickData[poolId]),\n };\n }\n\n public async getSwapPoolInfo(\n poolId: string | PublicKey,\n zeroForOne = true,\n ): Promise<{\n poolInfo: SimpleClmmPoolInfo;\n rpcData: ClmmParsedRpcData;\n configInfo: ReturnType<typeof ClmmConfigLayout.decode>;\n tickArrays: {\n address: PublicKey;\n value: ReturnType<typeof TickArrayLayout.decode>;\n }[];\n }> {\n const { poolInfo, rpcData } = await this.getSimplePoolInfo(poolId);\n\n const res = await this.scope.connection.getAccountInfo(rpcData.configId);\n const configInfo = ClmmConfigLayout.decode(res!.data);\n const programId = new PublicKey(poolInfo.programId);\n const poolIdPub = new PublicKey(poolId);\n\n const tickArrays = await fetchTickArrays(\n programId,\n this.scope.connection,\n poolIdPub,\n rpcData.tickCurrent,\n configInfo.tickSpacing,\n rpcData.tickArrayBitmap,\n zeroForOne,\n );\n\n return {\n poolInfo,\n rpcData,\n configInfo,\n tickArrays,\n };\n }\n public async getSimplePoolInfo(poolId: string | PublicKey): Promise<{\n poolInfo: SimpleClmmPoolInfo;\n rpcData: ClmmParsedRpcData;\n }> {\n const rpcData = await this.getRpcClmmPoolInfo({ poolId });\n const mintDataRes = await this.scope.connection.getMultipleAccountsInfo([rpcData.mintA, rpcData.mintB]);\n\n return {\n poolInfo: {\n id: poolId.toString(),\n programId: rpcData.programId.toString(),\n mintA: {\n address: rpcData.mintA.toString(),\n programId: mintDataRes[0]!.owner.toString(),\n decimals: rpcData.mintDecimalsA,\n },\n mintB: {\n address: rpcData.mintB.toString(),\n programId: mintDataRes[1]!.owner.toString(),\n decimals: rpcData.mintDecimalsB,\n },\n config: {\n id: rpcData.configId.toBase58(),\n tickSpacing: rpcData.tickSpacing,\n },\n },\n rpcData,\n };\n }\n\n public async getMultipleSimplePoolInfo(poolIdList: (string | PublicKey)[]): Promise<\n Record<\n string,\n {\n poolInfo: SimpleClmmPoolInfo;\n rpcData: ClmmParsedRpcData;\n }\n >\n > {\n const poolInfoMap = await this.getRpcClmmPoolInfos({ poolIds: poolIdList });\n const mintSet = new Set(\n Object.values(poolInfoMap)\n .map((p) => [p.mintA.toBase58(), p.mintB.toBase58()])\n .flat(),\n );\n\n const mintInfos = await fetchMultipleMintInfos({\n connection: this.scope.connection,\n mints: Array.from(mintSet).map((p) => new PublicKey(p)),\n });\n\n const poolData: Record<\n string,\n {\n poolInfo: SimpleClmmPoolInfo;\n rpcData: ClmmParsedRpcData;\n }\n > = {};\n\n poolIdList.forEach((poolId) => {\n const rpcData = poolInfoMap[poolId.toString()];\n if (!rpcData) return null;\n const mintA = mintInfos[rpcData.mintA.toBase58()];\n const mintB = mintInfos[rpcData.mintB.toBase58()];\n poolData[poolId.toString()] = {\n poolInfo: {\n id: poolId.toString(),\n programId: rpcData.programId.toString(),\n mintA: {\n address: rpcData.mintA.toString(),\n programId: mintA.programId.toString(),\n decimals: rpcData.mintDecimalsA,\n },\n mintB: {\n address: rpcData.mintB.toString(),\n programId: mintB.programId.toString(),\n decimals: rpcData.mintDecimalsB,\n },\n config: {\n id: rpcData.configId.toBase58(),\n tickSpacing: rpcData.tickSpacing,\n },\n },\n rpcData,\n };\n });\n\n return poolData;\n }\n}\n","import { BigNumberish } from \"@/common/bignumber\";\nimport { RawMint, TOKEN_PROGRAM_ID, TransferFeeConfigLayout } from \"@solana/spl-token\";\nimport { Connection, PublicKey } from \"@solana/web3.js\";\nimport { Token, TokenAmount } from \"../../module\";\nimport { SOL_INFO, TOKEN_WSOL } from \"./constant\";\nimport { TokenInfo } from \"./type\";\n\nimport { solToWSol } from \"@/common\";\nimport { ApiV3Token } from \"../../api\";\nimport { SPL_MINT_LAYOUT } from \"./layout\";\n\nexport const parseTokenInfo = async ({\n connection,\n mint,\n}: {\n connection: Connection;\n mint: PublicKey | string;\n}): Promise<RawMint | undefined> => {\n const accountData = await connection.getAccountInfo(new PublicKey(mint));\n if (!accountData || accountData.data.length !== SPL_MINT_LAYOUT.span) return;\n const tokenInfo = SPL_MINT_LAYOUT.decode(accountData.data);\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n //@ts-ignore\n return tokenInfo;\n};\n\nexport const toTokenInfo = ({\n mint,\n decimals,\n programId = TOKEN_PROGRAM_ID,\n logoURI = \"\",\n priority = 3,\n}: {\n mint: PublicKey;\n decimals: number;\n programId?: PublicKey | string;\n priority?: number;\n logoURI?: string;\n}): TokenInfo => {\n const pubStr = mint.toBase58().substring(0, 6);\n return {\n address: mint.toBase58(),\n decimals,\n symbol: pubStr,\n logoURI,\n extensions: {},\n chainId: 101,\n programId: programId.toString(),\n name: pubStr,\n tags: [],\n priority,\n };\n};\n\nexport const toToken = (props: Omit<TokenInfo, \"priority\">): Token =>\n new Token({\n mint: props.address,\n decimals: props.decimals,\n symbol: props.symbol,\n name: props.name,\n });\n\nexport const toTokenAmount = ({\n amount,\n isRaw,\n name,\n ...props\n}: Omit<TokenInfo, \"priority\"> & {\n amount: BigNumberish;\n isRaw?: boolean;\n name?: string;\n}): TokenAmount =>\n new TokenAmount(\n new Token({\n mint: solToWSol(props.address).toBase58(),\n decimals: props.decimals,\n symbol: props.symbol,\n name,\n }),\n amount,\n isRaw,\n name,\n );\n\nexport function solToWSolToken<T extends ApiV3Token | TokenInfo>(token: T): T {\n if (token.address === SOL_INFO.address) return TOKEN_WSOL as T;\n return token;\n}\n\nexport function wSolToSolToken<T extends ApiV3Token | TokenInfo>(token: T): T {\n if (token.address === TOKEN_WSOL.address) return SOL_INFO as T;\n return token;\n}\n\nexport const toApiV3Token = ({\n address,\n programId,\n decimals,\n ...props\n}: {\n address: string;\n programId: string;\n decimals: number;\n} & Partial<ApiV3Token>): ApiV3Token => ({\n chainId: 101,\n address: solToWSol(address).toBase58(),\n programId,\n logoURI: \"\",\n symbol: \"\",\n name: \"\",\n decimals,\n tags: [],\n extensions: props.extensions || {},\n ...props,\n});\n\nexport const toFeeConfig = (\n config?: ReturnType<typeof TransferFeeConfigLayout.decode> | undefined | null,\n): ApiV3Token[\"extensions\"][\"feeConfig\"] | undefined =>\n config\n ? {\n ...config,\n transferFeeConfigAuthority: config.transferFeeConfigAuthority.toBase58(),\n withdrawWithheldAuthority: config.withdrawWithheldAuthority.toBase58(),\n withheldAmount: config.withheldAmount.toString(),\n olderTransferFee: {\n ...config.olderTransferFee,\n epoch: config.olderTransferFee.epoch.toString(),\n maximumFee: config.olderTransferFee.maximumFee.toString(),\n },\n newerTransferFee: {\n ...config.newerTransferFee,\n epoch: config.newerTransferFee.epoch.toString(),\n maximumFee: config.newerTransferFee.maximumFee.toString(),\n },\n }\n : undefined;\n","import { publicKey, struct, u32, u64, u8 } from \"../../marshmallow\";\n\nexport const SPL_MINT_LAYOUT = struct([\n u32(\"mintAuthorityOption\"),\n publicKey(\"mintAuthority\"),\n u64(\"supply\"),\n u8(\"decimals\"),\n u8(\"isInitialized\"),\n u32(\"freezeAuthorityOption\"),\n publicKey(\"freezeAuthority\"),\n]);\n\nexport type SplMintLayout = typeof SPL_MINT_LAYOUT;\n","import BN from \"bn.js\"\nimport Decimal from \"decimal.js\"\nimport { BN_ONE, BN_ZERO, Q128, U128_MAX } from \"./constants\"\n\nexport function mask(bits: number): BN {\n return new BN(1).shln(bits).subn(1)\n}\n\nexport function checkedAdd(a: BN, b: BN, maxBits: number): BN {\n const result = a.add(b)\n const maxValue = mask(maxBits)\n if (result.gt(maxValue)) {\n throw new Error(`Addition overflow: result exceeds ${maxBits} bits`)\n }\n return result\n}\n\nexport function checkedSub(a: BN, b: BN): BN {\n if (a.lt(b)) {\n throw new Error(\"Subtraction underflow\")\n }\n return a.sub(b)\n}\n\nexport function checkedMul(a: BN, b: BN, maxBits: number): BN {\n const result = a.mul(b)\n const maxValue = mask(maxBits)\n if (result.gt(maxValue)) {\n throw new Error(`Multiplication overflow: result exceeds ${maxBits} bits`)\n }\n return result\n}\n\nexport function mulFull(a: BN, b: BN): [BN, BN] {\n const result = a.mul(b)\n const low = result.and(mask(128))\n const high = result.shrn(128)\n return [low, high]\n}\n\nexport function mulDivFloor(a: BN, b: BN, denominator: BN): BN {\n if (denominator.isZero()) {\n throw new Error(\"Division by zero\")\n }\n return a.mul(b).div(denominator)\n}\n\nexport function mulDivCeil(a: BN, b: BN, denominator: BN): BN {\n if (denominator.isZero()) {\n throw new Error(\"Division by zero\")\n }\n const product = a.mul(b)\n const quotient = product.div(denominator)\n const remainder = product.mod(denominator)\n\n if (remainder.isZero()) {\n return quotient\n }\n return quotient.addn(1)\n}\n\nexport function mulDivRound(a: BN, b: BN, denominator: BN, roundUp: boolean): BN {\n return roundUp ? mulDivCeil(a, b, denominator) : mulDivFloor(a, b, denominator)\n}\n\nexport function divRoundingUp(x: BN, y: BN) {\n return x.div(y).add(x.mod(y).isZero() ? BN_ZERO : BN_ONE)\n}\n\nexport function u128SaturatingAdd(a: BN, b: BN): BN {\n const result = a.add(b)\n return result.gt(U128_MAX) ? U128_MAX : result\n}\n\nexport function u128SaturatingSub(a: BN, b: BN): BN {\n return a.gt(b) ? a.sub(b) : new BN(0)\n}\n\nexport function u128CheckedMul(a: BN, b: BN): BN {\n const result = a.mul(b)\n if (result.gt(U128_MAX)) {\n throw new Error(\"U128 multiplication overflow\")\n }\n return result\n}\n\nexport const U256_MAX = new BN(1).shln(256).subn(1)\n\nexport function u256MulDivFloor(a: BN, b: BN, denominator: BN): BN {\n if (denominator.isZero()) {\n throw new Error(\"Division by zero\")\n }\n return a.mul(b).div(denominator)\n}\n\nexport function u256MulDivCeil(a: BN, b: BN, denominator: BN): BN {\n if (denominator.isZero()) {\n throw new Error(\"Division by zero\")\n }\n const product = a.mul(b)\n const quotient = product.div(denominator)\n const remainder = product.mod(denominator)\n\n if (remainder.isZero()) {\n return quotient\n }\n return quotient.addn(1)\n}\n\nexport function mostSignificantBit(n: BN): number {\n if (n.isZero()) {\n return -1\n }\n return n.bitLength() - 1\n}\n\nexport function leastSignificantBit(n: BN): number {\n if (n.isZero()) {\n return -1\n }\n\n let pos = 0\n let temp = n.clone()\n\n while (temp.and(new BN(1)).isZero()) {\n temp = temp.shrn(1)\n pos++\n }\n\n return pos\n}\n\nexport function isBitSet(n: BN, bit: number): boolean {\n return n.testn(bit)\n}\n\nexport function setBit(n: BN, bit: number): BN {\n return n.or(new BN(1).shln(bit))\n}\n\nexport function clearBit(n: BN, bit: number): BN {\n return n.and(new BN(1).shln(bit).notn(256))\n}\n\nexport function toggleBit(n: BN, bit: number): BN {\n return n.xor(new BN(1).shln(bit))\n}\n\nexport function toSignedI128(n: BN): BN {\n const signBit = new BN(1).shln(127)\n if (n.and(signBit).isZero()) {\n return n\n }\n return n.sub(new BN(1).shln(128))\n}\n\nexport function fromSignedI128(n: BN): BN {\n if (n.isNeg()) {\n return n.add(new BN(1).shln(128))\n }\n return n\n}\n\nexport function abs(n: BN): BN {\n return n.isNeg() ? n.neg() : n\n}\n\nexport function x64ToDecimal(num: BN, decimalPlaces?: number): Decimal {\n return new Decimal(num.toString()).div(Decimal.pow(2, 64)).toDecimalPlaces(decimalPlaces)\n}\n\nexport function decimalToX64(num: Decimal): BN {\n return new BN(num.mul(Decimal.pow(2, 64)).floor().toFixed())\n}\n\nexport function wrappingSubU128(n0: BN, n1: BN): BN {\n return n0.add(Q128).sub(n1).mod(Q128)\n}\n","import BN from \"bn.js\";\nimport { LimitOrderLayout, TickLayout } from \"../layout\";\nimport { mulDivFloor } from \"./bigNum\";\nimport { BN_ONE, BN_ZERO } from \"./constants\";\nimport { TickUtil } from \"./tickArrayUtil\";\n\nexport class LimitOrderMath {\n public static isFullyFilled({ orderInfo }: { orderInfo: ReturnType<typeof LimitOrderLayout.decode> }): boolean {\n return orderInfo.totalAmount.eq(orderInfo.filledAmount);\n }\n\n public static getUnFilledAmount({ orderInfo }: { orderInfo: ReturnType<typeof LimitOrderLayout.decode> }): BN {\n return orderInfo.totalAmount.sub(orderInfo.filledAmount);\n }\n\n public static settleFilledOrder({\n orderInfo,\n tickInfo,\n }: {\n orderInfo: ReturnType<typeof LimitOrderLayout.decode>;\n tickInfo: ReturnType<typeof TickLayout.decode>;\n }): BN {\n if (orderInfo.settleBase.isZero()) return BN_ZERO\n\n if (orderInfo.orderPhase.eq(tickInfo.orderPhase)) {\n return BN_ZERO\n } else if (orderInfo.orderPhase.add(BN_ONE).eq(tickInfo.orderPhase)) {\n const numerator = orderInfo.settleBase.mul(tickInfo.unfilledRatioX64)\n const denominator = orderInfo.unfilledRatioX64\n\n const idealRemaining = numerator.div(denominator)\n const isExact = numerator.mod(denominator).isZero()\n\n const totalFilled = orderInfo.settleBase.sub(idealRemaining)\n if (totalFilled.isZero()) return BN_ZERO\n\n const effectiveFilled = isExact ? totalFilled : totalFilled.sub(BN_ONE)\n\n const totalOutput = TickUtil.getLimitOrderOutput({ amountIn: effectiveFilled, tick: tickInfo.tick, zeroForOne: orderInfo.zeroForOne })\n\n const payout = totalOutput.sub(orderInfo.settleOutput)\n // orderInfo.filledAmount = orderInfo.totalAmount.sub(idealRemaining)\n // orderInfo.settleOutput = totalOutput\n\n return payout\n } else if (orderInfo.orderPhase.add(new BN(2)).lte(tickInfo.orderPhase)) {\n const totalOutput = TickUtil.getLimitOrderOutput({ amountIn: orderInfo.settleBase, tick: tickInfo.tick, zeroForOne: orderInfo.zeroForOne })\n const payout = totalOutput.sub(orderInfo.settleOutput)\n // orderInfo.filledAmount = orderInfo.totalAmount\n // orderInfo.settleBase = BN_ZERO\n // orderInfo.settleOutput = BN_ZERO\n return payout\n } else {\n throw Error('invalid order phase')\n }\n }\n}\n","import { FEE_RATE_DENOMINATOR_VALUE, getMultipleAccountsInfo } from \"@/common\";\nimport { Connection, PublicKey } from \"@solana/web3.js\";\nimport BN from \"bn.js\";\nimport Decimal from \"decimal.js\";\nimport { PoolInfoLayout, TickArrayBitmapExtensionLayout, TickArrayLayout, TickLayout } from \"../layout\";\nimport { mostSignificantBit, mulDivCeil, mulDivFloor } from \"./bigNum\";\nimport {\n BIT_PRECISION,\n BN_ONE,\n BN_ZERO,\n EXTENSION_TICKARRAY_BITMAP_SIZE,\n LOG_B_2_X32,\n LOG_B_P_ERR_MARGIN_LOWER_X64,\n LOG_B_P_ERR_MARGIN_UPPER_X64,\n MAX_SQRT_PRICE_X64,\n MAX_TICK,\n MIN_SQRT_PRICE_X64,\n MIN_TICK,\n Q64,\n TICK_ARRAY_BITMAP_SIZE,\n TICK_ARRAY_SIZE,\n TICK_TO_SQRT_PRICE_FACTORS,\n} from \"./constants\";\nimport { getPdaExBitmapAccount, getPdaTickArrayAddress } from \"./pda\";\n\nexport interface LimitOrderMatchResult {\n amountIn: BN;\n amountOut: BN;\n ammFeeAmount: BN;\n}\n\nexport class TickArrayBitmapUtil {\n private static scanLinearBitmap({\n bitmap,\n tickSpacing,\n offset,\n checkInfo,\n }: {\n bitmap: Buffer;\n tickSpacing: number;\n offset: number;\n checkInfo?: { tick: number; valueType: \"lte\" | \"gte\" };\n }): number[] {\n const result: number[] = [];\n const totalBits = bitmap.length * 8;\n\n let startBit = 0;\n let endBit = totalBits - 1;\n\n if (checkInfo) {\n const threshold = checkInfo.tick / (tickSpacing * TICK_ARRAY_SIZE) - offset;\n if (checkInfo.valueType === \"gte\") {\n startBit = Math.max(0, Math.ceil(threshold));\n } else {\n endBit = Math.min(totalBits - 1, Math.floor(threshold));\n }\n }\n\n if (startBit > endBit) return result;\n\n const startByte = Math.floor(startBit / 8);\n const endByte = Math.floor(endBit / 8);\n\n for (let i = startByte; i <= endByte; i++) {\n if (!bitmap[i]) continue;\n\n const jStart = i === startByte ? startBit % 8 : 0;\n const jEnd = i === endByte ? endBit % 8 : 7;\n for (let j = jStart; j <= jEnd; j++) {\n if (bitmap[i] & (1 << j)) {\n result.push((i * 8 + j + offset) * tickSpacing * TICK_ARRAY_SIZE);\n }\n }\n }\n return result;\n }\n\n private static findPoolBitmap({\n bitmap,\n tickSpacing,\n checkInfo,\n }: {\n bitmap: Buffer;\n tickSpacing: number;\n checkInfo?: { tick: number; valueType: \"lte\" | \"gte\" };\n }): number[] {\n if (checkInfo) {\n const _i = Math.floor(checkInfo.tick / TICK_ARRAY_SIZE / tickSpacing);\n if (checkInfo.valueType === \"lte\" && _i < -512) return [];\n if (checkInfo.valueType === \"gte\" && _i > 512) return [];\n }\n return this.scanLinearBitmap({ bitmap, tickSpacing, offset: -TICK_ARRAY_BITMAP_SIZE, checkInfo });\n }\n\n private static findPositiveTickArrayBitmap({\n bitmap,\n tickSpacing,\n checkInfo,\n }: {\n bitmap: Buffer;\n tickSpacing: number;\n checkInfo?: { tick: number; valueType: \"lte\" | \"gte\" };\n }): number[] {\n if (checkInfo) {\n const _i = Math.floor(checkInfo.tick / TICK_ARRAY_SIZE / tickSpacing);\n if (checkInfo.valueType === \"lte\" && _i < 512) return [];\n }\n return this.scanLinearBitmap({ bitmap, tickSpacing, offset: TICK_ARRAY_BITMAP_SIZE, checkInfo });\n }\n\n private static findNegativeTickArrayBitmap({\n bitmap,\n tickSpacing,\n count,\n checkInfo,\n }: {\n bitmap: Buffer;\n tickSpacing: number;\n count?: number;\n checkInfo?: { tick: number; valueType: \"lte\" | \"gte\" };\n }): number[] {\n const result: number[] = [];\n\n if (checkInfo) {\n const _i = Math.floor(checkInfo.tick / TICK_ARRAY_SIZE / tickSpacing);\n if (checkInfo.valueType === \"gte\" && _i >= -512) return result;\n }\n\n const maxFlatIndex =\n checkInfo?.valueType === \"lte\" ? Math.floor(checkInfo.tick / (TICK_ARRAY_SIZE * tickSpacing)) + 7680 : Infinity;\n const minFlatIndex =\n checkInfo?.valueType === \"gte\" ? Math.ceil(checkInfo.tick / (TICK_ARRAY_SIZE * tickSpacing)) + 7680 : 0;\n\n outer: for (let arrayIndex = 0; arrayIndex < EXTENSION_TICKARRAY_BITMAP_SIZE; arrayIndex++) {\n const reversedIndex = EXTENSION_TICKARRAY_BITMAP_SIZE - 1 - arrayIndex;\n for (let searchIndex = 0; searchIndex < 512; searchIndex++) {\n const flatIndex = arrayIndex * 512 + searchIndex;\n\n if (flatIndex > maxFlatIndex) break outer;\n if (flatIndex < minFlatIndex) continue;\n\n const byteOffset = reversedIndex * 64 + Math.floor(searchIndex / 8);\n if (!bitmap[byteOffset]) {\n searchIndex = Math.floor(searchIndex / 8) * 8 + 7;\n continue;\n }\n if (bitmap[byteOffset] & (1 << searchIndex % 8)) {\n const tick = (arrayIndex * 512 + searchIndex - 7680) * TICK_ARRAY_SIZE * tickSpacing;\n result.push(tick);\n\n if (count !== undefined && result.length >= count) break outer;\n }\n }\n }\n return result;\n }\n\n static findTickArrayStartIndex({\n tickSpacing,\n poolBitmap,\n tickArrayBitmap,\n findInfo,\n }: {\n tickSpacing: number;\n poolBitmap: ReturnType<typeof PoolInfoLayout.decode>[\"tickArrayBitmap\"];\n tickArrayBitmap: ReturnType<typeof TickArrayBitmapExtensionLayout.decode>;\n findInfo: { type: \"zeroForOne\" | \"oneForZero\"; count?: number; tickArrayCurrent: number } | { type: \"all\" };\n }): number[] {\n if (findInfo.type === \"all\") {\n return [\n ...this.findNegativeTickArrayBitmap({ tickSpacing, bitmap: tickArrayBitmap.negativeTickArrayBitmap }),\n ...this.findPoolBitmap({ tickSpacing, bitmap: poolBitmap }),\n ...this.findPositiveTickArrayBitmap({ tickSpacing, bitmap: tickArrayBitmap.positiveTickArrayBitmap }),\n ];\n }\n\n const tickStart = TickArrayUtil.getTickArrayStartIndex(findInfo.tickArrayCurrent, tickSpacing);\n const { count } = findInfo;\n\n if (findInfo.type === \"oneForZero\") {\n const checkInfo = { tick: tickStart, valueType: \"gte\" } as const;\n const finders = [\n () =>\n this.findNegativeTickArrayBitmap({ tickSpacing, bitmap: tickArrayBitmap.negativeTickArrayBitmap, checkInfo }),\n () => this.findPoolBitmap({ tickSpacing, bitmap: poolBitmap, checkInfo }),\n () =>\n this.findPositiveTickArrayBitmap({ tickSpacing, bitmap: tickArrayBitmap.positiveTickArrayBitmap, checkInfo }),\n ];\n return this.collectUntil(finders, count);\n }\n\n if (findInfo.type === \"zeroForOne\") {\n const checkInfo = { tick: tickStart, valueType: \"lte\" } as const;\n const finders = [\n () =>\n this.findPositiveTickArrayBitmap({\n tickSpacing,\n bitmap: tickArrayBitmap.positiveTickArrayBitmap,\n checkInfo,\n }).sort((a, b) => b - a),\n () => this.findPoolBitmap({ tickSpacing, bitmap: poolBitmap, checkInfo }).sort((a, b) => b - a),\n () =>\n this.findNegativeTickArrayBitmap({\n tickSpacing,\n bitmap: tickArrayBitmap.negativeTickArrayBitmap,\n checkInfo,\n }).sort((a, b) => b - a),\n ];\n return this.collectUntil(finders, count);\n }\n\n throw new Error(\"find info type check error\");\n }\n\n private static collectUntil(finders: Array<() => number[]>, count: number | undefined): number[] {\n const collected: number[] = [];\n for (const finder of finders) {\n if (count !== undefined && collected.length >= count) break;\n collected.push(...finder());\n }\n return collected.slice(0, count);\n }\n\n static findTickArrayAddress(params: {\n programId: PublicKey;\n poolId: PublicKey;\n tickSpacing: number;\n poolBitmap: ReturnType<typeof PoolInfoLayout.decode>[\"tickArrayBitmap\"];\n tickArrayBitmap: ReturnType<typeof TickArrayBitmapExtensionLayout.decode>;\n findInfo: { type: \"zeroForOne\" | \"oneForZero\"; count?: number; tickArrayCurrent: number } | { type: \"all\" };\n }) {\n return this.findTickArrayStartIndex(params).map(\n (i) => getPdaTickArrayAddress(params.programId, params.poolId, i).publicKey,\n );\n }\n\n static maxTickInTickarrayBitmap(tickSpacing: number): number {\n return tickSpacing * TICK_ARRAY_SIZE * TICK_ARRAY_BITMAP_SIZE;\n }\n}\n\nexport class TickArrayUtil {\n static firstinitializedTick({\n data,\n zeroForOne,\n }: {\n data: ReturnType<typeof TickArrayLayout.decode>;\n zeroForOne: boolean;\n }) {\n if (zeroForOne) {\n for (let i = data.ticks.length - 1; i >= 0; i--) {\n if (TickUtil.isInitialized({ data: data.ticks[i] })) return data.ticks[i];\n }\n } else {\n for (let i = 0; i < data.ticks.length; i++) {\n if (TickUtil.isInitialized({ data: data.ticks[i] })) return data.ticks[i];\n }\n }\n }\n\n static nextInitalizedTick({\n data,\n currentTickIndex,\n tickSpacing,\n zeroForOne,\n }: {\n data: ReturnType<typeof TickArrayLayout.decode>;\n currentTickIndex: number;\n tickSpacing: number;\n zeroForOne: boolean;\n }) {\n const currentTickArrayStartIndex = this.getTickArrayStartIndex(currentTickIndex, tickSpacing);\n if (currentTickArrayStartIndex !== data.startTickIndex) return undefined;\n const offsetInArray = Math.floor((currentTickIndex - data.startTickIndex) / tickSpacing);\n\n if (zeroForOne) {\n for (let i = offsetInArray; i >= 0; i--) {\n if (TickUtil.isInitialized({ data: data.ticks[i] })) {\n return data.ticks[i];\n }\n }\n } else {\n for (let i = offsetInArray + 1; i < TICK_ARRAY_SIZE; i++) {\n if (TickUtil.isInitialized({ data: data.ticks[i] })) {\n return data.ticks[i];\n }\n }\n }\n return undefined;\n }\n\n static getTickArrayStartIndex(tickIndex: number, tickSpacing: number) {\n const ticksInArray = this.tickCount(tickSpacing);\n const start = Math.floor(tickIndex / ticksInArray);\n\n return start * ticksInArray;\n }\n\n static getTickOffsetInArray(tick: number, tickSpacing: number): number {\n if (tick % tickSpacing != 0) {\n throw new Error(\"tickIndex % tickSpacing not equal 0\");\n }\n const startIndex = this.getTickArrayStartIndex(tick, tickSpacing);\n return Math.floor((tick - startIndex) / tickSpacing);\n }\n\n static tickCount(tickSpacing: number) {\n return TICK_ARRAY_SIZE * tickSpacing;\n }\n\n static getMinTick(tickSpacing: number): number {\n return Math.ceil(MIN_TICK / tickSpacing) * tickSpacing;\n }\n\n static getMaxTick(tickSpacing: number): number {\n return Math.floor(MAX_TICK / tickSpacing) * tickSpacing;\n }\n}\n\nexport class TickUtil {\n static isInitialized({ data }: { data: ReturnType<typeof TickLayout.decode> }): boolean {\n return this.hasLiquidity({ data }) || this.hasLimitOrders({ data });\n }\n\n static hasLimitOrders({ data }: { data: ReturnType<typeof TickLayout.decode> }): boolean {\n return !data.ordersAmount.isZero() || !data.partFilledOrdersRemaining.isZero();\n }\n\n static hasLiquidity({ data }: { data: ReturnType<typeof TickLayout.decode> }): boolean {\n return !data.liquidityGross.isZero();\n }\n\n static isValidTick(tick: number): boolean {\n return tick >= MIN_TICK && tick <= MAX_TICK;\n }\n static checkTick(tick: number): void {\n if (!this.isValidTick(tick)) {\n throw new Error(`Tick ${tick} is out of range [${MIN_TICK}, ${MAX_TICK}]`);\n }\n }\n static getSqrtPriceAtTick(tick: number): BN {\n this.checkTick(tick);\n\n const absTick = Math.abs(tick);\n\n let ratio = Q64.clone();\n\n for (const { bit, factor } of TICK_TO_SQRT_PRICE_FACTORS) {\n if ((absTick & (1 << bit)) !== 0) {\n ratio = mulDivFloor(ratio, factor, Q64);\n }\n }\n\n if (tick > 0) {\n ratio = mulDivFloor(Q64, Q64, ratio);\n }\n\n return ratio;\n }\n\n static getLimitOrderOutput({ amountIn, tick, zeroForOne }: { amountIn: BN; tick: number; zeroForOne: boolean }): BN {\n if (zeroForOne) {\n const priceX64 = TickUtil.getPriceAtTick(tick, false);\n return mulDivFloor(amountIn, priceX64, Q64);\n } else {\n const priceX64 = TickUtil.getPriceAtTick(tick, true);\n return mulDivFloor(amountIn, Q64, priceX64);\n }\n }\n static getLimitOrderInput({ amountOut, tick, zeroForOne }: { amountOut: BN; tick: number; zeroForOne: boolean }): BN {\n if (zeroForOne) {\n const priceX64 = TickUtil.getPriceAtTick(tick, true);\n return mulDivCeil(amountOut, priceX64, Q64);\n } else {\n const priceX64 = TickUtil.getPriceAtTick(tick, false);\n return mulDivCeil(amountOut, Q64, priceX64);\n }\n }\n\n static limitOrderUnfilledAmount({ tick }: { tick: ReturnType<typeof TickLayout.decode> }): BN {\n return tick.ordersAmount.add(tick.partFilledOrdersRemaining);\n }\n\n static matchLimitOrder({\n tick,\n swapAmount,\n swapDirectionZeroForOne,\n isBaseInput,\n feeRate,\n isFeeOnInput,\n }: {\n tick: ReturnType<typeof TickLayout.decode>;\n swapAmount: BN;\n swapDirectionZeroForOne: boolean;\n isBaseInput: boolean;\n feeRate: number;\n isFeeOnInput: boolean;\n }): LimitOrderMatchResult {\n const result: LimitOrderMatchResult = {\n amountIn: BN_ZERO,\n amountOut: BN_ZERO,\n ammFeeAmount: BN_ZERO,\n };\n\n const totalUnfilledAmount = this.limitOrderUnfilledAmount({ tick });\n if (swapAmount.isZero() || totalUnfilledAmount.isZero()) {\n return result;\n }\n\n if (isBaseInput) {\n if (isFeeOnInput) {\n result.ammFeeAmount = mulDivCeil(swapAmount, new BN(feeRate), FEE_RATE_DENOMINATOR_VALUE);\n result.amountIn = swapAmount.sub(result.ammFeeAmount);\n } else {\n result.amountIn = swapAmount;\n }\n\n result.amountOut = this.getLimitOrderOutput({\n amountIn: result.amountIn,\n tick: tick.tick,\n zeroForOne: swapDirectionZeroForOne,\n });\n\n if (result.amountOut.gt(totalUnfilledAmount)) {\n result.amountOut = totalUnfilledAmount;\n result.amountIn = this.getLimitOrderInput({\n amountOut: totalUnfilledAmount,\n tick: tick.tick,\n zeroForOne: !swapDirectionZeroForOne,\n });\n\n if (isFeeOnInput) {\n result.ammFeeAmount = mulDivCeil(\n result.amountIn,\n new BN(feeRate),\n FEE_RATE_DENOMINATOR_VALUE.sub(new BN(feeRate)),\n );\n }\n }\n } else {\n const netOutput = BN.min(swapAmount, totalUnfilledAmount);\n\n if (isFeeOnInput) {\n result.amountOut = netOutput;\n } else {\n result.amountOut = BN.min(\n mulDivCeil(netOutput, FEE_RATE_DENOMINATOR_VALUE, FEE_RATE_DENOMINATOR_VALUE.sub(new BN(feeRate))),\n totalUnfilledAmount,\n );\n }\n\n result.amountIn = this.getLimitOrderInput({\n amountOut: result.amountOut,\n tick: tick.tick,\n zeroForOne: !swapDirectionZeroForOne,\n });\n\n if (isFeeOnInput) {\n result.ammFeeAmount = mulDivCeil(\n result.amountIn,\n new BN(feeRate),\n FEE_RATE_DENOMINATOR_VALUE.sub(new BN(feeRate)),\n );\n }\n }\n\n let consumeFromPartRemaining = BN_ZERO;\n if (tick.partFilledOrdersRemaining.gt(BN_ZERO)) {\n consumeFromPartRemaining = BN.min(tick.partFilledOrdersRemaining, result.amountOut);\n\n if (consumeFromPartRemaining.gt(BN_ZERO)) {\n tick.unfilledRatioX64 = mulDivFloor(tick.unfilledRatioX64, tick.partFilledOrdersRemaining.sub(consumeFromPartRemaining), tick.partFilledOrdersRemaining)\n }\n\n tick.partFilledOrdersRemaining = tick.partFilledOrdersRemaining.sub(consumeFromPartRemaining);\n }\n const amountOutContinueToConsume = result.amountOut.sub(consumeFromPartRemaining);\n\n if (amountOutContinueToConsume.gt(BN_ZERO)) {\n if (!tick.partFilledOrdersRemaining.isZero()) throw Error(\"!tick.partFilledOrdersRemaining.isZero()\");\n if (tick.ordersAmount.lt(amountOutContinueToConsume)) throw Error(\"InvalidLimitOrderAmount\");\n\n tick.orderPhase = tick.orderPhase.add(BN_ONE);\n tick.unfilledRatioX64 = mulDivFloor(Q64, tick.ordersAmount.sub(amountOutContinueToConsume), tick.ordersAmount);\n tick.partFilledOrdersRemaining = tick.ordersAmount.sub(amountOutContinueToConsume);\n tick.ordersAmount = BN_ZERO;\n }\n\n if (!isFeeOnInput) {\n result.ammFeeAmount = mulDivCeil(result.amountOut, new BN(feeRate), FEE_RATE_DENOMINATOR_VALUE);\n result.amountOut = result.amountOut.sub(result.ammFeeAmount);\n }\n\n return result;\n }\n\n private static getPriceAtTick(tick: number, roundUp: boolean): BN {\n const sqrtPriceX64 = this.getSqrtPriceAtTick(tick);\n\n if (roundUp) {\n return sqrtPriceX64.mul(sqrtPriceX64).add(Q64.subn(1)).div(Q64);\n } else {\n return sqrtPriceX64.mul(sqrtPriceX64).div(Q64);\n }\n }\n\n static getTickAtSqrtPrice(sqrtPriceX64: BN): number {\n if (!(sqrtPriceX64.gte(MIN_SQRT_PRICE_X64) && sqrtPriceX64.lte(MAX_SQRT_PRICE_X64))) throw Error(\"SqrtPriceX64\");\n\n const msb = mostSignificantBit(sqrtPriceX64);\n\n const msbMinus64 = msb - 64;\n let log2pIntegerX32: BN;\n if (msbMinus64 >= 0) {\n log2pIntegerX32 = new BN(msbMinus64).shln(32);\n } else {\n log2pIntegerX32 = new BN(-msbMinus64).shln(32).neg();\n }\n\n let r: BN;\n if (msb >= 64) {\n r = sqrtPriceX64.shrn(msb - 63);\n } else {\n r = sqrtPriceX64.shln(63 - msb);\n }\n\n let log2pFractionX64 = new BN(0);\n let bit = new BN(1).shln(63);\n\n for (let precision = 0; precision < BIT_PRECISION && !bit.isZero(); precision++) {\n r = r.mul(r);\n\n const isRMoreThanTwo = r.shrn(127).toNumber();\n\n r = r.shrn(63 + isRMoreThanTwo);\n\n if (isRMoreThanTwo) {\n log2pFractionX64 = log2pFractionX64.add(bit);\n }\n\n bit = bit.shrn(1);\n }\n\n const log2pFractionX32 = log2pFractionX64.shrn(32);\n const log2pX32 = log2pIntegerX32.add(log2pFractionX32);\n\n const logSqrt10001X64 = log2pX32.mul(LOG_B_2_X32);\n\n const tickLowBN = logSqrt10001X64.sub(LOG_B_P_ERR_MARGIN_LOWER_X64);\n const tickHighBN = logSqrt10001X64.add(LOG_B_P_ERR_MARGIN_UPPER_X64);\n\n const tickLow = this.signedShrn64(tickLowBN);\n const tickHigh = this.signedShrn64(tickHighBN);\n\n if (tickLow === tickHigh) {\n return tickLow;\n }\n\n const sqrtPriceAtTickHigh = TickUtil.getSqrtPriceAtTick(tickHigh);\n if (sqrtPriceAtTickHigh.lte(sqrtPriceX64)) {\n return tickHigh;\n }\n\n return tickLow;\n }\n\n private static signedShrn64(bn: BN): number {\n if (bn.isNeg()) {\n const Q64 = new BN(1).shln(64);\n const result = bn.div(Q64);\n if (!bn.mod(Q64).isZero() && bn.isNeg()) {\n return result.subn(1).toNumber();\n }\n return result.toNumber();\n } else {\n return bn.shrn(64).toNumber();\n }\n }\n\n static sqrtPriceX64ToPrice(sqrtPriceX64: BN, decimalsA: number, decimalsB: number): Decimal {\n const sqrtPriceSquared = sqrtPriceX64.mul(sqrtPriceX64);\n\n const decimalDiff = decimalsA - decimalsB;\n\n const DECIMAL_PRECISION = 20;\n const PRECISION_MULTIPLIER = new BN(10).pow(new BN(DECIMAL_PRECISION));\n\n const numerator = sqrtPriceSquared.mul(PRECISION_MULTIPLIER);\n const denominator = new BN(1).shln(128);\n const scaledResult = numerator.div(denominator);\n\n let resultStr = scaledResult.toString();\n\n while (resultStr.length <= DECIMAL_PRECISION) {\n resultStr = \"0\" + resultStr;\n }\n\n const integerPart = resultStr.slice(0, -DECIMAL_PRECISION);\n const decimalPart = resultStr.slice(-DECIMAL_PRECISION);\n const priceStr = integerPart + \".\" + decimalPart;\n\n const price = new Decimal(priceStr).mul(new Decimal(10).pow(decimalDiff));\n\n return price;\n }\n\n static tickToPrice(tick: number, decimalsA: number, decimalsB: number): Decimal {\n const sqrtPriceX64 = TickUtil.getSqrtPriceAtTick(tick);\n return this.sqrtPriceX64ToPrice(sqrtPriceX64, decimalsA, decimalsB);\n }\n\n static priceToTick(price: Decimal, decimalsA: number, decimalsB: number): number {\n const adjustedPrice = price.div(Math.pow(10, decimalsA - decimalsB));\n\n const tick = adjustedPrice.log().div(new Decimal(1.0001).log()).floor();\n return Math.max(MIN_TICK, Math.min(MAX_TICK, tick.toNumber()));\n }\n\n static priceToSqrtPriceX64(price: Decimal, decimalsA: number, decimalsB: number): BN {\n const adjustedPrice = price.div(Math.pow(10, decimalsA - decimalsB));\n const sqrtPrice = adjustedPrice.sqrt();\n const sqrtPriceX64 = sqrtPrice.mul(new Decimal(2).pow(64));\n\n return new BN(sqrtPriceX64.toFixed(0));\n }\n\n static toTickIndex(tick: number, tickSpacing: number) {\n if (tick >= 0) {\n return tick - (tick % tickSpacing);\n }\n return tick - (tick % tickSpacing) - (tick % tickSpacing !== 0 ? tickSpacing : 0);\n }\n\n static getPriceAndTick({\n price,\n mintADecimals,\n mintBDecimals,\n zeroForOne,\n tickSpacing,\n }: {\n price: Decimal;\n mintADecimals: number;\n mintBDecimals: number;\n zeroForOne: boolean;\n tickSpacing: number;\n }): { tick: number; price: Decimal } {\n let p = price.clamp(1 / 10 ** Math.max(mintADecimals, mintBDecimals), Number.MAX_SAFE_INTEGER);\n if (!zeroForOne) p = new Decimal(1).div(p);\n const newTick = TickUtil.toTickIndex(TickUtil.priceToTick(p, mintADecimals, mintBDecimals), tickSpacing);\n const newPrice = TickUtil.tickToPrice(newTick, mintADecimals, mintBDecimals);\n return {\n price: zeroForOne ? newPrice : new Decimal(1).div(newPrice),\n tick: newTick,\n };\n }\n}\n\n/**\n * Fetch tick arrays for swap simulation\n */\nexport async function fetchTickArrays(\n programId: PublicKey,\n connection: Connection,\n poolId: PublicKey,\n currentTick: number,\n tickSpacing: number,\n tickArrayBitmap: Buffer,\n zeroForOne = true,\n): Promise<{ address: PublicKey; value: ReturnType<typeof TickArrayLayout.decode> }[]> {\n const tickArrays: { address: PublicKey; value: ReturnType<typeof TickArrayLayout.decode> }[] = [];\n const tickArrayBitmapExtension = getPdaExBitmapAccount(programId, poolId).publicKey;\n const tickArrayBitmapExtensionRes = await connection.getAccountInfo(tickArrayBitmapExtension);\n const tickArraysAddress = TickArrayBitmapUtil.findTickArrayAddress({\n programId,\n poolId,\n poolBitmap: tickArrayBitmap,\n tickArrayBitmap: TickArrayBitmapExtensionLayout.decode(tickArrayBitmapExtensionRes!.data),\n tickSpacing,\n findInfo: { type: zeroForOne ? \"zeroForOne\" : \"oneForZero\", tickArrayCurrent: currentTick },\n });\n\n const tickArrayRes = await getMultipleAccountsInfo(connection, tickArraysAddress);\n tickArrayRes.forEach((res, idx) => {\n if (res) tickArrays.push({ address: tickArraysAddress[idx], value: TickArrayLayout.decode(res.data) });\n });\n\n return tickArrays;\n}\n","import BN from \"bn.js\";\nimport Decimal from \"decimal.js\";\nimport { divRoundingUp, mulDivCeil, mulDivFloor } from \"./bigNum\";\nimport { BN_ZERO, Q64, RESOLUTION, U64_MAX } from \"./constants\";\nimport { SqrtPriceMath } from \"./sqrtPriceMath\";\n\nexport class LiquidityMathUtil {\n static getDeltaAmountAUnsigned(sqrtPriceX64A: BN, sqrtPriceX64B: BN, liquidity: BN, roundUp: boolean): BN {\n if (sqrtPriceX64A.gt(sqrtPriceX64B)) {\n [sqrtPriceX64A, sqrtPriceX64B] = [sqrtPriceX64B, sqrtPriceX64A];\n }\n\n const numerator1 = liquidity.shln(RESOLUTION);\n const numerator2 = sqrtPriceX64B.sub(sqrtPriceX64A);\n\n if (!sqrtPriceX64A.gt(BN_ZERO)) throw Error(\"!sqrtPriceX64A.gt(BN_ZERO)\");\n\n const result = roundUp\n ? divRoundingUp(mulDivCeil(numerator1, numerator2, sqrtPriceX64B), sqrtPriceX64A)\n : mulDivFloor(numerator1, numerator2, sqrtPriceX64B).div(sqrtPriceX64A);\n\n if (result.gt(U64_MAX)) throw Error(\"MaxTokenOverflow\");\n\n return result;\n }\n\n static getDeltaAmountBUnsigned(sqrtPriceX64A: BN, sqrtPriceX64B: BN, liquidity: BN, roundUp: boolean): BN {\n if (sqrtPriceX64A.gt(sqrtPriceX64B)) {\n [sqrtPriceX64A, sqrtPriceX64B] = [sqrtPriceX64B, sqrtPriceX64A];\n }\n\n const result = roundUp\n ? mulDivCeil(liquidity, sqrtPriceX64B.sub(sqrtPriceX64A), Q64)\n : mulDivFloor(liquidity, sqrtPriceX64B.sub(sqrtPriceX64A), Q64);\n\n if (result.gt(U64_MAX)) throw Error(\"MaxTokenOverflow\");\n\n return result;\n }\n\n static addDelta(x: BN, y: BN): BN {\n if (y.isNeg()) {\n const absY = y.neg();\n if (x.lt(absY)) {\n throw new Error(\"Liquidity underflow\");\n }\n return x.sub(absY);\n } else {\n return x.add(y);\n }\n }\n\n static getLiquidityFromAmountA(sqrtPriceLowerX64: BN, sqrtPriceUpperX64: BN, amountA: BN): BN {\n if (amountA.isZero()) return BN_ZERO\n\n if (sqrtPriceLowerX64.gt(sqrtPriceUpperX64)) {\n [sqrtPriceLowerX64, sqrtPriceUpperX64] = [sqrtPriceUpperX64, sqrtPriceLowerX64];\n }\n\n const intermediate = mulDivFloor(sqrtPriceLowerX64, sqrtPriceUpperX64, Q64);\n\n const priceDelta = sqrtPriceUpperX64.sub(sqrtPriceLowerX64);\n\n return mulDivFloor(amountA, intermediate, priceDelta);\n }\n\n static getLiquidityFromAmountB(sqrtPriceLowerX64: BN, sqrtPriceUpperX64: BN, amountB: BN): BN {\n if (amountB.isZero()) return BN_ZERO\n\n if (sqrtPriceLowerX64.gt(sqrtPriceUpperX64)) {\n [sqrtPriceLowerX64, sqrtPriceUpperX64] = [sqrtPriceUpperX64, sqrtPriceLowerX64];\n }\n\n const priceDelta = sqrtPriceUpperX64.sub(sqrtPriceLowerX64);\n\n return mulDivFloor(amountB, Q64, priceDelta);\n }\n\n static getLiquidityFromAmounts(\n sqrtPriceCurrentX64: BN,\n sqrtPriceLowerX64: BN,\n sqrtPriceUpperX64: BN,\n amountA: BN,\n amountB: BN,\n ): BN {\n if (sqrtPriceLowerX64.gt(sqrtPriceUpperX64)) {\n [sqrtPriceLowerX64, sqrtPriceUpperX64] = [sqrtPriceUpperX64, sqrtPriceLowerX64];\n }\n\n if (sqrtPriceCurrentX64.lte(sqrtPriceLowerX64)) {\n return this.getLiquidityFromAmountA(sqrtPriceLowerX64, sqrtPriceUpperX64, amountA);\n } else if (sqrtPriceCurrentX64.lt(sqrtPriceUpperX64)) {\n const liquidityA = this.getLiquidityFromAmountA(sqrtPriceCurrentX64, sqrtPriceUpperX64, amountA);\n const liquidityB = this.getLiquidityFromAmountB(sqrtPriceLowerX64, sqrtPriceCurrentX64, amountB);\n return liquidityA.lt(liquidityB) ? liquidityA : liquidityB;\n } else {\n return this.getLiquidityFromAmountB(sqrtPriceLowerX64, sqrtPriceUpperX64, amountB);\n }\n }\n\n static getAmountsForLiquidity(\n sqrtPriceCurrentX64: BN,\n sqrtPriceLowerX64: BN,\n sqrtPriceUpperX64: BN,\n liquidity: BN,\n roundUp: boolean,\n ) {\n if (sqrtPriceLowerX64.gt(sqrtPriceUpperX64)) {\n [sqrtPriceLowerX64, sqrtPriceUpperX64] = [sqrtPriceUpperX64, sqrtPriceLowerX64];\n }\n\n let amountA = BN_ZERO;\n let amountB = BN_ZERO;\n\n if (sqrtPriceCurrentX64.lte(sqrtPriceLowerX64)) {\n amountA = this.getDeltaAmountAUnsigned(sqrtPriceLowerX64, sqrtPriceUpperX64, liquidity, roundUp)\n } else if (sqrtPriceCurrentX64.lt(sqrtPriceUpperX64)) {\n amountA = this.getDeltaAmountAUnsigned(sqrtPriceCurrentX64, sqrtPriceUpperX64, liquidity, roundUp)\n amountB = this.getDeltaAmountBUnsigned(sqrtPriceLowerX64, sqrtPriceCurrentX64, liquidity, roundUp)\n } else {\n amountB = this.getDeltaAmountBUnsigned(sqrtPriceLowerX64, sqrtPriceUpperX64, liquidity, roundUp)\n }\n\n return { amountA, amountB };\n }\n\n static getAmountsFromLiquidityWithSlippage(\n sqrtPriceCurrentX64: BN,\n sqrtPriceX64A: BN,\n sqrtPriceX64B: BN,\n liquidity: BN,\n amountMax: boolean,\n roundUp: boolean,\n amountSlippage: number,\n ): { amountSlippageA: BN; amountSlippageB: BN } {\n const { amountA, amountB } = this.getAmountsForLiquidity(\n sqrtPriceCurrentX64,\n sqrtPriceX64A,\n sqrtPriceX64B,\n liquidity,\n roundUp,\n );\n const coefficient = amountMax ? 1 + amountSlippage : 1 - amountSlippage;\n\n const amount0Slippage = new BN(new Decimal(amountA.toString()).mul(coefficient).toFixed(0));\n const amount1Slippage = new BN(new Decimal(amountB.toString()).mul(coefficient).toFixed(0));\n return {\n amountSlippageA: amount0Slippage,\n amountSlippageB: amount1Slippage,\n };\n }\n\n static getLiquidityAndAmountsFromAmount({\n sqrtPriceCurrentX64,\n sqrtPriceLowerX64,\n sqrtPriceUpperX64,\n amountInfo,\n }: {\n sqrtPriceCurrentX64: BN;\n sqrtPriceLowerX64: BN;\n sqrtPriceUpperX64: BN;\n amountInfo: { type: \"liquidity\" | \"amountA\" | \"amountB\"; amount: BN };\n }): { liquidity: BN; amountA: BN; amountB: BN } {\n let liquidity;\n if (amountInfo.type === \"liquidity\") {\n liquidity = amountInfo.amount;\n } else if (amountInfo.type === \"amountA\") {\n liquidity = sqrtPriceCurrentX64.gte(sqrtPriceUpperX64)\n ? BN_ZERO\n : this.getLiquidityFromAmountA(\n BN.max(sqrtPriceCurrentX64, sqrtPriceLowerX64),\n sqrtPriceUpperX64,\n amountInfo.amount,\n );\n } else if (amountInfo.type === \"amountB\") {\n liquidity = sqrtPriceCurrentX64.lte(sqrtPriceLowerX64)\n ? BN_ZERO\n : this.getLiquidityFromAmountB(\n sqrtPriceLowerX64,\n BN.min(sqrtPriceCurrentX64, sqrtPriceUpperX64),\n amountInfo.amount,\n );\n } else {\n throw Error(\"amount info type check error\");\n }\n\n return {\n liquidity,\n ...this.getAmountsForLiquidity(\n sqrtPriceCurrentX64,\n sqrtPriceLowerX64,\n sqrtPriceUpperX64,\n amountInfo.amount,\n true,\n ),\n };\n }\n}\n","import { PublicKey } from \"@solana/web3.js\";\nimport BN from \"bn.js\";\nimport { DynamicFeeInfoLayout, PoolInfoLayout } from \"../layout\";\nimport { mulDivCeil, mulDivFloor } from \"./bigNum\";\nimport {\n BN_ZERO,\n CollectFeeOn,\n MAX_TICK,\n MIN_TICK,\n Q64,\n REDUCTION_FACTOR_DENOMINATOR,\n U64_MAX,\n VOLATILITY_ACCUMULATOR_SCALE,\n} from \"./constants\";\nimport { TickArrayBitmapUtil, TickArrayUtil, TickUtil } from \"./tickArrayUtil\";\n\nexport class PoolFee {\n static tickSpacingIndexFromTick(tickIndex: number, tickSpacing: number): number {\n return Math.floor(tickIndex / tickSpacing);\n }\n}\n\nexport class DynamicFeeInfo {\n static getDynamicFeeInfo({ poolInfo }: { poolInfo: ReturnType<typeof PoolInfoLayout.decode> }) {\n if (\n poolInfo.dynamicFeeInfo.filterPeriod === 0 &&\n poolInfo.dynamicFeeInfo.decayPeriod === 0 &&\n poolInfo.dynamicFeeInfo.reductionFactor === 0 &&\n poolInfo.dynamicFeeInfo.dynamicFeeControl === 0 &&\n poolInfo.dynamicFeeInfo.maxVolatilityAccumulator === 0 &&\n poolInfo.dynamicFeeInfo.tickSpacingIndexReference === 0 &&\n poolInfo.dynamicFeeInfo.volatilityReference === 0 &&\n poolInfo.dynamicFeeInfo.volatilityAccumulator === 0 &&\n poolInfo.dynamicFeeInfo.lastUpdateTimestamp.isZero()\n ) {\n return undefined;\n }\n return poolInfo.dynamicFeeInfo;\n }\n\n static updateReference({\n dynamicFeeInfo,\n tickSpacingIndex,\n currentTimestamp,\n }: {\n dynamicFeeInfo: ReturnType<typeof DynamicFeeInfoLayout.decode>;\n tickSpacingIndex: number;\n currentTimestamp: number;\n }) {\n const timeSinceReferenceUpdate = currentTimestamp - dynamicFeeInfo.lastUpdateTimestamp.toNumber();\n\n if (timeSinceReferenceUpdate < dynamicFeeInfo.filterPeriod) {\n //\n } else if (timeSinceReferenceUpdate < dynamicFeeInfo.decayPeriod) {\n dynamicFeeInfo.tickSpacingIndexReference = tickSpacingIndex;\n dynamicFeeInfo.volatilityReference = Math.floor(\n (dynamicFeeInfo.volatilityAccumulator * dynamicFeeInfo.reductionFactor) / REDUCTION_FACTOR_DENOMINATOR,\n );\n dynamicFeeInfo.lastUpdateTimestamp = new BN(currentTimestamp);\n } else {\n dynamicFeeInfo.tickSpacingIndexReference = tickSpacingIndex;\n dynamicFeeInfo.volatilityReference = 0;\n dynamicFeeInfo.lastUpdateTimestamp = new BN(currentTimestamp);\n }\n }\n\n static updateVolatilityAccumulator({\n state,\n tickSpacingIndex,\n }: {\n state: ReturnType<typeof DynamicFeeInfoLayout.decode>;\n tickSpacingIndex: number;\n }) {\n const indexDelta = Math.abs(state.tickSpacingIndexReference - tickSpacingIndex);\n const volatilityAccumulator = state.volatilityReference + indexDelta * VOLATILITY_ACCUMULATOR_SCALE;\n\n state.volatilityAccumulator = Math.min(volatilityAccumulator, state.maxVolatilityAccumulator);\n }\n}\n\nexport class PoolUtil {\n static isFeeOnInput(feeOn: number, zeroForOne: boolean): boolean {\n switch (feeOn) {\n case CollectFeeOn.FromInput:\n return true;\n case CollectFeeOn.TokenOnlyA:\n return zeroForOne;\n case CollectFeeOn.TokenOnlyB:\n return !zeroForOne;\n default:\n return true;\n }\n }\n\n static isFeeOnTokenA(poolInfo: ReturnType<typeof PoolInfoLayout.decode>, zeroForOne: boolean) {\n if (poolInfo.feeOn === CollectFeeOn.FromInput) return zeroForOne;\n if (poolInfo.feeOn === CollectFeeOn.TokenOnlyA) return true;\n return false;\n }\n\n static isOverflowDefaultTickarrayBitmap({ tickSpacing, tickIndexs }: { tickSpacing: number; tickIndexs: number[] }) {\n const { maxTickBoundary, minTickBoundary } = this.tickArrayStartIndexRange({ tickSpacing });\n for (const tickIndex of tickIndexs) {\n const tickarrayStartIndex = TickArrayUtil.getTickArrayStartIndex(tickIndex, tickSpacing);\n\n if (tickarrayStartIndex >= maxTickBoundary || tickarrayStartIndex < minTickBoundary) {\n return true;\n }\n }\n\n return false;\n }\n\n static tickArrayStartIndexRange({ tickSpacing }: { tickSpacing: number }) {\n let maxTickBoundary = TickArrayBitmapUtil.maxTickInTickarrayBitmap(tickSpacing);\n let minTickBoundary = -maxTickBoundary;\n\n if (maxTickBoundary > MAX_TICK) {\n maxTickBoundary =\n TickArrayUtil.getTickArrayStartIndex(MAX_TICK, tickSpacing) + TickArrayUtil.tickCount(tickSpacing);\n }\n if (minTickBoundary < MIN_TICK) {\n minTickBoundary = TickArrayUtil.getTickArrayStartIndex(MIN_TICK, tickSpacing);\n }\n return { maxTickBoundary, minTickBoundary };\n }\n\n public static async updatePoolRewardInfos({\n connection,\n apiPoolInfo,\n chainTime,\n poolLiquidity,\n rewardInfos,\n }: {\n connection: Connection;\n apiPoolInfo: ApiV3PoolInfoConcentratedItem;\n chainTime: number;\n poolLiquidity: BN;\n rewardInfos: ReturnType<typeof RewardInfoLayout.decode>[];\n }): Promise<ClmmPoolRewardInfo[]> {\n const nRewardInfo: ClmmPoolRewardInfo[] = [];\n for (let i = 0; i < rewardInfos.length; i++) {\n const _itemReward = rewardInfos[i];\n const apiRewardProgram =\n apiPoolInfo.rewardDefaultInfos[i]?.mint.programId ?? (await connection.getAccountInfo(_itemReward.mint))?.owner;\n if (apiRewardProgram === undefined) throw Error(\"get new reward mint info error\");\n\n const itemReward: ClmmPoolRewardInfo = {\n ..._itemReward,\n perSecond: x64ToDecimal(_itemReward.emissionsPerSecondX64),\n remainingRewards: undefined,\n tokenProgramId: new PublicKey(apiRewardProgram),\n };\n\n if (itemReward.mint.equals(PublicKey.default) || itemReward.totalEmissioned.eq(U64_MAX)) continue;\n if (chainTime <= itemReward.openTime.toNumber() || poolLiquidity.eq(BN_ZERO)) {\n nRewardInfo.push(itemReward);\n continue;\n }\n\n const latestUpdateTime = new BN(Math.min(itemReward.endTime.toNumber(), chainTime));\n const timeDelta = latestUpdateTime.sub(itemReward.lastUpdateTime);\n if (timeDelta.isZero()) {\n nRewardInfo.push(itemReward);\n continue;\n }\n const rewardDelta = mulDivCeil(timeDelta, itemReward.emissionsPerSecondX64, Q64);\n let rewardGrowthDeltaX64 = mulDivFloor(timeDelta, itemReward.emissionsPerSecondX64, poolLiquidity);\n\n let totalEmissioned;\n const newTotal = itemReward.totalEmissioned.add(rewardDelta);\n if (newTotal.lte(U64_MAX)) {\n totalEmissioned = newTotal;\n } else {\n const remain = U64_MAX.sub(itemReward.totalEmissioned);\n totalEmissioned = U64_MAX;\n rewardGrowthDeltaX64 = mulDivFloor(remain, Q64, poolLiquidity);\n }\n\n const growthGlobalX64 = itemReward.growthGlobalX64.add(rewardGrowthDeltaX64);\n nRewardInfo.push({\n ...itemReward,\n growthGlobalX64,\n totalEmissioned,\n lastUpdateTime: latestUpdateTime,\n });\n }\n return nRewardInfo;\n }\n}\n\nimport { ApiV3PoolInfoConcentratedItem } from \"@/api\";\nimport { RewardInfoLayout } from \"../layout\";\nimport { ComputeClmmPoolInfo } from \"../type\";\nimport { x64ToDecimal } from \"./bigNum\";\n\nimport { TOKEN_2022_PROGRAM_ID, TOKEN_PROGRAM_ID } from \"@solana/spl-token\";\nimport { Connection, EpochInfo } from \"@solana/web3.js\";\n\nimport {\n ClmmPoolRewardInfo,\n ReturnTypeComputeAmountOut,\n ReturnTypeComputeAmountOutBaseOut,\n ReturnTypeComputeAmountOutFormat,\n ReturnTypeFetchExBitmaps,\n ReturnTypeFetchMultiplePoolTickArrays,\n ReturnTypeGetLiquidityAmountOut,\n} from \"../type\";\n\nimport { ApiV3Token } from \"@/api/type\";\n\nimport {\n getMultipleAccountsInfo,\n getMultipleAccountsInfoWithCustomFlags,\n getTransferAmountFeeV2,\n minExpirationTime,\n solToWSol,\n} from \"@/common\";\nimport { Percent, Price, Token, TokenAmount } from \"@/module\";\nimport Decimal from \"decimal.js\";\nimport { TickArrayBitmapExtensionLayout, TickArrayLayout } from \"../layout\";\nimport { MAX_SQRT_PRICE_X64, MIN_SQRT_PRICE_X64 } from \"./constants\";\nimport { LiquidityMathUtil } from \"./liquidityMath\";\nimport { getPdaExBitmapAccount, getPdaTickArrayAddress } from \"./pda\";\nimport { swapInternal } from \"./swapSimulator\";\nimport { ReturnTypeFetchMultipleMintInfos, toApiV3Token } from \"@/raydium\";\n\nexport class PoolUtils {\n public static getOutputAmountAndRemainAccounts(\n poolInfo: ComputeClmmPoolInfo,\n tickarrayBitmapExtension: ReturnType<typeof TickArrayBitmapExtensionLayout.decode>,\n tickArrayCache: { [key: string]: ReturnType<typeof TickArrayLayout.decode> & { address: PublicKey } },\n inputTokenMint: PublicKey,\n inputAmount: BN,\n blockTimestamp: number,\n sqrtPriceLimitX64?: BN,\n ): {\n allTrade: boolean;\n expectedAmountOut: BN;\n remainingAccounts: PublicKey[];\n executionPrice: BN;\n feeAmount: BN;\n } {\n const zeroForOne = inputTokenMint.toBase58() === poolInfo.mintA.address;\n\n const currentTickArrayStartIndex = TickArrayUtil.getTickArrayStartIndex(\n poolInfo.accInfo.tickCurrent,\n poolInfo.accInfo.tickSpacing,\n );\n const { allTrade, amountCalculated, feeAmount, sqrtPriceX64, accounts } = swapInternal({\n programId: poolInfo.programId,\n poolId: poolInfo.id,\n poolInfo: poolInfo.accInfo,\n tickArrays: Object.entries(tickArrayCache)\n .map((i) => ({\n address: i[1].address,\n value: i[1],\n }))\n .filter((a) =>\n zeroForOne\n ? a.value.startTickIndex <= currentTickArrayStartIndex\n : a.value.startTickIndex >= currentTickArrayStartIndex,\n )\n .sort((a, b) =>\n zeroForOne\n ? b.value.startTickIndex - a.value.startTickIndex\n : a.value.startTickIndex - b.value.startTickIndex,\n ),\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n configInfo: poolInfo.ammConfig,\n tickarrayBitmapExtension,\n amountSpecified: inputAmount,\n sqrtPriceLimitX64: sqrtPriceLimitX64 ?? BN_ZERO,\n zeroForOne,\n isBaseInput: true,\n blockTimestamp,\n includeExtraTickArrays: true,\n });\n\n return {\n allTrade,\n expectedAmountOut: amountCalculated,\n remainingAccounts: accounts,\n executionPrice: sqrtPriceX64,\n feeAmount,\n };\n }\n\n public static getInputAmountAndRemainAccounts(\n poolInfo: ComputeClmmPoolInfo,\n tickarrayBitmapExtension: ReturnType<typeof TickArrayBitmapExtensionLayout.decode>,\n tickArrayCache: { [key: string]: ReturnType<typeof TickArrayLayout.decode> },\n outputTokenMint: PublicKey,\n outputAmount: BN,\n blockTimestamp: number,\n sqrtPriceLimitX64?: BN,\n ): { allTrade: boolean; expectedAmountIn: BN; remainingAccounts: PublicKey[]; executionPrice: BN; feeAmount: BN } {\n const zeroForOne = outputTokenMint.toBase58() === poolInfo.mintB.address;\n\n const currentTickArrayStartIndex = TickArrayUtil.getTickArrayStartIndex(\n poolInfo.accInfo.tickCurrent,\n poolInfo.accInfo.tickSpacing,\n );\n const { allTrade, amountCalculated, feeAmount, sqrtPriceX64, accounts } = swapInternal({\n programId: poolInfo.programId,\n poolId: poolInfo.id,\n poolInfo: poolInfo.accInfo,\n tickArrays: Object.entries(tickArrayCache)\n .map((i) => ({ address: new PublicKey(i[0]), value: i[1] }))\n .filter((a) =>\n zeroForOne\n ? a.value.startTickIndex <= currentTickArrayStartIndex\n : a.value.startTickIndex >= currentTickArrayStartIndex,\n )\n .sort((a, b) =>\n zeroForOne\n ? b.value.startTickIndex - a.value.startTickIndex\n : a.value.startTickIndex - b.value.startTickIndex,\n ),\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n configInfo: poolInfo.ammConfig,\n tickarrayBitmapExtension,\n amountSpecified: outputAmount,\n sqrtPriceLimitX64: sqrtPriceLimitX64 ?? BN_ZERO,\n zeroForOne,\n isBaseInput: false,\n blockTimestamp,\n includeExtraTickArrays: true,\n });\n\n return {\n allTrade,\n expectedAmountIn: amountCalculated,\n remainingAccounts: accounts,\n executionPrice: sqrtPriceX64,\n feeAmount,\n };\n }\n\n static async fetchExBitmaps({\n connection,\n exBitmapAddress,\n batchRequest,\n }: {\n connection: Connection;\n exBitmapAddress: PublicKey[];\n batchRequest: boolean;\n }): Promise<ReturnTypeFetchExBitmaps> {\n const fetchedBitmapAccount = await getMultipleAccountsInfoWithCustomFlags(\n connection,\n exBitmapAddress.map((i) => ({ pubkey: i })),\n { batchRequest },\n );\n\n const returnTypeFetchExBitmaps: ReturnTypeFetchExBitmaps = {};\n for (const item of fetchedBitmapAccount) {\n if (item.accountInfo === null) continue;\n\n returnTypeFetchExBitmaps[item.pubkey.toString()] = TickArrayBitmapExtensionLayout.decode(item.accountInfo.data);\n }\n return returnTypeFetchExBitmaps;\n }\n\n static async fetchMultiplePoolTickArrays({\n connection,\n poolKeys,\n batchRequest,\n }: {\n connection: Connection;\n poolKeys: Omit<ComputeClmmPoolInfo, \"ammConfig\">[];\n batchRequest?: boolean;\n }): Promise<ReturnTypeFetchMultiplePoolTickArrays> {\n const tickArraysToPoolId: { [key: string]: PublicKey } = {};\n const tickArrays: { pubkey: PublicKey }[] = [];\n for (const itemPoolInfo of poolKeys) {\n const startIndexArray = [\n ...TickArrayBitmapUtil.findTickArrayStartIndex({\n tickSpacing: itemPoolInfo.tickSpacing,\n poolBitmap: itemPoolInfo.tickArrayBitmap,\n tickArrayBitmap: itemPoolInfo.exBitmapInfo,\n findInfo: { type: \"zeroForOne\", count: 7, tickArrayCurrent: itemPoolInfo.tickCurrent },\n }),\n ...TickArrayBitmapUtil.findTickArrayStartIndex({\n tickSpacing: itemPoolInfo.tickSpacing,\n poolBitmap: itemPoolInfo.tickArrayBitmap,\n tickArrayBitmap: itemPoolInfo.exBitmapInfo,\n findInfo: { type: \"oneForZero\", count: 7, tickArrayCurrent: itemPoolInfo.tickCurrent },\n }),\n ];\n\n for (const itemIndex of startIndexArray) {\n const { publicKey: tickArrayAddress } = getPdaTickArrayAddress(\n itemPoolInfo.programId,\n itemPoolInfo.id,\n itemIndex,\n );\n if (tickArraysToPoolId[tickArrayAddress.toString()] !== undefined) continue;\n tickArrays.push({ pubkey: tickArrayAddress });\n tickArraysToPoolId[tickArrayAddress.toString()] = itemPoolInfo.id;\n }\n }\n\n const fetchedTickArrays = await getMultipleAccountsInfoWithCustomFlags(connection, tickArrays, { batchRequest });\n\n const tickArrayCache: ReturnTypeFetchMultiplePoolTickArrays = {};\n\n for (const itemAccountInfo of fetchedTickArrays) {\n if (!itemAccountInfo.accountInfo) continue;\n const poolId = tickArraysToPoolId[itemAccountInfo.pubkey.toString()];\n if (!poolId) continue;\n if (tickArrayCache[poolId.toString()] === undefined) tickArrayCache[poolId.toString()] = {};\n\n const accountLayoutData = TickArrayLayout.decode(itemAccountInfo.accountInfo.data);\n\n tickArrayCache[poolId.toString()][accountLayoutData.startTickIndex] = {\n ...accountLayoutData,\n address: itemAccountInfo.pubkey,\n };\n }\n return tickArrayCache;\n }\n\n static computeAmountOut({\n poolInfo,\n tickarrayBitmapExtension,\n tickArrayCache,\n baseMint,\n epochInfo,\n amountIn,\n slippage,\n blockTimestamp,\n priceLimit = new Decimal(0),\n }: {\n poolInfo: ComputeClmmPoolInfo;\n tickarrayBitmapExtension: ReturnType<typeof TickArrayBitmapExtensionLayout.decode>;\n tickArrayCache: { [key: string]: ReturnType<typeof TickArrayLayout.decode> & { address: PublicKey } };\n baseMint: PublicKey;\n\n epochInfo: EpochInfo;\n\n amountIn: BN;\n slippage: number;\n priceLimit?: Decimal;\n catchLiquidityInsufficient: boolean;\n blockTimestamp: number;\n }): ReturnTypeComputeAmountOut {\n let sqrtPriceLimitX64: BN;\n const isBaseIn = baseMint.toBase58() === poolInfo.mintA.address;\n const [baseFeeConfig, outFeeConfig] = isBaseIn\n ? [poolInfo.mintA.extensions.feeConfig, poolInfo.mintB.extensions.feeConfig]\n : [poolInfo.mintB.extensions.feeConfig, poolInfo.mintA.extensions.feeConfig];\n\n if (priceLimit.equals(new Decimal(0))) {\n sqrtPriceLimitX64 = isBaseIn ? MIN_SQRT_PRICE_X64.add(new BN(1)) : MAX_SQRT_PRICE_X64.sub(new BN(1));\n } else {\n sqrtPriceLimitX64 = TickUtil.priceToSqrtPriceX64(priceLimit, poolInfo.mintA.decimals, poolInfo.mintB.decimals);\n }\n\n const realAmountIn = getTransferAmountFeeV2(amountIn, baseFeeConfig, epochInfo, false);\n\n const {\n allTrade,\n expectedAmountOut: _expectedAmountOut,\n remainingAccounts,\n executionPrice: _executionPriceX64,\n feeAmount,\n } = PoolUtils.getOutputAmountAndRemainAccounts(\n poolInfo,\n tickarrayBitmapExtension,\n tickArrayCache,\n baseMint,\n realAmountIn.amount.sub(realAmountIn.fee ?? BN_ZERO),\n blockTimestamp,\n sqrtPriceLimitX64,\n );\n\n const amountOut = getTransferAmountFeeV2(_expectedAmountOut, outFeeConfig, epochInfo, false);\n\n const _executionPrice = TickUtil.sqrtPriceX64ToPrice(\n _executionPriceX64,\n poolInfo.mintA.decimals,\n poolInfo.mintB.decimals,\n );\n const executionPrice = isBaseIn ? _executionPrice : new Decimal(1).div(_executionPrice);\n\n const _minAmountOut = _expectedAmountOut\n .mul(new BN(Math.floor((1 - slippage) * 10000000000)))\n .div(new BN(10000000000));\n const minAmountOut = getTransferAmountFeeV2(_minAmountOut, outFeeConfig, epochInfo, false);\n\n const poolPrice = isBaseIn ? poolInfo.currentPrice : new Decimal(1).div(poolInfo.currentPrice);\n\n const _numerator = new Decimal(executionPrice).sub(poolPrice).abs();\n const _denominator = poolPrice;\n const priceImpact = new Percent(\n new Decimal(_numerator).mul(10 ** 15).toFixed(0),\n new Decimal(_denominator).mul(10 ** 15).toFixed(0),\n );\n\n return {\n allTrade,\n realAmountIn,\n amountOut,\n minAmountOut,\n expirationTime: minExpirationTime(realAmountIn.expirationTime, amountOut.expirationTime),\n currentPrice: poolInfo.currentPrice,\n executionPrice,\n priceImpact,\n fee: feeAmount,\n remainingAccounts,\n executionPriceX64: _executionPriceX64,\n };\n }\n\n static computeAmountOutFormat({\n poolInfo,\n tickarrayBitmapExtension,\n tickArrayCache,\n amountIn,\n tokenOut: _tokenOut,\n slippage,\n epochInfo,\n blockTimestamp,\n catchLiquidityInsufficient = false,\n }: {\n poolInfo: ComputeClmmPoolInfo;\n tickarrayBitmapExtension: ReturnType<typeof TickArrayBitmapExtensionLayout.decode>;\n tickArrayCache: { [key: string]: ReturnType<typeof TickArrayLayout.decode> & { address: PublicKey } };\n amountIn: BN;\n tokenOut: ApiV3Token;\n slippage: number;\n epochInfo: EpochInfo;\n blockTimestamp: number;\n catchLiquidityInsufficient?: boolean;\n }): ReturnTypeComputeAmountOutFormat {\n const baseIn = _tokenOut.address === poolInfo.mintB.address;\n const [inputMint, outMint] = baseIn ? [poolInfo.mintA, poolInfo.mintB] : [poolInfo.mintB, poolInfo.mintA];\n const [baseToken, outToken] = [\n new Token({\n ...inputMint,\n mint: inputMint.address,\n isToken2022: inputMint.programId === TOKEN_2022_PROGRAM_ID.toBase58(),\n }),\n new Token({\n ...outMint,\n mint: outMint.address,\n isToken2022: outMint.programId === TOKEN_2022_PROGRAM_ID.toBase58(),\n }),\n ];\n\n const {\n allTrade,\n realAmountIn: _realAmountIn,\n amountOut: _amountOut,\n minAmountOut: _minAmountOut,\n expirationTime,\n currentPrice,\n executionPrice,\n priceImpact,\n fee,\n remainingAccounts,\n executionPriceX64,\n } = PoolUtils.computeAmountOut({\n poolInfo,\n tickarrayBitmapExtension,\n tickArrayCache,\n baseMint: new PublicKey(inputMint.address),\n amountIn,\n slippage,\n epochInfo,\n catchLiquidityInsufficient,\n blockTimestamp,\n });\n\n const realAmountIn = {\n ..._realAmountIn,\n amount: new TokenAmount(baseToken, _realAmountIn.amount),\n fee: _realAmountIn.fee === undefined ? undefined : new TokenAmount(baseToken, _realAmountIn.fee),\n };\n\n const amountOut = {\n ..._amountOut,\n amount: new TokenAmount(outToken, _amountOut.amount),\n fee: _amountOut.fee === undefined ? undefined : new TokenAmount(outToken, _amountOut.fee),\n };\n const minAmountOut = {\n ..._minAmountOut,\n amount: new TokenAmount(outToken, _minAmountOut.amount),\n fee: _minAmountOut.fee === undefined ? undefined : new TokenAmount(outToken, _minAmountOut.fee),\n };\n\n const _currentPrice = new Price({\n baseToken,\n denominator: new BN(10).pow(new BN(20 + baseToken.decimals)),\n quoteToken: outToken,\n numerator: currentPrice.mul(new Decimal(10 ** (20 + outToken.decimals))).toFixed(0),\n });\n const _executionPrice = new Price({\n baseToken,\n denominator: new BN(10).pow(new BN(20 + baseToken.decimals)),\n quoteToken: outToken,\n numerator: executionPrice.mul(new Decimal(10 ** (20 + outToken.decimals))).toFixed(0),\n });\n const _fee = new TokenAmount(baseToken, fee);\n\n return {\n allTrade,\n realAmountIn,\n amountOut,\n minAmountOut,\n expirationTime,\n currentPrice: _currentPrice,\n executionPrice: _executionPrice,\n priceImpact,\n fee: _fee,\n remainingAccounts,\n executionPriceX64,\n };\n }\n\n static computeAmountIn({\n poolInfo,\n tickarrayBitmapExtension,\n tickArrayCache,\n baseMint,\n epochInfo,\n amountOut,\n slippage,\n priceLimit = new Decimal(0),\n blockTimestamp,\n }: {\n poolInfo: ComputeClmmPoolInfo;\n tickarrayBitmapExtension: ReturnType<typeof TickArrayBitmapExtensionLayout.decode>;\n tickArrayCache: { [key: string]: ReturnType<typeof TickArrayLayout.decode> };\n baseMint: PublicKey;\n\n epochInfo: EpochInfo;\n\n amountOut: BN;\n slippage: number;\n priceLimit?: Decimal;\n blockTimestamp: number;\n }): ReturnTypeComputeAmountOutBaseOut {\n const isBaseIn = baseMint.toBase58() === poolInfo.mintA.address;\n const feeConfigs = {\n [poolInfo.mintA.address]: poolInfo.mintA.extensions.feeConfig,\n [poolInfo.mintB.address]: poolInfo.mintB.extensions.feeConfig,\n };\n\n let sqrtPriceLimitX64: BN;\n if (priceLimit.equals(new Decimal(0))) {\n sqrtPriceLimitX64 = !isBaseIn ? MIN_SQRT_PRICE_X64.add(new BN(1)) : MAX_SQRT_PRICE_X64.sub(new BN(1));\n } else {\n sqrtPriceLimitX64 = TickUtil.priceToSqrtPriceX64(priceLimit, poolInfo.mintA.decimals, poolInfo.mintB.decimals);\n }\n\n const realAmountOut = getTransferAmountFeeV2(amountOut, feeConfigs[baseMint.toString()], epochInfo, true);\n const {\n allTrade,\n expectedAmountIn: _expectedAmountIn,\n remainingAccounts,\n executionPrice: _executionPriceX64,\n feeAmount,\n } = PoolUtils.getInputAmountAndRemainAccounts(\n poolInfo,\n tickarrayBitmapExtension,\n tickArrayCache,\n baseMint,\n realAmountOut.amount.sub(realAmountOut.fee ?? BN_ZERO),\n blockTimestamp,\n sqrtPriceLimitX64,\n );\n const inMint = isBaseIn ? poolInfo.mintB.address : poolInfo.mintA.address;\n\n const amountIn = getTransferAmountFeeV2(_expectedAmountIn, feeConfigs[inMint], epochInfo, false);\n\n const _executionPrice = TickUtil.sqrtPriceX64ToPrice(\n _executionPriceX64,\n poolInfo.mintA.decimals,\n poolInfo.mintB.decimals,\n );\n const executionPrice = isBaseIn ? _executionPrice : new Decimal(1).div(_executionPrice);\n\n const _maxAmountIn = _expectedAmountIn\n .mul(new BN(Math.floor((1 + slippage) * 10000000000)))\n .div(new BN(10000000000));\n\n const maxAmountIn = getTransferAmountFeeV2(_maxAmountIn, feeConfigs[inMint], epochInfo, true);\n\n const poolPrice = isBaseIn ? poolInfo.currentPrice : new Decimal(1).div(poolInfo.currentPrice);\n\n const _numerator = new Decimal(executionPrice).sub(poolPrice).abs();\n const _denominator = poolPrice;\n const priceImpact = new Percent(\n new Decimal(_numerator).mul(10 ** 15).toFixed(0),\n new Decimal(_denominator).mul(10 ** 15).toFixed(0),\n );\n\n return {\n allTrade,\n amountIn,\n maxAmountIn,\n realAmountOut,\n expirationTime: minExpirationTime(amountIn.expirationTime, realAmountOut.expirationTime),\n currentPrice: poolInfo.currentPrice,\n executionPrice,\n priceImpact,\n fee: feeAmount,\n\n remainingAccounts,\n };\n }\n\n static estimateAprsForPriceRangeMultiplier({\n poolInfo,\n aprType,\n positionTickLowerIndex,\n positionTickUpperIndex,\n }: {\n poolInfo: ApiV3PoolInfoConcentratedItem;\n aprType: \"day\" | \"week\" | \"month\";\n\n positionTickLowerIndex: number;\n positionTickUpperIndex: number;\n }): {\n feeApr: number;\n rewardsApr: number[];\n apr: number;\n } {\n const aprInfo = poolInfo[aprType];\n\n const priceLower = TickUtil.tickToPrice(\n positionTickLowerIndex,\n poolInfo.mintA.decimals,\n poolInfo.mintB.decimals,\n ).toNumber();\n const priceUpper = TickUtil.tickToPrice(\n positionTickUpperIndex,\n poolInfo.mintA.decimals,\n poolInfo.mintB.decimals,\n ).toNumber();\n\n const _minPrice = Math.max(priceLower, aprInfo.priceMin);\n const _maxPrice = Math.min(priceUpper, aprInfo.priceMax);\n\n const sub = _maxPrice - _minPrice;\n\n const userRange = priceUpper - priceLower;\n const tradeRange = aprInfo.priceMax - aprInfo.priceMin;\n\n let p: number;\n\n if (sub <= 0) p = 0;\n else if (userRange === sub) p = tradeRange / sub;\n else if (tradeRange === sub) p = sub / userRange;\n else p = (sub / tradeRange) * (sub / userRange);\n\n return {\n feeApr: aprInfo.feeApr * p,\n rewardsApr: [(aprInfo.rewardApr[0] ?? 0) * p, (aprInfo.rewardApr[1] ?? 0) * p, (aprInfo.rewardApr[2] ?? 0) * p],\n apr: aprInfo.apr * p,\n };\n }\n\n static estimateAprsForPriceRangeDelta({\n poolInfo,\n poolLiquidity,\n aprType,\n mintPrice,\n liquidity,\n positionTickLowerIndex,\n positionTickUpperIndex,\n chainTime,\n }: {\n poolInfo: ApiV3PoolInfoConcentratedItem;\n poolLiquidity: BN;\n aprType: \"day\" | \"week\" | \"month\";\n\n mintPrice: { [mint: string]: { value: number } };\n\n liquidity: BN;\n positionTickLowerIndex: number;\n positionTickUpperIndex: number;\n\n chainTime: number;\n }): {\n feeApr: number;\n rewardsApr: number[];\n apr: number;\n } {\n const aprTypeDay = aprType === \"day\" ? 1 : aprType === \"week\" ? 7 : aprType === \"month\" ? 30 : 0;\n const aprInfo = poolInfo[aprType];\n const mintPriceA = mintPrice[solToWSol(poolInfo.mintA.address).toString()];\n const mintPriceB = mintPrice[solToWSol(poolInfo.mintB.address).toString()];\n const mintDecimalsA = poolInfo.mintA.decimals;\n const mintDecimalsB = poolInfo.mintB.decimals;\n\n if (!aprInfo || !mintPriceA || !mintPriceB) return { feeApr: 0, rewardsApr: [0, 0, 0], apr: 0 };\n\n const sqrtPriceX64 = TickUtil.priceToSqrtPriceX64(\n new Decimal(poolInfo.price),\n poolInfo.mintA.decimals,\n poolInfo.mintB.decimals,\n );\n\n const sqrtPriceX64A = TickUtil.getSqrtPriceAtTick(positionTickLowerIndex);\n const sqrtPriceX64B = TickUtil.getSqrtPriceAtTick(positionTickUpperIndex);\n\n const { amountSlippageA: poolLiquidityA, amountSlippageB: poolLiquidityB } =\n LiquidityMathUtil.getAmountsFromLiquidityWithSlippage(\n sqrtPriceX64,\n sqrtPriceX64A,\n sqrtPriceX64B,\n poolLiquidity,\n false,\n false,\n 0,\n );\n\n const { amountSlippageA: userLiquidityA, amountSlippageB: userLiquidityB } =\n LiquidityMathUtil.getAmountsFromLiquidityWithSlippage(\n sqrtPriceX64,\n sqrtPriceX64A,\n sqrtPriceX64B,\n liquidity,\n false,\n false,\n 0,\n );\n\n const poolTvl = new Decimal(poolLiquidityA.toString())\n .div(new Decimal(10).pow(mintDecimalsA))\n .mul(mintPriceA.value)\n .add(new Decimal(poolLiquidityB.toString()).div(new Decimal(10).pow(mintDecimalsB)).mul(mintPriceB.value));\n const userTvl = new Decimal(userLiquidityA.toString())\n .div(new Decimal(10).pow(mintDecimalsA))\n .mul(mintPriceA.value)\n .add(new Decimal(userLiquidityB.toString()).div(new Decimal(10).pow(mintDecimalsB)).mul(mintPriceB.value));\n\n const p = new Decimal(1).div(poolTvl.add(userTvl));\n\n const feesPerYear = new Decimal(aprInfo.volumeFee).mul(365).div(aprTypeDay);\n const feeApr = feesPerYear.mul(p).mul(100).toNumber();\n\n const SECONDS_PER_YEAR = 3600 * 24 * 365;\n\n const rewardsApr = poolInfo.rewardDefaultInfos.map((i) => {\n const iDecimal = i.mint.decimals;\n const iPrice = mintPrice[i.mint.address];\n\n if (\n chainTime < ((i as any).startTime ?? 0) ||\n chainTime > ((i as any).endTime ?? 0) ||\n !i.perSecond ||\n !iPrice ||\n iDecimal === undefined\n )\n return 0;\n\n return new Decimal(iPrice.value)\n .mul(new Decimal(i.perSecond).mul(SECONDS_PER_YEAR))\n .div(new Decimal(10).pow(iDecimal))\n .mul(p)\n .mul(100)\n .toNumber();\n });\n\n return {\n feeApr,\n rewardsApr,\n apr: feeApr + rewardsApr.reduce((a, b) => a + b, 0),\n };\n }\n\n static async getLiquidityAmountOutFromAmountIn({\n poolInfo,\n inputA,\n tickLower,\n tickUpper,\n amount,\n slippage,\n add,\n epochInfo,\n amountHasFee,\n }: {\n poolInfo: ApiV3PoolInfoConcentratedItem;\n inputA: boolean;\n tickLower: number;\n tickUpper: number;\n amount: BN;\n slippage: number;\n add: boolean;\n epochInfo: EpochInfo;\n amountHasFee: boolean;\n }): Promise<ReturnTypeGetLiquidityAmountOut> {\n const sqrtPriceX64 = TickUtil.priceToSqrtPriceX64(\n new Decimal(poolInfo.price),\n poolInfo.mintA.decimals,\n poolInfo.mintB.decimals,\n );\n const sqrtPriceX64A = TickUtil.getSqrtPriceAtTick(tickLower);\n const sqrtPriceX64B = TickUtil.getSqrtPriceAtTick(tickUpper);\n\n // const coefficient = add ? 1 - slippage : 1 + slippage;\n const addFeeAmount = getTransferAmountFeeV2(\n amount,\n poolInfo[inputA ? \"mintA\" : \"mintB\"].extensions?.feeConfig,\n epochInfo,\n !amountHasFee,\n );\n const _amount = new BN(\n new Decimal(addFeeAmount.amount.sub(addFeeAmount.fee ?? BN_ZERO).toString()).toFixed(0), // .mul(coefficient).toFixed(0),\n );\n\n let liquidity: BN;\n if (sqrtPriceX64.lte(sqrtPriceX64A)) {\n liquidity = inputA ? LiquidityMathUtil.getLiquidityFromAmountA(sqrtPriceX64A, sqrtPriceX64B, _amount) : new BN(0);\n } else if (sqrtPriceX64.lte(sqrtPriceX64B)) {\n const liquidity0 = LiquidityMathUtil.getLiquidityFromAmountA(sqrtPriceX64, sqrtPriceX64B, _amount);\n const liquidity1 = LiquidityMathUtil.getLiquidityFromAmountB(sqrtPriceX64A, sqrtPriceX64, _amount);\n liquidity = inputA ? liquidity0 : liquidity1;\n } else {\n liquidity = inputA ? new BN(0) : LiquidityMathUtil.getLiquidityFromAmountB(sqrtPriceX64A, sqrtPriceX64B, _amount);\n }\n\n const amountFromLiquidity = await PoolUtils.getAmountsFromLiquidity({\n epochInfo,\n poolInfo,\n tickLower,\n tickUpper,\n liquidity,\n slippage,\n add,\n });\n return {\n liquidity,\n amountA: inputA ? addFeeAmount : amountFromLiquidity.amountA,\n amountB: inputA ? amountFromLiquidity.amountB : addFeeAmount,\n amountSlippageA: inputA ? addFeeAmount : amountFromLiquidity.amountSlippageA,\n amountSlippageB: inputA ? amountFromLiquidity.amountSlippageB : addFeeAmount,\n expirationTime: amountFromLiquidity.expirationTime,\n };\n }\n\n static async getAmountsFromLiquidity({\n epochInfo,\n poolInfo,\n tickLower,\n tickUpper,\n liquidity,\n slippage,\n add,\n }: {\n epochInfo: EpochInfo;\n poolInfo: ApiV3PoolInfoConcentratedItem;\n tickLower: number;\n tickUpper: number;\n liquidity: BN;\n slippage: number;\n add: boolean;\n }): Promise<ReturnTypeGetLiquidityAmountOut> {\n const sqrtPriceX64A = TickUtil.getSqrtPriceAtTick(tickLower);\n const sqrtPriceX64B = TickUtil.getSqrtPriceAtTick(tickUpper);\n\n const coefficientRe = add ? 1 + slippage : 1 - slippage;\n\n const amounts = LiquidityMathUtil.getAmountsForLiquidity(\n TickUtil.priceToSqrtPriceX64(new Decimal(poolInfo.price), poolInfo.mintA.decimals, poolInfo.mintB.decimals),\n sqrtPriceX64A,\n sqrtPriceX64B,\n liquidity,\n add,\n );\n const [amountA, amountB] = [\n getTransferAmountFeeV2(amounts.amountA, poolInfo.mintA.extensions?.feeConfig, epochInfo, true),\n getTransferAmountFeeV2(amounts.amountB, poolInfo.mintB.extensions?.feeConfig, epochInfo, true),\n ];\n const [amountSlippageA, amountSlippageB] = [\n getTransferAmountFeeV2(\n amounts.amountA.muln(coefficientRe),\n poolInfo.mintA.extensions?.feeConfig,\n epochInfo,\n true,\n ),\n getTransferAmountFeeV2(\n amounts.amountB.muln(coefficientRe),\n poolInfo.mintB.extensions?.feeConfig,\n epochInfo,\n true,\n ),\n ];\n\n return {\n liquidity,\n amountA,\n amountB,\n amountSlippageA,\n amountSlippageB,\n expirationTime: minExpirationTime(amountA.expirationTime, amountB.expirationTime),\n };\n }\n\n static async fetchComputeMultipleClmmInfo({\n connection,\n poolList,\n rpcDataMap = {},\n }: {\n rpcDataMap?: Record<string, ReturnType<typeof PoolInfoLayout.decode>>;\n connection: Connection;\n poolList: Pick<ApiV3PoolInfoConcentratedItem, \"id\" | \"programId\" | \"mintA\" | \"mintB\" | \"config\" | \"price\">[];\n }): Promise<Record<string, ComputeClmmPoolInfo>> {\n const fetchRpcList = poolList.filter((p) => !rpcDataMap[p.id]).map((p) => new PublicKey(p.id));\n const rpcRes = await getMultipleAccountsInfo(connection, fetchRpcList);\n rpcRes.forEach((r, idx) => {\n if (!r) return;\n rpcDataMap[fetchRpcList[idx].toBase58()] = PoolInfoLayout.decode(r.data);\n });\n\n const pdaList = poolList.map(\n (poolInfo) => getPdaExBitmapAccount(new PublicKey(poolInfo.programId), new PublicKey(poolInfo.id)).publicKey,\n );\n\n const exBitData = await PoolUtils.fetchExBitmaps({\n connection,\n exBitmapAddress: pdaList,\n batchRequest: false,\n });\n\n const kv: Record<string, ComputeClmmPoolInfo> = {};\n\n return poolList.reduce(\n (acc, cur) => ({\n ...acc,\n [cur.id]: {\n accInfo: rpcDataMap[cur.id],\n ...rpcDataMap[cur.id],\n id: new PublicKey(cur.id),\n version: 6,\n programId: new PublicKey(cur.programId),\n mintA: cur.mintA,\n mintB: cur.mintB,\n ammConfig: {\n ...cur.config,\n id: new PublicKey(cur.config.id),\n fundOwner: \"\",\n },\n currentPrice: new Decimal(cur.price),\n exBitmapAccount: getPdaExBitmapAccount(new PublicKey(cur.programId), new PublicKey(cur.id)).publicKey,\n exBitmapInfo:\n exBitData[getPdaExBitmapAccount(new PublicKey(cur.programId), new PublicKey(cur.id)).publicKey.toBase58()],\n startTime: rpcDataMap[cur.id].startTime.toNumber(),\n rewardInfos: rpcDataMap[cur.id].rewardInfos,\n },\n }),\n {} as Record<string, ComputeClmmPoolInfo>,\n );\n }\n\n static async fetchComputeClmmInfo({\n connection,\n poolInfo,\n rpcData,\n }: {\n connection: Connection;\n poolInfo: Pick<ApiV3PoolInfoConcentratedItem, \"id\" | \"programId\" | \"mintA\" | \"mintB\" | \"config\" | \"price\">;\n rpcData?: ReturnType<typeof PoolInfoLayout.decode>;\n }): Promise<ComputeClmmPoolInfo> {\n return (\n await this.fetchComputeMultipleClmmInfo({\n connection,\n rpcDataMap: rpcData ? { [poolInfo.id]: rpcData } : undefined,\n poolList: [poolInfo],\n })\n )[poolInfo.id];\n }\n\n static async fetchTickArrayInfo({\n connection,\n programId,\n poolId,\n tick,\n tickSpacing,\n }: {\n connection: Connection;\n programId: PublicKey;\n poolId: PublicKey;\n tick: number;\n tickSpacing: number;\n }): Promise<ReturnType<typeof TickArrayLayout.decode>> {\n const tickArrayStart = TickArrayUtil.getTickArrayStartIndex(tick, tickSpacing);\n const tickArray = getPdaTickArrayAddress(programId, poolId, tickArrayStart).publicKey;\n const tickData = await connection.getAccountInfo(tickArray);\n if (!tickData) throw new Error(`tick array ${tickArray.toBase58()} not found`);\n return TickArrayLayout.decode(tickData.data);\n }\n\n static async fetchMultipleTickArrayInfo({\n connection,\n tickInfoList,\n }: {\n connection: Connection;\n tickInfoList: { programId: PublicKey; poolId: PublicKey; tick: number; tickSpacing: number }[];\n }): Promise<(ReturnType<typeof TickArrayLayout.decode> | null)[]> {\n const tickPda = tickInfoList.map((data) => {\n const tickArrayStart = TickArrayUtil.getTickArrayStartIndex(data.tick, data.tickSpacing);\n return getPdaTickArrayAddress(data.programId, data.poolId, tickArrayStart).publicKey;\n });\n\n const data = await getMultipleAccountsInfo(connection, tickPda);\n return data.map((d) => (d ? TickArrayLayout.decode(d.data) : d));\n }\n}\n\nconst mockRewardData = {\n volume: 0,\n volumeQuote: 0,\n volumeFee: 0,\n apr: 0,\n feeApr: 0,\n priceMin: 0,\n priceMax: 0,\n rewardApr: [],\n};\n\nexport function clmmComputeInfoToApiInfo(\n pool: ComputeClmmPoolInfo,\n mintInfos?: ReturnTypeFetchMultipleMintInfos,\n): ApiV3PoolInfoConcentratedItem {\n const mintData = mintInfos ?? {};\n return {\n ...pool,\n type: \"Concentrated\",\n programId: pool.programId.toString(),\n id: pool.id.toString(),\n rewardDefaultInfos: pool.rewardInfos\n .filter((r) => !r.mint.equals(PublicKey.default))\n .map((r) => ({\n mint: toApiV3Token({\n address: r.mint.toBase58(),\n programId: TOKEN_PROGRAM_ID.toBase58(),\n decimals: mintData[r.mint.toBase58()].decimals ?? 6,\n }),\n perSecond: Number(r.emissionsPerSecondX64.divn(10 ** (mintData[r.mint.toBase58()].decimals ?? 6)).toString()),\n startTime: r.openTime.toNumber(),\n endTime: r.endTime.toNumber(),\n })),\n rewardDefaultPoolInfos: \"Clmm\",\n price: pool.currentPrice.toNumber(),\n mintAmountA: 0,\n mintAmountB: 0,\n feeRate: pool.ammConfig.tradeFeeRate,\n openTime: pool.startTime.toString(),\n tvl: 0,\n\n day: mockRewardData,\n week: mockRewardData,\n month: mockRewardData,\n pooltype: [],\n\n farmUpcomingCount: 0,\n farmOngoingCount: 0,\n farmFinishedCount: 0,\n burnPercent: 0,\n config: {\n ...pool.ammConfig,\n id: pool.ammConfig.id.toString(),\n defaultRange: 0,\n defaultRangePoint: [],\n },\n hasDynamicFee: false,\n feeOn: \"\",\n launchMigratePool: false,\n tips: [],\n };\n}\n","import { PublicKey } from \"@solana/web3.js\";\nimport BN from \"bn.js\";\nimport { ClmmConfigLayout, PoolInfoLayout, TickArrayBitmapExtensionLayout, TickArrayLayout } from \"../layout\";\nimport { BN_ZERO, MAX_SQRT_PRICE_X64, MIN_SQRT_PRICE_X64 } from \"./constants\";\nimport { LiquidityMathUtil } from \"./liquidityMath\";\nimport { PoolUtil } from \"./pool\";\nimport { SwapMathUtil, SwapState } from \"./swapMath\";\nimport { TickArrayBitmapUtil, TickArrayUtil, TickUtil } from \"./tickArrayUtil\";\n\nexport interface SwapSimulationResult {\n allTrade: boolean;\n amountSpecifiedRemaining: BN;\n amountCalculated: BN;\n feeAmount: BN;\n sqrtPriceX64: BN;\n liquidity: BN;\n tickCurrent: number;\n accounts: PublicKey[];\n}\n\nexport function swapInternal({\n programId,\n poolId,\n poolInfo,\n tickArrays,\n configInfo,\n tickarrayBitmapExtension,\n amountSpecified,\n sqrtPriceLimitX64,\n zeroForOne,\n isBaseInput,\n blockTimestamp,\n includeExtraTickArrays,\n}: {\n programId: PublicKey;\n poolId: PublicKey;\n poolInfo: ReturnType<typeof PoolInfoLayout.decode>;\n tickArrays: { address: PublicKey; value: ReturnType<typeof TickArrayLayout.decode> }[];\n configInfo: ReturnType<typeof ClmmConfigLayout.decode>;\n tickarrayBitmapExtension: ReturnType<typeof TickArrayBitmapExtensionLayout.decode>;\n amountSpecified: BN;\n sqrtPriceLimitX64: BN;\n zeroForOne: boolean;\n isBaseInput: boolean;\n blockTimestamp: number;\n includeExtraTickArrays: boolean;\n}): SwapSimulationResult {\n if (sqrtPriceLimitX64.isZero()) {\n sqrtPriceLimitX64 = zeroForOne ? new BN(MIN_SQRT_PRICE_X64).addn(1) : new BN(MAX_SQRT_PRICE_X64).subn(1);\n }\n\n let tickArrayListIndex = 0;\n\n if (tickArrays.length === 0) {\n return {\n allTrade: false,\n amountSpecifiedRemaining: amountSpecified,\n amountCalculated: BN_ZERO,\n feeAmount: BN_ZERO,\n sqrtPriceX64: poolInfo.sqrtPriceX64,\n liquidity: poolInfo.liquidity,\n tickCurrent: poolInfo.tickCurrent,\n accounts: [],\n };\n }\n\n const addTickArrayAddress = includeExtraTickArrays\n ? TickArrayBitmapUtil.findTickArrayAddress({\n programId,\n poolId,\n tickSpacing: poolInfo.tickSpacing,\n poolBitmap: poolInfo.tickArrayBitmap,\n tickArrayBitmap: tickarrayBitmapExtension,\n findInfo: { type: !zeroForOne ? \"zeroForOne\" : \"oneForZero\", count: 2, tickArrayCurrent: poolInfo.tickCurrent },\n }).filter((i) => i.toString() !== tickArrays[0].address.toString())\n : [];\n\n const _startTickIndex = TickArrayUtil.getTickArrayStartIndex(poolInfo.tickCurrent, poolInfo.tickSpacing);\n const { firstItckArrayContainsPoolTick: _firstItckArrayContainsPoolTick, firstValidTickArrayStartIndex } = {\n firstItckArrayContainsPoolTick: tickArrays[tickArrayListIndex].value.startTickIndex === _startTickIndex,\n firstValidTickArrayStartIndex: tickArrays[tickArrayListIndex].value.startTickIndex,\n };\n let firstItckArrayContainsPoolTick = _firstItckArrayContainsPoolTick;\n\n let currentValidTIckArrayStrartIndex = firstValidTickArrayStartIndex;\n\n let tickArrayCurrent = tickArrays[tickArrayListIndex];\n\n const isFeeOnInput = PoolUtil.isFeeOnInput(poolInfo.feeOn, zeroForOne);\n\n const state = SwapState.newValue({\n poolInfo,\n amountSpecified,\n zeroForOne,\n feeRate: configInfo.tradeFeeRate,\n blockTimestamp,\n });\n\n while (!state.amountSpecifiedRemaining.isZero() && !state.sqrtPriceX64.eq(sqrtPriceLimitX64)) {\n const nextInitializedTick = (() => {\n const tickState = TickArrayUtil.nextInitalizedTick({\n data: tickArrayCurrent.value,\n tickSpacing: state.tickSpacing,\n zeroForOne,\n currentTickIndex: state.tick,\n });\n if (tickState !== undefined) {\n return tickState;\n } else if (!firstItckArrayContainsPoolTick) {\n firstItckArrayContainsPoolTick = true;\n return TickArrayUtil.firstinitializedTick({ data: tickArrayCurrent.value, zeroForOne });\n } else {\n const nextTickArrayIndex = tickArrays[++tickArrayListIndex];\n if (nextTickArrayIndex === undefined) {\n return undefined;\n }\n\n currentValidTIckArrayStrartIndex = nextTickArrayIndex.value.startTickIndex;\n tickArrayCurrent = nextTickArrayIndex;\n return TickArrayUtil.firstinitializedTick({ data: nextTickArrayIndex.value, zeroForOne });\n }\n })();\n\n if (nextInitializedTick === undefined) {\n return {\n allTrade: false,\n amountSpecifiedRemaining: state.amountSpecifiedRemaining,\n amountCalculated: state.amountCalculated,\n feeAmount: state.lpFee.add(state.fundFee).add(state.protocolFee),\n sqrtPriceX64: state.sqrtPriceX64,\n liquidity: state.liquidity,\n tickCurrent: state.tick,\n accounts: tickArrays.slice(0, tickArrayListIndex).map((i) => i.address),\n };\n }\n\n const targetPrice = SwapState.getTargetPriceBasedOnNextTick({\n data: state,\n tickNext: nextInitializedTick.tick,\n zeroForOne,\n sqrtPriceLimitX64,\n });\n\n let liquidityNext = state.liquidity;\n do {\n SwapState.updateVolatilityAccumulator({ state });\n\n const totalFeeRate = SwapState.getTotalFeeRate({ data: state });\n const { isSkipped: isSkippedTickSpacing, boundedPrice } = SwapState.getSpacingBoundedPrice({\n data: state,\n targetPrice,\n zeroForOne,\n });\n\n const isPriceChange = !state.sqrtPriceX64.eq(boundedPrice);\n\n let swapComputedResult;\n if (isPriceChange) {\n swapComputedResult = SwapMathUtil.computeSwap(\n state.sqrtPriceX64,\n boundedPrice,\n state.liquidity,\n state.amountSpecifiedRemaining,\n totalFeeRate,\n isBaseInput,\n zeroForOne,\n isFeeOnInput,\n );\n\n SwapState.applySwapAmounts({\n state,\n amountIn: swapComputedResult.amountIn,\n amountOut: swapComputedResult.amountOut,\n feeAmount: swapComputedResult.feeAmount,\n isBaseInput,\n isFeeOnInput,\n protocolFeeRate: new BN(configInfo.protocolFeeRate),\n fundFeeRate: new BN(configInfo.fundFeeRate),\n });\n } else {\n swapComputedResult = SwapMathUtil.newSwapComputationResult({ sqrtPriceNextX64: boundedPrice });\n }\n\n const limitOrderUnfilledAmountBefore = TickUtil.limitOrderUnfilledAmount({ tick: nextInitializedTick });\n if (state.sqrtPriceNextX64.eq(swapComputedResult.sqrtPriceNextX64)) {\n const limitOrderResult = TickUtil.matchLimitOrder({\n tick: nextInitializedTick,\n swapAmount: state.amountSpecifiedRemaining,\n swapDirectionZeroForOne: zeroForOne,\n isBaseInput,\n feeRate: totalFeeRate,\n isFeeOnInput,\n });\n\n if (limitOrderResult.amountIn.gt(BN_ZERO)) {\n SwapState.applySwapAmounts({\n state,\n amountIn: limitOrderResult.amountIn,\n amountOut: limitOrderResult.amountOut,\n feeAmount: limitOrderResult.ammFeeAmount,\n isBaseInput,\n isFeeOnInput,\n protocolFeeRate: new BN(configInfo.protocolFeeRate),\n fundFeeRate: new BN(configInfo.fundFeeRate),\n });\n }\n\n if (\n TickUtil.hasLiquidity({ data: nextInitializedTick }) &&\n !TickUtil.hasLimitOrders({ data: nextInitializedTick })\n ) {\n const liquidityNet = zeroForOne ? nextInitializedTick.liquidityNet.neg() : nextInitializedTick.liquidityNet;\n\n liquidityNext = LiquidityMathUtil.addDelta(state.liquidity, liquidityNet);\n }\n\n state.tick =\n (zeroForOne && !TickUtil.hasLimitOrders({ data: nextInitializedTick })) ||\n (!zeroForOne && TickUtil.hasLimitOrders({ data: nextInitializedTick }))\n ? state.tickNext - 1\n : state.tickNext;\n } else if (!state.sqrtPriceX64.eq(swapComputedResult.sqrtPriceNextX64)) {\n state.tick = TickUtil.getTickAtSqrtPrice(swapComputedResult.sqrtPriceNextX64);\n }\n\n state.sqrtPriceX64 = swapComputedResult.sqrtPriceNextX64;\n SwapState.updateDynamicFeeIndex({ state, zeroForOne, isSkippedTickSpacing });\n if (state.amountSpecifiedRemaining.isZero() || state.sqrtPriceX64.eq(targetPrice)) {\n const limitOrderUnfilledAmountAfter = TickUtil.limitOrderUnfilledAmount({ tick: nextInitializedTick });\n\n if (\n !state.amountSpecifiedRemaining.isZero() &&\n !limitOrderUnfilledAmountAfter.eq(limitOrderUnfilledAmountBefore)\n ) {\n if (!limitOrderUnfilledAmountAfter.isZero()) throw Error(\"!limitOrderUnfilledAmountAfter.isZero()\");\n }\n break;\n }\n\n // eslint-disable-next-line no-constant-condition\n } while (true);\n state.liquidity = liquidityNext;\n }\n\n return {\n allTrade: true,\n amountSpecifiedRemaining: BN_ZERO,\n amountCalculated: state.amountCalculated,\n feeAmount: state.lpFee.add(state.fundFee).add(state.protocolFee),\n sqrtPriceX64: state.sqrtPriceX64,\n liquidity: state.liquidity,\n tickCurrent: state.tick,\n accounts: [\n ...addTickArrayAddress,\n ...tickArrays.slice(0, tickArrayListIndex + 1 + (includeExtraTickArrays ? 1 : 0)).map((i) => i.address),\n ],\n };\n}\n","import { FEE_RATE_DENOMINATOR_VALUE } from \"@/common\"\nimport BN from \"bn.js\"\nimport { DynamicFeeInfoLayout, PoolInfoLayout } from \"../layout\"\nimport { mulDivCeil, mulDivFloor } from \"./bigNum\"\nimport { BN_ZERO, DYNAMIC_FEE_CONTROL_DENOMINATOR, FEE_RATE_DENOMINATOR, MAX_FEE_RATE_NUMERATOR, MAX_TICK, MIN_TICK, Q64, VOLATILITY_ACCUMULATOR_SCALE } from \"./constants\"\nimport { LiquidityMathUtil } from \"./liquidityMath\"\nimport { DynamicFeeInfo, PoolFee } from \"./pool\"\nimport { SqrtPriceMath } from \"./sqrtPriceMath\"\nimport { TickUtil } from \"./tickArrayUtil\"\n\nexport interface SwapStepResult {\n sqrtPriceNextX64: BN\n amountIn: BN\n amountOut: BN\n feeAmount: BN\n}\n\ninterface SwapStateInterface {\n amountSpecifiedRemaining: BN,\n amountCalculated: BN,\n sqrtPriceX64: BN,\n tick: number,\n feeGrowthGlobalX64: BN,\n lpFee: BN,\n protocolFee: BN,\n fundFee: BN,\n liquidity: BN,\n sqrtPriceNextX64: BN,\n tickNext: number,\n baseFeeRate: number,\n tickSpacing: number,\n tickSpacingIndex: number,\n dynamicFeeInfo: ReturnType<typeof DynamicFeeInfoLayout.decode> | undefined,\n}\nexport class SwapState {\n static newValue({ poolInfo, amountSpecified, zeroForOne, feeRate, blockTimestamp }: {\n poolInfo: ReturnType<typeof PoolInfoLayout.decode>,\n amountSpecified: BN,\n zeroForOne: boolean,\n feeRate: number,\n blockTimestamp: number,\n }): SwapStateInterface {\n const state: SwapStateInterface = {\n amountSpecifiedRemaining: amountSpecified,\n amountCalculated: BN_ZERO,\n sqrtPriceX64: poolInfo.sqrtPriceX64,\n tick: poolInfo.tickCurrent,\n feeGrowthGlobalX64: zeroForOne ? poolInfo.feeGrowthGlobalX64A : poolInfo.feeGrowthGlobalX64B,\n lpFee: BN_ZERO,\n protocolFee: BN_ZERO,\n fundFee: BN_ZERO,\n liquidity: poolInfo.liquidity,\n sqrtPriceNextX64: BN_ZERO,\n tickNext: 0,\n baseFeeRate: feeRate,\n tickSpacing: poolInfo.tickSpacing,\n tickSpacingIndex: 0,\n dynamicFeeInfo: DynamicFeeInfo.getDynamicFeeInfo({ poolInfo }),\n }\n\n if (state.dynamicFeeInfo) {\n state.tickSpacingIndex = PoolFee.tickSpacingIndexFromTick(state.tick, state.tickSpacing)\n DynamicFeeInfo.updateReference({ dynamicFeeInfo: state.dynamicFeeInfo, tickSpacingIndex: state.tickSpacingIndex, currentTimestamp: blockTimestamp })\n }\n\n return state\n }\n\n static getTargetPriceBasedOnNextTick({ data, tickNext, zeroForOne, sqrtPriceLimitX64 }: {\n data: SwapStateInterface,\n tickNext: number,\n zeroForOne: boolean,\n sqrtPriceLimitX64: BN,\n }) {\n data.tickNext = tickNext\n if (data.tickNext < MIN_TICK) {\n data.tickNext = MIN_TICK\n } else if (data.tickNext > MAX_TICK) {\n data.tickNext = MAX_TICK\n }\n\n data.sqrtPriceNextX64 = TickUtil.getSqrtPriceAtTick(data.tickNext)\n\n let targetPrice: BN\n\n if ((zeroForOne && data.sqrtPriceNextX64.lt(sqrtPriceLimitX64)) || (!zeroForOne && data.sqrtPriceNextX64.gt(sqrtPriceLimitX64))) {\n targetPrice = sqrtPriceLimitX64\n } else {\n targetPrice = data.sqrtPriceNextX64\n }\n\n if (zeroForOne) {\n if (data.tick < data.tickNext) throw Error('data.tick < data.tickNext')\n if (data.sqrtPriceX64.lt(data.sqrtPriceNextX64)) throw Error('data.sqrtPriceX64.lt(data.sqrtPriceNextX64)')\n if (data.sqrtPriceX64.lt(targetPrice)) throw Error('data.sqrtPriceX64.lt(targetPrice)')\n } else {\n if (data.tickNext <= data.tick) throw Error('data.tickNext <= data.tick')\n if (data.sqrtPriceNextX64.lt(data.sqrtPriceX64)) throw Error('data.sqrtPriceNextX64.lt(data.sqrtPriceX64)')\n if (targetPrice.lt(data.sqrtPriceX64)) throw Error('targetPrice.lt(data.sqrtPriceX64)')\n }\n\n return targetPrice\n }\n\n static updateVolatilityAccumulator({ state }: {\n state: SwapStateInterface,\n }) {\n if (!state.dynamicFeeInfo) return\n\n DynamicFeeInfo.updateVolatilityAccumulator({ state: state.dynamicFeeInfo, tickSpacingIndex: state.tickSpacingIndex })\n }\n\n static computeDynamicFeeRate({ data, tickSpacing }: {\n data: ReturnType<typeof DynamicFeeInfoLayout.decode>,\n tickSpacing: number,\n }) {\n const crossed = data.volatilityAccumulator * tickSpacing\n\n const squared = crossed * crossed\n\n const denominator = DYNAMIC_FEE_CONTROL_DENOMINATOR * VOLATILITY_ACCUMULATOR_SCALE * VOLATILITY_ACCUMULATOR_SCALE\n\n const feeRate = mulDivCeil(new BN(data.dynamicFeeControl), new BN(squared), new BN(denominator)).toNumber()\n\n if (feeRate > MAX_FEE_RATE_NUMERATOR) {\n return MAX_FEE_RATE_NUMERATOR\n } else {\n return feeRate\n }\n }\n\n static getTotalFeeRate({ data }: {\n data: SwapStateInterface,\n }) {\n if (data.dynamicFeeInfo) {\n const dynamicFeeRate = this.computeDynamicFeeRate({ data: data.dynamicFeeInfo, tickSpacing: data.tickSpacing })\n\n const totalFeeRate = data.baseFeeRate + dynamicFeeRate\n return Math.min(MAX_FEE_RATE_NUMERATOR, totalFeeRate)\n }\n return data.baseFeeRate\n }\n\n static getSpacingBoundedPrice({ data, targetPrice, zeroForOne }: {\n data: SwapStateInterface,\n targetPrice: BN,\n zeroForOne: boolean\n }) {\n if (data.dynamicFeeInfo === undefined) return { isSkipped: true, boundedPrice: targetPrice }\n\n if (data.liquidity.isZero() || data.dynamicFeeInfo.volatilityAccumulator === data.dynamicFeeInfo.maxVolatilityAccumulator) return { isSkipped: true, boundedPrice: targetPrice }\n\n const tickSpacingI32 = data.tickSpacing\n const boundedTick = zeroForOne ? data.tickSpacingIndex * tickSpacingI32 : (data.tickSpacingIndex + 1) * tickSpacingI32\n\n const clampedTick = Math.max(MIN_TICK, Math.min(MAX_TICK, boundedTick))\n const boundedSqrtPrice = TickUtil.getSqrtPriceAtTick(clampedTick)\n\n if (zeroForOne) {\n return { isSkipped: false, boundedPrice: BN.max(targetPrice, boundedSqrtPrice) }\n } else {\n return { isSkipped: false, boundedPrice: BN.min(targetPrice, boundedSqrtPrice) }\n }\n }\n\n static applySwapAmounts({ state, amountIn, amountOut, feeAmount, isBaseInput, isFeeOnInput, protocolFeeRate, fundFeeRate, }: {\n state: SwapStateInterface,\n amountIn: BN,\n amountOut: BN,\n feeAmount: BN,\n isBaseInput: boolean,\n isFeeOnInput: boolean,\n protocolFeeRate: BN,\n fundFeeRate: BN,\n }) {\n const amountInConsumed = isFeeOnInput ? amountIn.add(feeAmount) : amountIn\n\n if (isBaseInput) {\n state.amountSpecifiedRemaining = state.amountSpecifiedRemaining.sub(amountInConsumed)\n state.amountCalculated = state.amountCalculated.add(amountOut)\n } else {\n state.amountSpecifiedRemaining = state.amountSpecifiedRemaining.sub(amountOut)\n state.amountCalculated = state.amountCalculated.add(amountInConsumed)\n }\n\n this.splitFee({ state, feeAmount, protocolFeeRate, fundFeeRate })\n }\n\n static updateDynamicFeeIndex({ state, zeroForOne, isSkippedTickSpacing }: {\n state: SwapStateInterface,\n zeroForOne: boolean,\n isSkippedTickSpacing: boolean,\n }) {\n if (state.dynamicFeeInfo === undefined) return\n if (isSkippedTickSpacing) {\n const tickIndex = state.sqrtPriceX64.eq(state.sqrtPriceNextX64) ? state.tickNext : state.tick\n\n let tickSpacingIndex = PoolFee.tickSpacingIndexFromTick(tickIndex, state.tickSpacing)\n\n if (!zeroForOne && tickIndex % state.tickSpacing === 0) {\n tickSpacingIndex = tickSpacingIndex - 1\n }\n\n state.tickSpacingIndex = tickSpacingIndex\n\n if (state.dynamicFeeInfo.volatilityAccumulator !== state.dynamicFeeInfo.maxVolatilityAccumulator) {\n this.updateVolatilityAccumulator({ state })\n }\n }\n\n state.tickSpacingIndex += zeroForOne ? -1 : 1\n }\n\n static splitFee({ state, feeAmount, protocolFeeRate, fundFeeRate }: {\n state: SwapStateInterface,\n feeAmount: BN,\n protocolFeeRate: BN,\n fundFeeRate: BN\n }) {\n let remainingFee = feeAmount\n if (protocolFeeRate.gt(BN_ZERO)) {\n const protocolFeeDelta = feeAmount.mul(protocolFeeRate).div(new BN(FEE_RATE_DENOMINATOR_VALUE))\n state.protocolFee = state.protocolFee.add(protocolFeeDelta)\n remainingFee = remainingFee.sub(protocolFeeDelta)\n }\n\n if (fundFeeRate.gt(BN_ZERO)) {\n const fundFeeDelta = feeAmount.mul(fundFeeRate).div(new BN(FEE_RATE_DENOMINATOR_VALUE))\n state.fundFee = state.fundFee.add(fundFeeDelta)\n remainingFee = remainingFee.sub(fundFeeDelta)\n }\n\n if (state.liquidity.gt(BN_ZERO)) {\n const feeGrowthGlobalX64Delta = mulDivFloor(remainingFee, Q64, state.liquidity)\n state.feeGrowthGlobalX64 = state.feeGrowthGlobalX64.add(feeGrowthGlobalX64Delta)\n state.lpFee = state.lpFee.add(remainingFee)\n }\n }\n\n}\n\n\nexport class SwapMathUtil {\n static newSwapComputationResult({ sqrtPriceNextX64 }: { sqrtPriceNextX64?: BN }): SwapStepResult {\n return {\n sqrtPriceNextX64: sqrtPriceNextX64 ?? BN_ZERO,\n amountIn: BN_ZERO,\n amountOut: BN_ZERO,\n feeAmount: BN_ZERO,\n }\n }\n\n static calculateAmountInRange({ sqrtPriceCurrentX64, sqrtPriceTargetX64, liquidity, zeroForOne, isBaseInput }: {\n sqrtPriceCurrentX64: BN,\n sqrtPriceTargetX64: BN,\n liquidity: BN,\n zeroForOne: boolean,\n isBaseInput: boolean,\n }) {\n if (isBaseInput) {\n try {\n const result = zeroForOne ? LiquidityMathUtil.getDeltaAmountAUnsigned(sqrtPriceTargetX64, sqrtPriceCurrentX64, liquidity, true) : LiquidityMathUtil.getDeltaAmountBUnsigned(sqrtPriceCurrentX64, sqrtPriceTargetX64, liquidity, true)\n return result\n } catch (e) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n if (e.message === 'MaxTokenOverflow') return null\n throw e\n }\n } else {\n try {\n const result = zeroForOne ? LiquidityMathUtil.getDeltaAmountBUnsigned(sqrtPriceTargetX64, sqrtPriceCurrentX64, liquidity, false) : LiquidityMathUtil.getDeltaAmountAUnsigned(sqrtPriceCurrentX64, sqrtPriceTargetX64, liquidity, false)\n return result\n } catch (e) {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n if (e.message === 'MaxTokenOverflow') return null\n throw e\n }\n }\n }\n\n static computeSwap(\n sqrtPriceCurrentX64: BN,\n sqrtPriceTargetX64: BN,\n liquidity: BN,\n amountRemaining: BN,\n feeRate: number,\n isBaseInput: boolean,\n zeroForOne: boolean,\n isFeeOnInput: boolean\n ): SwapStepResult {\n const result = this.newSwapComputationResult({})\n\n if (isBaseInput) {\n const amountForPriceCalc = isFeeOnInput ? mulDivFloor(amountRemaining, new BN(FEE_RATE_DENOMINATOR - feeRate), new BN(FEE_RATE_DENOMINATOR)) : amountRemaining\n\n const amountIn = this.calculateAmountInRange({ sqrtPriceCurrentX64, sqrtPriceTargetX64, liquidity, zeroForOne, isBaseInput })\n\n if (amountIn !== null) result.amountIn = amountIn\n\n result.sqrtPriceNextX64 = amountIn !== null && amountForPriceCalc.gte(result.amountIn) ? sqrtPriceTargetX64 : SqrtPriceMath.getNextSqrtPriceFromInput(sqrtPriceCurrentX64, liquidity, amountForPriceCalc, zeroForOne)\n } else {\n const amountForPriceCalc = isFeeOnInput\n ? amountRemaining\n : mulDivCeil(\n amountRemaining,\n new BN(FEE_RATE_DENOMINATOR),\n new BN(FEE_RATE_DENOMINATOR - feeRate)\n )\n\n const amountOut = this.calculateAmountInRange({ sqrtPriceCurrentX64, sqrtPriceTargetX64, liquidity, zeroForOne, isBaseInput })\n if (amountOut !== null) result.amountOut = amountOut\n\n result.sqrtPriceNextX64 = amountOut !== null && amountForPriceCalc.gte(result.amountOut) ? sqrtPriceTargetX64 : SqrtPriceMath.getNextSqrtPriceFromOutput(sqrtPriceCurrentX64, liquidity, amountForPriceCalc, zeroForOne)\n }\n\n if (zeroForOne) {\n if (!result.sqrtPriceNextX64.gte(sqrtPriceTargetX64)) throw Error('!result.sqrtPriceNextX64.gte(sqrtPriceTargetX64)')\n } else {\n if (!sqrtPriceTargetX64.gte(result.sqrtPriceNextX64)) throw Error('!sqrtPriceTargetX64.gte(result.sqrtPriceNextX64)')\n }\n\n const max = sqrtPriceTargetX64.eq(result.sqrtPriceNextX64)\n\n if (zeroForOne) {\n if (!(max && isBaseInput)) {\n result.amountIn = LiquidityMathUtil.getDeltaAmountAUnsigned(result.sqrtPriceNextX64, sqrtPriceCurrentX64, liquidity, true)\n }\n if (!(max && !isBaseInput)) {\n result.amountOut = LiquidityMathUtil.getDeltaAmountBUnsigned(result.sqrtPriceNextX64, sqrtPriceCurrentX64, liquidity, false)\n }\n } else {\n if (!(max && isBaseInput)) {\n result.amountIn = LiquidityMathUtil.getDeltaAmountBUnsigned(sqrtPriceCurrentX64, result.sqrtPriceNextX64, liquidity, true)\n }\n if (!(max && !isBaseInput)) {\n result.amountOut = LiquidityMathUtil.getDeltaAmountAUnsigned(sqrtPriceCurrentX64, result.sqrtPriceNextX64, liquidity, false)\n }\n }\n\n if (isBaseInput) {\n if (isFeeOnInput) {\n if (!result.sqrtPriceNextX64.eq(sqrtPriceTargetX64)) {\n result.feeAmount = amountRemaining.sub(result.amountIn)\n } else {\n result.feeAmount = mulDivCeil(\n result.amountIn,\n new BN(feeRate),\n new BN(FEE_RATE_DENOMINATOR - feeRate)\n )\n }\n } else {\n result.feeAmount = mulDivCeil(result.amountOut, new BN(feeRate), new BN(FEE_RATE_DENOMINATOR))\n result.amountOut = result.amountOut.sub(result.feeAmount)\n\n if (!max) {\n result.amountIn = amountRemaining\n }\n }\n } else {\n if (isFeeOnInput) {\n result.amountOut = BN.min(result.amountOut, amountRemaining)\n result.feeAmount = mulDivCeil(\n result.amountIn,\n new BN(feeRate),\n new BN(FEE_RATE_DENOMINATOR - feeRate)\n )\n } else {\n result.feeAmount = mulDivCeil(result.amountOut, new BN(feeRate), new BN(FEE_RATE_DENOMINATOR))\n const netOutput = result.amountOut.sub(result.feeAmount)\n\n if (netOutput.gt(amountRemaining)) {\n result.feeAmount = result.amountOut.sub(amountRemaining)\n result.amountOut = amountRemaining\n } else {\n result.amountOut = netOutput\n }\n }\n }\n\n return result\n }\n}","import BN from 'bn.js';\n\nimport { TickLayout } from '../layout';\nimport { mulDivFloor, wrappingSubU128 } from './bigNum';\nimport { Q64 } from './constants';\n\nexport class PositionUtils {\n\n static getfeeGrowthInside(\n poolState: {\n tickCurrent: number,\n feeGrowthGlobalX64A: BN,\n feeGrowthGlobalX64B: BN,\n },\n tickLowerState: ReturnType<typeof TickLayout.decode>,\n tickUpperState: ReturnType<typeof TickLayout.decode>\n ): { feeGrowthInsideX64A: BN, feeGrowthInsideBX64: BN } {\n let feeGrowthBelowX64A = new BN(0)\n let feeGrowthBelowX64B = new BN(0)\n if (poolState.tickCurrent >= tickLowerState.tick) {\n feeGrowthBelowX64A = tickLowerState.feeGrowthOutsideX64A\n feeGrowthBelowX64B = tickLowerState.feeGrowthOutsideX64B\n } else {\n feeGrowthBelowX64A = wrappingSubU128(poolState.feeGrowthGlobalX64A, tickLowerState.feeGrowthOutsideX64A)\n feeGrowthBelowX64B = wrappingSubU128(poolState.feeGrowthGlobalX64B, tickLowerState.feeGrowthOutsideX64B)\n }\n\n let feeGrowthAboveX64A = new BN(0)\n let feeGrowthAboveX64B = new BN(0)\n if (poolState.tickCurrent < tickUpperState.tick) {\n feeGrowthAboveX64A = tickUpperState.feeGrowthOutsideX64A\n feeGrowthAboveX64B = tickUpperState.feeGrowthOutsideX64B\n } else {\n feeGrowthAboveX64A = wrappingSubU128(poolState.feeGrowthGlobalX64A, tickUpperState.feeGrowthOutsideX64A)\n feeGrowthAboveX64B = wrappingSubU128(poolState.feeGrowthGlobalX64B, tickUpperState.feeGrowthOutsideX64B)\n }\n\n const feeGrowthInsideX64A = wrappingSubU128(\n wrappingSubU128(poolState.feeGrowthGlobalX64A, feeGrowthBelowX64A),\n feeGrowthAboveX64A,\n )\n const feeGrowthInsideBX64 = wrappingSubU128(\n wrappingSubU128(poolState.feeGrowthGlobalX64B, feeGrowthBelowX64B),\n feeGrowthAboveX64B,\n )\n return { feeGrowthInsideX64A, feeGrowthInsideBX64 }\n }\n\n static GetPositionFees(\n ammPool: {\n tickCurrent: number,\n feeGrowthGlobalX64A: BN,\n feeGrowthGlobalX64B: BN,\n },\n positionState: {\n liquidity: BN\n feeGrowthInsideLastX64A: BN\n feeGrowthInsideLastX64B: BN\n tokenFeesOwedA: BN\n tokenFeesOwedB: BN\n },\n tickLowerState: ReturnType<typeof TickLayout.decode>,\n tickUpperState: ReturnType<typeof TickLayout.decode>,\n ): { tokenFeeAmountA: BN, tokenFeeAmountB: BN } {\n const { feeGrowthInsideX64A, feeGrowthInsideBX64 } = this.getfeeGrowthInside(\n ammPool,\n tickLowerState,\n tickUpperState,\n )\n\n const feeGrowthdeltaA = mulDivFloor(\n wrappingSubU128(feeGrowthInsideX64A, positionState.feeGrowthInsideLastX64A),\n positionState.liquidity,\n Q64,\n )\n const tokenFeeAmountA = positionState.tokenFeesOwedA.add(feeGrowthdeltaA)\n\n const feeGrowthdelta1 = mulDivFloor(\n wrappingSubU128(feeGrowthInsideBX64, positionState.feeGrowthInsideLastX64B),\n positionState.liquidity,\n Q64,\n )\n const tokenFeeAmountB = positionState.tokenFeesOwedB.add(feeGrowthdelta1)\n\n return { tokenFeeAmountA, tokenFeeAmountB }\n }\n\n static GetPositionRewards(\n ammPool: { tickCurrent: number, rewardInfos: { growthGlobalX64: BN }[] },\n positionState: { liquidity: BN, rewardInfos: { growthInsideLastX64: BN, rewardAmountOwed: BN }[] },\n tickLowerState: ReturnType<typeof TickLayout.decode>,\n tickUpperState: ReturnType<typeof TickLayout.decode>,\n ): BN[] {\n const rewards: BN[] = []\n\n const rewardGrowthsInside = this.getRewardGrowthInside(\n ammPool.tickCurrent,\n tickLowerState,\n tickUpperState,\n ammPool.rewardInfos,\n )\n for (let i = 0; i < rewardGrowthsInside.length; i++) {\n const rewardGrowthInside = rewardGrowthsInside[i]\n const currRewardInfo = positionState.rewardInfos[i]\n\n const rewardGrowthDelta = wrappingSubU128(rewardGrowthInside, currRewardInfo.growthInsideLastX64)\n const amountOwedDelta = mulDivFloor(rewardGrowthDelta, positionState.liquidity, Q64)\n const rewardAmountOwed = currRewardInfo.rewardAmountOwed.add(amountOwedDelta)\n rewards.push(rewardAmountOwed)\n }\n return rewards\n }\n\n static getRewardGrowthInside(\n tickCurrentIndex: number,\n tickLowerState: ReturnType<typeof TickLayout.decode>,\n tickUpperState: ReturnType<typeof TickLayout.decode>,\n rewardInfos: { growthGlobalX64: BN }[]\n ): BN[] {\n const rewardGrowthsInside: BN[] = []\n for (let i = 0; i < rewardInfos.length; i++) {\n let rewardGrowthsBelow = new BN(0)\n if (tickLowerState.liquidityGross.eqn(0)) {\n rewardGrowthsBelow = rewardInfos[i].growthGlobalX64\n } else if (tickCurrentIndex < tickLowerState.tick) {\n rewardGrowthsBelow = wrappingSubU128(rewardInfos[i].growthGlobalX64, tickLowerState.rewardGrowthsOutsideX64[i])\n } else {\n rewardGrowthsBelow = tickLowerState.rewardGrowthsOutsideX64[i]\n }\n\n let rewardGrowthsAbove = new BN(0)\n if (tickUpperState.liquidityGross.eqn(0)) {\n //\n } else if (tickCurrentIndex < tickUpperState.tick) {\n rewardGrowthsAbove = tickUpperState.rewardGrowthsOutsideX64[i]\n } else {\n rewardGrowthsAbove = wrappingSubU128(rewardInfos[i].growthGlobalX64, tickUpperState.rewardGrowthsOutsideX64[i])\n }\n\n rewardGrowthsInside.push(\n wrappingSubU128(\n wrappingSubU128(rewardInfos[i].growthGlobalX64, rewardGrowthsBelow),\n rewardGrowthsAbove,\n ),\n )\n }\n\n return rewardGrowthsInside\n }\n}\n","import BN from \"bn.js\";\n\nexport function u16ToBytes(num: number): Buffer {\n const buf = Buffer.alloc(2);\n buf.writeUInt16LE(num);\n return buf;\n}\n\nexport function u16ToBytesBE(num: number): Buffer {\n const buf = Buffer.alloc(2);\n buf.writeUInt16BE(num);\n return buf;\n}\n\nexport function i32ToBytes(num: number): Buffer {\n const buf = Buffer.alloc(4);\n buf.writeInt32LE(num);\n return buf;\n}\n\nexport function i32ToBytesBE(num: number): Buffer {\n const buf = Buffer.alloc(4);\n buf.writeInt32BE(num);\n return buf;\n}\n\nexport function u64ToBytes(num: BN | number | bigint): Buffer {\n if (typeof num === \"number\" || typeof num === \"bigint\") {\n num = new BN(num.toString());\n }\n return num.toArrayLike(Buffer, \"be\", 8);\n}\n\nexport function u8ToBytes(num: number): Uint8Array {\n const arr = new ArrayBuffer(1);\n const view = new DataView(arr);\n view.setUint8(0, num);\n return new Uint8Array(arr);\n}\n","import { u8ToBytes } from '@/raydium/clmm';\nimport { PublicKey } from '@solana/web3.js';\nimport BN from 'bn.js';\nimport { findProgramAddress, METADATA_PROGRAM_ID, ProgramAddress } from \"../../../common\";\nimport { i32ToBytes, i32ToBytesBE, u16ToBytes, u16ToBytesBE, u64ToBytes } from './utils';\n\nexport const AMM_CONFIG_SEED = Buffer.from('amm_config', 'utf8')\nexport const POOL_SEED = Buffer.from('pool', 'utf8')\nexport const POOL_VAULT_SEED = Buffer.from('pool_vault', 'utf8')\nexport const POOL_REWARD_VAULT_SEED = Buffer.from('pool_reward_vault', 'utf8')\nexport const POSITION_SEED = Buffer.from('position', 'utf8')\nexport const TICK_ARRAY_SEED = Buffer.from('tick_array', 'utf8')\nexport const OPERATION_SEED = Buffer.from('operation', 'utf8')\nexport const POOL_TICK_ARRAY_BITMAP_SEED = Buffer.from('pool_tick_array_bitmap_extension', 'utf8')\nexport const POOL_OBSERVATION_SEED = Buffer.from('observation', 'utf8')\nexport const SUPPORT_MINT_SEED = Buffer.from('support_mint', 'utf8')\nexport const DYNAMIC_FEE_CONFIG_SEED = Buffer.from('dynamic_fee_config', 'utf8')\nexport const PERMISSION_SEED = Buffer.from('permission', 'utf8')\n\n\nexport function getPdaAmmConfigId(programId: PublicKey, index: number): ProgramAddress {\n return findProgramAddress([AMM_CONFIG_SEED, u16ToBytesBE(index)], programId)\n}\n\nexport function getPdaPoolId(\n programId: PublicKey,\n ammConfigId: PublicKey,\n mintA: PublicKey,\n mintB: PublicKey\n): ProgramAddress {\n return findProgramAddress(\n [POOL_SEED, ammConfigId.toBuffer(), mintA.toBuffer(), mintB.toBuffer()],\n programId\n )\n}\n\nexport function getPdaPermission(programId: PublicKey, payer: PublicKey): ProgramAddress {\n return findProgramAddress([PERMISSION_SEED, payer.toBuffer()], programId)\n}\n\nexport function getPdaPermissionedPoolId(\n programId: PublicKey,\n ammConfigId: PublicKey,\n mintA: PublicKey,\n mintB: PublicKey,\n seedIndex: number\n): ProgramAddress {\n return findProgramAddress(\n [POOL_SEED, ammConfigId.toBuffer(), mintA.toBuffer(), mintB.toBuffer(), u16ToBytes(seedIndex)],\n programId\n )\n}\n\nexport function getPdaPoolVaultId(\n programId: PublicKey,\n poolId: PublicKey,\n vaultMint: PublicKey\n): ProgramAddress {\n return findProgramAddress(\n [POOL_VAULT_SEED, poolId.toBuffer(), vaultMint.toBuffer()],\n programId\n )\n}\n\nexport function getPdaPoolRewardVaultId(\n programId: PublicKey,\n poolId: PublicKey,\n rewardMint: PublicKey\n): ProgramAddress {\n return findProgramAddress(\n [POOL_REWARD_VAULT_SEED, poolId.toBuffer(), rewardMint.toBuffer()],\n programId\n )\n}\n\nexport function getPdaTickArrayAddress(\n programId: PublicKey,\n poolId: PublicKey,\n startIndex: number\n): ProgramAddress {\n return findProgramAddress(\n [TICK_ARRAY_SEED, poolId.toBuffer(), i32ToBytesBE(startIndex)],\n programId\n )\n}\n\nexport function getPdaProtocolPositionAddress(\n programId: PublicKey,\n poolId: PublicKey,\n tickLower: number,\n tickUpper: number\n): ProgramAddress {\n return findProgramAddress(\n [POSITION_SEED, poolId.toBuffer(), i32ToBytes(tickLower), i32ToBytes(tickUpper)],\n programId\n )\n}\n\nexport function getPdaPersonalPositionAddress(\n programId: PublicKey,\n nftMint: PublicKey\n): ProgramAddress {\n return findProgramAddress([POSITION_SEED, nftMint.toBuffer()], programId)\n}\n\nexport function getPdaMetadataKey(mint: PublicKey): ProgramAddress {\n return findProgramAddress(\n [\n Buffer.from('metadata', 'utf8'),\n METADATA_PROGRAM_ID.toBuffer(),\n mint.toBuffer(),\n ],\n METADATA_PROGRAM_ID\n )\n}\n\nexport function getPdaOperationAccount(programId: PublicKey): ProgramAddress {\n return findProgramAddress([OPERATION_SEED], programId)\n}\n\nexport function getPdaExBitmapAccount(\n programId: PublicKey,\n poolId: PublicKey\n): ProgramAddress {\n return findProgramAddress([POOL_TICK_ARRAY_BITMAP_SEED, poolId.toBuffer()], programId)\n}\n\nexport function getPdaObservationAccount(\n programId: PublicKey,\n poolId: PublicKey\n): ProgramAddress {\n return findProgramAddress([POOL_OBSERVATION_SEED, poolId.toBuffer()], programId)\n}\n\nexport function getPdaMintExAccount(\n programId: PublicKey,\n mintAddress: PublicKey\n): ProgramAddress {\n return findProgramAddress([SUPPORT_MINT_SEED, mintAddress.toBuffer()], programId)\n}\n\nexport function getPdaLimitOrderAddress(\n programId: PublicKey,\n payer: PublicKey,\n limitOrderNonce: PublicKey,\n orderNonce: BN,\n): ProgramAddress {\n return findProgramAddress(\n [\n payer.toBuffer(),\n limitOrderNonce.toBuffer(),\n u64ToBytes(orderNonce),\n ],\n programId\n )\n}\n\nexport function getPdaDynamicFeeConfigAddress(\n programId: PublicKey,\n index: number\n): ProgramAddress {\n return findProgramAddress(\n [DYNAMIC_FEE_CONFIG_SEED, u16ToBytesBE(index)],\n programId\n )\n}\n\nexport function getPdaLimitOrderNonceAddress(\n programId: PublicKey,\n wallet: PublicKey,\n index: number\n): ProgramAddress {\n return findProgramAddress(\n [wallet.toBuffer(), u8ToBytes(index)],\n programId\n )\n}\n\n\nexport const POOL_LOCK_ID_SEED = Buffer.from(\"locked_position\", \"utf8\");\nexport function getPdaLockPositionId(\n programId: PublicKey,\n positionId: PublicKey,\n): ProgramAddress {\n return findProgramAddress([POOL_LOCK_ID_SEED, positionId.toBuffer()], programId);\n}\n\nexport function getPdaLockClPositionIdV2(\n programId: PublicKey,\n lockNftMint: PublicKey,\n): ProgramAddress {\n return findProgramAddress([POOL_LOCK_ID_SEED, lockNftMint.toBuffer()], programId);\n}","import BN from \"bn.js\";\nimport { SerumVersion } from \"../serum\";\n\nexport const LIQUIDITY_FEES_NUMERATOR = new BN(25);\nexport const LIQUIDITY_FEES_DENOMINATOR = new BN(10000);\n\n// liquidity version => serum version\nexport const LIQUIDITY_VERSION_TO_SERUM_VERSION: {\n [key in 4 | 5]?: SerumVersion;\n} = {\n 4: 3,\n 5: 3,\n};\n\n// mainnet only\nexport const poolLpAuthority = new Set([\n \"5Q544fKrFoe6tsEbD7S8EmxGTJYAKtTVhAW5Q5pge4j1\",\n \"3uaZBfHPfmpAHW7dsimC1SnyR61X4bJqQZKWmRSCXJxv\",\n \"GpMZbSM2GgvTKHJirzeGfMFoaZ8UR2X7F4v8vHTvxFbL\",\n]);\n","import { ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_PROGRAM_ID } from \"@solana/spl-token\";\nimport { PublicKey, SystemProgram, SYSVAR_RENT_PUBKEY, TransactionInstruction } from \"@solana/web3.js\";\n\nimport { AmmV4Keys, AmmV5Keys } from \"@/api/type\";\nimport { MODEL_DATA_PUBKEY, parseBigNumberish } from \"@/common\";\nimport { createLogger } from \"@/common/logger\";\nimport { accountMeta, RENT_PROGRAM_ID } from \"@/common/pubKey\";\nimport { InstructionType } from \"@/common/txTool/txType\";\nimport { struct, u64, u8 } from \"@/marshmallow\";\n\nimport { jsonInfo2PoolKeys } from \"@/common/utility\";\nimport BN from \"bn.js\";\nimport { BN_ONE, BN_ZERO } from \"../clmm\";\nimport { InstructionReturn } from \"../type\";\nimport {\n addLiquidityLayout,\n fixedSwapInLayout,\n fixedSwapOutLayout,\n initPoolLayout,\n removeLiquidityLayout,\n} from \"./layout\";\nimport {\n InitPoolInstructionParamsV4,\n LiquidityAddInstructionParams,\n RemoveLiquidityInstruction,\n SwapFixedInInstructionParamsV4,\n SwapFixedOutInstructionParamsV4,\n SwapInstructionParams,\n} from \"./type\";\n\nconst logger = createLogger(\"Raydium_liquidity_instruction\");\nexport function makeAddLiquidityInstruction(params: LiquidityAddInstructionParams): TransactionInstruction {\n const {\n poolInfo,\n poolKeys,\n userKeys,\n baseAmountIn,\n quoteAmountIn,\n fixedSide,\n otherAmountMin,\n modelDataPubKey = MODEL_DATA_PUBKEY,\n } = params;\n\n const data = Buffer.alloc(addLiquidityLayout.span);\n addLiquidityLayout.encode(\n {\n instruction: 3,\n baseAmountIn: parseBigNumberish(baseAmountIn),\n quoteAmountIn: parseBigNumberish(quoteAmountIn),\n otherAmountMin: parseBigNumberish(otherAmountMin),\n fixedSide: fixedSide === \"base\" ? BN_ZERO : BN_ONE,\n },\n data,\n );\n\n const keys = [\n accountMeta({ pubkey: TOKEN_PROGRAM_ID, isWritable: false }),\n // amm\n accountMeta({ pubkey: new PublicKey(poolInfo.id) }),\n accountMeta({ pubkey: new PublicKey(poolKeys.authority), isWritable: false }),\n accountMeta({ pubkey: new PublicKey(poolKeys.openOrders), isWritable: false }),\n accountMeta({ pubkey: new PublicKey(poolKeys.targetOrders) }),\n accountMeta({ pubkey: new PublicKey(poolInfo.lpMint.address) }),\n accountMeta({ pubkey: new PublicKey(poolKeys.vault.A) }),\n accountMeta({ pubkey: new PublicKey(poolKeys.vault.B) }),\n ];\n\n if (poolInfo.pooltype.includes(\"StablePool\")) {\n keys.push(accountMeta({ pubkey: modelDataPubKey }));\n }\n\n keys.push(\n // serum\n accountMeta({ pubkey: new PublicKey(poolInfo.marketId), isWritable: false }),\n // user\n accountMeta({ pubkey: userKeys.baseTokenAccount }),\n accountMeta({ pubkey: userKeys.quoteTokenAccount }),\n accountMeta({ pubkey: userKeys.lpTokenAccount }),\n accountMeta({ pubkey: userKeys.owner, isWritable: false, isSigner: true }),\n accountMeta({ pubkey: new PublicKey(poolKeys.marketEventQueue), isWritable: false }),\n );\n\n return new TransactionInstruction({\n programId: new PublicKey(poolInfo.programId),\n keys,\n data,\n });\n}\n\nexport function removeLiquidityInstruction(params: RemoveLiquidityInstruction): TransactionInstruction {\n const {\n poolInfo,\n poolKeys: poolKeyProps,\n userKeys,\n lpAmount,\n baseAmountMin,\n quoteAmountMin,\n modelDataPubKey = MODEL_DATA_PUBKEY,\n } = params;\n const poolKeys = jsonInfo2PoolKeys(poolKeyProps);\n\n let version = 4;\n if (poolInfo.pooltype.includes(\"StablePool\")) version = 5;\n\n if (version === 4 || version === 5) {\n const data = Buffer.alloc(removeLiquidityLayout.span);\n removeLiquidityLayout.encode(\n {\n instruction: 4,\n lpAmount: parseBigNumberish(lpAmount),\n baseAmountMin: parseBigNumberish(baseAmountMin),\n quoteAmountMin: parseBigNumberish(quoteAmountMin),\n },\n data,\n );\n\n const keys = [\n // system\n accountMeta({ pubkey: TOKEN_PROGRAM_ID, isWritable: false }),\n // amm\n accountMeta({ pubkey: poolKeys.id }),\n accountMeta({ pubkey: poolKeys.authority, isWritable: false }),\n accountMeta({ pubkey: poolKeys.openOrders }),\n accountMeta({ pubkey: poolKeys.targetOrders }),\n accountMeta({ pubkey: poolKeys.mintLp.address }),\n accountMeta({ pubkey: poolKeys.vault.A }),\n accountMeta({ pubkey: poolKeys.vault.B }),\n ];\n\n if (version === 5) {\n keys.push(accountMeta({ pubkey: modelDataPubKey }));\n } else {\n keys.push(accountMeta({ pubkey: poolKeys.id }));\n keys.push(accountMeta({ pubkey: poolKeys.id }));\n }\n\n keys.push(\n // serum\n accountMeta({ pubkey: poolKeys.marketProgramId, isWritable: false }),\n accountMeta({ pubkey: poolKeys.marketId }),\n accountMeta({ pubkey: poolKeys.marketBaseVault }),\n accountMeta({ pubkey: poolKeys.marketQuoteVault }),\n accountMeta({ pubkey: poolKeys.marketAuthority, isWritable: false }),\n // user\n accountMeta({ pubkey: userKeys.lpTokenAccount }),\n accountMeta({ pubkey: userKeys.baseTokenAccount }),\n accountMeta({ pubkey: userKeys.quoteTokenAccount }),\n accountMeta({ pubkey: userKeys.owner, isWritable: false, isSigner: true }),\n // serum orderbook\n accountMeta({ pubkey: poolKeys.marketEventQueue }),\n accountMeta({ pubkey: poolKeys.marketBids }),\n accountMeta({ pubkey: poolKeys.marketAsks }),\n );\n\n return new TransactionInstruction({\n programId: poolKeys.programId,\n keys,\n data,\n });\n }\n\n // logger.logWithError(\"invalid version\", \"poolKeys.version\", version);\n return new TransactionInstruction({ programId: poolKeys.programId, keys: [] }); // won't reach\n}\n\nexport function createPoolV4InstructionV2({\n programId,\n ammId,\n ammAuthority,\n ammOpenOrders,\n lpMint,\n coinMint,\n pcMint,\n coinVault,\n pcVault,\n withdrawQueue,\n ammTargetOrders,\n poolTempLp,\n marketProgramId,\n marketId,\n userWallet,\n userCoinVault,\n userPcVault,\n userLpVault,\n nonce,\n openTime,\n coinAmount,\n pcAmount,\n ammConfigId,\n feeDestinationId,\n}: {\n programId: PublicKey;\n ammId: PublicKey;\n ammAuthority: PublicKey;\n ammOpenOrders: PublicKey;\n lpMint: PublicKey;\n coinMint: PublicKey;\n pcMint: PublicKey;\n coinVault: PublicKey;\n pcVault: PublicKey;\n withdrawQueue: PublicKey;\n ammTargetOrders: PublicKey;\n poolTempLp: PublicKey;\n marketProgramId: PublicKey;\n marketId: PublicKey;\n userWallet: PublicKey;\n userCoinVault: PublicKey;\n userPcVault: PublicKey;\n userLpVault: PublicKey;\n ammConfigId: PublicKey;\n feeDestinationId: PublicKey;\n\n nonce: number;\n openTime: BN;\n coinAmount: BN;\n pcAmount: BN;\n}): InstructionReturn {\n const dataLayout = struct([u8(\"instruction\"), u8(\"nonce\"), u64(\"openTime\"), u64(\"pcAmount\"), u64(\"coinAmount\")]);\n\n const keys = [\n { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },\n { pubkey: RENT_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: ammId, isSigner: false, isWritable: true },\n { pubkey: ammAuthority, isSigner: false, isWritable: false },\n { pubkey: ammOpenOrders, isSigner: false, isWritable: true },\n { pubkey: lpMint, isSigner: false, isWritable: true },\n { pubkey: coinMint, isSigner: false, isWritable: false },\n { pubkey: pcMint, isSigner: false, isWritable: false },\n { pubkey: coinVault, isSigner: false, isWritable: true },\n { pubkey: pcVault, isSigner: false, isWritable: true }, //12\n { pubkey: ammTargetOrders, isSigner: false, isWritable: true }, //13\n { pubkey: ammConfigId, isSigner: false, isWritable: false },\n { pubkey: feeDestinationId, isSigner: false, isWritable: true },\n { pubkey: marketProgramId, isSigner: false, isWritable: false },\n { pubkey: marketId, isSigner: false, isWritable: false },\n { pubkey: userWallet, isSigner: true, isWritable: true },\n { pubkey: userCoinVault, isSigner: false, isWritable: true },\n { pubkey: userPcVault, isSigner: false, isWritable: true },\n { pubkey: userLpVault, isSigner: false, isWritable: true },\n ];\n\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode({ instruction: 1, nonce, openTime, coinAmount, pcAmount }, data);\n\n return {\n instruction: new TransactionInstruction({\n keys,\n programId,\n data,\n }),\n instructionType: InstructionType.AmmV4CreatePool,\n };\n}\n\nexport function simulatePoolInfoInstruction(poolKeys: AmmV4Keys | AmmV5Keys): TransactionInstruction {\n const simulatePoolLayout = struct([u8(\"instruction\"), u8(\"simulateType\")]);\n const data = Buffer.alloc(simulatePoolLayout.span);\n simulatePoolLayout.encode(\n {\n instruction: 12,\n simulateType: 0,\n },\n data,\n );\n\n const keys = [\n // amm\n accountMeta({ pubkey: new PublicKey(poolKeys.id), isWritable: false }),\n accountMeta({ pubkey: new PublicKey(poolKeys.authority), isWritable: false }),\n accountMeta({ pubkey: new PublicKey(poolKeys.openOrders), isWritable: false }),\n accountMeta({ pubkey: new PublicKey(poolKeys.vault.A), isWritable: false }),\n accountMeta({ pubkey: new PublicKey(poolKeys.vault.B), isWritable: false }),\n accountMeta({ pubkey: new PublicKey(poolKeys.mintLp.address), isWritable: false }),\n // serum\n accountMeta({ pubkey: new PublicKey(poolKeys.marketId), isWritable: false }),\n accountMeta({ pubkey: new PublicKey(poolKeys.marketEventQueue), isWritable: false }),\n ];\n\n return new TransactionInstruction({\n programId: new PublicKey(poolKeys.programId),\n keys,\n data,\n });\n}\n\nexport function makeSwapFixedInInstruction(\n {\n poolKeys: propPoolKeys,\n userKeys,\n amountIn,\n minAmountOut,\n modelDataPubKey = MODEL_DATA_PUBKEY,\n }: SwapFixedInInstructionParamsV4,\n version: number,\n): TransactionInstruction {\n const poolKeys = jsonInfo2PoolKeys(propPoolKeys);\n const data = Buffer.alloc(fixedSwapInLayout.span);\n fixedSwapInLayout.encode(\n {\n instruction: 9,\n amountIn: parseBigNumberish(amountIn),\n minAmountOut: parseBigNumberish(minAmountOut),\n },\n data,\n );\n const keys = [\n // amm\n accountMeta({ pubkey: TOKEN_PROGRAM_ID, isWritable: false }),\n accountMeta({ pubkey: poolKeys.id }),\n accountMeta({ pubkey: poolKeys.authority, isWritable: false }),\n accountMeta({ pubkey: poolKeys.openOrders }),\n ];\n\n if (version === 4) keys.push(accountMeta({ pubkey: poolKeys.targetOrders }));\n keys.push(accountMeta({ pubkey: poolKeys.vault.A }), accountMeta({ pubkey: poolKeys.vault.B }));\n if (version === 5) keys.push(accountMeta({ pubkey: modelDataPubKey }));\n keys.push(\n // serum\n accountMeta({ pubkey: poolKeys.marketProgramId, isWritable: false }),\n accountMeta({ pubkey: poolKeys.marketId }),\n accountMeta({ pubkey: poolKeys.marketBids }),\n accountMeta({ pubkey: poolKeys.marketAsks }),\n accountMeta({ pubkey: poolKeys.marketEventQueue }),\n accountMeta({ pubkey: poolKeys.marketBaseVault }),\n accountMeta({ pubkey: poolKeys.marketQuoteVault }),\n accountMeta({ pubkey: poolKeys.marketAuthority, isWritable: false }),\n // user\n accountMeta({ pubkey: userKeys.tokenAccountIn }),\n accountMeta({ pubkey: userKeys.tokenAccountOut }),\n accountMeta({ pubkey: userKeys.owner, isWritable: false, isSigner: true }),\n );\n\n return new TransactionInstruction({\n programId: poolKeys.programId,\n keys,\n data,\n });\n}\n\nexport function makeSwapFixedOutInstruction(\n {\n poolKeys: propPoolKeys,\n userKeys,\n maxAmountIn,\n amountOut,\n modelDataPubKey = MODEL_DATA_PUBKEY,\n }: SwapFixedOutInstructionParamsV4,\n version: number,\n): TransactionInstruction {\n const poolKeys = jsonInfo2PoolKeys(propPoolKeys);\n const data = Buffer.alloc(fixedSwapOutLayout.span);\n fixedSwapOutLayout.encode(\n {\n instruction: 11,\n maxAmountIn: parseBigNumberish(maxAmountIn),\n amountOut: parseBigNumberish(amountOut),\n },\n data,\n );\n\n const keys = [\n accountMeta({ pubkey: TOKEN_PROGRAM_ID, isWritable: false }),\n // amm\n accountMeta({ pubkey: poolKeys.id }),\n accountMeta({ pubkey: poolKeys.authority, isWritable: false }),\n accountMeta({ pubkey: poolKeys.openOrders }),\n accountMeta({ pubkey: poolKeys.targetOrders }),\n accountMeta({ pubkey: poolKeys.vault.A }),\n accountMeta({ pubkey: poolKeys.vault.B }),\n ];\n\n if (version === 5) keys.push(accountMeta({ pubkey: modelDataPubKey }));\n\n keys.push(\n // serum\n accountMeta({ pubkey: poolKeys.marketProgramId, isWritable: false }),\n accountMeta({ pubkey: poolKeys.marketId }),\n accountMeta({ pubkey: poolKeys.marketBids }),\n accountMeta({ pubkey: poolKeys.marketAsks }),\n accountMeta({ pubkey: poolKeys.marketEventQueue }),\n accountMeta({ pubkey: poolKeys.marketBaseVault }),\n accountMeta({ pubkey: poolKeys.marketQuoteVault }),\n accountMeta({ pubkey: poolKeys.marketAuthority, isWritable: false }),\n accountMeta({ pubkey: userKeys.tokenAccountIn }),\n accountMeta({ pubkey: userKeys.tokenAccountOut }),\n accountMeta({ pubkey: userKeys.owner, isWritable: false, isSigner: true }),\n );\n\n return new TransactionInstruction({\n programId: poolKeys.programId,\n keys,\n data,\n });\n}\n\nexport function swapBaseInV2Instruction(\n programId: PublicKey,\n poolId: PublicKey,\n auth: PublicKey,\n vaultA: PublicKey,\n vaultB: PublicKey,\n ownerTokenIn: PublicKey,\n ownerTokenOut: PublicKey,\n owner: PublicKey,\n amountIn: BN,\n minAmountOut: BN,\n): TransactionInstruction {\n const dataLayout = struct([u8(\"instructionId\"), u64(\"amountIn\"), u64(\"minAmountOut\")]);\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode(\n {\n instructionId: 16,\n amountIn,\n minAmountOut,\n },\n data,\n );\n const keys = [\n // amm\n { pubkey: TOKEN_PROGRAM_ID, isWritable: false, isSigner: false },\n { pubkey: poolId, isWritable: true, isSigner: false },\n { pubkey: auth, isWritable: false, isSigner: false },\n { pubkey: vaultA, isWritable: true, isSigner: false },\n { pubkey: vaultB, isWritable: true, isSigner: false },\n { pubkey: ownerTokenIn, isWritable: true, isSigner: false },\n { pubkey: ownerTokenOut, isWritable: true, isSigner: false },\n { pubkey: owner, isWritable: false, isSigner: true },\n ];\n return new TransactionInstruction({\n programId,\n keys,\n data,\n });\n}\nexport function swapBaseOutV2Instruction(\n programId: PublicKey,\n poolId: PublicKey,\n auth: PublicKey,\n vaultA: PublicKey,\n vaultB: PublicKey,\n ownerTokenIn: PublicKey,\n ownerTokenOut: PublicKey,\n onwer: PublicKey,\n maxAmountIn: BN,\n amountOut: BN,\n): TransactionInstruction {\n const dataLayout = struct([u8(\"instructionId\"), u64(\"maxAmountIn\"), u64(\"amountOut\")]);\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode(\n {\n instructionId: 17,\n maxAmountIn,\n amountOut,\n },\n data,\n );\n const keys = [\n { pubkey: TOKEN_PROGRAM_ID, isWritable: false, isSigner: false },\n { pubkey: poolId, isWritable: true, isSigner: false },\n { pubkey: auth, isWritable: false, isSigner: false },\n { pubkey: vaultA, isWritable: true, isSigner: false },\n { pubkey: vaultB, isWritable: true, isSigner: false },\n // user\n { pubkey: ownerTokenIn, isWritable: true, isSigner: false },\n { pubkey: ownerTokenOut, isWritable: true, isSigner: false },\n { pubkey: onwer, isWritable: false, isSigner: true },\n ];\n return new TransactionInstruction({\n programId,\n keys,\n data,\n });\n}\n\nexport function makeAMMSwapV2Instruction(params: SwapInstructionParams): TransactionInstruction {\n const { poolKeys, version, userKeys, amountIn, amountOut, fixedSide } = params;\n if (version === 4) {\n if (fixedSide === \"in\") {\n return swapBaseInV2Instruction(\n new PublicKey(poolKeys.programId),\n new PublicKey(poolKeys.id),\n new PublicKey(poolKeys.authority),\n new PublicKey(poolKeys.vault.A),\n new PublicKey(poolKeys.vault.B),\n userKeys.tokenAccountIn,\n userKeys.tokenAccountOut,\n userKeys.owner,\n new BN(amountIn.toString()),\n new BN(amountOut.toString()),\n );\n } else if (fixedSide === \"out\") {\n return swapBaseOutV2Instruction(\n new PublicKey(poolKeys.programId),\n new PublicKey(poolKeys.id),\n new PublicKey(poolKeys.authority),\n new PublicKey(poolKeys.vault.A),\n new PublicKey(poolKeys.vault.B),\n userKeys.tokenAccountIn,\n userKeys.tokenAccountOut,\n userKeys.owner,\n new BN(amountIn.toString()),\n new BN(amountOut.toString()),\n );\n }\n logger.logWithError(\"invalid params\", \"params\", params);\n }\n\n logger.logWithError(\"invalid version, only support pool v4\", \"poolKeys.version\", version);\n throw new Error(\"invalid version\");\n}\n\nexport function makeAMMSwapInstruction(params: SwapInstructionParams): TransactionInstruction {\n const { poolKeys, version, userKeys, amountIn, amountOut, fixedSide } = params;\n if (version === 4 || version === 5) {\n const props = { poolKeys, userKeys };\n if (fixedSide === \"in\") {\n return makeSwapFixedInInstruction(\n {\n ...props,\n amountIn,\n minAmountOut: amountOut,\n },\n version,\n );\n } else if (fixedSide === \"out\") {\n return makeSwapFixedOutInstruction(\n {\n ...props,\n maxAmountIn: amountIn,\n amountOut,\n },\n version,\n );\n }\n logger.logWithError(\"invalid params\", \"params\", params);\n }\n\n logger.logWithError(\"invalid version\", \"poolKeys.version\", version);\n throw new Error(\"invalid version\");\n}\n\nexport function makeInitPoolInstructionV4({\n poolKeys: propPoolKeys,\n userKeys,\n startTime,\n}: InitPoolInstructionParamsV4): TransactionInstruction {\n const data = Buffer.alloc(initPoolLayout.span);\n initPoolLayout.encode(\n {\n instruction: 0,\n // nonce: poolKeys.nonce, // to do fix\n nonce: 5,\n startTime: parseBigNumberish(startTime),\n },\n data,\n );\n const poolKeys = jsonInfo2PoolKeys(propPoolKeys);\n\n const keys = [\n // system\n accountMeta({ pubkey: TOKEN_PROGRAM_ID, isWritable: false }),\n accountMeta({ pubkey: SystemProgram.programId, isWritable: false }),\n accountMeta({ pubkey: SYSVAR_RENT_PUBKEY, isWritable: false }),\n // amm\n accountMeta({ pubkey: poolKeys.id }),\n accountMeta({ pubkey: poolKeys.authority, isWritable: false }),\n accountMeta({ pubkey: poolKeys.openOrders }),\n accountMeta({ pubkey: poolKeys.mintLp.address }),\n accountMeta({ pubkey: poolKeys.mintA.address, isWritable: false }),\n accountMeta({ pubkey: poolKeys.mintB.address, isWritable: false }),\n accountMeta({ pubkey: poolKeys.vault.A, isWritable: false }),\n accountMeta({ pubkey: poolKeys.vault.B, isWritable: false }),\n accountMeta({ pubkey: poolKeys.id }),\n accountMeta({ pubkey: poolKeys.targetOrders }),\n accountMeta({ pubkey: userKeys.lpTokenAccount }),\n accountMeta({ pubkey: poolKeys.id, isWritable: false }),\n // serum\n accountMeta({ pubkey: poolKeys.marketProgramId, isWritable: false }),\n accountMeta({ pubkey: poolKeys.marketId, isWritable: false }),\n // user\n accountMeta({ pubkey: userKeys.payer, isSigner: true }),\n ];\n\n return new TransactionInstruction({\n programId: poolKeys.programId,\n keys,\n data,\n });\n}\n","import { GetStructureSchema, publicKey, seq, struct, u128, u64, u8 } from \"../../marshmallow\";\n\nexport const fixedSwapInLayout = struct([u8(\"instruction\"), u64(\"amountIn\"), u64(\"minAmountOut\")]);\nexport const fixedSwapOutLayout = struct([u8(\"instruction\"), u64(\"maxAmountIn\"), u64(\"amountOut\")]);\n\nexport const createPoolV4Layout = struct([u8(\"instruction\"), u8(\"nonce\")]);\nexport const initPoolLayout = struct([u8(\"instruction\"), u8(\"nonce\"), u64(\"startTime\")]);\n/* ================= state layouts ================= */\nexport const liquidityStateV4Layout = struct([\n u64(\"status\"),\n u64(\"nonce\"),\n u64(\"maxOrder\"),\n u64(\"depth\"),\n u64(\"baseDecimal\"),\n u64(\"quoteDecimal\"),\n u64(\"state\"),\n u64(\"resetFlag\"),\n u64(\"minSize\"),\n u64(\"volMaxCutRatio\"),\n u64(\"amountWaveRatio\"),\n u64(\"baseLotSize\"),\n u64(\"quoteLotSize\"),\n u64(\"minPriceMultiplier\"),\n u64(\"maxPriceMultiplier\"),\n u64(\"systemDecimalValue\"),\n u64(\"minSeparateNumerator\"),\n u64(\"minSeparateDenominator\"),\n u64(\"tradeFeeNumerator\"),\n u64(\"tradeFeeDenominator\"),\n u64(\"pnlNumerator\"),\n u64(\"pnlDenominator\"),\n u64(\"swapFeeNumerator\"),\n u64(\"swapFeeDenominator\"),\n u64(\"baseNeedTakePnl\"),\n u64(\"quoteNeedTakePnl\"),\n u64(\"quoteTotalPnl\"),\n u64(\"baseTotalPnl\"),\n u64(\"poolOpenTime\"),\n u64(\"punishPcAmount\"),\n u64(\"punishCoinAmount\"),\n u64(\"orderbookToInitTime\"),\n // u128('poolTotalDepositPc'),\n // u128('poolTotalDepositCoin'),\n u128(\"swapBaseInAmount\"),\n u128(\"swapQuoteOutAmount\"),\n u64(\"swapBase2QuoteFee\"),\n u128(\"swapQuoteInAmount\"),\n u128(\"swapBaseOutAmount\"),\n u64(\"swapQuote2BaseFee\"),\n // amm vault\n publicKey(\"baseVault\"),\n publicKey(\"quoteVault\"),\n // mint\n publicKey(\"baseMint\"),\n publicKey(\"quoteMint\"),\n publicKey(\"lpMint\"),\n // market\n publicKey(\"openOrders\"),\n publicKey(\"marketId\"),\n publicKey(\"marketProgramId\"),\n publicKey(\"targetOrders\"),\n publicKey(\"withdrawQueue\"),\n publicKey(\"lpVault\"),\n publicKey(\"owner\"),\n // true circulating supply without lock up\n u64(\"lpReserve\"),\n seq(u64(), 3, \"padding\"),\n]);\n\nexport type LiquidityStateLayoutV4 = typeof liquidityStateV4Layout;\nexport type LiquidityStateV4 = GetStructureSchema<LiquidityStateLayoutV4>;\n\nexport const liquidityStateV5Layout = struct([\n u64(\"accountType\"),\n u64(\"status\"),\n u64(\"nonce\"),\n u64(\"maxOrder\"),\n u64(\"depth\"),\n u64(\"baseDecimal\"),\n u64(\"quoteDecimal\"),\n u64(\"state\"),\n u64(\"resetFlag\"),\n u64(\"minSize\"),\n u64(\"volMaxCutRatio\"),\n u64(\"amountWaveRatio\"),\n u64(\"baseLotSize\"),\n u64(\"quoteLotSize\"),\n u64(\"minPriceMultiplier\"),\n u64(\"maxPriceMultiplier\"),\n u64(\"systemDecimalsValue\"),\n u64(\"abortTradeFactor\"),\n u64(\"priceTickMultiplier\"),\n u64(\"priceTick\"),\n // Fees\n u64(\"minSeparateNumerator\"),\n u64(\"minSeparateDenominator\"),\n u64(\"tradeFeeNumerator\"),\n u64(\"tradeFeeDenominator\"),\n u64(\"pnlNumerator\"),\n u64(\"pnlDenominator\"),\n u64(\"swapFeeNumerator\"),\n u64(\"swapFeeDenominator\"),\n // OutPutData\n u64(\"baseNeedTakePnl\"),\n u64(\"quoteNeedTakePnl\"),\n u64(\"quoteTotalPnl\"),\n u64(\"baseTotalPnl\"),\n u64(\"poolOpenTime\"),\n u64(\"punishPcAmount\"),\n u64(\"punishCoinAmount\"),\n u64(\"orderbookToInitTime\"),\n u128(\"swapBaseInAmount\"),\n u128(\"swapQuoteOutAmount\"),\n u128(\"swapQuoteInAmount\"),\n u128(\"swapBaseOutAmount\"),\n u64(\"swapQuote2BaseFee\"),\n u64(\"swapBase2QuoteFee\"),\n\n publicKey(\"baseVault\"),\n publicKey(\"quoteVault\"),\n publicKey(\"baseMint\"),\n publicKey(\"quoteMint\"),\n publicKey(\"lpMint\"),\n\n publicKey(\"modelDataAccount\"),\n publicKey(\"openOrders\"),\n publicKey(\"marketId\"),\n publicKey(\"marketProgramId\"),\n publicKey(\"targetOrders\"),\n publicKey(\"owner\"),\n seq(u64(), 64, \"padding\"),\n]);\n\nexport const addLiquidityLayout = struct([\n u8(\"instruction\"),\n u64(\"baseAmountIn\"),\n u64(\"quoteAmountIn\"),\n u64(\"fixedSide\"),\n u64(\"otherAmountMin\"),\n]);\n\nexport const removeLiquidityLayout = struct([\n u8(\"instruction\"),\n u64(\"lpAmount\"),\n u64(\"baseAmountMin\"),\n u64(\"quoteAmountMin\"),\n]);\n\nexport type LiquidityStateLayoutV5 = typeof liquidityStateV5Layout;\nexport type LiquidityStateV5 = GetStructureSchema<LiquidityStateLayoutV5>;\n\nexport type LiquidityState = LiquidityStateV4 | LiquidityStateV5;\nexport type LiquidityStateLayout = LiquidityStateLayoutV4 | LiquidityStateLayoutV5;\n\n/* ================= index ================= */\n// version => liquidity state layout\nexport const LIQUIDITY_VERSION_TO_STATE_LAYOUT: {\n [version: number]: LiquidityStateLayout;\n} = {\n 4: liquidityStateV4Layout,\n 5: liquidityStateV5Layout,\n};\nexport const createPoolFeeLayout = struct([u64(\"fee\")]);\n","import { Connection, PublicKey } from \"@solana/web3.js\";\n\nimport { seq, struct, u64 } from \"../../marshmallow\";\nimport { MODEL_DATA_PUBKEY } from \"@/common\";\n\nconst ELEMENT_SIZE = 50000;\n\nexport const DataElement = struct([u64(\"x\"), u64(\"y\"), u64(\"price\")]);\n\nexport const modelDataInfoLayout = struct([\n u64(\"accountType\"),\n u64(\"status\"),\n u64(\"multiplier\"),\n u64(\"validDataCount\"),\n seq(DataElement, ELEMENT_SIZE, \"DataElement\"),\n]);\n\nexport interface StableModelLayout {\n accountType: number;\n status: number;\n multiplier: number;\n validDataCount: number;\n DataElement: { x: number; y: number; price: number }[];\n}\n\nfunction estimateRangeByXyReal(_xReal: number, _yReal: number): number[] {\n return [0, ELEMENT_SIZE - 2];\n}\n\nfunction estimateRangeByX(_x: number): number[] {\n return [0, ELEMENT_SIZE - 2];\n}\n\nfunction estimateRangeByY(_y: number): number[] {\n return [0, ELEMENT_SIZE - 2];\n}\n\nfunction getMininumRangeByXyReal(\n layoutData: StableModelLayout,\n xReal: number,\n yReal: number,\n): [number, number, boolean] {\n const [min, max] = estimateRangeByXyReal(xReal, yReal);\n let minRangeIdx = min;\n let maxRangeIdx = max;\n let mid = 0;\n const target = (xReal * layoutData.multiplier) / yReal;\n while (minRangeIdx <= maxRangeIdx) {\n mid = Math.floor((maxRangeIdx + minRangeIdx) / 2);\n if (mid === 0 || mid >= ELEMENT_SIZE - 2) {\n return [mid, mid, false];\n }\n const cur = (layoutData.DataElement[mid].x * layoutData.multiplier) / layoutData.DataElement[mid].y;\n const left = (layoutData.DataElement[mid - 1].x * layoutData.multiplier) / layoutData.DataElement[mid - 1].y;\n const right = (layoutData.DataElement[mid + 1].x * layoutData.multiplier) / layoutData.DataElement[mid + 1].y;\n\n if (target === cur) {\n return [mid, mid, true];\n } else if (target === left) {\n return [mid - 1, mid - 1, true];\n } else if (target === right) {\n return [mid + 1, mid + 1, true];\n } else if (target < left) {\n maxRangeIdx = mid - 1;\n } else if (target > left && target < cur) {\n return [mid - 1, mid, true];\n } else if (target > cur && target < right) {\n return [mid, mid + 1, true];\n } else {\n minRangeIdx = mid + 1;\n }\n }\n return [mid, mid, false];\n}\nfunction getRatio(layoutData: StableModelLayout, xReal: number, yReal: number): number {\n const [minRangeIdx, maxRangeIdx, find] = getMininumRangeByXyReal(layoutData, xReal, yReal);\n\n if (!find) {\n return 0;\n }\n\n if (minRangeIdx === maxRangeIdx) {\n const x = layoutData.DataElement[minRangeIdx].x;\n const ratio = (xReal * layoutData.multiplier) / x;\n return ratio;\n } else {\n const x1 = layoutData.DataElement[minRangeIdx].x;\n const y1 = layoutData.DataElement[minRangeIdx].y;\n const x2 = layoutData.DataElement[maxRangeIdx].x;\n const y2 = layoutData.DataElement[maxRangeIdx].y;\n\n const xDenominator = yReal * (x2 * y1 - x1 * y2);\n const xNumerator1 = x1 * xDenominator;\n const xNumerator2 = (x2 - x1) * (xReal * y1 - x1 * yReal) * y2;\n\n const xNumerator = xNumerator1 + xNumerator2;\n const ratio = (xReal * layoutData.multiplier * xDenominator) / xNumerator;\n return ratio;\n }\n}\n\nfunction realToTable(layoutData: StableModelLayout, realValue: number, ratio: number): number {\n return (realValue * layoutData.multiplier) / ratio;\n}\n\nfunction tableToReal(layoutData: StableModelLayout, tableValue: number, ratio: number): number {\n return (tableValue * ratio) / layoutData.multiplier;\n}\n\nfunction getMinimumRangeByX(layoutData: StableModelLayout, x: number): [number, number, boolean] {\n const [min, max] = estimateRangeByX(x);\n let minRangeIdx = min;\n let maxRangeIdx = max;\n let mid = 0;\n const target = x;\n while (minRangeIdx < maxRangeIdx) {\n mid = Math.floor((maxRangeIdx + minRangeIdx) / 2);\n\n if (mid <= 0 || mid > ELEMENT_SIZE - 2) {\n return [mid, mid, false];\n }\n const cur = layoutData.DataElement[mid].x;\n const left = layoutData.DataElement[mid - 1].x;\n const right = layoutData.DataElement[mid + 1].x;\n\n if (target === cur) return [mid, mid, true];\n else if (target === left) return [mid - 1, mid - 1, true];\n else if (target === right) return [mid + 1, mid + 1, true];\n else if (target < left) maxRangeIdx = mid - 1;\n else if (target > left && target < cur) return [mid - 1, mid, true];\n else if (target > cur && target < right) return [mid, mid + 1, true];\n else minRangeIdx = mid + 1;\n }\n return [mid, mid, false];\n}\n\nfunction getMinimumRangeByY(layoutData: StableModelLayout, y: number): [number, number, boolean] {\n const [min, max] = estimateRangeByY(y);\n let minRangeIdx = min;\n let maxRangeIdx = max;\n let mid = 0;\n const target = y;\n while (minRangeIdx <= maxRangeIdx) {\n mid = Math.floor((maxRangeIdx + minRangeIdx) / 2);\n if (mid <= 0 || mid >= ELEMENT_SIZE - 2) {\n return [mid, mid, false];\n }\n\n const cur = layoutData.DataElement[mid].y;\n const left = layoutData.DataElement[mid - 1].y;\n const right = layoutData.DataElement[mid + 1].y;\n if (target === cur) return [mid, mid, true];\n else if (target === left) return [mid - 1, mid - 1, true];\n else if (target === right) return [mid + 1, mid + 1, true];\n else if (target < right) {\n minRangeIdx = mid + 1;\n } else if (target < left && target > cur) return [mid - 1, mid, true];\n else if (target < cur && target > right) return [mid, mid + 1, true];\n else maxRangeIdx = mid - 1;\n }\n return [mid, mid, false];\n}\n\nfunction getDataByX(\n layoutData: StableModelLayout,\n x: number,\n dx: number,\n priceUp: boolean,\n): [number, number, boolean, boolean] {\n const xWithDx = priceUp ? x + dx : x - dx;\n const [minIdx, maxIdx, find] = getMinimumRangeByX(layoutData, xWithDx);\n if (!find) return [0, 0, false, find];\n\n if (minIdx === maxIdx) return [layoutData.DataElement[maxIdx].price, layoutData.DataElement[maxIdx].y, false, find];\n else {\n const x1 = layoutData.DataElement[minIdx].x;\n const x2 = layoutData.DataElement[maxIdx].x;\n const p1 = layoutData.DataElement[minIdx].price;\n const p2 = layoutData.DataElement[maxIdx].price;\n const y1 = layoutData.DataElement[minIdx].y;\n const y2 = layoutData.DataElement[maxIdx].y;\n\n if (x >= x1 && x <= x2) {\n if (priceUp) return [p2, y2, true, find];\n else return [p1, y1, true, find];\n } else {\n let p, y;\n if (priceUp) {\n p = p1 + ((p2 - p1) * (x - x1)) / (x2 - x1);\n y = y1 - ((xWithDx - x1) * layoutData.multiplier) / p2;\n } else {\n p = p1 + ((p2 - p1) * (x - x1)) / (x2 - x1);\n y = y2 + ((x2 - xWithDx) * layoutData.multiplier) / p1;\n }\n return [p, y, false, find];\n }\n }\n}\n\nfunction getDataByY(\n layoutData: StableModelLayout,\n y: number,\n dy: number,\n priceUp: boolean,\n): [number, number, boolean, boolean] {\n const yWithDy = priceUp ? y - dy : y + dy;\n const [minIdx, maxIdx, find] = getMinimumRangeByY(layoutData, yWithDy);\n if (!find) return [0, 0, false, find];\n if (minIdx === maxIdx) return [layoutData.DataElement[maxIdx].price, layoutData.DataElement[maxIdx].x, false, find];\n else {\n const x1 = layoutData.DataElement[minIdx].x;\n const x2 = layoutData.DataElement[maxIdx].x;\n const p1 = layoutData.DataElement[minIdx].price;\n const p2 = layoutData.DataElement[maxIdx].price;\n const y1 = layoutData.DataElement[minIdx].y;\n const y2 = layoutData.DataElement[maxIdx].y;\n\n if (y >= y2 && y <= y1) {\n return priceUp ? [p2, x2, true, find] : [p1, x1, true, find];\n } else {\n let p, x;\n if (priceUp) {\n p = p1 + ((p2 - p1) * (y1 - y)) / (y1 - y2);\n x = x1 + (p2 * (y1 - yWithDy)) / layoutData.multiplier;\n } else {\n p = p1 + ((p2 - p1) * (y1 - y)) / (y1 - y2);\n x = x2 - (p1 * (yWithDy - y2)) / layoutData.multiplier;\n }\n return [p, x, false, find];\n }\n }\n}\n\nfunction getMidPrice(layoutData: StableModelLayout, x: number): number {\n const ret = getDataByX(layoutData, x, 0, false);\n if (ret[3]) return ret[0];\n else return 0;\n}\n\nexport function getDyByDxBaseIn(layoutData: StableModelLayout, xReal: number, yReal: number, dxReal: number): number {\n const ratio = getRatio(layoutData, xReal, yReal);\n const x = realToTable(layoutData, xReal, ratio);\n const y = realToTable(layoutData, yReal, ratio);\n const dx = realToTable(layoutData, dxReal, ratio);\n const priceUp = true;\n const [p, y2, lessTrade, find] = getDataByX(layoutData, x, dx, priceUp);\n if (!find) return 0;\n if (lessTrade) {\n const dyReal = (dxReal * layoutData.multiplier) / p;\n return dyReal;\n } else {\n const dy = y - y2;\n const dyReal = tableToReal(layoutData, dy, ratio);\n return dyReal;\n }\n}\n\nexport function getDxByDyBaseIn(layoutData: StableModelLayout, xReal: number, yReal: number, dyReal: number): number {\n const ratio = getRatio(layoutData, xReal, yReal);\n const x = realToTable(layoutData, xReal, ratio);\n const y = realToTable(layoutData, yReal, ratio);\n const dy = realToTable(layoutData, dyReal, ratio);\n const priceUp = false;\n const [p, x2, lessTrade, find] = getDataByY(layoutData, y, dy, priceUp);\n if (!find) return 0;\n if (lessTrade) {\n const dxReal = (dyReal * p) / layoutData.multiplier;\n return dxReal;\n } else {\n const dx = x - x2;\n const dxReal = tableToReal(layoutData, dx, ratio);\n return dxReal;\n }\n}\n\nexport function formatLayout(buffer: Buffer): StableModelLayout {\n const layoutInfo = modelDataInfoLayout.decode(buffer);\n return {\n accountType: layoutInfo.accountType.toNumber(),\n status: layoutInfo.status.toNumber(),\n multiplier: layoutInfo.multiplier.toNumber(),\n validDataCount: layoutInfo.validDataCount.toNumber(),\n DataElement: layoutInfo.DataElement.map((item: any) => ({\n x: item.x.toNumber(),\n y: item.y.toNumber(),\n price: item.price.toNumber(),\n })),\n };\n}\n\nexport function getStablePrice(\n layoutData: StableModelLayout,\n coinReal: number,\n pcReal: number,\n baseCoin: boolean,\n): number {\n const price =\n getMidPrice(layoutData, realToTable(layoutData, coinReal, getRatio(layoutData, coinReal, pcReal))) /\n layoutData.multiplier;\n return baseCoin ? price : 1 / price;\n}\n\nexport class StableLayout {\n private readonly connection: Connection;\n public modelDataPubKey: PublicKey;\n private _layoutData: StableModelLayout = {\n accountType: 0,\n status: 0,\n multiplier: 0,\n validDataCount: 0,\n DataElement: [],\n };\n\n constructor({\n connection,\n modelDataPubKey = MODEL_DATA_PUBKEY,\n }: {\n connection: Connection;\n modelDataPubKey?: PublicKey;\n }) {\n this.connection = connection;\n this.modelDataPubKey = modelDataPubKey;\n }\n\n get stableModelData(): StableModelLayout {\n return this._layoutData;\n }\n\n public async initStableModelLayout(): Promise<void> {\n if (this._layoutData.validDataCount === 0) {\n if (this.connection) {\n const acc = await this.connection.getAccountInfo(this.modelDataPubKey);\n if (acc) this._layoutData = formatLayout(acc?.data);\n }\n }\n }\n}\n","import { Connection, PublicKey } from \"@solana/web3.js\";\nimport BN from \"bn.js\";\nimport Decimal from \"decimal.js\";\nimport { AmmV4Keys, AmmV5Keys } from \"../../api/type\";\nimport { TOKEN_PROGRAM_ID } from \"@solana/spl-token\";\nimport {\n findProgramAddress,\n parseSimulateLogToJson,\n parseSimulateValue,\n simulateMultipleInstruction,\n} from \"@/common/txTool/txUtils\";\nimport { toApiV3Token } from \"../../raydium/token/utils\";\nimport { getSerumAssociatedAuthority } from \"./serum\";\nimport { StableLayout } from \"./stable\";\nimport { AmmRpcData, ComputeAmountOutParam, LiquidityPoolKeys } from \"./type\";\nimport { liquidityStateV4Layout } from \"./layout\";\nimport { splAccountLayout } from \"../account\";\nimport { SPL_MINT_LAYOUT } from \"../token\";\n\ntype AssociatedName =\n | \"amm_associated_seed\"\n | \"lp_mint_associated_seed\"\n | \"coin_vault_associated_seed\"\n | \"pc_vault_associated_seed\"\n | \"lp_mint_associated_seed\"\n | \"temp_lp_token_associated_seed\"\n | \"open_order_associated_seed\"\n | \"target_associated_seed\"\n | \"withdraw_associated_seed\";\n\ninterface GetAssociatedParam {\n name: AssociatedName;\n programId: PublicKey;\n marketId: PublicKey;\n}\n\nexport function getAssociatedConfigId({ programId }: { programId: PublicKey }): PublicKey {\n const { publicKey } = findProgramAddress([Buffer.from(\"amm_config_account_seed\", \"utf-8\")], programId);\n return publicKey;\n}\n\nexport function getLiquidityAssociatedId({ name, programId, marketId }: GetAssociatedParam): PublicKey {\n const { publicKey } = findProgramAddress(\n [programId.toBuffer(), marketId.toBuffer(), Buffer.from(name, \"utf-8\")],\n programId,\n );\n return publicKey;\n}\n\nexport function getAssociatedOpenOrders({ programId, marketId }: { programId: PublicKey; marketId: PublicKey }) {\n const { publicKey } = findProgramAddress(\n [programId.toBuffer(), marketId.toBuffer(), Buffer.from(\"open_order_associated_seed\", \"utf-8\")],\n programId,\n );\n return publicKey;\n}\n\nexport function getLiquidityAssociatedAuthority({ programId }: { programId: PublicKey }): {\n publicKey: PublicKey;\n nonce: number;\n} {\n return findProgramAddress([Buffer.from([97, 109, 109, 32, 97, 117, 116, 104, 111, 114, 105, 116, 121])], programId);\n}\n\nexport function getAssociatedPoolKeys({\n version,\n marketVersion,\n marketId,\n baseMint,\n quoteMint,\n baseDecimals,\n quoteDecimals,\n programId,\n marketProgramId,\n}: {\n version: 4 | 5;\n marketVersion: 3;\n marketId: PublicKey;\n baseMint: PublicKey;\n quoteMint: PublicKey;\n baseDecimals: number;\n quoteDecimals: number;\n programId: PublicKey;\n marketProgramId: PublicKey;\n}): LiquidityPoolKeys {\n const id = getLiquidityAssociatedId({ name: \"amm_associated_seed\", programId, marketId });\n const lpMint = getLiquidityAssociatedId({ name: \"lp_mint_associated_seed\", programId, marketId });\n const { publicKey: authority, nonce } = getLiquidityAssociatedAuthority({ programId });\n const baseVault = getLiquidityAssociatedId({ name: \"coin_vault_associated_seed\", programId, marketId });\n const quoteVault = getLiquidityAssociatedId({ name: \"pc_vault_associated_seed\", programId, marketId });\n const lpVault = getLiquidityAssociatedId({ name: \"temp_lp_token_associated_seed\", programId, marketId });\n const openOrders = getAssociatedOpenOrders({ programId, marketId });\n const targetOrders = getLiquidityAssociatedId({ name: \"target_associated_seed\", programId, marketId });\n const withdrawQueue = getLiquidityAssociatedId({ name: \"withdraw_associated_seed\", programId, marketId });\n\n const { publicKey: marketAuthority } = getSerumAssociatedAuthority({\n programId: marketProgramId,\n marketId,\n });\n\n return {\n // base\n id,\n baseMint,\n quoteMint,\n lpMint,\n baseDecimals,\n quoteDecimals,\n lpDecimals: baseDecimals,\n // version\n version,\n programId,\n // keys\n authority,\n nonce,\n baseVault,\n quoteVault,\n lpVault,\n openOrders,\n targetOrders,\n withdrawQueue,\n // market version\n marketVersion,\n marketProgramId,\n // market keys\n marketId,\n marketAuthority,\n lookupTableAccount: PublicKey.default,\n configId: getAssociatedConfigId({ programId }),\n };\n}\n\nconst mockRewardData = {\n volume: 0,\n volumeQuote: 0,\n volumeFee: 0,\n apr: 0,\n feeApr: 0,\n priceMin: 0,\n priceMax: 0,\n rewardApr: [],\n};\n\nexport const toAmmComputePoolInfo = (\n poolData: Record<string, AmmRpcData>,\n): Record<string, ComputeAmountOutParam[\"poolInfo\"]> => {\n const data: Record<string, ComputeAmountOutParam[\"poolInfo\"]> = {};\n const tokenProgramStr = TOKEN_PROGRAM_ID.toBase58();\n\n Object.keys(poolData).map((poolId) => {\n const poolInfo = poolData[poolId];\n const [mintA, mintB] = [poolInfo.baseMint.toBase58(), poolInfo.quoteMint.toBase58()];\n data[poolId] = {\n id: poolId,\n version: 4,\n status: poolInfo.status.toNumber(),\n programId: poolInfo.programId.toBase58(), // needed\n mintA: toApiV3Token({\n address: mintA, // needed\n programId: tokenProgramStr,\n decimals: poolInfo.baseDecimal.toNumber(),\n }),\n mintB: toApiV3Token({\n address: mintB, // needed\n programId: tokenProgramStr,\n decimals: poolInfo.quoteDecimal.toNumber(),\n }),\n rewardDefaultInfos: [],\n rewardDefaultPoolInfos: \"Ecosystem\",\n price: poolInfo.poolPrice.toNumber(),\n mintAmountA: new Decimal(poolInfo.mintAAmount.toString()).div(10 ** poolInfo.baseDecimal.toNumber()).toNumber(),\n mintAmountB: new Decimal(poolInfo.mintBAmount.toString()).div(10 ** poolInfo.quoteDecimal.toNumber()).toNumber(),\n baseReserve: poolInfo.baseReserve, // needed\n quoteReserve: poolInfo.quoteReserve, // needed\n feeRate: new Decimal(poolInfo.tradeFeeNumerator.toString())\n .div(poolInfo.tradeFeeDenominator.toString())\n .toNumber(),\n openTime: poolInfo.poolOpenTime.toString(),\n tvl: 0,\n day: mockRewardData,\n week: mockRewardData,\n month: mockRewardData,\n pooltype: [],\n farmUpcomingCount: 0,\n farmOngoingCount: 0,\n farmFinishedCount: 0,\n type: \"Standard\",\n marketId: poolInfo.marketId.toBase58(),\n configId: getAssociatedConfigId({ programId: poolInfo.programId }).toBase58(),\n lpPrice: 0,\n lpAmount: new Decimal(poolInfo.lpReserve.toString())\n .div(10 ** Math.min(poolInfo.baseDecimal.toNumber(), poolInfo.quoteDecimal.toNumber()))\n .toNumber(),\n lpMint: toApiV3Token({\n address: poolInfo.lpMint.toBase58(),\n programId: tokenProgramStr,\n decimals: Math.min(poolInfo.baseDecimal.toNumber(), poolInfo.quoteDecimal.toNumber()),\n }),\n burnPercent: 0,\n feeOn: \"Both\",\n hasDynamicFee: false,\n tips: [],\n launchMigratePool: false,\n };\n });\n return data;\n};\n","import { PublicKey } from \"@solana/web3.js\";\nimport { createLogger } from \"../../common/logger\";\nimport { SerumVersion } from \"../serum\";\nimport { LIQUIDITY_VERSION_TO_SERUM_VERSION } from \"./constant\";\n\nconst logger = createLogger(\"Raydium_liquidity_serum\");\n\nexport function getSerumVersion(version: number): SerumVersion {\n const serumVersion = LIQUIDITY_VERSION_TO_SERUM_VERSION[version];\n if (!serumVersion) logger.logWithError(\"invalid version\", \"version\", version);\n\n return serumVersion;\n}\n\nexport function getSerumAssociatedAuthority({ programId, marketId }: { programId: PublicKey; marketId: PublicKey }): {\n publicKey: PublicKey;\n nonce: number;\n} {\n const seeds = [marketId.toBuffer()];\n\n let nonce = 0;\n let publicKey: PublicKey;\n\n while (nonce < 100) {\n try {\n const seedsWithNonce = seeds.concat(Buffer.from([nonce]), Buffer.alloc(7));\n publicKey = PublicKey.createProgramAddressSync(seedsWithNonce, programId);\n } catch (err) {\n if (err instanceof TypeError) {\n throw err;\n }\n nonce++;\n continue;\n }\n return { publicKey, nonce };\n }\n\n logger.logWithError(\"unable to find a viable program address nonce\", \"params\", {\n programId,\n marketId,\n });\n throw new Error(\"unable to find a viable program address nonce\");\n}\n","import { MakeMultiTxData } from \"@/common/txTool/txTool\";\nimport { TxVersion } from \"@/common/txTool/txType\";\nimport { TOKEN_PROGRAM_ID } from \"@solana/spl-token\";\nimport { PublicKey } from \"@solana/web3.js\";\nimport BN from \"bn.js\";\nimport { ComputeBudgetConfig, TxTipConfig } from \"../../raydium/type\";\nimport { generatePubKey } from \"../account/util\";\nimport { BN_ZERO } from \"../clmm\";\nimport ModuleBase from \"../moduleBase\";\nimport { makeCreateMarketInstruction } from \"./instrument\";\n\nexport interface MarketExtInfo {\n address: {\n marketId: PublicKey;\n requestQueue: PublicKey;\n eventQueue: PublicKey;\n bids: PublicKey;\n asks: PublicKey;\n baseVault: PublicKey;\n quoteVault: PublicKey;\n baseMint: PublicKey;\n quoteMint: PublicKey;\n };\n}\n\nexport default class MarketV2 extends ModuleBase {\n public async create<T extends TxVersion>({\n baseInfo,\n quoteInfo,\n lotSize, // 1\n tickSize, // 0.01\n dexProgramId,\n requestQueueSpace,\n eventQueueSpace,\n orderbookQueueSpace,\n lowestFeeMarket,\n assignSeed,\n txVersion,\n computeBudgetConfig,\n txTipConfig,\n feePayer,\n }: {\n baseInfo: {\n mint: PublicKey;\n decimals: number;\n };\n quoteInfo: {\n mint: PublicKey;\n decimals: number;\n };\n lotSize: number;\n tickSize: number;\n dexProgramId: PublicKey;\n eventQueue?: PublicKey;\n requestQueue?: PublicKey;\n requestQueueSpace?: number;\n eventQueueSpace?: number;\n orderbookQueueSpace?: number;\n\n lowestFeeMarket?: boolean;\n assignSeed?: string;\n\n txVersion?: T;\n computeBudgetConfig?: ComputeBudgetConfig;\n txTipConfig?: TxTipConfig;\n feePayer?: PublicKey;\n }): Promise<MakeMultiTxData<T, MarketExtInfo>> {\n const wallet = this.scope.ownerPubKey;\n const seed = assignSeed\n ? `${baseInfo.mint.toBase58().slice(0, 10)}-${quoteInfo.mint.toBase58().slice(0, 10)}-${assignSeed}`\n : undefined;\n const market = generatePubKey({\n fromPublicKey: wallet,\n programId: dexProgramId,\n assignSeed: seed ? `${seed}-market` : seed,\n });\n const requestQueue = generatePubKey({\n fromPublicKey: wallet,\n programId: dexProgramId,\n assignSeed: seed ? `${seed}-request` : seed,\n });\n const eventQueue = generatePubKey({\n fromPublicKey: wallet,\n programId: dexProgramId,\n assignSeed: seed ? `${seed}-event` : seed,\n });\n const bids = generatePubKey({\n fromPublicKey: wallet,\n programId: dexProgramId,\n assignSeed: seed ? `${seed}-bids` : seed,\n });\n const asks = generatePubKey({\n fromPublicKey: wallet,\n programId: dexProgramId,\n assignSeed: seed ? `${seed}-asks` : seed,\n });\n const baseVault = generatePubKey({\n fromPublicKey: wallet,\n programId: TOKEN_PROGRAM_ID,\n assignSeed: seed ? `${seed}-baseVault` : seed,\n });\n const quoteVault = generatePubKey({\n fromPublicKey: wallet,\n programId: TOKEN_PROGRAM_ID,\n assignSeed: seed ? `${seed}-quoteVault` : seed,\n });\n const feeRateBps = 0;\n const quoteDustThreshold = new BN(100);\n function getVaultOwnerAndNonce() {\n const vaultSignerNonce = new BN(0);\n // eslint-disable-next-line no-constant-condition\n while (true) {\n try {\n const vaultOwner = PublicKey.createProgramAddressSync(\n [market.publicKey.toBuffer(), vaultSignerNonce.toArrayLike(Buffer, \"le\", 8)],\n dexProgramId,\n );\n return { vaultOwner, vaultSignerNonce };\n } catch (e) {\n vaultSignerNonce.iaddn(1);\n if (vaultSignerNonce.gt(new BN(25555))) throw Error(\"find vault owner error\");\n }\n }\n }\n const { vaultOwner, vaultSignerNonce } = getVaultOwnerAndNonce();\n const baseLotSize = new BN(Math.round(10 ** baseInfo.decimals * lotSize));\n const quoteLotSize = new BN(Math.round(lotSize * 10 ** quoteInfo.decimals * tickSize));\n\n if (baseLotSize.eq(BN_ZERO)) throw Error(\"lot size is too small\");\n if (quoteLotSize.eq(BN_ZERO)) throw Error(\"tick size or lot size is too small\");\n const allTxArr = await makeCreateMarketInstruction({\n connection: this.scope.connection,\n wallet: this.scope.ownerPubKey,\n marketInfo: {\n programId: dexProgramId,\n id: market,\n baseMint: baseInfo.mint,\n quoteMint: quoteInfo.mint,\n baseVault,\n quoteVault,\n vaultOwner,\n requestQueue,\n eventQueue,\n bids,\n asks,\n\n feeRateBps,\n quoteDustThreshold,\n vaultSignerNonce,\n baseLotSize,\n quoteLotSize,\n\n requestQueueSpace,\n eventQueueSpace,\n orderbookQueueSpace,\n\n lowestFeeMarket,\n },\n });\n const txBuilder = this.createTxBuilder(feePayer);\n txBuilder.addInstruction({\n instructions: allTxArr[0].transaction.instructions,\n signers: allTxArr[0].signer,\n });\n\n for await (const txData of allTxArr.slice(1, allTxArr.length)) {\n txBuilder.addInstruction({\n instructions: txData.transaction.instructions,\n signers: txData.signer,\n instructionTypes: txData.instructionTypes,\n });\n }\n\n if (txVersion === TxVersion.V0)\n return txBuilder.sizeCheckBuildV0({\n computeBudgetConfig,\n address: {\n marketId: market.publicKey,\n requestQueue: requestQueue.publicKey,\n eventQueue: eventQueue.publicKey,\n bids: bids.publicKey,\n asks: asks.publicKey,\n baseVault: baseVault.publicKey,\n quoteVault: quoteVault.publicKey,\n baseMint: new PublicKey(baseInfo.mint),\n quoteMint: new PublicKey(quoteInfo.mint),\n },\n }) as Promise<MakeMultiTxData<T, MarketExtInfo>>;\n\n return txBuilder.sizeCheckBuild({\n computeBudgetConfig,\n address: {\n marketId: market.publicKey,\n requestQueue: requestQueue.publicKey,\n eventQueue: eventQueue.publicKey,\n bids: bids.publicKey,\n asks: asks.publicKey,\n baseVault: baseVault.publicKey,\n quoteVault: quoteVault.publicKey,\n baseMint: new PublicKey(baseInfo.mint),\n quoteMint: new PublicKey(quoteInfo.mint),\n },\n }) as Promise<MakeMultiTxData<T, MarketExtInfo>>;\n }\n}\n","import {\n Connection,\n Keypair,\n PublicKey,\n SystemProgram,\n SYSVAR_RENT_PUBKEY,\n Transaction,\n TransactionInstruction,\n} from \"@solana/web3.js\";\nimport BN from \"bn.js\";\nimport { createInitializeAccountInstruction, TOKEN_PROGRAM_ID } from \"@solana/spl-token\";\nimport { InstructionType } from \"@/common/txTool/txType\";\nimport { struct, u16, u32, u64, u8 } from \"../../marshmallow\";\nimport { MARKET_STATE_LAYOUT_V2 } from \"./layout\";\n\ntype Transactions = {\n transaction: Transaction;\n signer?: Keypair[] | undefined;\n instructionTypes?: string[];\n}[];\n\nexport function initializeMarket({\n programId,\n marketInfo,\n}: {\n programId: PublicKey;\n marketInfo: {\n id: PublicKey;\n requestQueue: PublicKey;\n eventQueue: PublicKey;\n bids: PublicKey;\n asks: PublicKey;\n baseVault: PublicKey;\n quoteVault: PublicKey;\n baseMint: PublicKey;\n quoteMint: PublicKey;\n authority?: PublicKey;\n pruneAuthority?: PublicKey;\n\n baseLotSize: BN;\n quoteLotSize: BN;\n feeRateBps: number;\n vaultSignerNonce: BN;\n quoteDustThreshold: BN;\n };\n}): TransactionInstruction {\n const dataLayout = struct([\n u8(\"version\"),\n u32(\"instruction\"),\n u64(\"baseLotSize\"),\n u64(\"quoteLotSize\"),\n u16(\"feeRateBps\"),\n u64(\"vaultSignerNonce\"),\n u64(\"quoteDustThreshold\"),\n ]);\n\n const keys = [\n { pubkey: marketInfo.id, isSigner: false, isWritable: true },\n { pubkey: marketInfo.requestQueue, isSigner: false, isWritable: true },\n { pubkey: marketInfo.eventQueue, isSigner: false, isWritable: true },\n { pubkey: marketInfo.bids, isSigner: false, isWritable: true },\n { pubkey: marketInfo.asks, isSigner: false, isWritable: true },\n { pubkey: marketInfo.baseVault, isSigner: false, isWritable: true },\n { pubkey: marketInfo.quoteVault, isSigner: false, isWritable: true },\n { pubkey: marketInfo.baseMint, isSigner: false, isWritable: false },\n { pubkey: marketInfo.quoteMint, isSigner: false, isWritable: false },\n // Use a dummy address if using the new dex upgrade to save tx space.\n {\n pubkey: marketInfo.authority ? marketInfo.quoteMint : SYSVAR_RENT_PUBKEY,\n isSigner: false,\n isWritable: false,\n },\n ]\n .concat(marketInfo.authority ? { pubkey: marketInfo.authority, isSigner: false, isWritable: false } : [])\n .concat(\n marketInfo.authority && marketInfo.pruneAuthority\n ? { pubkey: marketInfo.pruneAuthority, isSigner: false, isWritable: false }\n : [],\n );\n\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode(\n {\n version: 0,\n instruction: 0,\n baseLotSize: marketInfo.baseLotSize,\n quoteLotSize: marketInfo.quoteLotSize,\n feeRateBps: marketInfo.feeRateBps,\n vaultSignerNonce: marketInfo.vaultSignerNonce,\n quoteDustThreshold: marketInfo.quoteDustThreshold,\n },\n data,\n );\n\n return new TransactionInstruction({\n keys,\n programId,\n data,\n });\n}\n\nexport async function makeCreateMarketInstruction({\n connection,\n wallet,\n marketInfo,\n}: {\n connection: Connection;\n wallet: PublicKey;\n marketInfo: {\n programId: PublicKey;\n id: { publicKey: PublicKey; seed: string };\n baseMint: PublicKey;\n quoteMint: PublicKey;\n baseVault: { publicKey: PublicKey; seed: string };\n quoteVault: { publicKey: PublicKey; seed: string };\n vaultOwner: PublicKey;\n\n requestQueue: { publicKey: PublicKey; seed: string };\n eventQueue: { publicKey: PublicKey; seed: string };\n bids: { publicKey: PublicKey; seed: string };\n asks: { publicKey: PublicKey; seed: string };\n\n feeRateBps: number;\n vaultSignerNonce: BN;\n quoteDustThreshold: BN;\n\n baseLotSize: BN;\n quoteLotSize: BN;\n\n requestQueueSpace?: number;\n eventQueueSpace?: number;\n orderbookQueueSpace?: number;\n\n lowestFeeMarket?: boolean;\n };\n}): Promise<Transactions> {\n const tx1 = new Transaction();\n const accountLamports = await connection.getMinimumBalanceForRentExemption(165);\n tx1.add(\n SystemProgram.createAccountWithSeed({\n fromPubkey: wallet,\n basePubkey: wallet,\n seed: marketInfo.baseVault.seed,\n newAccountPubkey: marketInfo.baseVault.publicKey,\n lamports: accountLamports,\n space: 165,\n programId: TOKEN_PROGRAM_ID,\n }),\n SystemProgram.createAccountWithSeed({\n fromPubkey: wallet,\n basePubkey: wallet,\n seed: marketInfo.quoteVault.seed,\n newAccountPubkey: marketInfo.quoteVault.publicKey,\n lamports: accountLamports,\n space: 165,\n programId: TOKEN_PROGRAM_ID,\n }),\n createInitializeAccountInstruction(marketInfo.baseVault.publicKey, marketInfo.baseMint, marketInfo.vaultOwner),\n createInitializeAccountInstruction(marketInfo.quoteVault.publicKey, marketInfo.quoteMint, marketInfo.vaultOwner),\n SystemProgram.createAccountWithSeed({\n fromPubkey: wallet,\n basePubkey: wallet,\n seed: marketInfo.id.seed,\n newAccountPubkey: marketInfo.id.publicKey,\n lamports: await connection.getMinimumBalanceForRentExemption(MARKET_STATE_LAYOUT_V2.span),\n space: MARKET_STATE_LAYOUT_V2.span,\n programId: marketInfo.programId,\n }),\n );\n\n const tx2 = new Transaction();\n tx2.add(\n SystemProgram.createAccountWithSeed({\n fromPubkey: wallet,\n basePubkey: wallet,\n seed: marketInfo.requestQueue.seed,\n newAccountPubkey: marketInfo.requestQueue.publicKey,\n lamports: marketInfo.lowestFeeMarket\n ? 6208320\n : await connection.getMinimumBalanceForRentExemption(marketInfo.requestQueueSpace ?? 5120 + 12),\n space: marketInfo.lowestFeeMarket ? 764 : marketInfo.requestQueueSpace ?? 5120 + 12,\n programId: marketInfo.programId,\n }),\n SystemProgram.createAccountWithSeed({\n fromPubkey: wallet,\n basePubkey: wallet,\n seed: marketInfo.eventQueue.seed,\n newAccountPubkey: marketInfo.eventQueue.publicKey,\n lamports: marketInfo.lowestFeeMarket\n ? 79594560\n : await connection.getMinimumBalanceForRentExemption(marketInfo.eventQueueSpace ?? 262144 + 12),\n space: marketInfo.lowestFeeMarket ? 11308 : marketInfo.eventQueueSpace ?? 262144 + 12,\n programId: marketInfo.programId,\n }),\n SystemProgram.createAccountWithSeed({\n fromPubkey: wallet,\n basePubkey: wallet,\n seed: marketInfo.bids.seed,\n newAccountPubkey: marketInfo.bids.publicKey,\n lamports: marketInfo.lowestFeeMarket\n ? 101977920\n : await connection.getMinimumBalanceForRentExemption(marketInfo.orderbookQueueSpace ?? 65536 + 12),\n space: marketInfo.lowestFeeMarket ? 14524 : marketInfo.orderbookQueueSpace ?? 65536 + 12,\n programId: marketInfo.programId,\n }),\n SystemProgram.createAccountWithSeed({\n fromPubkey: wallet,\n basePubkey: wallet,\n seed: marketInfo.asks.seed,\n newAccountPubkey: marketInfo.asks.publicKey,\n lamports: marketInfo.lowestFeeMarket\n ? 101977920\n : await connection.getMinimumBalanceForRentExemption(marketInfo.orderbookQueueSpace ?? 65536 + 12),\n space: marketInfo.lowestFeeMarket ? 14524 : marketInfo.orderbookQueueSpace ?? 65536 + 12,\n programId: marketInfo.programId,\n }),\n initializeMarket({\n programId: marketInfo.programId,\n marketInfo: {\n id: marketInfo.id.publicKey,\n requestQueue: marketInfo.requestQueue.publicKey,\n eventQueue: marketInfo.eventQueue.publicKey,\n bids: marketInfo.bids.publicKey,\n asks: marketInfo.asks.publicKey,\n baseVault: marketInfo.baseVault.publicKey,\n quoteVault: marketInfo.quoteVault.publicKey,\n baseMint: marketInfo.baseMint,\n quoteMint: marketInfo.quoteMint,\n\n baseLotSize: marketInfo.baseLotSize,\n quoteLotSize: marketInfo.quoteLotSize,\n feeRateBps: marketInfo.feeRateBps,\n vaultSignerNonce: marketInfo.vaultSignerNonce,\n quoteDustThreshold: marketInfo.quoteDustThreshold,\n },\n }),\n );\n\n return [\n {\n transaction: tx1,\n signer: [],\n instructionTypes: [\n InstructionType.CreateAccount,\n InstructionType.CreateAccount,\n InstructionType.InitAccount,\n InstructionType.InitAccount,\n ],\n },\n {\n transaction: tx2,\n signer: [],\n instructionTypes: [\n InstructionType.CreateAccount,\n InstructionType.CreateAccount,\n InstructionType.CreateAccount,\n InstructionType.CreateAccount,\n InstructionType.CreateAccount,\n InstructionType.InitMarket,\n ],\n },\n ];\n}\n","import { blob, publicKey, struct, u64, WideBits } from \"../../marshmallow\";\n\nfunction accountFlagsLayout(property = \"accountFlags\"): WideBits<string> {\n const ACCOUNT_FLAGS_LAYOUT = new WideBits(property);\n ACCOUNT_FLAGS_LAYOUT.addBoolean(\"initialized\");\n ACCOUNT_FLAGS_LAYOUT.addBoolean(\"market\");\n ACCOUNT_FLAGS_LAYOUT.addBoolean(\"openOrders\");\n ACCOUNT_FLAGS_LAYOUT.addBoolean(\"requestQueue\");\n ACCOUNT_FLAGS_LAYOUT.addBoolean(\"eventQueue\");\n ACCOUNT_FLAGS_LAYOUT.addBoolean(\"bids\");\n ACCOUNT_FLAGS_LAYOUT.addBoolean(\"asks\");\n return ACCOUNT_FLAGS_LAYOUT;\n}\n\nexport const MARKET_STATE_LAYOUT_V2 = struct([\n blob(5),\n accountFlagsLayout(\"accountFlags\"),\n publicKey(\"ownAddress\"),\n u64(\"vaultSignerNonce\"),\n publicKey(\"baseMint\"),\n publicKey(\"quoteMint\"),\n publicKey(\"baseVault\"),\n u64(\"baseDepositsTotal\"),\n u64(\"baseFeesAccrued\"),\n publicKey(\"quoteVault\"),\n u64(\"quoteDepositsTotal\"),\n u64(\"quoteFeesAccrued\"),\n u64(\"quoteDustThreshold\"),\n publicKey(\"requestQueue\"),\n publicKey(\"eventQueue\"),\n publicKey(\"bids\"),\n publicKey(\"asks\"),\n u64(\"baseLotSize\"),\n u64(\"quoteLotSize\"),\n u64(\"feeRateBps\"),\n u64(\"referrerRebatesAccrued\"),\n blob(7),\n]);\n","import { PublicKey } from \"@solana/web3.js\";\nimport { ApiV3PoolInfoStandardItemCpmm, CpmmKeys, CpmmLockInfo } from \"../../api/type\";\nimport {\n AccountLayout,\n NATIVE_MINT,\n TOKEN_2022_PROGRAM_ID,\n TOKEN_PROGRAM_ID,\n createAssociatedTokenAccountIdempotentInstruction,\n} from \"@solana/spl-token\";\nimport { getATAAddress } from \"@/common/pda\";\nimport { WSOLMint } from \"@/common/pubKey\";\nimport { MakeMultiTxData, MakeTxData } from \"@/common/txTool/txTool\";\nimport { InstructionType, TxVersion } from \"@/common/txTool/txType\";\nimport { Percent } from \"../../module\";\nimport { CurveCalculator, SwapResult } from \"./curve/calculator\";\n\nimport BN from \"bn.js\";\nimport Decimal from \"decimal.js\";\nimport {\n CREATE_CPMM_POOL_PROGRAM,\n DEVNET_PROGRAM_ID,\n fetchMultipleMintInfos,\n getMultipleAccountsInfo,\n getMultipleAccountsInfoWithCustomFlags,\n getTransferAmountFeeV2,\n LOCK_CPMM_AUTH,\n LOCK_CPMM_PROGRAM,\n} from \"@/common\";\nimport { GetTransferAmountFee, ReturnTypeFetchMultipleMintInfos } from \"../../raydium/type\";\nimport ModuleBase, { ModuleBaseProps } from \"../moduleBase\";\nimport { toApiV3Token, toFeeConfig } from \"../token\";\nimport {\n makeCreateCpmmPoolInInstruction,\n makeDepositCpmmInInstruction,\n makeSwapCpmmBaseInInstruction,\n makeSwapCpmmBaseOutInstruction,\n makeWithdrawCpmmInInstruction,\n makeCpmmLockInstruction,\n collectCpFeeInstruction,\n initializeWithPermission,\n makeCollectCreatorFeeInstruction,\n collectCreatorFeePermissionlessInInstruction,\n} from \"./instruction\";\nimport { CpmmConfigInfoLayout, CpmmPoolInfoLayout } from \"./layout\";\nimport {\n getCreatePoolKeys,\n getPdaMintExAccountCp,\n getPdaObservationId,\n getPdaPermissionId,\n getPdaPoolAuthority,\n} from \"./pda\";\nimport {\n AddCpmmLiquidityParams,\n ComputePairAmountParams,\n CpmmComputeData,\n CpmmLockExtInfo,\n CpmmParsedRpcData,\n CpmmSwapParams,\n CreateCpmmPoolAddress,\n CreateCpmmPoolParam,\n LockCpmmLpParams,\n HarvestLockCpmmLpParams,\n WithdrawCpmmLiquidityParams,\n HarvestMultiLockCpmmLpParams,\n FeeOn,\n CreateCpmmPoolPermissionParam,\n CollectCreatorFees,\n CollectMultiCreatorFees,\n} from \"./type\";\nimport { getCpLockPda } from \"./pda\";\nimport { BN_ZERO } from \"../clmm\";\n\nexport default class CpmmModule extends ModuleBase {\n constructor(params: ModuleBaseProps) {\n super(params);\n }\n\n public async load(): Promise<void> {\n this.checkDisabled();\n }\n\n public async getCpmmPoolKeys(poolId: string): Promise<CpmmKeys> {\n return ((await this.scope.api.fetchPoolKeysById({ idList: [poolId] })) as CpmmKeys[])[0];\n }\n\n public async getRpcPoolInfo(poolId: string, fetchConfigInfo?: boolean): Promise<CpmmParsedRpcData> {\n return (await this.getRpcPoolInfos([poolId], fetchConfigInfo))[poolId];\n }\n\n public async getRpcPoolInfos(\n poolIds: string[],\n fetchConfigInfo?: boolean,\n ): Promise<{\n [poolId: string]: CpmmParsedRpcData;\n }> {\n const accounts = await getMultipleAccountsInfoWithCustomFlags(\n this.scope.connection,\n poolIds.map((i) => ({ pubkey: new PublicKey(i) })),\n );\n const poolInfos: { [poolId: string]: ReturnType<typeof CpmmPoolInfoLayout.decode> & { programId: PublicKey } } = {};\n\n const needFetchConfigId = new Set<string>();\n const needFetchVaults: PublicKey[] = [];\n\n for (let i = 0; i < poolIds.length; i++) {\n const item = accounts[i];\n if (item.accountInfo === null) throw Error(\"fetch pool info error: \" + String(poolIds[i]));\n const rpc = CpmmPoolInfoLayout.decode(item.accountInfo.data);\n poolInfos[String(poolIds[i])] = {\n ...rpc,\n programId: item.accountInfo.owner,\n };\n needFetchConfigId.add(String(rpc.configId));\n\n needFetchVaults.push(rpc.vaultA, rpc.vaultB);\n }\n\n const configInfo: { [configId: string]: ReturnType<typeof CpmmConfigInfoLayout.decode> } = {};\n\n if (fetchConfigInfo) {\n const configIds = [...needFetchConfigId];\n const configState = await getMultipleAccountsInfoWithCustomFlags(\n this.scope.connection,\n configIds.map((i) => ({ pubkey: new PublicKey(i) })),\n );\n\n for (let i = 0; i < configIds.length; i++) {\n const configItemInfo = configState[i].accountInfo;\n if (configItemInfo === null) throw Error(\"fetch pool config error: \" + configIds[i]);\n configInfo[configIds[i]] = CpmmConfigInfoLayout.decode(configItemInfo.data);\n }\n }\n\n const vaultInfo: { [vaultId: string]: BN } = {};\n\n const vaultAccountInfo = await getMultipleAccountsInfoWithCustomFlags(\n this.scope.connection,\n needFetchVaults.map((i) => ({ pubkey: new PublicKey(i) })),\n );\n\n for (let i = 0; i < needFetchVaults.length; i++) {\n const vaultItemInfo = vaultAccountInfo[i].accountInfo;\n if (vaultItemInfo === null) throw Error(\"fetch vault info error: \" + needFetchVaults[i]);\n\n // eslint-disable-next-line\n // @ts-ignore\n vaultInfo[String(needFetchVaults[i])] = new BN(AccountLayout.decode(vaultItemInfo.data).amount.toString());\n }\n\n const returnData: { [poolId: string]: CpmmParsedRpcData } = {};\n\n for (const [id, info] of Object.entries(poolInfos)) {\n const baseReserve = vaultInfo[info.vaultA.toString()]\n .sub(info.protocolFeesMintA)\n .sub(info.fundFeesMintA)\n .sub(info.creatorFeesMintA);\n const quoteReserve = vaultInfo[info.vaultB.toString()]\n .sub(info.protocolFeesMintB)\n .sub(info.fundFeesMintB)\n .sub(info.creatorFeesMintB);\n returnData[id] = {\n ...info,\n baseReserve,\n quoteReserve,\n vaultAAmount: vaultInfo[info.vaultA.toString()],\n vaultBAmount: vaultInfo[info.vaultB.toString()],\n configInfo: configInfo[info.configId.toString()],\n poolPrice: new Decimal(quoteReserve.toString())\n .div(new Decimal(10).pow(info.mintDecimalB))\n .div(new Decimal(baseReserve.toString()).div(new Decimal(10).pow(info.mintDecimalA))),\n };\n }\n\n return returnData;\n }\n\n public toComputePoolInfos({\n pools,\n mintInfos,\n }: {\n pools: Record<string, CpmmParsedRpcData>;\n mintInfos: ReturnTypeFetchMultipleMintInfos;\n }): Record<string, CpmmComputeData> {\n return Object.keys(pools).reduce((acc, cur) => {\n const pool = pools[cur];\n const [mintA, mintB] = [pool.mintA.toBase58(), pool.mintB.toBase58()];\n\n return {\n ...acc,\n [cur]: {\n ...pool,\n id: new PublicKey(cur),\n configInfo: pool.configInfo!,\n version: 7 as const,\n authority: getPdaPoolAuthority(pool.programId).publicKey,\n mintA: toApiV3Token({\n address: mintA,\n decimals: pool.mintDecimalA,\n programId: pool.mintProgramA.toBase58(),\n extensions: {\n feeConfig: mintInfos[mintA]?.feeConfig ? toFeeConfig(mintInfos[mintA]?.feeConfig) : undefined,\n },\n }),\n mintB: toApiV3Token({\n address: mintB,\n decimals: pool.mintDecimalB,\n programId: pool.mintProgramB.toBase58(),\n extensions: {\n feeConfig: mintInfos[mintB]?.feeConfig ? toFeeConfig(mintInfos[mintB]?.feeConfig) : undefined,\n },\n }),\n },\n };\n }, {} as Record<string, CpmmComputeData>);\n }\n\n public async getPoolInfoFromRpc(poolId: string): Promise<{\n poolInfo: ApiV3PoolInfoStandardItemCpmm;\n poolKeys: CpmmKeys;\n rpcData: CpmmParsedRpcData;\n computePoolInfo: CpmmComputeData;\n }> {\n const rpcData = await this.getRpcPoolInfo(poolId, true);\n const mintInfos = await fetchMultipleMintInfos({\n connection: this.scope.connection,\n mints: [rpcData.mintA, rpcData.mintB],\n });\n\n const mintA = toApiV3Token({\n address: rpcData.mintA.toBase58(),\n decimals: rpcData.mintDecimalA,\n programId: rpcData.mintProgramA.toBase58(),\n extensions: {\n feeConfig: mintInfos[rpcData.mintA.toBase58()].feeConfig\n ? toFeeConfig(mintInfos[rpcData.mintA.toBase58()].feeConfig)\n : undefined,\n },\n });\n const mintB = toApiV3Token({\n address: rpcData.mintB.toBase58(),\n decimals: rpcData.mintDecimalB,\n programId: rpcData.mintProgramB.toBase58(),\n extensions: {\n feeConfig: mintInfos[rpcData.mintB.toBase58()].feeConfig\n ? toFeeConfig(mintInfos[rpcData.mintB.toBase58()].feeConfig)\n : undefined,\n },\n });\n\n const lpMint = toApiV3Token({\n address: rpcData.mintLp.toBase58(),\n decimals: rpcData.lpDecimals,\n programId: TOKEN_PROGRAM_ID.toBase58(),\n });\n\n const configInfo = {\n id: rpcData.configId.toBase58(),\n index: rpcData.configInfo!.index,\n protocolFeeRate: rpcData.configInfo!.protocolFeeRate.toNumber(),\n tradeFeeRate: rpcData.configInfo!.tradeFeeRate.toNumber(),\n fundFeeRate: rpcData.configInfo!.fundFeeRate.toNumber(),\n createPoolFee: rpcData.configInfo!.createPoolFee.toString(),\n };\n\n const mockRewardData = {\n volume: 0,\n volumeQuote: 0,\n volumeFee: 0,\n apr: 0,\n feeApr: 0,\n priceMin: 0,\n priceMax: 0,\n rewardApr: [],\n };\n\n return {\n poolInfo: {\n programId: rpcData.programId.toBase58(),\n id: poolId,\n type: \"Standard\",\n lpMint,\n lpPrice: 0,\n lpAmount: rpcData.lpAmount.toNumber(),\n config: configInfo,\n mintA,\n mintB,\n rewardDefaultInfos: [],\n rewardDefaultPoolInfos: \"Ecosystem\",\n price: rpcData.poolPrice.toNumber(),\n mintAmountA: new Decimal(rpcData.vaultAAmount.toString()).div(10 ** mintA.decimals).toNumber(),\n mintAmountB: new Decimal(rpcData.vaultBAmount.toString()).div(10 ** mintB.decimals).toNumber(),\n feeRate: rpcData.configInfo!.tradeFeeRate.toNumber(),\n openTime: rpcData.openTime.toString(),\n tvl: 0,\n burnPercent: 0,\n\n day: mockRewardData,\n week: mockRewardData,\n month: mockRewardData,\n pooltype: [],\n\n farmUpcomingCount: 0,\n farmOngoingCount: 0,\n farmFinishedCount: 0,\n feeOn: \"\",\n hasDynamicFee: false,\n launchMigratePool: false,\n tips: [],\n },\n poolKeys: {\n programId: rpcData.programId.toBase58(),\n id: poolId,\n mintA,\n mintB,\n openTime: rpcData.openTime.toString(),\n vault: { A: rpcData.vaultA.toBase58(), B: rpcData.vaultB.toBase58() },\n authority: getPdaPoolAuthority(rpcData.programId).publicKey.toBase58(),\n mintLp: lpMint,\n config: configInfo,\n observationId: getPdaObservationId(rpcData.programId, new PublicKey(poolId)).publicKey.toBase58(),\n },\n rpcData,\n computePoolInfo: {\n ...rpcData,\n id: new PublicKey(poolId),\n configInfo: rpcData.configInfo!,\n version: 7 as const,\n authority: getPdaPoolAuthority(rpcData.programId).publicKey,\n mintA,\n mintB,\n },\n };\n }\n\n public async createPool<T extends TxVersion>({\n poolId,\n programId,\n poolFeeAccount,\n startTime,\n ownerInfo,\n associatedOnly = false,\n checkCreateATAOwner = false,\n txVersion,\n feeConfig,\n computeBudgetConfig,\n txTipConfig,\n feePayer,\n addSupportMintExt,\n ...params\n }: CreateCpmmPoolParam<T>): Promise<MakeTxData<T, { address: CreateCpmmPoolAddress }>> {\n const payer = ownerInfo.feePayer || this.scope.owner?.publicKey;\n const isFront = new BN(new PublicKey(params.mintA.address).toBuffer()).lte(\n new BN(new PublicKey(params.mintB.address).toBuffer()),\n );\n\n const [mintA, mintB] = isFront ? [params.mintA, params.mintB] : [params.mintB, params.mintA];\n const [mintAAmount, mintBAmount] = isFront\n ? [params.mintAAmount, params.mintBAmount]\n : [params.mintBAmount, params.mintAAmount];\n\n const mintAUseSOLBalance = ownerInfo.useSOLBalance && mintA.address === NATIVE_MINT.toBase58();\n const mintBUseSOLBalance = ownerInfo.useSOLBalance && mintB.address === NATIVE_MINT.toBase58();\n const [mintAPubkey, mintBPubkey] = [new PublicKey(mintA.address), new PublicKey(mintB.address)];\n const txBuilder = this.createTxBuilder(feePayer);\n\n const { account: userVaultA, instructionParams: userVaultAInstruction } =\n await this.scope.account.getOrCreateTokenAccount({\n mint: mintAPubkey,\n tokenProgram: mintA.programId,\n owner: this.scope.ownerPubKey,\n createInfo: mintAUseSOLBalance\n ? {\n payer: payer!,\n amount: mintAAmount,\n }\n : undefined,\n notUseTokenAccount: mintAUseSOLBalance,\n skipCloseAccount: !mintAUseSOLBalance,\n associatedOnly: mintAUseSOLBalance ? false : associatedOnly,\n checkCreateATAOwner,\n });\n txBuilder.addInstruction(userVaultAInstruction || {});\n const { account: userVaultB, instructionParams: userVaultBInstruction } =\n await this.scope.account.getOrCreateTokenAccount({\n mint: new PublicKey(mintB.address),\n tokenProgram: mintB.programId,\n owner: this.scope.ownerPubKey,\n createInfo: mintBUseSOLBalance\n ? {\n payer: payer!,\n amount: mintBAmount,\n }\n : undefined,\n notUseTokenAccount: mintBUseSOLBalance,\n skipCloseAccount: !mintBUseSOLBalance,\n associatedOnly: mintBUseSOLBalance ? false : associatedOnly,\n checkCreateATAOwner,\n });\n txBuilder.addInstruction(userVaultBInstruction || {});\n\n if (userVaultA === undefined || userVaultB === undefined)\n throw Error(\n `you don't has some token account, userVaultA: ${userVaultA?.toBase58()}, userVaultB: ${userVaultB?.toBase58()}`,\n );\n\n const poolKeys = getCreatePoolKeys({\n poolId,\n programId,\n configId: new PublicKey(feeConfig.id),\n mintA: mintAPubkey,\n mintB: mintBPubkey,\n });\n\n const extendMintAccount: PublicKey[] = [];\n const fetchAccounts: PublicKey[] = [];\n if (addSupportMintExt) {\n if (mintA.programId === TOKEN_2022_PROGRAM_ID.toBase58())\n fetchAccounts.push(getPdaMintExAccountCp(programId, new PublicKey(mintA.address)).publicKey);\n if (mintB.programId === TOKEN_2022_PROGRAM_ID.toBase58())\n fetchAccounts.push(getPdaMintExAccountCp(programId, new PublicKey(mintB.address)).publicKey);\n const extMintRes = await this.scope.connection.getMultipleAccountsInfo(fetchAccounts);\n\n extMintRes.forEach((r, idx) => {\n if (r) extendMintAccount.push(fetchAccounts[idx]);\n });\n }\n\n txBuilder.addInstruction({\n instructions: [\n makeCreateCpmmPoolInInstruction(\n programId,\n this.scope.ownerPubKey,\n new PublicKey(feeConfig.id),\n poolKeys.authority,\n poolKeys.poolId,\n mintAPubkey,\n mintBPubkey,\n poolKeys.lpMint,\n userVaultA,\n userVaultB,\n getATAAddress(this.scope.ownerPubKey, poolKeys.lpMint).publicKey,\n poolKeys.vaultA,\n poolKeys.vaultB,\n poolFeeAccount,\n new PublicKey(mintA.programId ?? TOKEN_PROGRAM_ID),\n new PublicKey(mintB.programId ?? TOKEN_PROGRAM_ID),\n poolKeys.observationId,\n mintAAmount,\n mintBAmount,\n startTime,\n extendMintAccount,\n ),\n ],\n instructionTypes: [InstructionType.CpmmCreatePool],\n });\n\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n return txBuilder.versionBuild({\n txVersion,\n extInfo: {\n address: { ...poolKeys, mintA, mintB, programId, poolFeeAccount, feeConfig },\n },\n }) as Promise<MakeTxData<T, { address: CreateCpmmPoolAddress }>>;\n }\n\n public async addLiquidity<T extends TxVersion>(params: AddCpmmLiquidityParams<T>): Promise<MakeTxData<T>> {\n const {\n poolInfo,\n poolKeys: propPoolKeys,\n inputAmount,\n baseIn,\n slippage,\n computeResult,\n computeBudgetConfig,\n txTipConfig,\n config,\n txVersion,\n feePayer,\n } = params;\n\n if (this.scope.availability.addStandardPosition === false)\n this.logAndCreateError(\"add liquidity feature disabled in your region\");\n\n if (inputAmount.isZero())\n this.logAndCreateError(\"amounts must greater than zero\", \"amountInA\", {\n amountInA: inputAmount.toString(),\n });\n const { account } = this.scope;\n const { bypassAssociatedCheck, checkCreateATAOwner } = {\n // default\n ...{ bypassAssociatedCheck: false, checkCreateATAOwner: false },\n // custom\n ...config,\n };\n const rpcPoolData = computeResult ? undefined : await this.getRpcPoolInfo(poolInfo.id);\n\n const {\n liquidity,\n inputAmountFee,\n anotherAmount: _anotherAmount,\n } = computeResult ||\n this.computePairAmount({\n poolInfo: {\n ...poolInfo,\n lpAmount: new Decimal(rpcPoolData!.lpAmount.toString()).div(10 ** poolInfo.lpMint.decimals).toNumber(),\n },\n baseReserve: rpcPoolData!.baseReserve,\n quoteReserve: rpcPoolData!.quoteReserve,\n slippage: new Percent(0),\n baseIn,\n epochInfo: await this.scope.fetchEpochInfo(),\n amount: new Decimal(inputAmount.toString()).div(\n 10 ** (baseIn ? poolInfo.mintA.decimals : poolInfo.mintB.decimals),\n ),\n });\n\n const anotherAmount = _anotherAmount.amount;\n const mintAUseSOLBalance = poolInfo.mintA.address === NATIVE_MINT.toString();\n const mintBUseSOLBalance = poolInfo.mintB.address === NATIVE_MINT.toString();\n\n const txBuilder = this.createTxBuilder(feePayer);\n const [mintA, mintB] = [new PublicKey(poolInfo.mintA.address), new PublicKey(poolInfo.mintB.address)];\n\n const { account: tokenAccountA, instructionParams: _tokenAccountAInstruction } =\n await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: poolInfo.mintA.programId,\n mint: new PublicKey(poolInfo.mintA.address),\n owner: this.scope.ownerPubKey,\n\n createInfo:\n mintAUseSOLBalance || (baseIn ? inputAmount : anotherAmount).isZero()\n ? {\n payer: this.scope.ownerPubKey,\n amount: baseIn ? inputAmount : anotherAmount,\n }\n : undefined,\n skipCloseAccount: !mintAUseSOLBalance,\n notUseTokenAccount: mintAUseSOLBalance,\n associatedOnly: false,\n checkCreateATAOwner,\n });\n\n txBuilder.addInstruction(_tokenAccountAInstruction || {});\n\n const { account: tokenAccountB, instructionParams: _tokenAccountBInstruction } =\n await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: poolInfo.mintB.programId,\n mint: new PublicKey(poolInfo.mintB.address),\n owner: this.scope.ownerPubKey,\n\n createInfo:\n mintBUseSOLBalance || (baseIn ? anotherAmount : inputAmount).isZero()\n ? {\n payer: this.scope.ownerPubKey,\n amount: baseIn ? anotherAmount : inputAmount,\n }\n : undefined,\n skipCloseAccount: !mintBUseSOLBalance,\n notUseTokenAccount: mintBUseSOLBalance,\n associatedOnly: false,\n checkCreateATAOwner,\n });\n\n txBuilder.addInstruction(_tokenAccountBInstruction || {});\n\n if (!tokenAccountA && !tokenAccountB)\n this.logAndCreateError(\"cannot found target token accounts\", \"tokenAccounts\", account.tokenAccounts);\n const lpTokenAccount = await account.getCreatedTokenAccount({\n mint: new PublicKey(poolInfo.lpMint.address),\n });\n const { tokenAccount: _lpTokenAccount, ...lpInstruction } = await account.handleTokenAccount({\n side: \"out\",\n amount: 0,\n mint: new PublicKey(poolInfo.lpMint.address),\n tokenAccount: lpTokenAccount,\n bypassAssociatedCheck,\n checkCreateATAOwner,\n });\n txBuilder.addInstruction(lpInstruction);\n const poolKeys = propPoolKeys ?? (await this.getCpmmPoolKeys(poolInfo.id));\n const _slippage = new Percent(new BN(1)).sub(slippage);\n\n txBuilder.addInstruction({\n instructions: [\n makeDepositCpmmInInstruction(\n new PublicKey(poolInfo.programId),\n this.scope.ownerPubKey,\n new PublicKey(poolKeys.authority),\n new PublicKey(poolInfo.id),\n _lpTokenAccount!,\n tokenAccountA!,\n tokenAccountB!,\n new PublicKey(poolKeys.vault.A),\n new PublicKey(poolKeys.vault.B),\n mintA,\n mintB,\n new PublicKey(poolInfo.lpMint.address),\n\n computeResult ? computeResult?.liquidity : _slippage.mul(liquidity).quotient,\n baseIn ? inputAmountFee.amount : anotherAmount,\n baseIn ? anotherAmount : inputAmountFee.amount,\n ),\n ],\n instructionTypes: [InstructionType.CpmmAddLiquidity],\n lookupTableAddress: poolKeys.lookupTableAccount ? [poolKeys.lookupTableAccount] : [],\n });\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n return txBuilder.versionBuild({\n txVersion,\n lookupTableAddress: poolKeys.lookupTableAccount ? [poolKeys.lookupTableAccount] : undefined,\n }) as Promise<MakeTxData<T>>;\n }\n\n public async withdrawLiquidity<T extends TxVersion>(params: WithdrawCpmmLiquidityParams<T>): Promise<MakeTxData<T>> {\n const {\n poolInfo,\n poolKeys: propPoolKeys,\n lpAmount,\n slippage,\n computeBudgetConfig,\n txTipConfig,\n txVersion,\n feePayer,\n closeWsol = true,\n } = params;\n\n if (this.scope.availability.addStandardPosition === false)\n this.logAndCreateError(\"add liquidity feature disabled in your region\");\n\n const _slippage = new Percent(new BN(1)).sub(slippage);\n\n const rpcPoolData = await this.getRpcPoolInfo(poolInfo.id);\n const [amountMintA, amountMintB] = [\n _slippage.mul(lpAmount.mul(rpcPoolData.baseReserve).div(rpcPoolData.lpAmount)).quotient,\n _slippage.mul(lpAmount.mul(rpcPoolData.quoteReserve).div(rpcPoolData.lpAmount)).quotient,\n ];\n\n const epochInfo = await this.scope.fetchEpochInfo();\n const [mintAAmountFee, mintBAmountFee] = [\n getTransferAmountFeeV2(amountMintA, poolInfo.mintA.extensions.feeConfig, epochInfo, false),\n getTransferAmountFeeV2(amountMintB, poolInfo.mintB.extensions.feeConfig, epochInfo, false),\n ];\n\n const { account } = this.scope;\n const txBuilder = this.createTxBuilder(feePayer);\n const [mintA, mintB] = [new PublicKey(poolInfo.mintA.address), new PublicKey(poolInfo.mintB.address)];\n\n const mintAUseSOLBalance = mintA.equals(WSOLMint);\n const mintBUseSOLBalance = mintB.equals(WSOLMint);\n\n let tokenAccountA: PublicKey | undefined = undefined;\n let tokenAccountB: PublicKey | undefined = undefined;\n const { account: _ownerTokenAccountA, instructionParams: accountAInstructions } =\n await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: poolInfo.mintA.programId,\n mint: new PublicKey(poolInfo.mintA.address),\n notUseTokenAccount: mintAUseSOLBalance,\n owner: this.scope.ownerPubKey,\n createInfo: {\n payer: this.scope.ownerPubKey,\n amount: 0,\n },\n skipCloseAccount: !(mintAUseSOLBalance && closeWsol),\n associatedOnly: mintAUseSOLBalance ? false : true,\n checkCreateATAOwner: false,\n });\n tokenAccountA = _ownerTokenAccountA;\n accountAInstructions && txBuilder.addInstruction(accountAInstructions);\n\n const { account: _ownerTokenAccountB, instructionParams: accountBInstructions } =\n await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: poolInfo.mintB.programId,\n mint: new PublicKey(poolInfo.mintB.address),\n notUseTokenAccount: mintBUseSOLBalance,\n owner: this.scope.ownerPubKey,\n createInfo: {\n payer: this.scope.ownerPubKey,\n amount: 0,\n },\n skipCloseAccount: !(mintBUseSOLBalance && closeWsol),\n associatedOnly: mintBUseSOLBalance ? false : true,\n checkCreateATAOwner: false,\n });\n tokenAccountB = _ownerTokenAccountB;\n accountBInstructions && txBuilder.addInstruction(accountBInstructions);\n\n if (!tokenAccountA || !tokenAccountB)\n this.logAndCreateError(\"cannot found target token accounts\", \"tokenAccounts\", account.tokenAccounts);\n\n const lpTokenAccount = await account.getCreatedTokenAccount({\n mint: new PublicKey(poolInfo.lpMint.address),\n });\n\n if (!lpTokenAccount)\n this.logAndCreateError(\"cannot found lp token account\", \"tokenAccounts\", account.tokenAccounts);\n const poolKeys = propPoolKeys ?? (await this.getCpmmPoolKeys(poolInfo.id));\n txBuilder.addInstruction({\n instructions: [\n makeWithdrawCpmmInInstruction(\n new PublicKey(poolInfo.programId),\n this.scope.ownerPubKey,\n new PublicKey(poolKeys.authority),\n new PublicKey(poolInfo.id),\n lpTokenAccount!,\n tokenAccountA!,\n tokenAccountB!,\n new PublicKey(poolKeys.vault.A),\n new PublicKey(poolKeys.vault.B),\n mintA,\n mintB,\n new PublicKey(poolInfo.lpMint.address),\n\n lpAmount,\n amountMintA.sub(mintAAmountFee.fee ?? new BN(0)),\n amountMintB.sub(mintBAmountFee.fee ?? new BN(0)),\n ),\n ],\n instructionTypes: [InstructionType.CpmmWithdrawLiquidity],\n lookupTableAddress: poolKeys.lookupTableAccount ? [poolKeys.lookupTableAccount] : [],\n });\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n return txBuilder.versionBuild({\n txVersion,\n lookupTableAddress: poolKeys.lookupTableAccount ? [poolKeys.lookupTableAccount] : undefined,\n }) as Promise<MakeTxData<T>>;\n }\n\n public async swap<T extends TxVersion>(params: CpmmSwapParams<T>): Promise<MakeTxData<T>> {\n const {\n poolInfo,\n poolKeys: propPoolKeys,\n baseIn,\n fixedOut,\n inputAmount,\n swapResult,\n slippage = 0,\n config,\n computeBudgetConfig,\n txTipConfig,\n txVersion,\n feePayer,\n } = params;\n\n const { bypassAssociatedCheck, checkCreateATAOwner, associatedOnly } = {\n // default\n ...{ bypassAssociatedCheck: false, checkCreateATAOwner: false, associatedOnly: true },\n // custom\n ...config,\n };\n\n const txBuilder = this.createTxBuilder(feePayer);\n\n const [mintA, mintB] = [new PublicKey(poolInfo.mintA.address), new PublicKey(poolInfo.mintB.address)];\n\n if (!fixedOut) {\n swapResult.outputAmount = swapResult.outputAmount.mul(new BN((1 - slippage) * 10000)).div(new BN(10000));\n } else {\n swapResult.inputAmount = swapResult.inputAmount.mul(new BN((1 + slippage) * 10000)).div(new BN(10000));\n }\n\n const mintAUseSOLBalance = poolInfo.mintA.address === WSOLMint.toBase58();\n const mintBUseSOLBalance = poolInfo.mintB.address === WSOLMint.toBase58();\n const { account: mintATokenAcc, instructionParams: mintATokenAccInstruction } =\n await this.scope.account.getOrCreateTokenAccount({\n mint: mintA,\n tokenProgram: new PublicKey(poolInfo.mintA.programId ?? TOKEN_PROGRAM_ID),\n owner: this.scope.ownerPubKey,\n createInfo:\n mintAUseSOLBalance || !baseIn\n ? {\n payer: feePayer || this.scope.ownerPubKey,\n amount: baseIn ? swapResult.inputAmount : 0,\n }\n : undefined,\n notUseTokenAccount: mintAUseSOLBalance,\n skipCloseAccount: !mintAUseSOLBalance,\n associatedOnly: mintAUseSOLBalance ? false : associatedOnly,\n checkCreateATAOwner,\n });\n mintATokenAccInstruction && txBuilder.addInstruction(mintATokenAccInstruction);\n\n const { account: mintBTokenAcc, instructionParams: mintBTokenAccInstruction } =\n await this.scope.account.getOrCreateTokenAccount({\n mint: mintB,\n tokenProgram: new PublicKey(poolInfo.mintB.programId ?? TOKEN_PROGRAM_ID),\n owner: this.scope.ownerPubKey,\n createInfo:\n mintBUseSOLBalance || baseIn\n ? {\n payer: feePayer || this.scope.ownerPubKey,\n amount: baseIn ? 0 : swapResult.inputAmount,\n }\n : undefined,\n notUseTokenAccount: mintBUseSOLBalance,\n skipCloseAccount: !mintBUseSOLBalance,\n associatedOnly: mintBUseSOLBalance ? false : associatedOnly,\n checkCreateATAOwner,\n });\n mintBTokenAccInstruction && txBuilder.addInstruction(mintBTokenAccInstruction);\n\n if (!mintATokenAcc || !mintBTokenAcc)\n this.logAndCreateError(\"user do not have token account\", {\n mintA: poolInfo.mintA.symbol || poolInfo.mintA.address,\n mintB: poolInfo.mintB.symbol || poolInfo.mintB.address,\n mintATokenAcc,\n mintBTokenAcc,\n mintAUseSOLBalance,\n mintBUseSOLBalance,\n associatedOnly,\n });\n\n const poolKeys = propPoolKeys ?? (await this.getCpmmPoolKeys(poolInfo.id));\n\n txBuilder.addInstruction({\n instructions: [\n !fixedOut\n ? makeSwapCpmmBaseInInstruction(\n new PublicKey(poolInfo.programId),\n this.scope.ownerPubKey,\n new PublicKey(poolKeys.authority),\n new PublicKey(poolKeys.config.id),\n new PublicKey(poolInfo.id),\n baseIn ? mintATokenAcc! : mintBTokenAcc!,\n baseIn ? mintBTokenAcc! : mintATokenAcc!,\n new PublicKey(poolKeys.vault[baseIn ? \"A\" : \"B\"]),\n new PublicKey(poolKeys.vault[baseIn ? \"B\" : \"A\"]),\n new PublicKey(poolInfo[baseIn ? \"mintA\" : \"mintB\"].programId ?? TOKEN_PROGRAM_ID),\n new PublicKey(poolInfo[baseIn ? \"mintB\" : \"mintA\"].programId ?? TOKEN_PROGRAM_ID),\n baseIn ? mintA : mintB,\n baseIn ? mintB : mintA,\n getPdaObservationId(new PublicKey(poolInfo.programId), new PublicKey(poolInfo.id)).publicKey,\n\n inputAmount,\n swapResult.outputAmount,\n )\n : makeSwapCpmmBaseOutInstruction(\n new PublicKey(poolInfo.programId),\n this.scope.ownerPubKey,\n new PublicKey(poolKeys.authority),\n new PublicKey(poolKeys.config.id),\n new PublicKey(poolInfo.id),\n\n baseIn ? mintATokenAcc! : mintBTokenAcc!,\n baseIn ? mintBTokenAcc! : mintATokenAcc!,\n\n new PublicKey(poolKeys.vault[baseIn ? \"A\" : \"B\"]),\n new PublicKey(poolKeys.vault[baseIn ? \"B\" : \"A\"]),\n new PublicKey(poolInfo[baseIn ? \"mintA\" : \"mintB\"].programId ?? TOKEN_PROGRAM_ID),\n new PublicKey(poolInfo[baseIn ? \"mintB\" : \"mintA\"].programId ?? TOKEN_PROGRAM_ID),\n baseIn ? mintA : mintB,\n baseIn ? mintB : mintA,\n\n getPdaObservationId(new PublicKey(poolInfo.programId), new PublicKey(poolInfo.id)).publicKey,\n\n swapResult.inputAmount,\n swapResult.outputAmount,\n ),\n ],\n instructionTypes: [fixedOut ? InstructionType.CpmmSwapBaseOut : InstructionType.ClmmSwapBaseIn],\n });\n\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n return txBuilder.versionBuild({\n txVersion,\n lookupTableAddress: poolKeys.lookupTableAccount ? [poolKeys.lookupTableAccount] : undefined,\n }) as Promise<MakeTxData<T>>;\n }\n\n public async lockLp<T extends TxVersion>(params: LockCpmmLpParams<T>): Promise<MakeTxData<CpmmLockExtInfo>> {\n const { poolInfo, lpAmount, computeBudgetConfig, txTipConfig, txVersion, feePayer, feeNftOwner } = params;\n\n if (lpAmount.isZero())\n this.logAndCreateError(\"lpAmount must greater than zero\", {\n lpAmount: lpAmount.toString(),\n });\n\n const txBuilder = this.createTxBuilder(feePayer);\n\n const poolKeys = params.poolKeys ?? (await this.getCpmmPoolKeys(poolInfo.id));\n\n const insData = await makeCpmmLockInstruction({\n poolInfo,\n poolKeys,\n ownerInfo: {\n wallet: this.scope.ownerPubKey,\n feePayer: params.feePayer ?? this.scope.ownerPubKey,\n },\n feeNftOwner: feeNftOwner ?? this.scope.ownerPubKey,\n lockProgram: params.programId ?? LOCK_CPMM_PROGRAM,\n lockAuthProgram: params.authProgram ?? LOCK_CPMM_AUTH,\n lpAmount,\n withMetadata: params.withMetadata ?? true,\n getEphemeralSigners: params.getEphemeralSigners,\n });\n\n txBuilder.addInstruction(insData);\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n return txBuilder.versionBuild({\n txVersion,\n extInfo: insData.address,\n lookupTableAddress: poolKeys.lookupTableAccount ? [poolKeys.lookupTableAccount] : undefined,\n }) as Promise<MakeTxData<CpmmLockExtInfo>>;\n }\n\n public async harvestLockLp<T extends TxVersion>(params: HarvestLockCpmmLpParams<T>): Promise<MakeTxData> {\n const {\n poolInfo,\n lpFeeAmount,\n nftMint,\n programId = LOCK_CPMM_PROGRAM,\n authProgram = LOCK_CPMM_AUTH,\n cpmmProgram,\n computeBudgetConfig,\n txTipConfig,\n txVersion,\n closeWsol = true,\n } = params;\n\n if (lpFeeAmount.isZero())\n this.logAndCreateError(\"lpFeeAmount must greater than zero\", {\n lpAmount: lpFeeAmount.toString(),\n });\n\n const feePayer = params.feePayer || this.scope.ownerPubKey;\n\n const txBuilder = this.createTxBuilder(feePayer);\n\n const [mintA, mintB] = [new PublicKey(poolInfo.mintA.address), new PublicKey(poolInfo.mintB.address)];\n\n const mintAUseSOLBalance = mintA.equals(WSOLMint);\n const mintBUseSOLBalance = mintB.equals(WSOLMint);\n\n let tokenAccountA: PublicKey | undefined = undefined;\n let tokenAccountB: PublicKey | undefined = undefined;\n const { account: _ownerTokenAccountA, instructionParams: accountAInstructions } =\n await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: poolInfo.mintA.programId,\n mint: new PublicKey(poolInfo.mintA.address),\n notUseTokenAccount: mintAUseSOLBalance,\n owner: this.scope.ownerPubKey,\n createInfo: {\n payer: this.scope.ownerPubKey,\n amount: 0,\n },\n skipCloseAccount: !(mintAUseSOLBalance && closeWsol),\n associatedOnly: mintAUseSOLBalance ? false : true,\n checkCreateATAOwner: false,\n });\n tokenAccountA = _ownerTokenAccountA;\n accountAInstructions && txBuilder.addInstruction(accountAInstructions);\n\n const { account: _ownerTokenAccountB, instructionParams: accountBInstructions } =\n await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: poolInfo.mintB.programId,\n mint: new PublicKey(poolInfo.mintB.address),\n notUseTokenAccount: mintBUseSOLBalance,\n owner: this.scope.ownerPubKey,\n createInfo: {\n payer: this.scope.ownerPubKey,\n amount: 0,\n },\n skipCloseAccount: !(mintBUseSOLBalance && closeWsol),\n associatedOnly: mintBUseSOLBalance ? false : true,\n checkCreateATAOwner: false,\n });\n tokenAccountB = _ownerTokenAccountB;\n accountBInstructions && txBuilder.addInstruction(accountBInstructions);\n\n if (!tokenAccountA || !tokenAccountB)\n this.logAndCreateError(\"cannot found target token accounts\", { tokenAccountA, tokenAccountB });\n\n const poolKeys = params.poolKeys ?? (await this.getCpmmPoolKeys(poolInfo.id));\n\n const { publicKey: nftAccount } = getATAAddress(feePayer, nftMint, TOKEN_PROGRAM_ID);\n const { publicKey: lockPda } = getCpLockPda(programId, nftMint);\n const { publicKey: lockLpVault } = getATAAddress(\n authProgram,\n new PublicKey(poolInfo.lpMint.address),\n TOKEN_PROGRAM_ID,\n );\n\n txBuilder.addInstruction({\n instructions: [\n collectCpFeeInstruction({\n programId,\n nftOwner: this.scope.ownerPubKey,\n auth: authProgram,\n\n nftMint,\n nftAccount,\n\n lockPda,\n poolId: new PublicKey(poolInfo.id),\n mintLp: new PublicKey(poolKeys.mintLp.address),\n\n userVaultA: tokenAccountA!,\n userVaultB: tokenAccountB!,\n poolVaultA: new PublicKey(poolKeys.vault.A),\n poolVaultB: new PublicKey(poolKeys.vault.B),\n\n mintA,\n mintB,\n lockLpVault,\n lpFeeAmount,\n\n cpmmProgram: cpmmProgram?.programId,\n cpmmAuthProgram: cpmmProgram?.authProgram,\n }),\n ],\n instructionTypes: [InstructionType.CpmmCollectLockFee],\n });\n\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n return txBuilder.versionBuild({\n txVersion,\n lookupTableAddress: poolKeys.lookupTableAccount ? [poolKeys.lookupTableAccount] : undefined,\n }) as Promise<MakeTxData>;\n }\n\n public async harvestMultiLockLp<T extends TxVersion>(\n params: HarvestMultiLockCpmmLpParams<T>,\n ): Promise<MakeMultiTxData<T>> {\n const {\n lockInfo,\n programId = LOCK_CPMM_PROGRAM,\n authProgram = LOCK_CPMM_AUTH,\n cpmmProgram,\n computeBudgetConfig,\n txVersion,\n closeWsol = true,\n } = params;\n\n const feePayer = params.feePayer || this.scope.ownerPubKey;\n const txBuilder = this.createTxBuilder(feePayer);\n const tokenAccRecord: Record<string, PublicKey | undefined> = {};\n const lookupTableAccounts: string[] = [];\n\n for (const lockData of lockInfo) {\n const { poolInfo, lpFeeAmount, nftMint } = lockData;\n if (lpFeeAmount.isZero()) continue;\n\n const [mintA, mintB] = [new PublicKey(poolInfo.mintA.address), new PublicKey(poolInfo.mintB.address)];\n\n const mintAUseSOLBalance = mintA.equals(WSOLMint);\n const mintBUseSOLBalance = mintB.equals(WSOLMint);\n\n let tokenAccountA: PublicKey | undefined = tokenAccRecord[poolInfo.mintA.address];\n let tokenAccountB: PublicKey | undefined = tokenAccRecord[poolInfo.mintB.address];\n\n if (!tokenAccountA) {\n if (mintAUseSOLBalance) {\n const { account: _ownerTokenAccountA, instructionParams: accountAInstructions } =\n await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: poolInfo.mintA.programId,\n mint: new PublicKey(poolInfo.mintA.address),\n notUseTokenAccount: true,\n owner: this.scope.ownerPubKey,\n createInfo: {\n payer: this.scope.ownerPubKey,\n amount: 0,\n },\n skipCloseAccount: !closeWsol,\n associatedOnly: false,\n checkCreateATAOwner: false,\n });\n tokenAccountA = _ownerTokenAccountA;\n accountAInstructions && txBuilder.addInstruction(accountAInstructions);\n tokenAccRecord[poolInfo.mintA.address] = _ownerTokenAccountA;\n } else {\n const mint = new PublicKey(poolInfo.mintA.address);\n tokenAccountA = this.scope.account.getAssociatedTokenAccount(mint, new PublicKey(poolInfo.mintA.programId));\n txBuilder.addInstruction({\n instructions: [\n createAssociatedTokenAccountIdempotentInstruction(\n this.scope.ownerPubKey,\n tokenAccountA,\n this.scope.ownerPubKey,\n mint,\n new PublicKey(poolInfo.mintA.programId),\n ),\n ],\n });\n tokenAccRecord[poolInfo.mintA.address] = tokenAccountA;\n }\n }\n\n if (!tokenAccountB) {\n if (mintBUseSOLBalance) {\n const { account: _ownerTokenAccountB, instructionParams: accountBInstructions } =\n await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: poolInfo.mintB.programId,\n mint: new PublicKey(poolInfo.mintB.address),\n notUseTokenAccount: true,\n owner: this.scope.ownerPubKey,\n createInfo: {\n payer: this.scope.ownerPubKey,\n amount: 0,\n },\n skipCloseAccount: !closeWsol,\n associatedOnly: false,\n checkCreateATAOwner: false,\n });\n tokenAccountB = _ownerTokenAccountB;\n accountBInstructions && txBuilder.addInstruction(accountBInstructions);\n tokenAccRecord[poolInfo.mintB.address] = _ownerTokenAccountB;\n } else {\n const mint = new PublicKey(poolInfo.mintB.address);\n tokenAccountB = this.scope.account.getAssociatedTokenAccount(mint, new PublicKey(poolInfo.mintB.programId));\n txBuilder.addInstruction({\n instructions: [\n createAssociatedTokenAccountIdempotentInstruction(\n this.scope.ownerPubKey,\n tokenAccountB,\n this.scope.ownerPubKey,\n mint,\n new PublicKey(poolInfo.mintB.programId),\n ),\n ],\n });\n tokenAccRecord[poolInfo.mintB.address] = tokenAccountB;\n }\n }\n\n if (!tokenAccountA || !tokenAccountB)\n this.logAndCreateError(\"cannot found target token accounts\", { tokenAccountA, tokenAccountB });\n\n const poolKeys = lockData.poolKeys ?? (await this.getCpmmPoolKeys(poolInfo.id));\n if (poolKeys.lookupTableAccount) lookupTableAccounts.push(poolKeys.lookupTableAccount);\n\n const { publicKey: nftAccount } = getATAAddress(feePayer, nftMint, TOKEN_PROGRAM_ID);\n const { publicKey: lockPda } = getCpLockPda(programId, nftMint);\n const { publicKey: lockLpVault } = getATAAddress(\n authProgram,\n new PublicKey(poolInfo.lpMint.address),\n TOKEN_PROGRAM_ID,\n );\n\n txBuilder.addInstruction({\n instructions: [\n collectCpFeeInstruction({\n programId,\n nftOwner: this.scope.ownerPubKey,\n auth: authProgram,\n\n nftMint,\n nftAccount,\n\n lockPda,\n poolId: new PublicKey(poolInfo.id),\n mintLp: new PublicKey(poolKeys.mintLp.address),\n\n userVaultA: tokenAccountA!,\n userVaultB: tokenAccountB!,\n poolVaultA: new PublicKey(poolKeys.vault.A),\n poolVaultB: new PublicKey(poolKeys.vault.B),\n\n mintA,\n mintB,\n lockLpVault,\n lpFeeAmount,\n\n cpmmProgram: cpmmProgram?.programId,\n cpmmAuthProgram: cpmmProgram?.authProgram,\n }),\n ],\n instructionTypes: [InstructionType.CpmmCollectLockFee],\n });\n }\n\n if (txVersion === TxVersion.V0)\n return txBuilder.sizeCheckBuildV0({ computeBudgetConfig, lookupTableAddress: lookupTableAccounts }) as Promise<\n MakeMultiTxData<T>\n >;\n return txBuilder.sizeCheckBuild({ computeBudgetConfig }) as Promise<MakeMultiTxData<T>>;\n }\n\n public async createPoolWithPermission<T extends TxVersion>({\n poolId,\n programId,\n poolFeeAccount,\n startTime,\n ownerInfo,\n associatedOnly = false,\n checkCreateATAOwner = false,\n txVersion,\n feeConfig,\n computeBudgetConfig,\n txTipConfig,\n feePayer,\n feeOn,\n ...params\n }: CreateCpmmPoolPermissionParam<T>): Promise<MakeTxData<T, { address: CreateCpmmPoolAddress }>> {\n console.log(\"***this method only available for wallet with permissions***\");\n const payer = ownerInfo.feePayer || this.scope.owner?.publicKey;\n const isFront = new BN(new PublicKey(params.mintA.address).toBuffer()).lte(\n new BN(new PublicKey(params.mintB.address).toBuffer()),\n );\n\n const [mintA, mintB] = isFront ? [params.mintA, params.mintB] : [params.mintB, params.mintA];\n const [mintAAmount, mintBAmount] = isFront\n ? [params.mintAAmount, params.mintBAmount]\n : [params.mintBAmount, params.mintAAmount];\n\n const mintAUseSOLBalance = ownerInfo.useSOLBalance && mintA.address === NATIVE_MINT.toBase58();\n const mintBUseSOLBalance = ownerInfo.useSOLBalance && mintB.address === NATIVE_MINT.toBase58();\n const [mintAPubkey, mintBPubkey] = [new PublicKey(mintA.address), new PublicKey(mintB.address)];\n const txBuilder = this.createTxBuilder(feePayer);\n\n const { account: userVaultA, instructionParams: userVaultAInstruction } =\n await this.scope.account.getOrCreateTokenAccount({\n mint: mintAPubkey,\n tokenProgram: mintA.programId,\n owner: this.scope.ownerPubKey,\n createInfo: mintAUseSOLBalance\n ? {\n payer: payer!,\n amount: mintAAmount,\n }\n : undefined,\n notUseTokenAccount: mintAUseSOLBalance,\n skipCloseAccount: !mintAUseSOLBalance,\n associatedOnly: mintAUseSOLBalance ? false : associatedOnly,\n checkCreateATAOwner,\n });\n txBuilder.addInstruction(userVaultAInstruction || {});\n const { account: userVaultB, instructionParams: userVaultBInstruction } =\n await this.scope.account.getOrCreateTokenAccount({\n mint: new PublicKey(mintB.address),\n tokenProgram: mintB.programId,\n owner: this.scope.ownerPubKey,\n createInfo: mintBUseSOLBalance\n ? {\n payer: payer!,\n amount: mintBAmount,\n }\n : undefined,\n\n notUseTokenAccount: mintBUseSOLBalance,\n skipCloseAccount: !mintBUseSOLBalance,\n associatedOnly: mintBUseSOLBalance ? false : associatedOnly,\n checkCreateATAOwner,\n });\n txBuilder.addInstruction(userVaultBInstruction || {});\n\n if (userVaultA === undefined || userVaultB === undefined) throw Error(\"you don't has some token account\");\n\n const poolKeys = getCreatePoolKeys({\n poolId,\n programId,\n configId: new PublicKey(feeConfig.id),\n mintA: mintAPubkey,\n mintB: mintBPubkey,\n });\n\n txBuilder.addInstruction({\n instructions: [\n initializeWithPermission(\n programId,\n this.scope.ownerPubKey,\n this.scope.ownerPubKey,\n new PublicKey(feeConfig.id),\n poolKeys.authority,\n poolKeys.poolId,\n mintAPubkey,\n mintBPubkey,\n poolKeys.lpMint,\n userVaultA,\n userVaultB,\n getATAAddress(this.scope.ownerPubKey, poolKeys.lpMint).publicKey,\n poolKeys.vaultA,\n poolKeys.vaultB,\n poolFeeAccount,\n new PublicKey(mintA.programId ?? TOKEN_PROGRAM_ID),\n new PublicKey(mintB.programId ?? TOKEN_PROGRAM_ID),\n poolKeys.observationId,\n getPdaPermissionId(programId, this.scope.ownerPubKey).publicKey,\n\n mintAAmount,\n mintBAmount,\n startTime,\n\n feeOn,\n ),\n ],\n instructionTypes: [InstructionType.CpmmCreatePool],\n });\n\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n return txBuilder.versionBuild({\n txVersion,\n extInfo: {\n address: { ...poolKeys, mintA, mintB, programId, poolFeeAccount, feeConfig },\n },\n }) as Promise<MakeTxData<T, { address: CreateCpmmPoolAddress }>>;\n }\n\n public async collectCreatorFees<T extends TxVersion>({\n poolInfo,\n poolKeys: propPoolKeys,\n programId = CREATE_CPMM_POOL_PROGRAM,\n txVersion,\n computeBudgetConfig,\n txTipConfig,\n feePayer,\n }: CollectCreatorFees<T>): Promise<MakeTxData<T>> {\n const payer = feePayer || this.scope.ownerPubKey;\n const txBuilder = this.createTxBuilder(payer);\n\n const poolKeys = propPoolKeys ?? (await this.getCpmmPoolKeys(poolInfo.id));\n\n const [mintA, mintB, mintAProgram, mintBProgram] = [\n new PublicKey(poolInfo.mintA.address),\n new PublicKey(poolInfo.mintB.address),\n new PublicKey(poolInfo.mintA.programId),\n new PublicKey(poolInfo.mintB.programId),\n ];\n\n const tokenAccountA = this.scope.account.getAssociatedTokenAccount(mintA, mintAProgram);\n const tokenAccountB = this.scope.account.getAssociatedTokenAccount(mintB, mintBProgram);\n txBuilder.addInstruction({\n instructions: [\n createAssociatedTokenAccountIdempotentInstruction(\n this.scope.ownerPubKey,\n tokenAccountA,\n this.scope.ownerPubKey,\n mintA,\n new PublicKey(poolInfo.mintA.programId),\n ),\n createAssociatedTokenAccountIdempotentInstruction(\n this.scope.ownerPubKey,\n tokenAccountB,\n this.scope.ownerPubKey,\n mintB,\n new PublicKey(poolInfo.mintB.programId),\n ),\n ],\n });\n\n txBuilder.addInstruction({\n instructions: [\n makeCollectCreatorFeeInstruction(\n programId,\n this.scope.ownerPubKey,\n new PublicKey(poolKeys.authority),\n new PublicKey(poolKeys.id),\n new PublicKey(poolKeys.config.id),\n new PublicKey(poolKeys.vault.A),\n new PublicKey(poolKeys.vault.B),\n mintA,\n mintB,\n tokenAccountA,\n tokenAccountB,\n mintAProgram,\n mintBProgram,\n ),\n ],\n instructionTypes: [],\n });\n\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n return txBuilder.versionBuild({\n txVersion,\n }) as Promise<MakeTxData<T>>;\n }\n\n public async collectMultiCreatorFees<T extends TxVersion>({\n poolInfoList,\n poolKeyList: propsPoolKeyList,\n programId = CREATE_CPMM_POOL_PROGRAM,\n txVersion,\n computeBudgetConfig,\n feePayer,\n }: CollectMultiCreatorFees<T>): Promise<MakeMultiTxData<T>> {\n const payer = feePayer || this.scope.ownerPubKey;\n const txBuilder = this.createTxBuilder(payer);\n\n const tokenAccRecord: Record<string, PublicKey> = {};\n\n let poolKeyList = propsPoolKeyList ?? [];\n\n if (!poolKeyList.length) {\n const idList = poolInfoList.map((p) => p.id);\n const chunkSize = 95;\n const keyGroup: string[][] = [];\n for (let i = 0; i < idList.length; i += chunkSize) {\n keyGroup.push(idList.slice(i, i + chunkSize));\n }\n\n const r = (await Promise.all(\n keyGroup.map((list) => this.scope.api.fetchPoolKeysById({ idList: list })),\n )) as CpmmKeys[][];\n poolKeyList = r.flat();\n }\n const poolKeysRecord = poolKeyList.reduce(\n (acc, cur) => ({\n ...acc,\n [cur.id]: cur,\n }),\n {} as Record<string, CpmmKeys>,\n );\n\n for (const poolInfo of poolInfoList) {\n const poolKeys = (poolKeysRecord[poolInfo.id] || (await this.getCpmmPoolKeys(poolInfo.id))) as CpmmKeys;\n const [mintA, mintB, mintAProgram, mintBProgram] = [\n new PublicKey(poolInfo.mintA.address),\n new PublicKey(poolInfo.mintB.address),\n new PublicKey(poolInfo.mintA.programId),\n new PublicKey(poolInfo.mintB.programId),\n ];\n\n const tokenAccountA =\n tokenAccRecord[poolInfo.mintA.address] || this.scope.account.getAssociatedTokenAccount(mintA, mintAProgram);\n const tokenAccountB =\n tokenAccRecord[poolInfo.mintB.address] || this.scope.account.getAssociatedTokenAccount(mintB, mintBProgram);\n\n // if (!tokenAccRecord[poolInfo.mintA.address])\n // txBuilder.addInstruction({\n // instructions: [\n // createAssociatedTokenAccountIdempotentInstruction(\n // this.scope.ownerPubKey,\n // tokenAccountA,\n // this.scope.ownerPubKey,\n // mintA,\n // mintAProgram,\n // ),\n // ],\n // });\n\n // if (!tokenAccRecord[poolInfo.mintB.address])\n // txBuilder.addInstruction({\n // instructions: [\n // createAssociatedTokenAccountIdempotentInstruction(\n // this.scope.ownerPubKey,\n // tokenAccountB,\n // this.scope.ownerPubKey,\n // mintB,\n // mintBProgram,\n // ),\n // ],\n // });\n\n tokenAccRecord[poolInfo.mintA.address] = tokenAccountA;\n tokenAccRecord[poolInfo.mintB.address] = tokenAccountB;\n\n txBuilder.addInstruction({\n instructions: [\n makeCollectCreatorFeeInstruction(\n programId,\n this.scope.ownerPubKey,\n new PublicKey(poolKeys.authority),\n new PublicKey(poolKeys.id),\n new PublicKey(poolKeys.config.id),\n new PublicKey(poolKeys.vault.A),\n new PublicKey(poolKeys.vault.B),\n mintA,\n mintB,\n tokenAccountA,\n tokenAccountB,\n mintAProgram,\n mintBProgram,\n ),\n ],\n instructionTypes: [],\n });\n }\n\n if (txVersion === TxVersion.V0)\n return txBuilder.sizeCheckBuildV0({\n computeBudgetConfig,\n lookupTableAddress: poolKeyList.map((p) => p.lookupTableAccount).filter(Boolean) as string[],\n insCountLimit: 6,\n }) as Promise<MakeMultiTxData<T>>;\n return txBuilder.sizeCheckBuild({ computeBudgetConfig }) as Promise<MakeMultiTxData<T>>;\n }\n\n public async collectCreatorFeesPermissionless<T extends TxVersion>({\n poolInfo,\n poolKeys: propPoolKeys,\n programId = CREATE_CPMM_POOL_PROGRAM,\n txVersion,\n computeBudgetConfig,\n txTipConfig,\n feePayer,\n }: CollectCreatorFees<T>): Promise<MakeTxData<T>> {\n const payer = feePayer || this.scope.ownerPubKey;\n const txBuilder = this.createTxBuilder(payer);\n\n const poolKeys = propPoolKeys ?? (await this.getCpmmPoolKeys(poolInfo.id));\n\n const [mintA, mintB, mintAProgram, mintBProgram] = [\n new PublicKey(poolInfo.mintA.address),\n new PublicKey(poolInfo.mintB.address),\n new PublicKey(poolInfo.mintA.programId),\n new PublicKey(poolInfo.mintB.programId),\n ];\n\n const tokenAccountA = this.scope.account.getAssociatedTokenAccount(mintA, mintAProgram);\n const tokenAccountB = this.scope.account.getAssociatedTokenAccount(mintB, mintBProgram);\n txBuilder.addInstruction({\n instructions: [\n createAssociatedTokenAccountIdempotentInstruction(\n this.scope.ownerPubKey,\n tokenAccountA,\n this.scope.ownerPubKey,\n mintA,\n new PublicKey(poolInfo.mintA.programId),\n ),\n createAssociatedTokenAccountIdempotentInstruction(\n this.scope.ownerPubKey,\n tokenAccountB,\n this.scope.ownerPubKey,\n mintB,\n new PublicKey(poolInfo.mintB.programId),\n ),\n ],\n });\n\n txBuilder.addInstruction({\n instructions: [\n collectCreatorFeePermissionlessInInstruction(\n programId,\n payer,\n this.scope.ownerPubKey,\n new PublicKey(poolKeys.authority),\n new PublicKey(poolKeys.id),\n new PublicKey(poolKeys.vault.A),\n new PublicKey(poolKeys.vault.B),\n mintA,\n mintB,\n tokenAccountA,\n tokenAccountB,\n mintAProgram,\n mintBProgram,\n ),\n ],\n instructionTypes: [],\n });\n\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n return txBuilder.versionBuild({\n txVersion,\n }) as Promise<MakeTxData<T>>;\n }\n\n public computeSwapAmount({\n pool,\n amountIn,\n outputMint,\n slippage,\n swapBaseIn = true,\n }: {\n pool: CpmmComputeData;\n amountIn: BN;\n outputMint: string | PublicKey;\n slippage: number;\n swapBaseIn?: boolean;\n }): {\n allTrade: boolean;\n amountIn: BN;\n amountOut: BN;\n minAmountOut: BN;\n fee: BN;\n executionPrice: Decimal;\n priceImpact: Decimal;\n swapResult: SwapResult;\n } {\n const isBaseIn = outputMint.toString() === pool.mintB.address;\n const isCreatorFeeOnInput = pool.feeOn === FeeOn.BothToken || pool.feeOn === FeeOn.OnlyTokenB;\n const swapResult = swapBaseIn\n ? CurveCalculator.swapBaseInput(\n amountIn,\n isBaseIn ? pool.baseReserve : pool.quoteReserve,\n isBaseIn ? pool.quoteReserve : pool.baseReserve,\n pool.configInfo.tradeFeeRate,\n pool.configInfo.creatorFeeRate,\n pool.configInfo.protocolFeeRate,\n pool.configInfo.fundFeeRate,\n isCreatorFeeOnInput,\n )\n : CurveCalculator.swapBaseOutput(\n amountIn,\n isBaseIn ? pool.baseReserve : pool.quoteReserve,\n isBaseIn ? pool.quoteReserve : pool.baseReserve,\n pool.configInfo.tradeFeeRate,\n pool.configInfo.creatorFeeRate,\n pool.configInfo.protocolFeeRate,\n pool.configInfo.fundFeeRate,\n isCreatorFeeOnInput,\n );\n\n const executionPrice = new Decimal(swapResult.outputAmount.toString()).div(swapResult.inputAmount.toString());\n\n const minAmountOut = swapResult.outputAmount.mul(new BN((1 - slippage) * 10000)).div(new BN(10000));\n return {\n allTrade: swapBaseIn ? swapResult.inputAmount.eq(amountIn) : swapResult.outputAmount.eq(amountIn),\n amountIn: swapBaseIn ? amountIn : swapResult.inputAmount,\n amountOut: swapResult.outputAmount,\n minAmountOut,\n executionPrice,\n fee: swapResult.tradeFee,\n priceImpact: pool.poolPrice.sub(executionPrice).div(pool.poolPrice),\n swapResult,\n };\n }\n\n public computePairAmount({\n poolInfo,\n baseReserve,\n quoteReserve,\n amount,\n slippage,\n epochInfo,\n baseIn,\n }: ComputePairAmountParams): {\n inputAmountFee: GetTransferAmountFee;\n anotherAmount: GetTransferAmountFee;\n maxAnotherAmount: GetTransferAmountFee;\n minAnotherAmount: GetTransferAmountFee;\n liquidity: BN;\n } {\n const coefficient = 1 - Number(slippage.toSignificant()) / 100;\n const inputAmount = new BN(\n new Decimal(amount)\n .mul(10 ** poolInfo[baseIn ? \"mintA\" : \"mintB\"].decimals)\n .mul(coefficient)\n .toFixed(0),\n );\n const inputAmountFee = getTransferAmountFeeV2(\n inputAmount,\n poolInfo[baseIn ? \"mintA\" : \"mintB\"].extensions.feeConfig,\n epochInfo,\n false,\n );\n const _inputAmountWithoutFee = inputAmount.sub(inputAmountFee.fee ?? new BN(0));\n\n const lpAmount = new BN(\n new Decimal(poolInfo.lpAmount).mul(10 ** poolInfo.lpMint.decimals).toFixed(0, Decimal.ROUND_DOWN),\n );\n this.logDebug(\"baseReserve:\", baseReserve.toString(), \"quoteReserve:\", quoteReserve.toString());\n\n this.logDebug(\n \"tokenIn:\",\n baseIn ? poolInfo.mintA.symbol : poolInfo.mintB.symbol,\n \"amountIn:\",\n inputAmount.toString(),\n \"amountInFee:\",\n inputAmountFee.fee?.toString() ?? 0,\n \"anotherToken:\",\n baseIn ? poolInfo.mintB.symbol : poolInfo.mintA.symbol,\n \"slippage:\",\n `${slippage.toSignificant()}%`,\n );\n\n // input is fixed\n const input = baseIn ? \"base\" : \"quote\";\n this.logDebug(\"input side:\", input);\n\n const liquidity = _inputAmountWithoutFee.mul(lpAmount).div(input === \"base\" ? baseReserve : quoteReserve);\n let anotherAmountFee: GetTransferAmountFee = {\n amount: BN_ZERO,\n fee: undefined,\n expirationTime: undefined,\n };\n if (!_inputAmountWithoutFee.isZero()) {\n const lpAmountData = lpToAmount(liquidity, baseReserve, quoteReserve, lpAmount);\n this.logDebug(\"lpAmountData:\", {\n amountA: lpAmountData.amountA.toString(),\n amountB: lpAmountData.amountB.toString(),\n });\n anotherAmountFee = getTransferAmountFeeV2(\n lpAmountData[baseIn ? \"amountB\" : \"amountA\"],\n poolInfo[baseIn ? \"mintB\" : \"mintA\"].extensions.feeConfig,\n epochInfo,\n true,\n );\n }\n\n const _slippage = new Percent(new BN(1)).add(slippage);\n const _slippageMin = new Percent(new BN(1)).sub(slippage);\n const slippageAdjustedAmount = getTransferAmountFeeV2(\n _slippage.mul(anotherAmountFee.amount.sub(anotherAmountFee.fee ?? new BN(0))).quotient,\n poolInfo[baseIn ? \"mintB\" : \"mintA\"].extensions.feeConfig,\n epochInfo,\n true,\n );\n const slippageAdjustedMinAmount = getTransferAmountFeeV2(\n _slippageMin.mul(anotherAmountFee.amount.sub(anotherAmountFee.fee ?? new BN(0))).quotient,\n poolInfo[baseIn ? \"mintB\" : \"mintA\"].extensions.feeConfig,\n epochInfo,\n true,\n );\n\n this.logDebug(\n \"anotherAmount:\",\n anotherAmountFee.amount.toString(),\n \"anotherAmountFee:\",\n anotherAmountFee.fee?.toString() ?? 0,\n \"maxAnotherAmount:\",\n slippageAdjustedAmount.amount.toString(),\n \"maxAnotherAmountFee:\",\n slippageAdjustedAmount.fee?.toString() ?? 0,\n );\n\n return {\n inputAmountFee,\n anotherAmount: anotherAmountFee,\n maxAnotherAmount: slippageAdjustedAmount,\n minAnotherAmount: slippageAdjustedMinAmount,\n liquidity,\n };\n }\n\n public async fetchCpmmLockBalances(): Promise<(CpmmLockInfo & { nftMint: PublicKey })[]> {\n await this.scope.account.fetchWalletTokenAccounts({ forceUpdate: true });\n const balanceMints = this.scope.account.tokenAccountRawInfos.filter((acc) => acc.accountInfo.amount.eq(new BN(1)));\n const allPdaList = balanceMints.map(\n (m) =>\n getCpLockPda(\n this.scope.cluster === \"mainnet\" ? LOCK_CPMM_PROGRAM : DEVNET_PROGRAM_ID.LOCK_CPMM_PROGRAM,\n m.accountInfo.mint,\n ).publicKey,\n );\n\n const availableMints = await getMultipleAccountsInfoWithCustomFlags(\n this.scope.connection,\n allPdaList.map((a) => ({ pubkey: a })),\n );\n\n const pdaMintSet = new Map<string, string>();\n const mints = availableMints\n .filter((a, idx) => {\n pdaMintSet.set(a.pubkey.toString(), balanceMints[idx].accountInfo.mint.toString());\n return !!a.accountInfo;\n })\n .map((a) => a.pubkey);\n const lockInfo = await Promise.all(mints.map((m) => this.scope.api.fetchCpmmLockInfo(m)));\n\n return lockInfo.map((l, idx) => ({\n ...l,\n nftMint: new PublicKey(pdaMintSet.get(mints[idx].toString())!),\n }));\n }\n}\n\nfunction lpToAmount(lp: BN, poolAmountA: BN, poolAmountB: BN, supply: BN): { amountA: BN; amountB: BN } {\n let amountA = lp.mul(poolAmountA).div(supply);\n if (!amountA.isZero() && !lp.mul(poolAmountA).mod(supply).isZero()) amountA = amountA.add(new BN(1));\n let amountB = lp.mul(poolAmountB).div(supply);\n if (!amountB.isZero() && !lp.mul(poolAmountB).mod(supply).isZero()) amountB = amountB.add(new BN(1));\n\n return {\n amountA,\n amountB,\n };\n}\n","import { PublicKey } from \"@solana/web3.js\";\nimport BN from \"bn.js\";\nimport Decimal from \"decimal.js-light\";\nimport { ApiV3Token } from \"../../../api/type\";\nimport { BNDivCeil } from \"../../../common\";\nimport { ConstantProductCurve } from \"./constantProduct\";\nimport { CpmmFee as Fee } from \"./fee\";\n\nexport enum RoundDirection {\n Floor,\n Ceiling,\n}\n\nexport type SwapWithoutFeesResult = { destinationAmountSwapped: BN };\n\nexport type TradingTokenResult = { tokenAmount0: BN; tokenAmount1: BN };\n\nexport type SwapResult = {\n newInputVaultAmount: BN;\n newOutputVaultAmount: BN;\n inputAmount: BN;\n outputAmount: BN;\n tradeFee: BN;\n protocolFee: BN;\n fundFee: BN;\n creatorFee: BN;\n};\n\nexport enum TradeDirection {\n ZeroForOne,\n OneForZero,\n}\nexport enum TradeDirectionOpposite {\n OneForZero,\n ZeroForOne,\n}\n\nexport class CurveCalculator {\n static validate_supply(tokenAmount0: BN, tokenAmount1: BN): void {\n if (tokenAmount0.isZero()) throw Error(\"tokenAmount0 is zero\");\n if (tokenAmount1.isZero()) throw Error(\"tokenAmount1 is zero\");\n }\n\n static swapBaseInput(\n inputAmount: BN,\n inputVaultAmount: BN,\n outputVaultAmount: BN,\n tradeFeeRate: BN,\n creatorFeeRate: BN,\n protocolFeeRate: BN,\n fundFeeRate: BN,\n isCreatorFeeOnInput: boolean,\n ): SwapResult {\n let creatorFee = new BN(0);\n\n const tradeFee = Fee.tradingFee(inputAmount, tradeFeeRate);\n\n let inputAmountLessFees;\n if (isCreatorFeeOnInput) {\n creatorFee = Fee.creatorFee(inputAmount, creatorFeeRate);\n inputAmountLessFees = inputAmount.sub(tradeFee).sub(creatorFee);\n } else {\n inputAmountLessFees = inputAmount.sub(tradeFee);\n }\n\n const protocolFee = Fee.protocolFee(tradeFee, protocolFeeRate);\n const fundFee = Fee.protocolFee(tradeFee, fundFeeRate);\n\n const outputAmountSwapped = ConstantProductCurve.swapBaseInputWithoutFees(\n inputAmountLessFees,\n inputVaultAmount,\n outputVaultAmount,\n );\n\n let outputAmount;\n if (isCreatorFeeOnInput) {\n outputAmount = outputAmountSwapped;\n } else {\n creatorFee = Fee.creatorFee(outputAmountSwapped, creatorFeeRate);\n outputAmount = outputAmountSwapped.sub(creatorFee);\n }\n\n return {\n newInputVaultAmount: inputVaultAmount.add(inputAmountLessFees),\n newOutputVaultAmount: outputVaultAmount.sub(outputAmountSwapped),\n inputAmount,\n outputAmount,\n tradeFee,\n protocolFee,\n fundFee,\n creatorFee,\n };\n }\n\n static swapBaseOutput(\n outputAmount: BN,\n inputVaultAmount: BN,\n outputVaultAmount: BN,\n tradeFeeRate: BN,\n creatorFeeRate: BN,\n protocolFeeRate: BN,\n fundFeeRate: BN,\n isCreatorFeeOnInput: boolean,\n ): SwapResult {\n let tradeFee;\n let creatorFee = new BN(0);\n\n let actualOutputAmount;\n\n if (isCreatorFeeOnInput) {\n actualOutputAmount = outputAmount;\n } else {\n const outAmountWithCreatorFee = Fee.calculatePreFeeAmount(outputAmount, creatorFeeRate);\n creatorFee = outAmountWithCreatorFee.sub(outputAmount);\n actualOutputAmount = outAmountWithCreatorFee;\n }\n\n const inputAmountSwapped = ConstantProductCurve.swapBaseOutputWithoutFees(\n actualOutputAmount,\n inputVaultAmount,\n outputVaultAmount,\n );\n\n let inputAmount;\n if (isCreatorFeeOnInput) {\n const inputAmountWithFee = Fee.calculatePreFeeAmount(inputAmountSwapped, tradeFeeRate.add(creatorFeeRate));\n const totalFee = inputAmountWithFee.sub(inputAmountSwapped);\n creatorFee = Fee.splitCreatorFee(totalFee, tradeFeeRate, creatorFeeRate);\n tradeFee = totalFee.sub(creatorFee);\n inputAmount = inputAmountWithFee;\n } else {\n const inputAmountWithFee = Fee.calculatePreFeeAmount(inputAmountSwapped, tradeFeeRate);\n tradeFee = inputAmountWithFee.sub(inputAmountSwapped);\n inputAmount = inputAmountWithFee;\n }\n\n const protocolFee = Fee.protocolFee(tradeFee, protocolFeeRate);\n const fundFee = Fee.fundFee(tradeFee, fundFeeRate);\n\n return {\n newInputVaultAmount: inputVaultAmount.add(inputAmountSwapped),\n newOutputVaultAmount: outputVaultAmount.sub(actualOutputAmount),\n inputAmount,\n outputAmount,\n tradeFee,\n protocolFee,\n fundFee,\n creatorFee,\n };\n }\n}\n","import BN from \"bn.js\";\nimport { RoundDirection, TradingTokenResult } from \"./calculator\";\n\nfunction checkedRem(dividend: BN, divisor: BN): BN {\n if (divisor.isZero()) throw Error(\"divisor is zero\");\n\n const result = dividend.mod(divisor);\n return result;\n}\n\nfunction checkedCeilDiv(dividend: BN, rhs: BN): BN[] {\n if (rhs.isZero()) throw Error(\"rhs is zero\");\n\n let quotient = dividend.div(rhs);\n\n const remainder = checkedRem(dividend, rhs);\n\n if (remainder.gt(ZERO)) {\n quotient = quotient.add(new BN(1));\n }\n return [quotient, rhs];\n}\n\nconst ZERO = new BN(0);\n\nexport class ConstantProductCurve {\n static swapBaseInputWithoutFees(inputAmount: BN, inputVaultAmount: BN, onputVaultAmount: BN): BN {\n const numerator = inputAmount.mul(onputVaultAmount);\n const denominator = inputVaultAmount.add(inputAmount);\n\n const outputAmount = numerator.div(denominator);\n return outputAmount;\n }\n\n static swapBaseOutputWithoutFees(outputAmount: BN, inputVaultAmount: BN, onputVaultAmount: BN): BN {\n const numerator = inputVaultAmount.mul(outputAmount);\n const denominator = onputVaultAmount.sub(outputAmount);\n const [inputAmount] = checkedCeilDiv(numerator, denominator);\n\n return inputAmount;\n }\n\n static lpTokensToTradingTokens(\n lpTokenAmount: BN,\n lpTokenSupply: BN,\n swapTokenAmount0: BN,\n swapTokenAmount1: BN,\n roundDirection: RoundDirection,\n ): TradingTokenResult {\n let tokenAmount0 = lpTokenAmount.mul(swapTokenAmount0).div(lpTokenSupply);\n let tokenAmount1 = lpTokenAmount.mul(swapTokenAmount1).div(lpTokenSupply);\n\n if (roundDirection === RoundDirection.Floor) {\n return { tokenAmount0, tokenAmount1 };\n } else if (roundDirection === RoundDirection.Ceiling) {\n const tokenRemainder0 = checkedRem(lpTokenAmount.mul(swapTokenAmount0), lpTokenSupply);\n\n if (tokenRemainder0.gt(ZERO) && tokenAmount0.gt(ZERO)) {\n tokenAmount0 = tokenAmount0.add(new BN(1));\n }\n\n const token1Remainder = checkedRem(lpTokenAmount.mul(swapTokenAmount1), lpTokenSupply);\n\n if (token1Remainder.gt(ZERO) && tokenAmount1.gt(ZERO)) {\n tokenAmount1 = tokenAmount1.add(new BN(1));\n }\n\n return { tokenAmount0, tokenAmount1 };\n }\n throw Error(\"roundDirection value error\");\n }\n}\n","import BN from \"bn.js\";\nimport { ceilDiv, floorDiv } from \"@/common/bignumber\";\nimport { FEE_RATE_DENOMINATOR_VALUE } from \"@/common/fee\";\n\nexport class CpmmFee {\n static tradingFee(amount: BN, tradeFeeRate: BN): BN {\n return ceilDiv(amount, tradeFeeRate, FEE_RATE_DENOMINATOR_VALUE);\n }\n static protocolFee(amount: BN, protocolFeeRate: BN): BN {\n return floorDiv(amount, protocolFeeRate, FEE_RATE_DENOMINATOR_VALUE);\n }\n static fundFee(amount: BN, fundFeeRate: BN): BN {\n return floorDiv(amount, fundFeeRate, FEE_RATE_DENOMINATOR_VALUE);\n }\n\n static creatorFee(amount: BN, creatorFeeRate: BN): BN {\n return ceilDiv(amount, creatorFeeRate, FEE_RATE_DENOMINATOR_VALUE);\n }\n\n static splitCreatorFee(totalFee: BN, tradeFeeRate: BN, creatorFeeRate: BN): BN {\n return floorDiv(totalFee, creatorFeeRate, tradeFeeRate.add(creatorFeeRate));\n }\n\n static calculatePreFeeAmount(postFeeAmount: BN, tradeFeeRate: BN): BN {\n if (tradeFeeRate.isZero()) return postFeeAmount;\n\n const numerator = postFeeAmount.mul(FEE_RATE_DENOMINATOR_VALUE);\n const denominator = FEE_RATE_DENOMINATOR_VALUE.sub(tradeFeeRate);\n\n return numerator.add(denominator).sub(new BN(1)).div(denominator);\n }\n}\n","import BN from \"bn.js\";\nexport const FEE_RATE_DENOMINATOR_VALUE = new BN(1_000_000);\n","import BN from \"bn.js\";\n\nimport { AccountMeta, PublicKey, TransactionInstruction, Signer, Keypair, SystemProgram } from \"@solana/web3.js\";\nimport { ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_2022_PROGRAM_ID, TOKEN_PROGRAM_ID } from \"@solana/spl-token\";\nimport {\n MEMO_PROGRAM_ID,\n RENT_PROGRAM_ID,\n SYSTEM_PROGRAM_ID,\n METADATA_PROGRAM_ID,\n CREATE_CPMM_POOL_PROGRAM,\n CREATE_CPMM_POOL_AUTH,\n InstructionType,\n} from \"@/common\";\nimport { createLogger } from \"@/common/logger\";\nimport { getCpmmPdaPoolId, getCpLockPda } from \"./pda\";\n\nimport { struct, u8, u64, bool } from \"@/marshmallow\";\nimport { ReturnTypeMakeInstructions } from \"@/raydium/type\";\nimport { ApiV3PoolInfoStandardItemCpmm, CpmmKeys } from \"@/api\";\nimport { getATAAddress } from \"@/common\";\nimport { getPdaMetadataKey } from \"../clmm\";\nimport { CpmmLockExtInfo, FeeOn } from \"./type\";\n\nconst logger = createLogger(\"Raydium_cpmm\");\nconst anchorDataBuf = {\n initialize: [175, 175, 109, 31, 13, 152, 155, 237],\n deposit: [242, 35, 198, 137, 82, 225, 242, 182],\n withdraw: [183, 18, 70, 156, 148, 109, 161, 34],\n swapBaseInput: [143, 190, 90, 218, 196, 30, 51, 222],\n swapBaseOutput: [55, 217, 98, 86, 163, 74, 180, 173],\n lockCpLiquidity: [216, 157, 29, 78, 38, 51, 31, 26],\n collectCpFee: [8, 30, 51, 199, 209, 184, 247, 133],\n\n createPermissionPda: Buffer.from([135, 136, 2, 216, 137, 169, 181, 202]),\n closePermissionPda: Buffer.from([156, 84, 32, 118, 69, 135, 70, 123]),\n initializeWithPermission: Buffer.from([63, 55, 254, 65, 49, 178, 89, 121]),\n collectCreatorFee: Buffer.from([20, 22, 86, 123, 198, 28, 219, 132]),\n collectCreatorFeePermissionless: Buffer.from([202, 202, 34, 83, 226, 122, 145, 229]),\n};\n\nexport function makeCreateCpmmPoolInInstruction(\n programId: PublicKey,\n creator: PublicKey,\n configId: PublicKey,\n authority: PublicKey,\n poolId: PublicKey,\n mintA: PublicKey,\n mintB: PublicKey,\n lpMint: PublicKey,\n userVaultA: PublicKey,\n userVaultB: PublicKey,\n userLpAccount: PublicKey,\n vaultA: PublicKey,\n vaultB: PublicKey,\n createPoolFeeAccount: PublicKey,\n mintProgramA: PublicKey,\n mintProgramB: PublicKey,\n observationId: PublicKey,\n\n amountMaxA: BN,\n amountMaxB: BN,\n openTime: BN,\n\n supperMintEx?: PublicKey[],\n): TransactionInstruction {\n const dataLayout = struct([u64(\"amountMaxA\"), u64(\"amountMaxB\"), u64(\"openTime\")]);\n\n const pdaPoolId = getCpmmPdaPoolId(programId, configId, mintA, mintB).publicKey;\n\n const keys: Array<AccountMeta> = [\n { pubkey: creator, isSigner: true, isWritable: false },\n { pubkey: configId, isSigner: false, isWritable: false },\n { pubkey: authority, isSigner: false, isWritable: false },\n { pubkey: poolId, isSigner: !poolId.equals(pdaPoolId), isWritable: true },\n { pubkey: mintA, isSigner: false, isWritable: false },\n { pubkey: mintB, isSigner: false, isWritable: false },\n { pubkey: lpMint, isSigner: false, isWritable: true },\n { pubkey: userVaultA, isSigner: false, isWritable: true },\n { pubkey: userVaultB, isSigner: false, isWritable: true },\n { pubkey: userLpAccount, isSigner: false, isWritable: true },\n { pubkey: vaultA, isSigner: false, isWritable: true },\n { pubkey: vaultB, isSigner: false, isWritable: true },\n { pubkey: createPoolFeeAccount, isSigner: false, isWritable: true },\n { pubkey: observationId, isSigner: false, isWritable: true },\n\n { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: mintProgramA, isSigner: false, isWritable: false },\n { pubkey: mintProgramB, isSigner: false, isWritable: false },\n { pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: SYSTEM_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: RENT_PROGRAM_ID, isSigner: false, isWritable: false },\n ...(supperMintEx ?? []).map(i => ({ pubkey: i, isSigner: false, isWritable: false })),\n ];\n\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode(\n {\n amountMaxA,\n amountMaxB,\n openTime,\n },\n data,\n );\n\n return new TransactionInstruction({\n keys,\n programId,\n data: Buffer.from([...anchorDataBuf.initialize, ...data]),\n });\n}\n\nexport function makeDepositCpmmInInstruction(\n programId: PublicKey,\n owner: PublicKey,\n authority: PublicKey,\n poolId: PublicKey,\n userLpAccount: PublicKey,\n userVaultA: PublicKey,\n userVaultB: PublicKey,\n vaultA: PublicKey,\n vaultB: PublicKey,\n mintA: PublicKey,\n mintB: PublicKey,\n lpMint: PublicKey,\n\n lpAmount: BN,\n amountMaxA: BN,\n amountMaxB: BN,\n): TransactionInstruction {\n const dataLayout = struct([u64(\"lpAmount\"), u64(\"amountMaxA\"), u64(\"amountMaxB\")]);\n\n const keys: Array<AccountMeta> = [\n { pubkey: owner, isSigner: true, isWritable: false },\n { pubkey: authority, isSigner: false, isWritable: false },\n { pubkey: poolId, isSigner: false, isWritable: true },\n { pubkey: userLpAccount, isSigner: false, isWritable: true },\n { pubkey: userVaultA, isSigner: false, isWritable: true },\n { pubkey: userVaultB, isSigner: false, isWritable: true },\n { pubkey: vaultA, isSigner: false, isWritable: true },\n { pubkey: vaultB, isSigner: false, isWritable: true },\n { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: TOKEN_2022_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: mintA, isSigner: false, isWritable: false },\n { pubkey: mintB, isSigner: false, isWritable: false },\n { pubkey: lpMint, isSigner: false, isWritable: true },\n ];\n\n const data = Buffer.alloc(dataLayout.span);\n logger.debug(\"cpmm deposit data\", {\n lpAmount: lpAmount.toString(),\n amountMaxA: amountMaxA.toString(),\n amountMaxB: amountMaxB.toString(),\n });\n dataLayout.encode(\n {\n lpAmount,\n amountMaxA,\n amountMaxB,\n },\n data,\n );\n\n return new TransactionInstruction({\n keys,\n programId,\n data: Buffer.from([...anchorDataBuf.deposit, ...data]),\n });\n}\n\nexport function makeWithdrawCpmmInInstruction(\n programId: PublicKey,\n owner: PublicKey,\n authority: PublicKey,\n poolId: PublicKey,\n userLpAccount: PublicKey,\n userVaultA: PublicKey,\n userVaultB: PublicKey,\n vaultA: PublicKey,\n vaultB: PublicKey,\n mintA: PublicKey,\n mintB: PublicKey,\n lpMint: PublicKey,\n\n lpAmount: BN,\n amountMinA: BN,\n amountMinB: BN,\n): TransactionInstruction {\n const dataLayout = struct([u64(\"lpAmount\"), u64(\"amountMinA\"), u64(\"amountMinB\")]);\n\n const keys: Array<AccountMeta> = [\n { pubkey: owner, isSigner: true, isWritable: false },\n { pubkey: authority, isSigner: false, isWritable: false },\n { pubkey: poolId, isSigner: false, isWritable: true },\n { pubkey: userLpAccount, isSigner: false, isWritable: true },\n { pubkey: userVaultA, isSigner: false, isWritable: true },\n { pubkey: userVaultB, isSigner: false, isWritable: true },\n { pubkey: vaultA, isSigner: false, isWritable: true },\n { pubkey: vaultB, isSigner: false, isWritable: true },\n { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: TOKEN_2022_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: mintA, isSigner: false, isWritable: false },\n { pubkey: mintB, isSigner: false, isWritable: false },\n { pubkey: lpMint, isSigner: false, isWritable: true },\n { pubkey: MEMO_PROGRAM_ID, isSigner: false, isWritable: false },\n ];\n\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode(\n {\n lpAmount,\n amountMinA,\n amountMinB,\n },\n data,\n );\n\n return new TransactionInstruction({\n keys,\n programId,\n data: Buffer.from([...anchorDataBuf.withdraw, ...data]),\n });\n}\n\nexport function makeSwapCpmmBaseInInstruction(\n programId: PublicKey,\n payer: PublicKey,\n authority: PublicKey,\n configId: PublicKey,\n poolId: PublicKey,\n userInputAccount: PublicKey,\n userOutputAccount: PublicKey,\n inputVault: PublicKey,\n outputVault: PublicKey,\n inputTokenProgram: PublicKey,\n outputTokenProgram: PublicKey,\n inputMint: PublicKey,\n outputMint: PublicKey,\n observationId: PublicKey,\n\n amountIn: BN,\n amounOutMin: BN,\n): TransactionInstruction {\n const dataLayout = struct([u64(\"amountIn\"), u64(\"amounOutMin\")]);\n\n const keys: Array<AccountMeta> = [\n { pubkey: payer, isSigner: true, isWritable: false },\n { pubkey: authority, isSigner: false, isWritable: false },\n { pubkey: configId, isSigner: false, isWritable: false },\n { pubkey: poolId, isSigner: false, isWritable: true },\n { pubkey: userInputAccount, isSigner: false, isWritable: true },\n { pubkey: userOutputAccount, isSigner: false, isWritable: true },\n { pubkey: inputVault, isSigner: false, isWritable: true },\n { pubkey: outputVault, isSigner: false, isWritable: true },\n { pubkey: inputTokenProgram, isSigner: false, isWritable: false },\n { pubkey: outputTokenProgram, isSigner: false, isWritable: false },\n { pubkey: inputMint, isSigner: false, isWritable: false },\n { pubkey: outputMint, isSigner: false, isWritable: false },\n { pubkey: observationId, isSigner: false, isWritable: true },\n ];\n\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode(\n {\n amountIn,\n amounOutMin,\n },\n data,\n );\n\n return new TransactionInstruction({\n keys,\n programId,\n data: Buffer.from([...anchorDataBuf.swapBaseInput, ...data]),\n });\n}\nexport function makeSwapCpmmBaseOutInstruction(\n programId: PublicKey,\n payer: PublicKey,\n authority: PublicKey,\n configId: PublicKey,\n poolId: PublicKey,\n userInputAccount: PublicKey,\n userOutputAccount: PublicKey,\n inputVault: PublicKey,\n outputVault: PublicKey,\n inputTokenProgram: PublicKey,\n outputTokenProgram: PublicKey,\n inputMint: PublicKey,\n outputMint: PublicKey,\n observationId: PublicKey,\n\n amountInMax: BN,\n amountOut: BN,\n): TransactionInstruction {\n const dataLayout = struct([u64(\"amountInMax\"), u64(\"amountOut\")]);\n\n const keys: Array<AccountMeta> = [\n { pubkey: payer, isSigner: true, isWritable: false },\n { pubkey: authority, isSigner: false, isWritable: false },\n { pubkey: configId, isSigner: false, isWritable: false },\n { pubkey: poolId, isSigner: false, isWritable: true },\n { pubkey: userInputAccount, isSigner: false, isWritable: true },\n { pubkey: userOutputAccount, isSigner: false, isWritable: true },\n { pubkey: inputVault, isSigner: false, isWritable: true },\n { pubkey: outputVault, isSigner: false, isWritable: true },\n { pubkey: inputTokenProgram, isSigner: false, isWritable: false },\n { pubkey: outputTokenProgram, isSigner: false, isWritable: false },\n { pubkey: inputMint, isSigner: false, isWritable: false },\n { pubkey: outputMint, isSigner: false, isWritable: false },\n { pubkey: observationId, isSigner: false, isWritable: true },\n ];\n\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode(\n {\n amountInMax,\n amountOut,\n },\n data,\n );\n\n return new TransactionInstruction({\n keys,\n programId,\n data: Buffer.from([...anchorDataBuf.swapBaseOutput, ...data]),\n });\n}\n\nexport async function makeCpmmLockInstruction(props: {\n poolInfo: ApiV3PoolInfoStandardItemCpmm;\n poolKeys: CpmmKeys;\n ownerInfo: {\n feePayer: PublicKey;\n wallet: PublicKey;\n };\n feeNftOwner: PublicKey;\n\n lockProgram: PublicKey;\n lockAuthProgram: PublicKey;\n lpAmount: BN;\n withMetadata?: boolean;\n getEphemeralSigners?: (k: number) => any;\n}): Promise<ReturnTypeMakeInstructions<CpmmLockExtInfo>> {\n const { ownerInfo, poolInfo, poolKeys, feeNftOwner, getEphemeralSigners } = props;\n\n const signers: Signer[] = [];\n const [poolId, lpMint] = [new PublicKey(poolInfo.id), new PublicKey(poolInfo.lpMint.address)];\n\n let nftMintAccount: PublicKey;\n if (getEphemeralSigners) {\n nftMintAccount = new PublicKey((await getEphemeralSigners(1))[0]);\n } else {\n const _k = Keypair.generate();\n signers.push(_k);\n nftMintAccount = _k.publicKey;\n }\n\n const { publicKey: nftAccount } = getATAAddress(feeNftOwner, nftMintAccount, TOKEN_PROGRAM_ID);\n const { publicKey: metadataAccount } = getPdaMetadataKey(nftMintAccount);\n const { publicKey: lockPda } = getCpLockPda(props.lockProgram, nftMintAccount);\n\n const { publicKey: userLpVault } = getATAAddress(ownerInfo.wallet, lpMint, TOKEN_PROGRAM_ID);\n const { publicKey: lockLpVault } = getATAAddress(props.lockAuthProgram, lpMint, TOKEN_PROGRAM_ID);\n\n const ins = cpmmLockPositionInstruction({\n programId: props.lockProgram,\n auth: props.lockAuthProgram,\n payer: ownerInfo.feePayer,\n liquidityOwner: ownerInfo.wallet,\n nftOwner: feeNftOwner,\n nftMint: nftMintAccount,\n nftAccount,\n poolId,\n lockPda,\n mintLp: lpMint,\n userLpVault,\n lockLpVault,\n poolVaultA: new PublicKey(poolKeys.vault.A),\n poolVaultB: new PublicKey(poolKeys.vault.B),\n metadataAccount,\n lpAmount: props.lpAmount,\n withMetadata: props.withMetadata ?? true,\n });\n\n return {\n address: {\n nftMint: nftMintAccount,\n nftAccount,\n metadataAccount,\n lockPda,\n userLpVault,\n lockLpVault,\n },\n instructions: [ins],\n signers,\n instructionTypes: [InstructionType.CpmmLockLp],\n lookupTableAddress: [],\n };\n}\n\nexport function cpmmLockPositionInstruction({\n programId,\n auth,\n payer,\n liquidityOwner,\n nftOwner,\n nftMint,\n nftAccount,\n poolId,\n lockPda,\n mintLp,\n userLpVault,\n lockLpVault,\n poolVaultA,\n poolVaultB,\n metadataAccount,\n lpAmount,\n withMetadata,\n}: {\n programId: PublicKey;\n auth: PublicKey;\n payer: PublicKey;\n liquidityOwner: PublicKey;\n nftOwner: PublicKey;\n nftMint: PublicKey;\n nftAccount: PublicKey;\n poolId: PublicKey;\n lockPda: PublicKey;\n mintLp: PublicKey;\n userLpVault: PublicKey;\n lockLpVault: PublicKey;\n poolVaultA: PublicKey;\n poolVaultB: PublicKey;\n metadataAccount: PublicKey;\n lpAmount: BN;\n withMetadata: boolean;\n}): TransactionInstruction {\n const keys = [\n { pubkey: auth, isSigner: false, isWritable: false },\n { pubkey: payer, isSigner: true, isWritable: true },\n { pubkey: liquidityOwner, isSigner: true, isWritable: false },\n { pubkey: nftOwner, isSigner: false, isWritable: false },\n { pubkey: nftMint, isSigner: true, isWritable: true },\n { pubkey: nftAccount, isSigner: false, isWritable: true },\n { pubkey: poolId, isSigner: false, isWritable: false },\n { pubkey: lockPda, isSigner: false, isWritable: true },\n { pubkey: mintLp, isSigner: false, isWritable: false },\n { pubkey: userLpVault, isSigner: false, isWritable: true },\n { pubkey: lockLpVault, isSigner: false, isWritable: true },\n { pubkey: poolVaultA, isSigner: false, isWritable: true },\n { pubkey: poolVaultB, isSigner: false, isWritable: true },\n { pubkey: metadataAccount, isSigner: false, isWritable: true },\n { pubkey: RENT_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },\n { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: METADATA_PROGRAM_ID, isSigner: false, isWritable: false },\n ];\n const dataLayout = struct([u64(\"lpAmount\"), bool(\"withMetadata\")]);\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode(\n {\n lpAmount,\n withMetadata,\n },\n data,\n );\n const aData = Buffer.from([...anchorDataBuf.lockCpLiquidity, ...data]);\n return new TransactionInstruction({\n keys,\n programId,\n data: aData,\n });\n}\n\nexport function collectCpFeeInstruction({\n programId,\n nftOwner,\n auth,\n nftAccount,\n lockPda,\n poolId,\n mintLp,\n userVaultA,\n userVaultB,\n poolVaultA,\n poolVaultB,\n mintA,\n mintB,\n lockLpVault,\n lpFeeAmount,\n cpmmProgram,\n cpmmAuthProgram,\n}: {\n programId: PublicKey;\n nftOwner: PublicKey;\n auth: PublicKey;\n nftMint: PublicKey;\n nftAccount: PublicKey;\n lockPda: PublicKey;\n poolId: PublicKey;\n mintLp: PublicKey;\n userVaultA: PublicKey;\n userVaultB: PublicKey;\n poolVaultA: PublicKey;\n poolVaultB: PublicKey;\n mintA: PublicKey;\n mintB: PublicKey;\n lockLpVault: PublicKey;\n lpFeeAmount: BN;\n cpmmProgram?: PublicKey;\n cpmmAuthProgram?: PublicKey;\n}): TransactionInstruction {\n const keys = [\n { pubkey: auth, isSigner: false, isWritable: false },\n { pubkey: nftOwner, isSigner: true, isWritable: false },\n // { pubkey: nftMint, isSigner: false, isWritable: true },\n { pubkey: nftAccount, isSigner: false, isWritable: true },\n { pubkey: lockPda, isSigner: false, isWritable: true },\n { pubkey: cpmmProgram ?? CREATE_CPMM_POOL_PROGRAM, isSigner: false, isWritable: false },\n { pubkey: cpmmAuthProgram ?? CREATE_CPMM_POOL_AUTH, isSigner: false, isWritable: false },\n { pubkey: poolId, isSigner: false, isWritable: true },\n { pubkey: mintLp, isSigner: false, isWritable: true },\n { pubkey: userVaultA, isSigner: false, isWritable: true },\n { pubkey: userVaultB, isSigner: false, isWritable: true },\n { pubkey: poolVaultA, isSigner: false, isWritable: true },\n { pubkey: poolVaultB, isSigner: false, isWritable: true },\n { pubkey: mintA, isSigner: false, isWritable: false },\n { pubkey: mintB, isSigner: false, isWritable: false },\n { pubkey: lockLpVault, isSigner: false, isWritable: true },\n // { pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: TOKEN_2022_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: MEMO_PROGRAM_ID, isSigner: false, isWritable: false },\n ];\n const dataLayout = struct([u64(\"lpFeeAmount\")]);\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode(\n {\n lpFeeAmount,\n },\n data,\n );\n const aData = Buffer.from([...anchorDataBuf.collectCpFee, ...data]);\n return new TransactionInstruction({\n keys,\n programId,\n data: aData,\n });\n}\n\nexport function makeCollectCreatorFeeInstruction(\n programId: PublicKey,\n creator: PublicKey,\n authority: PublicKey,\n poolId: PublicKey,\n configId: PublicKey,\n vaultA: PublicKey,\n vaultB: PublicKey,\n mintA: PublicKey,\n mintB: PublicKey,\n ownerVaultA: PublicKey,\n ownerVaultB: PublicKey,\n mintProgramA: PublicKey,\n mintProgramB: PublicKey,\n): TransactionInstruction {\n const keys: Array<AccountMeta> = [\n { pubkey: creator, isSigner: true, isWritable: false },\n { pubkey: authority, isSigner: false, isWritable: false },\n { pubkey: poolId, isSigner: false, isWritable: true },\n { pubkey: configId, isSigner: false, isWritable: false },\n { pubkey: vaultA, isSigner: false, isWritable: true },\n { pubkey: vaultB, isSigner: false, isWritable: true },\n { pubkey: mintA, isSigner: false, isWritable: false },\n { pubkey: mintB, isSigner: false, isWritable: false },\n { pubkey: ownerVaultA, isSigner: false, isWritable: true },\n { pubkey: ownerVaultB, isSigner: false, isWritable: true },\n { pubkey: mintProgramA, isSigner: false, isWritable: false },\n { pubkey: mintProgramB, isSigner: false, isWritable: false },\n { pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },\n ];\n\n return new TransactionInstruction({\n keys,\n programId,\n data: anchorDataBuf.collectCreatorFee,\n });\n}\n\nexport function collectCreatorFeePermissionlessInInstruction(\n programId: PublicKey,\n payer: PublicKey,\n creator: PublicKey,\n authority: PublicKey,\n poolId: PublicKey,\n vaultA: PublicKey,\n vaultB: PublicKey,\n mintA: PublicKey,\n mintB: PublicKey,\n creatorVaultA: PublicKey,\n creatorVaultB: PublicKey,\n mintProgramA: PublicKey,\n mintProgramB: PublicKey,\n): TransactionInstruction {\n const keys: Array<AccountMeta> = [\n { pubkey: payer, isSigner: true, isWritable: true },\n { pubkey: creator, isSigner: false, isWritable: false },\n { pubkey: authority, isSigner: false, isWritable: false },\n { pubkey: poolId, isSigner: false, isWritable: true },\n { pubkey: vaultA, isSigner: false, isWritable: true },\n { pubkey: vaultB, isSigner: false, isWritable: true },\n { pubkey: mintA, isSigner: false, isWritable: false },\n { pubkey: mintB, isSigner: false, isWritable: false },\n { pubkey: creatorVaultA, isSigner: false, isWritable: true },\n { pubkey: creatorVaultB, isSigner: false, isWritable: true },\n { pubkey: mintProgramA, isSigner: false, isWritable: false },\n { pubkey: mintProgramB, isSigner: false, isWritable: false },\n { pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },\n ];\n\n return new TransactionInstruction({\n keys,\n programId,\n data: anchorDataBuf.collectCreatorFeePermissionless,\n });\n}\n\nexport function initializeWithPermission(\n programId: PublicKey,\n payer: PublicKey,\n creator: PublicKey,\n configId: PublicKey,\n authority: PublicKey,\n poolId: PublicKey,\n mintA: PublicKey,\n mintB: PublicKey,\n lpMint: PublicKey,\n payerVaultA: PublicKey,\n payerVaultB: PublicKey,\n payerLpAccount: PublicKey,\n vaultA: PublicKey,\n vaultB: PublicKey,\n createPoolFeeAccount: PublicKey,\n mintProgramA: PublicKey,\n mintProgramB: PublicKey,\n observationId: PublicKey,\n permissionPda: PublicKey,\n\n amountA: BN,\n amountB: BN,\n openTime: BN,\n\n feeOn: FeeOn,\n\n supperMintEx?: PublicKey[],\n): TransactionInstruction {\n const dataLayout = struct([u64(\"amountA\"), u64(\"amountB\"), u64(\"openTime\"), u8(\"feeOn\")]);\n\n const keys: Array<AccountMeta> = [\n { pubkey: payer, isSigner: true, isWritable: false },\n { pubkey: creator, isSigner: false, isWritable: false },\n { pubkey: configId, isSigner: false, isWritable: false },\n { pubkey: authority, isSigner: false, isWritable: false },\n { pubkey: poolId, isSigner: false, isWritable: true },\n { pubkey: mintA, isSigner: false, isWritable: false },\n { pubkey: mintB, isSigner: false, isWritable: false },\n { pubkey: lpMint, isSigner: false, isWritable: true },\n { pubkey: payerVaultA, isSigner: false, isWritable: true },\n { pubkey: payerVaultB, isSigner: false, isWritable: true },\n { pubkey: payerLpAccount, isSigner: false, isWritable: true },\n { pubkey: vaultA, isSigner: false, isWritable: true },\n { pubkey: vaultB, isSigner: false, isWritable: true },\n { pubkey: createPoolFeeAccount, isSigner: false, isWritable: true },\n { pubkey: observationId, isSigner: false, isWritable: true },\n { pubkey: permissionPda, isSigner: false, isWritable: true },\n\n { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: mintProgramA, isSigner: false, isWritable: false },\n { pubkey: mintProgramB, isSigner: false, isWritable: false },\n { pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },\n\n ...(supperMintEx ?? []).map(i => ({ pubkey: i, isSigner: false, isWritable: false })),\n ];\n\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode(\n {\n amountA,\n amountB,\n openTime,\n feeOn,\n },\n data,\n );\n\n return new TransactionInstruction({\n keys,\n programId,\n data: Buffer.from([...anchorDataBuf.initializeWithPermission, ...data]),\n });\n}\n","import { PublicKey } from \"@solana/web3.js\";\nimport { findProgramAddress } from \"../../common/txTool/txUtils\";\n\nconst AUTH_SEED = Buffer.from(\"vault_and_lp_mint_auth_seed\", \"utf8\");\nconst AMM_CONFIG_SEED = Buffer.from(\"amm_config\", \"utf8\");\nconst POOL_SEED = Buffer.from(\"pool\", \"utf8\");\nconst POOL_LP_MINT_SEED = Buffer.from(\"pool_lp_mint\", \"utf8\");\nconst POOL_VAULT_SEED = Buffer.from(\"pool_vault\", \"utf8\");\nconst OBSERVATION_SEED = Buffer.from(\"observation\", \"utf8\");\nconst PERMISSION_SEED = Buffer.from(\"permission\", \"utf8\");\nconst SUPPORT_MINT_SEED = Buffer.from('support_mint', 'utf8');\n\nexport function getPdaPoolAuthority(programId: PublicKey): {\n publicKey: PublicKey;\n nonce: number;\n} {\n return findProgramAddress([AUTH_SEED], programId);\n}\n\nexport function getCpmmPdaAmmConfigId(\n programId: PublicKey,\n index: number,\n): {\n publicKey: PublicKey;\n nonce: number;\n} {\n return findProgramAddress([AMM_CONFIG_SEED, u16ToBytes(index)], programId);\n}\n\nexport function getCpmmPdaPoolId(\n programId: PublicKey,\n ammConfigId: PublicKey,\n mintA: PublicKey,\n mintB: PublicKey,\n): {\n publicKey: PublicKey;\n nonce: number;\n} {\n return findProgramAddress([POOL_SEED, ammConfigId.toBuffer(), mintA.toBuffer(), mintB.toBuffer()], programId);\n}\n\nexport function getPdaLpMint(\n programId: PublicKey,\n poolId: PublicKey,\n): {\n publicKey: PublicKey;\n nonce: number;\n} {\n return findProgramAddress([POOL_LP_MINT_SEED, poolId.toBuffer()], programId);\n}\n\nexport function getPdaVault(\n programId: PublicKey,\n poolId: PublicKey,\n mint: PublicKey,\n): {\n publicKey: PublicKey;\n nonce: number;\n} {\n return findProgramAddress([POOL_VAULT_SEED, poolId.toBuffer(), mint.toBuffer()], programId);\n}\n\nexport function getPdaObservationId(\n programId: PublicKey,\n poolId: PublicKey,\n): {\n publicKey: PublicKey;\n nonce: number;\n} {\n return findProgramAddress([OBSERVATION_SEED, poolId.toBuffer()], programId);\n}\n\nfunction u16ToBytes(num: number): Uint8Array {\n const arr = new ArrayBuffer(2);\n const view = new DataView(arr);\n view.setUint16(0, num, false);\n return new Uint8Array(arr);\n}\n\nexport function getCreatePoolKeys({\n poolId: propPoolId,\n programId,\n configId,\n mintA,\n mintB,\n}: {\n poolId?: PublicKey;\n programId: PublicKey;\n configId: PublicKey;\n mintA: PublicKey;\n mintB: PublicKey;\n}): {\n poolId: PublicKey;\n configId: PublicKey;\n authority: PublicKey;\n lpMint: PublicKey;\n vaultA: PublicKey;\n vaultB: PublicKey;\n observationId: PublicKey;\n} {\n // const configId = getCpmmPdaAmmConfigId(programId, 0).publicKey;\n const authority = getPdaPoolAuthority(programId).publicKey;\n const poolId = propPoolId || getCpmmPdaPoolId(programId, configId, mintA, mintB).publicKey;\n const lpMint = getPdaLpMint(programId, poolId).publicKey;\n const vaultA = getPdaVault(programId, poolId, mintA).publicKey;\n const vaultB = getPdaVault(programId, poolId, mintB).publicKey;\n const observationId = getPdaObservationId(programId, poolId).publicKey;\n\n return {\n poolId,\n configId,\n authority,\n lpMint,\n vaultA,\n vaultB,\n observationId,\n };\n}\n\nexport const LOCK_LIQUIDITY_SEED = Buffer.from(\"locked_liquidity\", \"utf8\");\n\nexport function getCpLockPda(\n programId: PublicKey,\n mint: PublicKey,\n): {\n publicKey: PublicKey;\n nonce: number;\n} {\n return findProgramAddress([LOCK_LIQUIDITY_SEED, mint.toBuffer()], programId);\n}\n\nexport function getPdaPermissionId(\n programId: PublicKey,\n owner: PublicKey,\n): {\n publicKey: PublicKey;\n nonce: number;\n} {\n return findProgramAddress([PERMISSION_SEED, owner.toBuffer()], programId);\n}\n\nexport function getPdaMintExAccountCp(\n programId: PublicKey,\n mintAddress: PublicKey\n): {\n publicKey: PublicKey;\n nonce: number;\n} {\n return findProgramAddress([SUPPORT_MINT_SEED, mintAddress.toBuffer()], programId)\n}\n","import { blob, bool, publicKey, seq, struct, u16, u64, u8 } from \"../../marshmallow\";\n\nexport const CpmmConfigInfoLayout = struct([\n blob(8),\n u8(\"bump\"),\n bool(\"disableCreatePool\"),\n u16(\"index\"),\n u64(\"tradeFeeRate\"),\n u64(\"protocolFeeRate\"),\n u64(\"fundFeeRate\"),\n u64(\"createPoolFee\"),\n\n publicKey(\"protocolOwner\"),\n publicKey(\"fundOwner\"),\n\n u64(\"creatorFeeRate\"),\n seq(u64(), 15),\n]);\n\nexport const CpmmPoolInfoLayout = struct([\n blob(8),\n\n publicKey(\"configId\"),\n publicKey(\"poolCreator\"),\n publicKey(\"vaultA\"),\n publicKey(\"vaultB\"),\n\n publicKey(\"mintLp\"),\n publicKey(\"mintA\"),\n publicKey(\"mintB\"),\n\n publicKey(\"mintProgramA\"),\n publicKey(\"mintProgramB\"),\n\n publicKey(\"observationId\"),\n\n u8(\"bump\"),\n u8(\"status\"),\n\n u8(\"lpDecimals\"),\n u8(\"mintDecimalA\"),\n u8(\"mintDecimalB\"),\n\n u64(\"lpAmount\"),\n u64(\"protocolFeesMintA\"),\n u64(\"protocolFeesMintB\"),\n u64(\"fundFeesMintA\"),\n u64(\"fundFeesMintB\"),\n u64(\"openTime\"),\n u64(\"epoch\"),\n\n u8(\"feeOn\"),\n bool(\"enableCreatorFee\"),\n seq(u8(), 6),\n u64(\"creatorFeesMintA\"),\n u64(\"creatorFeesMintB\"),\n\n seq(u64(), 28),\n]);\n\nexport const CpmmPermission = struct([blob(8), publicKey(\"configId\"), seq(u64(), 30)]);\n","import { EpochInfo, PublicKey, SystemProgram } from \"@solana/web3.js\";\nimport {\n createTransferInstruction,\n TOKEN_PROGRAM_ID,\n TOKEN_2022_PROGRAM_ID,\n createAssociatedTokenAccountIdempotentInstruction,\n TransferFeeConfig,\n createSyncNativeInstruction,\n createTransferCheckedInstruction,\n} from \"@solana/spl-token\";\nimport BN from \"bn.js\";\nimport Decimal from \"decimal.js\";\nimport { AmmV4Keys, ApiV3PoolInfoConcentratedItem, ApiV3Token, ClmmKeys, CpmmKeys, PoolKeys } from \"@/api\";\nimport {\n AMM_V4,\n BigNumberish,\n CLMM_PROGRAM_ID,\n CREATE_CPMM_POOL_PROGRAM,\n fetchMultipleMintInfos,\n getMultipleAccountsInfoWithCustomFlags,\n minExpirationTime,\n parseBigNumberish,\n solToWSol,\n WSOLMint,\n} from \"@/common\";\nimport { MakeMultiTxData, MakeTxData } from \"@/common/txTool/txTool\";\nimport { InstructionType, TxVersion } from \"@/common/txTool/txType\";\nimport { publicKey, struct } from \"../../marshmallow\";\nimport { Price, TokenAmount } from \"../../module\";\nimport {\n ClmmInstrument,\n ClmmParsedRpcData,\n ComputeClmmPoolInfo,\n decimalToX64,\n ReturnTypeComputeAmountOutBaseOut,\n ReturnTypeComputeAmountOutFormat,\n ReturnTypeFetchMultiplePoolTickArrays,\n TickUtil,\n} from \"../../raydium/clmm\";\nimport { PoolInfoLayout } from \"../../raydium/clmm/layout\";\nimport {\n CpmmPoolInfoLayout,\n getPdaObservationId,\n getPdaPoolAuthority,\n makeSwapCpmmBaseInInstruction,\n SwapResult,\n} from \"../../raydium/cpmm\";\nimport {\n ComputeAmountOutParam,\n getLiquidityAssociatedAuthority,\n liquidityStateV4Layout,\n toAmmComputePoolInfo,\n} from \"../../raydium/liquidity\";\nimport { ComputeBudgetConfig, ReturnTypeFetchMultipleMintInfos } from \"../../raydium/type\";\nimport { closeAccountInstruction, createWSolAccountInstructions } from \"../account/instruction\";\nimport { TokenAccount } from \"../account/types\";\nimport { BN_ZERO, MAX_SQRT_PRICE_X64, MIN_SQRT_PRICE_X64 } from \"../clmm/libraries/constants\";\nimport { PoolUtils } from \"../clmm/libraries/pool\";\nimport { CpmmComputeData } from \"../cpmm\";\nimport {\n buyExactInInstruction,\n Curve,\n getPdaCreatorVault,\n getLaunchpadPoolMintAProgram,\n getPdaLaunchpadAuth,\n getPdaPlatformVault,\n LaunchpadConfigInfo,\n LaunchpadPlatformInfo,\n LaunchpadPoolInfo,\n PlatformConfig,\n sellExactInInstruction,\n SwapInfoReturn,\n} from \"../launchpad\";\nimport { AmmRpcData } from \"../liquidity\";\nimport ModuleBase, { ModuleBaseProps } from \"../moduleBase\";\nimport { Market, MARKET_STATE_LAYOUT_V3 } from \"../serum\";\nimport { toApiV3Token, toToken, toTokenAmount } from \"../token\";\nimport { makeSwapInstruction } from \"./instrument\";\nimport {\n BasicPoolInfo,\n ComputeAmountInAmmLayout,\n ComputeAmountInLayout,\n ComputeAmountOutAmmLayout,\n ComputeAmountOutLayout,\n ComputePoolType,\n ComputeRoutePathType,\n ReturnTypeFetchMultipleInfo,\n ReturnTypeGetAllRoute,\n RoutePathType,\n} from \"./type\";\n\nconst ZERO = new BN(0);\nexport function toTransferFeeConfig(token: ApiV3Token, epoch?: number): TransferFeeConfig | undefined {\n const feeConfig = token.extensions?.feeConfig;\n if (!feeConfig) return undefined;\n\n return {\n transferFeeConfigAuthority: PublicKey.default,\n withdrawWithheldAuthority: PublicKey.default,\n withheldAmount: BigInt(0),\n olderTransferFee: {\n epoch: BigInt(feeConfig.olderTransferFee.epoch ?? epoch ?? 0),\n maximumFee: BigInt(feeConfig.olderTransferFee.maximumFee),\n transferFeeBasisPoints: feeConfig.olderTransferFee.transferFeeBasisPoints,\n },\n newerTransferFee: {\n epoch: BigInt(feeConfig.newerTransferFee.epoch ?? epoch ?? 0),\n maximumFee: BigInt(feeConfig.newerTransferFee.maximumFee),\n transferFeeBasisPoints: feeConfig.newerTransferFee.transferFeeBasisPoints,\n },\n };\n}\n\n/** The quote mint of a launchpad pool may live on either token program */\nfunction getMintBProgram(token: ApiV3Token): PublicKey {\n return token.programId ? new PublicKey(token.programId) : TOKEN_PROGRAM_ID;\n}\n\nexport default class TradeV2 extends ModuleBase {\n constructor(params: ModuleBaseProps) {\n super(params);\n }\n\n private async getWSolAccounts(): Promise<TokenAccount[]> {\n this.scope.checkOwner();\n await this.scope.account.fetchWalletTokenAccounts();\n const tokenAccounts = this.scope.account.tokenAccounts.filter((acc) => acc.mint.equals(WSOLMint));\n tokenAccounts.sort((a, b) => {\n if (a.isAssociated) return 1;\n if (b.isAssociated) return -1;\n return a.amount.lt(b.amount) ? -1 : 1;\n });\n return tokenAccounts;\n }\n\n public async unWrapWSol<T extends TxVersion>(props: {\n amount: BigNumberish;\n computeBudgetConfig?: ComputeBudgetConfig;\n tokenProgram?: PublicKey;\n txVersion?: T;\n feePayer?: PublicKey;\n }): Promise<MakeTxData<T>> {\n const { amount, tokenProgram, txVersion = TxVersion.LEGACY, feePayer } = props;\n const tokenAccounts = await this.getWSolAccounts();\n const txBuilder = this.createTxBuilder(feePayer);\n txBuilder.addCustomComputeBudget(props.computeBudgetConfig);\n // const ins = await createWSolAccountInstructions({\n // connection: this.scope.connection,\n // owner: this.scope.ownerPubKey,\n // payer: this.scope.ownerPubKey,\n // amount: 0,\n // });\n // txBuilder.addInstruction(ins);\n\n const amountBN = parseBigNumberish(amount);\n for (let i = 0; i < tokenAccounts.length; i++) {\n if (amountBN.gte(tokenAccounts[i].amount)) {\n txBuilder.addInstruction({\n instructions: [\n closeAccountInstruction({\n tokenAccount: tokenAccounts[i].publicKey!,\n payer: this.scope.ownerPubKey,\n owner: this.scope.ownerPubKey,\n programId: tokenProgram,\n }),\n ],\n });\n amountBN.sub(tokenAccounts[i].amount);\n } else {\n txBuilder.addInstruction({\n instructions: [\n closeAccountInstruction({\n tokenAccount: tokenAccounts[i].publicKey!,\n payer: this.scope.ownerPubKey,\n owner: this.scope.ownerPubKey,\n programId: tokenProgram,\n }),\n ],\n });\n }\n }\n\n return txBuilder.versionBuild({ txVersion }) as Promise<MakeTxData<T>>;\n }\n\n public async wrapWSol<T extends TxVersion>(\n amount: BigNumberish,\n tokenProgram?: PublicKey,\n txVersion?: T,\n feePayer?: PublicKey,\n ): Promise<MakeTxData<T>> {\n // const tokenAccounts = await this.getWSolAccounts();\n\n const txBuilder = this.createTxBuilder(feePayer);\n\n const ins = await createWSolAccountInstructions({\n connection: this.scope.connection,\n owner: this.scope.ownerPubKey,\n payer: this.scope.ownerPubKey,\n amount,\n skipCloseAccount: true,\n });\n txBuilder.addInstruction(ins);\n\n // if (tokenAccounts.length) {\n // // already have wsol account\n // txBuilder.addInstruction({\n // instructions: [\n // makeTransferInstruction({\n // destination: tokenAccounts[0].publicKey!,\n // source: ins.addresses.newAccount,\n // amount,\n // owner: this.scope.ownerPubKey,\n // tokenProgram,\n // }),\n // ],\n // endInstructions: [\n // closeAccountInstruction({\n // tokenAccount: ins.addresses.newAccount,\n // payer: this.scope.ownerPubKey,\n // owner: this.scope.ownerPubKey,\n // programId: tokenProgram,\n // }),\n // ],\n // });\n // }\n return txBuilder.versionBuild({ txVersion: txVersion ?? TxVersion.LEGACY }) as Promise<MakeTxData<T>>;\n }\n\n public async swap<T extends TxVersion>({\n swapInfo,\n swapPoolKeys,\n ownerInfo,\n computeBudgetConfig,\n routeProgram,\n txVersion,\n feePayer,\n }: {\n txVersion: T;\n swapInfo: ComputeAmountOutLayout;\n swapPoolKeys?: PoolKeys[];\n ownerInfo: {\n associatedOnly: boolean;\n checkCreateATAOwner: boolean;\n };\n routeProgram: PublicKey;\n computeBudgetConfig?: ComputeBudgetConfig;\n feePayer?: PublicKey;\n }): Promise<MakeMultiTxData<T>> {\n const txBuilder = this.createTxBuilder(feePayer);\n const amountIn = swapInfo.amountIn;\n const amountOut = swapInfo.amountOut;\n const useSolBalance = amountIn.amount.token.mint.equals(WSOLMint);\n const isOutputSol = amountOut.amount.token.mint.equals(WSOLMint);\n const inputMint = amountIn.amount.token.mint;\n const outputMint = amountOut.amount.token.mint;\n\n const { account: sourceAcc, instructionParams: sourceAccInsParams } =\n await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: amountIn.amount.token.isToken2022 ? TOKEN_2022_PROGRAM_ID : TOKEN_PROGRAM_ID,\n mint: inputMint,\n notUseTokenAccount: useSolBalance,\n owner: this.scope.ownerPubKey,\n skipCloseAccount: !useSolBalance,\n createInfo: useSolBalance\n ? {\n payer: this.scope.ownerPubKey,\n amount: amountIn.amount.raw,\n }\n : undefined,\n associatedOnly: useSolBalance ? false : ownerInfo.associatedOnly,\n checkCreateATAOwner: ownerInfo.checkCreateATAOwner,\n });\n\n sourceAccInsParams && txBuilder.addInstruction(sourceAccInsParams);\n\n if (sourceAcc === undefined) {\n throw Error(\"input account check error\");\n }\n\n let destinationAcc: PublicKey;\n if (swapInfo.routeType === \"route\" && !isOutputSol) {\n destinationAcc = this.scope.account.getAssociatedTokenAccount(\n outputMint,\n amountOut.amount.token.isToken2022 ? TOKEN_2022_PROGRAM_ID : TOKEN_PROGRAM_ID,\n );\n } else {\n const { account, instructionParams } = await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: amountOut.amount.token.isToken2022 ? TOKEN_2022_PROGRAM_ID : TOKEN_PROGRAM_ID,\n mint: outputMint,\n notUseTokenAccount: isOutputSol,\n owner: this.scope.ownerPubKey,\n skipCloseAccount: true,\n createInfo: {\n payer: this.scope.ownerPubKey,\n amount: 0,\n },\n associatedOnly: isOutputSol ? false : ownerInfo.associatedOnly,\n checkCreateATAOwner: ownerInfo.checkCreateATAOwner,\n });\n destinationAcc = account!;\n instructionParams && txBuilder.addInstruction(instructionParams);\n }\n\n if (isOutputSol) {\n txBuilder.addInstruction({\n endInstructions: [\n closeAccountInstruction({\n owner: this.scope.ownerPubKey,\n payer: this.scope.ownerPubKey,\n tokenAccount: destinationAcc,\n programId: TOKEN_PROGRAM_ID,\n }),\n ],\n endInstructionTypes: [InstructionType.CloseAccount],\n });\n }\n\n let routeTokenAcc: PublicKey | undefined = undefined;\n if (swapInfo.routeType === \"route\") {\n const middleMint = swapInfo.middleToken;\n routeTokenAcc = this.scope.account.getAssociatedTokenAccount(\n middleMint.mint,\n middleMint.isToken2022 ? TOKEN_2022_PROGRAM_ID : TOKEN_PROGRAM_ID,\n );\n }\n\n const poolKeys = swapPoolKeys ? swapPoolKeys : await this.computePoolToPoolKeys({ pools: swapInfo.poolInfoList });\n const swapIns = makeSwapInstruction({\n routeProgram,\n inputMint,\n swapInfo: {\n ...swapInfo,\n poolInfo: [...swapInfo.poolInfoList],\n poolKey: poolKeys,\n outputMint,\n },\n ownerInfo: {\n wallet: this.scope.ownerPubKey,\n sourceToken: sourceAcc,\n routeToken: routeTokenAcc,\n destinationToken: destinationAcc!,\n },\n });\n\n if (swapInfo.feeConfig !== undefined) {\n const checkTxBuilder = this.createTxBuilder();\n\n // Use createTransferCheckedInstruction for Token2022, createTransferInstruction for regular tokens\n const transferInstruction = amountIn.amount.token.isToken2022\n ? createTransferCheckedInstruction(\n sourceAcc,\n amountIn.amount.token.mint, // mint parameter required for checked transfer\n swapInfo.feeConfig.feeAccount,\n this.scope.ownerPubKey,\n swapInfo.feeConfig.feeAmount.toNumber(),\n amountIn.amount.token.decimals, // decimals parameter required for checked transfer\n [],\n TOKEN_2022_PROGRAM_ID,\n )\n : createTransferInstruction(\n sourceAcc,\n swapInfo.feeConfig.feeAccount,\n this.scope.ownerPubKey,\n swapInfo.feeConfig.feeAmount.toNumber(),\n );\n\n checkTxBuilder.addInstruction({\n instructions: [transferInstruction],\n instructionTypes: [InstructionType.TransferAmount],\n });\n checkTxBuilder.addInstruction(swapIns);\n\n const { transactions } =\n txVersion === TxVersion.V0 ? await checkTxBuilder.sizeCheckBuildV0() : await checkTxBuilder.sizeCheckBuild();\n if (transactions.length < 2) {\n txBuilder.addInstruction({\n instructions: [\n createTransferInstruction(\n sourceAcc,\n swapInfo.feeConfig.feeAccount,\n this.scope.ownerPubKey,\n swapInfo.feeConfig.feeAmount.toNumber(),\n ),\n ],\n instructionTypes: [InstructionType.TransferAmount],\n });\n }\n }\n txBuilder.addInstruction(swapIns);\n\n if (txVersion === TxVersion.V0)\n return txBuilder.sizeCheckBuildV0({ computeBudgetConfig, address: swapIns.address }) as Promise<\n MakeMultiTxData<T>\n >;\n return txBuilder.sizeCheckBuild({ computeBudgetConfig, address: swapIns.address }) as Promise<MakeMultiTxData<T>>;\n }\n\n public async swapClmmToLaunchMint<T extends TxVersion>({\n inputMint,\n inputAmount,\n fixClmmOut = false,\n clmmPoolId,\n launchPoolId,\n priceLimit,\n slippage = 0.01,\n shareFeeRate = new BN(0),\n shareFeeReceiver,\n\n launchPlatformInfo,\n slot,\n mintInfo,\n epochInfo: propsEpochInfo,\n\n ownerInfo = { useSOLBalance: true },\n checkCreateATAOwner = false,\n computeBudgetConfig,\n txVersion,\n blockTimestamp,\n }: {\n inputMint: string | PublicKey;\n inputAmount: BN;\n fixClmmOut?: boolean;\n clmmPoolId: string | PublicKey;\n launchPoolId: string | PublicKey;\n priceLimit?: Decimal;\n epochInfo?: EpochInfo;\n slippage: number; // from 0~1\n shareFeeRate?: BN;\n shareFeeReceiver?: PublicKey;\n\n launchPlatformInfo?: Pick<LaunchpadPlatformInfo, \"feeRate\" | \"creatorFeeRate\">;\n slot?: number;\n mintInfo?: ApiV3Token;\n\n ownerInfo?: {\n useSOLBalance?: boolean;\n feePayer?: PublicKey;\n };\n checkCreateATAOwner?: boolean;\n computeBudgetConfig?: ComputeBudgetConfig;\n txVersion: T;\n blockTimestamp: number;\n }): Promise<\n MakeTxData<\n T,\n {\n routes: { mint: PublicKey; amount: BN; decimal: number }[];\n outAmount: BN;\n minOutAmount: BN;\n }\n >\n > {\n const feePayer = ownerInfo?.feePayer || this.scope.ownerPubKey;\n const epochInfo = propsEpochInfo ?? (await this.scope.fetchEpochInfo());\n\n const {\n clmmPoolData,\n clmmComputeAmount: { maxClmmAmountIn, clmmAmountOut, remainingAccounts },\n launchPoolInfo,\n launchAuthProgramId,\n launchSwapInfo,\n launchMintProgramB,\n outAmount,\n minOutAmount,\n } = await this.computeClmmToLaunchAmount({\n inputMint,\n inputAmount,\n fixClmmOut,\n clmmPoolId,\n launchPoolId,\n slippage,\n epochInfo,\n shareFeeRate,\n launchPlatformInfo,\n slot,\n mintInfo,\n blockTimestamp,\n });\n const baseIn = inputMint.toString() === clmmPoolData.poolInfo.mintA.address;\n\n const mintAUseSOLBalance = ownerInfo.useSOLBalance && clmmPoolData.poolInfo.mintA.address === WSOLMint.toBase58();\n const mintBUseSOLBalance = ownerInfo.useSOLBalance && clmmPoolData.poolInfo.mintB.address === WSOLMint.toBase58();\n const tokenAccountMap: Record<string, PublicKey> = {};\n\n let sqrtPriceLimitX64: BN;\n if (!priceLimit || priceLimit.equals(new Decimal(0))) {\n sqrtPriceLimitX64 = baseIn ? MIN_SQRT_PRICE_X64.add(new BN(1)) : MAX_SQRT_PRICE_X64.sub(new BN(1));\n } else {\n sqrtPriceLimitX64 = TickUtil.priceToSqrtPriceX64(\n priceLimit,\n clmmPoolData.poolInfo.mintA.decimals,\n clmmPoolData.poolInfo.mintB.decimals,\n );\n }\n\n const txBuilder = this.createTxBuilder(feePayer);\n\n const [clmmMintA, clmmMintB] = [\n new PublicKey(clmmPoolData.poolInfo.mintA.address),\n new PublicKey(clmmPoolData.poolInfo.mintB.address),\n ];\n const [clmmMintAProgram, clmmMintBProgram] = [\n new PublicKey(clmmPoolData.poolInfo.mintA.programId),\n new PublicKey(clmmPoolData.poolInfo.mintB.programId),\n ];\n\n const ownerTokenAccountA = this.scope.account.getAssociatedTokenAccount(clmmMintA, clmmMintAProgram);\n const ownerTokenAccountB = this.scope.account.getAssociatedTokenAccount(clmmMintB, clmmMintBProgram);\n\n txBuilder.addInstruction({\n instructions: [\n createAssociatedTokenAccountIdempotentInstruction(\n this.scope.ownerPubKey,\n ownerTokenAccountA,\n this.scope.ownerPubKey,\n clmmMintA,\n clmmMintAProgram,\n ),\n createAssociatedTokenAccountIdempotentInstruction(\n this.scope.ownerPubKey,\n ownerTokenAccountB,\n this.scope.ownerPubKey,\n clmmMintB,\n clmmMintBProgram,\n ),\n ],\n });\n\n if ((baseIn && mintAUseSOLBalance) || (!baseIn && mintBUseSOLBalance)) {\n txBuilder.addInstruction({\n instructions: [\n SystemProgram.transfer({\n fromPubkey: this.scope.ownerPubKey,\n toPubkey: baseIn ? ownerTokenAccountA : ownerTokenAccountB,\n lamports: BigInt(maxClmmAmountIn.toString()),\n }),\n createSyncNativeInstruction(baseIn ? ownerTokenAccountA : ownerTokenAccountB),\n ],\n });\n }\n\n tokenAccountMap[clmmPoolData.poolInfo.mintA.address] = ownerTokenAccountA;\n tokenAccountMap[clmmPoolData.poolInfo.mintB.address] = ownerTokenAccountB;\n\n if (!ownerTokenAccountA || !ownerTokenAccountB)\n this.logAndCreateError(\"user do not have token account\", {\n ownerTokenAccountA,\n ownerTokenAccountB,\n });\n\n txBuilder.addInstruction(\n fixClmmOut\n ? ClmmInstrument.makeSwapBaseOutInstructions({\n poolInfo: clmmPoolData.poolInfo,\n poolKeys: clmmPoolData.poolKeys,\n observationId: clmmPoolData.computePoolInfo.observationId,\n ownerInfo: {\n wallet: this.scope.ownerPubKey,\n tokenAccountA: ownerTokenAccountA!,\n tokenAccountB: ownerTokenAccountB!,\n },\n outputMint: baseIn ? clmmMintB : clmmMintA,\n amountOut: clmmAmountOut,\n amountInMax: maxClmmAmountIn,\n sqrtPriceLimitX64,\n remainingAccounts,\n })\n : ClmmInstrument.makeSwapBaseInInstructions({\n poolInfo: clmmPoolData.poolInfo,\n poolKeys: clmmPoolData.poolKeys,\n observationId: clmmPoolData.computePoolInfo.observationId,\n ownerInfo: {\n wallet: this.scope.ownerPubKey,\n tokenAccountA: ownerTokenAccountA!,\n tokenAccountB: ownerTokenAccountB!,\n },\n inputMint: new PublicKey(inputMint),\n amountIn: inputAmount,\n amountOutMin: clmmAmountOut,\n sqrtPriceLimitX64,\n remainingAccounts,\n }),\n );\n\n const launchMintAProgram = getLaunchpadPoolMintAProgram(launchPoolInfo.mintProgramFlag);\n const launchTokenAccountA = this.scope.account.getAssociatedTokenAccount(launchPoolInfo.mintA, launchMintAProgram);\n let launchTokenAccountB = tokenAccountMap[launchPoolInfo.mintB.toBase58()];\n\n txBuilder.addInstruction({\n instructions: [\n createAssociatedTokenAccountIdempotentInstruction(\n this.scope.ownerPubKey,\n launchTokenAccountA,\n this.scope.ownerPubKey,\n launchPoolInfo.mintA,\n launchMintAProgram,\n ),\n ],\n });\n\n if (!launchTokenAccountB) {\n const mintBUseSol = launchPoolInfo.mintB.equals(WSOLMint);\n const { account, instructionParams } = await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: launchMintProgramB,\n mint: launchPoolInfo.mintB,\n notUseTokenAccount: mintBUseSol,\n owner: this.scope.ownerPubKey,\n skipCloseAccount: !mintBUseSol,\n createInfo: mintBUseSol\n ? {\n payer: this.scope.ownerPubKey!,\n amount: clmmAmountOut,\n }\n : undefined,\n associatedOnly: false,\n checkCreateATAOwner,\n });\n launchTokenAccountB = account!;\n instructionParams && txBuilder.addInstruction(instructionParams);\n }\n\n txBuilder.addInstruction({\n instructions: [\n buyExactInInstruction(\n launchPoolInfo.programId,\n this.scope.ownerPubKey,\n launchAuthProgramId,\n launchPoolInfo.configId,\n launchPoolInfo.platformId,\n new PublicKey(launchPoolId),\n launchTokenAccountA,\n launchTokenAccountB,\n launchPoolInfo.vaultA,\n launchPoolInfo.vaultB,\n launchPoolInfo.mintA,\n launchPoolInfo.mintB,\n launchMintAProgram,\n launchMintProgramB,\n\n getPdaPlatformVault(launchPoolInfo.programId, launchPoolInfo.platformId, launchPoolInfo.mintB).publicKey,\n getPdaCreatorVault(launchPoolInfo.programId, launchPoolInfo.creator, launchPoolInfo.mintB).publicKey,\n\n launchSwapInfo.amountB.lt(clmmAmountOut) ? launchSwapInfo.amountB : clmmAmountOut,\n minOutAmount,\n shareFeeRate,\n shareFeeReceiver,\n ),\n ],\n });\n\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n\n return txBuilder.versionBuild({\n txVersion,\n extInfo: {\n routes: [\n {\n mint: new PublicKey(inputMint),\n amount: fixClmmOut ? maxClmmAmountIn : inputAmount,\n decimal: clmmPoolData.poolInfo[baseIn ? \"mintA\" : \"mintB\"].decimals,\n },\n {\n mint: baseIn ? clmmMintB : clmmMintA,\n amount: clmmAmountOut,\n decimal: clmmPoolData.poolInfo[baseIn ? \"mintB\" : \"mintA\"].decimals,\n },\n {\n mint: launchPoolInfo.mintA,\n amount: outAmount,\n decimal: launchPoolInfo.mintDecimalsA,\n },\n ],\n outAmount,\n minOutAmount,\n },\n }) as Promise<\n MakeTxData<\n T,\n {\n routes: { mint: PublicKey; amount: BN; decimal: number }[];\n outAmount: BN;\n minOutAmount: BN;\n }\n >\n >;\n }\n\n public async computeClmmToLaunchAmount({\n inputMint,\n inputAmount,\n fixClmmOut = false,\n clmmPoolId,\n launchPoolId,\n slippage: propsSlippage,\n epochInfo,\n shareFeeRate = new BN(0),\n\n clmmPoolData: propsClmmPoolData,\n launchPoolInfo: propsLaunchPoolInfo,\n launchPlatformInfo: propsLaunchPlatformInfo,\n slot,\n mintInfo: propsMintInfo,\n blockTimestamp,\n }: {\n clmmPoolId: string | PublicKey;\n launchPoolId: string | PublicKey;\n inputMint: string | PublicKey;\n inputAmount: BN;\n fixClmmOut?: boolean;\n slippage: number;\n epochInfo?: EpochInfo;\n shareFeeRate?: BN;\n\n clmmPoolData?: {\n poolInfo: ApiV3PoolInfoConcentratedItem;\n poolKeys: ClmmKeys;\n computePoolInfo: ComputeClmmPoolInfo;\n tickData: ReturnTypeFetchMultiplePoolTickArrays;\n };\n launchPoolInfo?: LaunchpadPoolInfo & { programId: PublicKey; configInfo: LaunchpadConfigInfo };\n launchPlatformInfo?: Pick<LaunchpadPlatformInfo, \"feeRate\" | \"creatorFeeRate\">;\n slot?: number;\n mintInfo?: ApiV3Token;\n blockTimestamp: number;\n }): Promise<{\n clmmPoolData: {\n poolInfo: ApiV3PoolInfoConcentratedItem;\n poolKeys: ClmmKeys;\n computePoolInfo: ComputeClmmPoolInfo;\n tickData: ReturnTypeFetchMultiplePoolTickArrays;\n };\n clmmComputeAmount: { maxClmmAmountIn: BN; clmmAmountOut: BN; remainingAccounts: PublicKey[] };\n clmmComputeInfo: ReturnTypeComputeAmountOutBaseOut | ReturnTypeComputeAmountOutFormat;\n launchPoolInfo: LaunchpadPoolInfo & { programId: PublicKey; configInfo: LaunchpadConfigInfo };\n launchAuthProgramId: PublicKey;\n outAmount: BN;\n minOutAmount: BN;\n launchSwapInfo: SwapInfoReturn;\n launchMintTransferFeeConfig?: TransferFeeConfig;\n launchMintProgramB: PublicKey;\n launchMintTransferFeeConfigB?: TransferFeeConfig;\n }> {\n // split slippage for clmm swap and launch buy\n const slippage =\n propsSlippage > 0\n ? new Decimal(propsSlippage).div(2).toDecimalPlaces(4, Decimal.ROUND_DOWN).toNumber()\n : propsSlippage;\n const clmmPoolData = propsClmmPoolData ?? (await this.scope.clmm.getPoolInfoFromRpc(clmmPoolId.toString()));\n if (\n inputMint.toString() !== clmmPoolData.poolInfo.mintA.address &&\n inputMint.toString() !== clmmPoolData.poolInfo.mintB.address\n )\n throw new Error(\"input mint does not match clmm pool mints, please check\");\n const baseIn = inputMint.toString() === clmmPoolData.poolInfo.mintA.address;\n const tokenOut = clmmPoolData.poolInfo[baseIn ? \"mintB\" : \"mintA\"];\n\n let launchPoolInfo = propsLaunchPoolInfo;\n if (!launchPoolInfo)\n launchPoolInfo = await this.scope.launchpad.getRpcPoolInfo({ poolId: new PublicKey(launchPoolId) });\n\n if (tokenOut.address !== launchPoolInfo.mintB.toBase58())\n throw new Error(`clmm swap mint(${tokenOut.address}) != launch pool mintB(${launchPoolInfo.mintB.toBase58()})`);\n\n const clmmComputeAmount = fixClmmOut\n ? await PoolUtils.computeAmountIn({\n poolInfo: clmmPoolData.computePoolInfo,\n tickarrayBitmapExtension: clmmPoolData.computePoolInfo.exBitmapInfo,\n tickArrayCache: clmmPoolData.tickData[clmmPoolId.toString()],\n amountOut: inputAmount,\n baseMint: new PublicKey(clmmPoolData.poolInfo[baseIn ? \"mintB\" : \"mintA\"].address),\n slippage,\n epochInfo: epochInfo ?? (await this.scope.fetchEpochInfo()),\n blockTimestamp,\n })\n : await PoolUtils.computeAmountOutFormat({\n poolInfo: clmmPoolData.computePoolInfo,\n tickarrayBitmapExtension: clmmPoolData.computePoolInfo.exBitmapInfo,\n tickArrayCache: clmmPoolData.tickData[clmmPoolId.toString()],\n amountIn: inputAmount,\n tokenOut,\n slippage,\n epochInfo: epochInfo ?? (await this.scope.fetchEpochInfo()),\n blockTimestamp,\n });\n\n let platformInfo = propsLaunchPlatformInfo;\n if (!platformInfo) {\n const data = await this.scope.connection.getAccountInfo(launchPoolInfo.platformId);\n platformInfo = PlatformConfig.decode(data!.data);\n }\n const mintInfo = propsMintInfo ?? (await this.scope.token.getTokenInfo(launchPoolInfo.mintA));\n const authProgramId = getPdaLaunchpadAuth(launchPoolInfo.programId).publicKey;\n\n const launchMintTransferFeeConfig = toTransferFeeConfig(mintInfo, epochInfo?.epoch);\n const launchMintProgramB = getMintBProgram(tokenOut);\n const launchMintTransferFeeConfigB = toTransferFeeConfig(tokenOut, epochInfo?.epoch);\n\n const launchBuyAmount = fixClmmOut\n ? inputAmount\n : (clmmComputeAmount as ReturnTypeComputeAmountOutFormat).minAmountOut.amount.raw;\n\n const launchSwapInfo = Curve.buyExactIn({\n poolInfo: launchPoolInfo,\n amountB: launchBuyAmount,\n protocolFeeRate: launchPoolInfo.configInfo.tradeFeeRate,\n platformFeeRate: platformInfo.feeRate,\n curveType: launchPoolInfo.configInfo.curveType,\n shareFeeRate,\n creatorFeeRate: platformInfo.creatorFeeRate,\n transferFeeConfigA: launchMintTransferFeeConfig,\n transferFeeConfigB: launchMintTransferFeeConfigB,\n slot: slot ?? (await this.scope.connection.getSlot()),\n });\n\n const outAmount = launchSwapInfo.amountA.amount.sub(launchSwapInfo.amountA.fee ?? new BN(0));\n const decimalAmountA = new Decimal(outAmount.toString());\n\n const SLIPPAGE_UNIT = new BN(10000);\n const multiplier = slippage\n ? new Decimal(SLIPPAGE_UNIT.sub(new BN(slippage * 10000)).toNumber() / SLIPPAGE_UNIT.toNumber()).clampedTo(0, 1)\n : new Decimal(1);\n\n return {\n clmmPoolData,\n clmmComputeAmount: {\n maxClmmAmountIn: fixClmmOut\n ? (clmmComputeAmount as ReturnTypeComputeAmountOutBaseOut).maxAmountIn.amount\n : inputAmount,\n clmmAmountOut: launchBuyAmount,\n remainingAccounts: clmmComputeAmount.remainingAccounts,\n },\n clmmComputeInfo: clmmComputeAmount,\n\n launchPoolInfo,\n launchAuthProgramId: authProgramId,\n launchMintTransferFeeConfig,\n launchMintProgramB,\n launchMintTransferFeeConfigB,\n launchSwapInfo,\n outAmount: launchSwapInfo.amountA.amount.sub(launchSwapInfo.amountA.fee ?? new BN(0)),\n minOutAmount: new BN(decimalAmountA.mul(multiplier).toFixed(0)),\n };\n }\n\n public async swapLaunchMintToClmm<T extends TxVersion>({\n inputAmount,\n clmmPoolId,\n launchPoolId,\n priceLimit,\n slippage = 0.01,\n shareFeeRate = new BN(0),\n shareFeeReceiver,\n ownerInfo = { useSOLBalance: true },\n checkCreateATAOwner = false,\n computeBudgetConfig,\n txVersion,\n blockTimestamp,\n }: {\n inputAmount: BN;\n clmmPoolId: string | PublicKey;\n launchPoolId: string | PublicKey;\n priceLimit?: Decimal;\n slippage: number; // from 0~1\n shareFeeRate?: BN;\n shareFeeReceiver?: PublicKey;\n ownerInfo?: {\n useSOLBalance?: boolean;\n feePayer?: PublicKey;\n };\n checkCreateATAOwner?: boolean;\n computeBudgetConfig?: ComputeBudgetConfig;\n txVersion: T;\n blockTimestamp: number;\n }): Promise<\n MakeTxData<\n T,\n {\n routes: { mint: PublicKey; amount: BN; decimal: number }[];\n outAmount: BN;\n minOutAmount: BN;\n }\n >\n > {\n const feePayer = ownerInfo?.feePayer || this.scope.ownerPubKey;\n const epochInfo = await this.scope.fetchEpochInfo();\n\n const {\n clmmPoolData,\n clmmComputeAmount: { remainingAccounts },\n launchPoolInfo,\n launchAuthProgramId,\n launchSwapInfo,\n launchMintProgramB,\n minLaunchOutAmount,\n outAmount,\n minOutAmount,\n } = await this.computeLaunchToClmmAmount({\n inputAmount,\n clmmPoolId,\n launchPoolId,\n slippage,\n epochInfo,\n shareFeeRate,\n blockTimestamp,\n });\n\n const txBuilder = this.createTxBuilder(feePayer);\n const tokenAccountMap: Record<string, PublicKey> = {};\n\n const launchMintAProgram = getLaunchpadPoolMintAProgram(launchPoolInfo.mintProgramFlag);\n\n const { account: launchTokenAccountA } = await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: launchMintAProgram,\n mint: launchPoolInfo.mintA,\n notUseTokenAccount: false,\n owner: this.scope.ownerPubKey,\n skipCloseAccount: true,\n createInfo: undefined,\n associatedOnly: true,\n checkCreateATAOwner,\n });\n if (!launchTokenAccountA)\n throw new Error(`do not have launch mint(${launchPoolInfo.mintA.toString()}) token account`);\n\n const mintBUseSol = launchPoolInfo.mintB.equals(WSOLMint);\n const { account: launchTokenAccountB, instructionParams } = await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: launchMintProgramB,\n mint: launchPoolInfo.mintB,\n notUseTokenAccount: mintBUseSol,\n owner: this.scope.ownerPubKey,\n skipCloseAccount: !mintBUseSol,\n createInfo: {\n payer: this.scope.ownerPubKey!,\n amount: 0,\n },\n associatedOnly: false,\n checkCreateATAOwner,\n });\n instructionParams && txBuilder.addInstruction(instructionParams);\n if (!launchTokenAccountB)\n throw new Error(`do not have launch mint(${launchPoolInfo.mintA.toString()}) token account`);\n tokenAccountMap[launchPoolInfo.mintB.toBase58()] = launchTokenAccountB;\n\n txBuilder.addInstruction({\n instructions: [\n sellExactInInstruction(\n launchPoolInfo.programId,\n this.scope.ownerPubKey,\n launchAuthProgramId,\n launchPoolInfo.configId,\n launchPoolInfo.platformId,\n new PublicKey(launchPoolId),\n launchTokenAccountA,\n launchTokenAccountB,\n launchPoolInfo.vaultA,\n launchPoolInfo.vaultB,\n launchPoolInfo.mintA,\n launchPoolInfo.mintB,\n launchMintAProgram,\n launchMintProgramB,\n\n getPdaPlatformVault(launchPoolInfo.programId, launchPoolInfo.platformId, launchPoolInfo.mintB).publicKey,\n getPdaCreatorVault(launchPoolInfo.programId, launchPoolInfo.creator, launchPoolInfo.mintB).publicKey,\n\n launchSwapInfo.amountA.amount.lt(inputAmount) ? launchSwapInfo.amountA.amount : inputAmount,\n minLaunchOutAmount,\n shareFeeRate,\n shareFeeReceiver,\n ),\n ],\n });\n\n const baseIn = launchPoolInfo.mintB.toString() === clmmPoolData.poolInfo.mintA.address;\n const mintAUseSOLBalance = ownerInfo.useSOLBalance && clmmPoolData.poolInfo.mintA.address === WSOLMint.toBase58();\n const mintBUseSOLBalance = ownerInfo.useSOLBalance && clmmPoolData.poolInfo.mintB.address === WSOLMint.toBase58();\n\n let sqrtPriceLimitX64: BN;\n if (!priceLimit || priceLimit.equals(new Decimal(0))) {\n sqrtPriceLimitX64 = baseIn ? MIN_SQRT_PRICE_X64.add(new BN(1)) : MAX_SQRT_PRICE_X64.sub(new BN(1));\n } else {\n sqrtPriceLimitX64 = TickUtil.priceToSqrtPriceX64(\n priceLimit,\n clmmPoolData.poolInfo.mintA.decimals,\n clmmPoolData.poolInfo.mintB.decimals,\n );\n }\n\n const [clmmMintA, clmmMintB] = [\n new PublicKey(clmmPoolData.poolInfo.mintA.address),\n new PublicKey(clmmPoolData.poolInfo.mintB.address),\n ];\n const [clmmMintAProgram, clmmMintBProgram] = [\n new PublicKey(clmmPoolData.poolInfo.mintA.programId),\n new PublicKey(clmmPoolData.poolInfo.mintB.programId),\n ];\n\n let ownerTokenAccountA = mintAUseSOLBalance\n ? undefined\n : this.scope.account.getAssociatedTokenAccount(clmmMintA, clmmMintAProgram);\n\n let ownerTokenAccountB = mintBUseSOLBalance\n ? undefined\n : this.scope.account.getAssociatedTokenAccount(clmmMintB, clmmMintBProgram);\n\n // this means mintA is wsol\n if (!ownerTokenAccountA) {\n const { account, instructionParams } = await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: clmmMintAProgram,\n mint: clmmMintA,\n notUseTokenAccount: true,\n owner: this.scope.ownerPubKey,\n skipCloseAccount: false,\n createInfo: {\n payer: ownerInfo.feePayer || this.scope.ownerPubKey,\n amount: baseIn ? inputAmount : 0,\n },\n associatedOnly: false,\n checkCreateATAOwner,\n });\n ownerTokenAccountA = account!;\n instructionParams && txBuilder.addInstruction(instructionParams);\n }\n\n // this means mintB is wsol\n if (!ownerTokenAccountB) {\n const { account, instructionParams } = await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: clmmMintBProgram,\n mint: clmmMintB,\n notUseTokenAccount: true,\n owner: this.scope.ownerPubKey,\n skipCloseAccount: false,\n createInfo: {\n payer: ownerInfo.feePayer || this.scope.ownerPubKey,\n amount: baseIn ? 0 : inputAmount,\n },\n associatedOnly: false,\n checkCreateATAOwner,\n });\n ownerTokenAccountB = account!;\n instructionParams && txBuilder.addInstruction(instructionParams);\n }\n tokenAccountMap[clmmPoolData.poolInfo.mintA.address] = ownerTokenAccountA;\n tokenAccountMap[clmmPoolData.poolInfo.mintB.address] = ownerTokenAccountB;\n\n if (!ownerTokenAccountA || !ownerTokenAccountB)\n this.logAndCreateError(\"user do not have token account\", {\n ownerTokenAccountA,\n ownerTokenAccountB,\n });\n\n txBuilder.addInstruction(\n ClmmInstrument.makeSwapBaseInInstructions({\n poolInfo: clmmPoolData.poolInfo,\n poolKeys: clmmPoolData.poolKeys,\n observationId: clmmPoolData.computePoolInfo.observationId,\n ownerInfo: {\n wallet: this.scope.ownerPubKey,\n tokenAccountA: ownerTokenAccountA!,\n tokenAccountB: ownerTokenAccountB!,\n },\n inputMint: new PublicKey(clmmPoolData.poolKeys[baseIn ? \"mintA\" : \"mintB\"].address),\n amountIn: minLaunchOutAmount,\n amountOutMin: minOutAmount,\n sqrtPriceLimitX64,\n remainingAccounts,\n }),\n );\n\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n\n return txBuilder.versionBuild({\n txVersion,\n extInfo: {\n routes: [\n {\n mint: launchPoolInfo.mintA,\n amount: inputAmount,\n decimal: launchPoolInfo.mintDecimalsA,\n },\n {\n mint: launchPoolInfo.mintB,\n amount: minLaunchOutAmount,\n decimal: launchPoolInfo.mintDecimalsB,\n },\n {\n mint: new PublicKey(clmmPoolData.poolKeys[baseIn ? \"mintB\" : \"mintA\"].address),\n amount: outAmount,\n decimal: clmmPoolData.poolKeys[baseIn ? \"mintB\" : \"mintA\"].decimals,\n },\n ],\n outAmount,\n minOutAmount,\n },\n }) as Promise<\n MakeTxData<\n T,\n {\n routes: { mint: PublicKey; amount: BN; decimal: number }[];\n outAmount: BN;\n minOutAmount: BN;\n }\n >\n >;\n }\n\n public async computeLaunchToClmmAmount({\n inputAmount,\n clmmPoolId,\n launchPoolId,\n slippage: propsSlippage,\n epochInfo,\n shareFeeRate = new BN(0),\n\n clmmPoolData: propsClmmPoolData,\n launchPoolInfo: propsLaunchPoolInfo,\n launchPlatformInfo: propsLaunchPlatformInfo,\n blockTimestamp,\n }: {\n clmmPoolId: string | PublicKey;\n launchPoolId: string | PublicKey;\n inputAmount: BN;\n slippage: number;\n epochInfo?: EpochInfo;\n shareFeeRate?: BN;\n\n clmmPoolData?: {\n poolInfo: ApiV3PoolInfoConcentratedItem;\n poolKeys: ClmmKeys;\n computePoolInfo: ComputeClmmPoolInfo;\n tickData: ReturnTypeFetchMultiplePoolTickArrays;\n };\n launchPoolInfo?: LaunchpadPoolInfo & { programId: PublicKey; configInfo: LaunchpadConfigInfo };\n launchPlatformInfo?: LaunchpadPlatformInfo;\n blockTimestamp: number;\n }): Promise<{\n clmmPoolData: {\n poolInfo: ApiV3PoolInfoConcentratedItem;\n poolKeys: ClmmKeys;\n computePoolInfo: ComputeClmmPoolInfo;\n tickData: ReturnTypeFetchMultiplePoolTickArrays;\n };\n clmmComputeAmount: ReturnTypeComputeAmountOutFormat;\n launchPoolInfo: LaunchpadPoolInfo & { programId: PublicKey; configInfo: LaunchpadConfigInfo };\n launchAuthProgramId: PublicKey;\n minLaunchOutAmount: BN;\n outAmount: BN;\n minOutAmount: BN;\n launchSwapInfo: SwapInfoReturn;\n launchMintTransferFeeConfig?: TransferFeeConfig;\n launchMintProgramB: PublicKey;\n launchMintTransferFeeConfigB?: TransferFeeConfig;\n }> {\n // split slippage for clmm swap and launch buy\n const slippage =\n propsSlippage > 0\n ? new Decimal(propsSlippage).div(2).toDecimalPlaces(4, Decimal.ROUND_DOWN).toNumber()\n : propsSlippage;\n\n let launchPoolInfo = propsLaunchPoolInfo;\n if (!launchPoolInfo)\n launchPoolInfo = await this.scope.launchpad.getRpcPoolInfo({ poolId: new PublicKey(launchPoolId) });\n\n const inputMint = launchPoolInfo.mintB;\n\n const clmmPoolData = propsClmmPoolData ?? (await this.scope.clmm.getPoolInfoFromRpc(clmmPoolId.toString()));\n if (\n inputMint.toString() !== clmmPoolData.poolInfo.mintA.address &&\n inputMint.toString() !== clmmPoolData.poolInfo.mintB.address\n )\n throw new Error(\"input mint does not match clmm pool mints, please check\");\n\n const baseIn = inputMint.toString() === clmmPoolData.poolInfo.mintA.address;\n const tokenOut = clmmPoolData.poolInfo[baseIn ? \"mintB\" : \"mintA\"];\n // the launch pool sells into mintB, which is what this clmm swap then takes in\n const tokenIn = clmmPoolData.poolInfo[baseIn ? \"mintA\" : \"mintB\"];\n\n let platformInfo = propsLaunchPlatformInfo;\n if (!platformInfo) {\n const data = await this.scope.connection.getAccountInfo(launchPoolInfo.platformId);\n platformInfo = PlatformConfig.decode(data!.data);\n }\n const mintInfo = await this.scope.token.getTokenInfo(launchPoolInfo.mintA);\n const authProgramId = getPdaLaunchpadAuth(launchPoolInfo.programId).publicKey;\n\n const launchMintTransferFeeConfig = toTransferFeeConfig(mintInfo, epochInfo?.epoch);\n const launchMintProgramB = getMintBProgram(tokenIn);\n const launchMintTransferFeeConfigB = toTransferFeeConfig(tokenIn, epochInfo?.epoch);\n\n const launchSwapInfo = Curve.sellExactIn({\n poolInfo: launchPoolInfo,\n amountA: inputAmount,\n protocolFeeRate: launchPoolInfo.configInfo.tradeFeeRate,\n platformFeeRate: platformInfo.feeRate,\n curveType: launchPoolInfo.configInfo.curveType,\n shareFeeRate,\n creatorFeeRate: platformInfo.creatorFeeRate,\n transferFeeConfigA: launchMintTransferFeeConfig,\n transferFeeConfigB: launchMintTransferFeeConfigB,\n slot: await this.scope.connection.getSlot(),\n });\n\n const outAmount = launchSwapInfo.amountB;\n const decimalAmountB = new Decimal(outAmount.toString());\n\n const SLIPPAGE_UNIT = new BN(10000);\n const multiplier = slippage\n ? new Decimal(SLIPPAGE_UNIT.sub(new BN(slippage * 10000)).toNumber() / SLIPPAGE_UNIT.toNumber()).clampedTo(0, 1)\n : new Decimal(1);\n\n const minLaunchOutAmount = new BN(decimalAmountB.mul(multiplier).toFixed(0));\n\n const clmmComputeAmount = await PoolUtils.computeAmountOutFormat({\n poolInfo: clmmPoolData.computePoolInfo,\n tickarrayBitmapExtension: clmmPoolData.computePoolInfo.exBitmapInfo,\n tickArrayCache: clmmPoolData.tickData[clmmPoolId.toString()],\n amountIn: minLaunchOutAmount,\n tokenOut,\n slippage,\n epochInfo: epochInfo ?? (await this.scope.fetchEpochInfo()),\n blockTimestamp,\n });\n\n return {\n clmmPoolData,\n clmmComputeAmount,\n\n launchPoolInfo,\n launchAuthProgramId: authProgramId,\n launchMintTransferFeeConfig,\n launchMintProgramB,\n launchMintTransferFeeConfigB,\n launchSwapInfo,\n minLaunchOutAmount,\n outAmount: clmmComputeAmount.amountOut.amount.raw,\n minOutAmount: clmmComputeAmount.minAmountOut.amount.raw,\n };\n }\n\n public async swapCpmmToLaunchMint<T extends TxVersion>({\n inputMint,\n inputAmount,\n cpmmPoolId,\n launchPoolId,\n poolKeys: propsPoolKeys,\n slippage = 0.01,\n shareFeeRate = new BN(0),\n shareFeeReceiver,\n\n launchPlatformInfo,\n slot,\n mintInfo,\n epochInfo: propsEpochInfo,\n\n ownerInfo = { useSOLBalance: true },\n checkCreateATAOwner = false,\n computeBudgetConfig,\n txVersion,\n }: {\n inputMint: string | PublicKey;\n inputAmount: BN;\n cpmmPoolId: string | PublicKey;\n poolKeys?: CpmmKeys;\n launchPoolId: string | PublicKey;\n priceLimit?: Decimal;\n epochInfo?: EpochInfo;\n slippage: number; // from 0~1\n shareFeeRate?: BN;\n shareFeeReceiver?: PublicKey;\n\n launchPlatformInfo?: Pick<LaunchpadPlatformInfo, \"feeRate\" | \"creatorFeeRate\">;\n slot?: number;\n mintInfo?: ApiV3Token;\n\n ownerInfo?: {\n useSOLBalance?: boolean;\n feePayer?: PublicKey;\n };\n checkCreateATAOwner?: boolean;\n computeBudgetConfig?: ComputeBudgetConfig;\n txVersion: T;\n }): Promise<\n MakeTxData<\n T,\n {\n routes: { mint: PublicKey; amount: BN; decimal: number }[];\n outAmount: BN;\n minOutAmount: BN;\n }\n >\n > {\n const feePayer = ownerInfo?.feePayer || this.scope.ownerPubKey;\n const epochInfo = propsEpochInfo ?? (await this.scope.fetchEpochInfo());\n\n const { computePoolInfo, poolKeys: cpmmKeys } = await this.scope.cpmm.getPoolInfoFromRpc(cpmmPoolId.toString());\n\n const {\n cpmmComputInfo,\n cpmmPoolData,\n launchPoolInfo,\n launchAuthProgramId,\n launchSwapInfo,\n launchMintProgramB,\n outAmount,\n minOutAmount,\n } = await this.computeCpmmToLaunchAmount({\n inputMint,\n inputAmount,\n cpmmPoolId,\n cpmmPoolData: computePoolInfo,\n launchPoolId,\n slippage,\n epochInfo,\n shareFeeRate,\n launchPlatformInfo,\n slot,\n mintInfo,\n });\n const baseIn = inputMint.toString() === cpmmPoolData.mintA.address;\n\n const mintAUseSOLBalance = ownerInfo.useSOLBalance && cpmmPoolData.mintA.address === WSOLMint.toBase58();\n const mintBUseSOLBalance = ownerInfo.useSOLBalance && cpmmPoolData.mintB.address === WSOLMint.toBase58();\n const tokenAccountMap: Record<string, PublicKey> = {};\n\n const txBuilder = this.createTxBuilder(feePayer);\n\n const [cpmmMintA, cpmmMintB] = [\n new PublicKey(cpmmPoolData.mintA.address),\n new PublicKey(cpmmPoolData.mintB.address),\n ];\n const [cpmmMintAProgram, cpmmMintBProgram] = [\n new PublicKey(cpmmPoolData.mintA.programId),\n new PublicKey(cpmmPoolData.mintB.programId),\n ];\n\n const ownerTokenAccountA = this.scope.account.getAssociatedTokenAccount(cpmmMintA, cpmmMintAProgram);\n const ownerTokenAccountB = this.scope.account.getAssociatedTokenAccount(cpmmMintB, cpmmMintBProgram);\n\n txBuilder.addInstruction({\n instructions: [\n createAssociatedTokenAccountIdempotentInstruction(\n this.scope.ownerPubKey,\n ownerTokenAccountA,\n this.scope.ownerPubKey,\n cpmmMintA,\n cpmmMintAProgram,\n ),\n createAssociatedTokenAccountIdempotentInstruction(\n this.scope.ownerPubKey,\n ownerTokenAccountB,\n this.scope.ownerPubKey,\n cpmmMintB,\n cpmmMintBProgram,\n ),\n ],\n });\n\n if ((baseIn && mintAUseSOLBalance) || (!baseIn && mintBUseSOLBalance)) {\n txBuilder.addInstruction({\n instructions: [\n SystemProgram.transfer({\n fromPubkey: this.scope.ownerPubKey,\n toPubkey: baseIn ? ownerTokenAccountA : ownerTokenAccountB,\n lamports: BigInt(cpmmComputInfo.amountIn.toString()),\n }),\n createSyncNativeInstruction(baseIn ? ownerTokenAccountA : ownerTokenAccountB),\n ],\n });\n }\n\n tokenAccountMap[cpmmPoolData.mintA.address] = ownerTokenAccountA;\n tokenAccountMap[cpmmPoolData.mintB.address] = ownerTokenAccountB;\n\n if (!ownerTokenAccountA || !ownerTokenAccountB)\n this.logAndCreateError(\"user do not have token account\", {\n ownerTokenAccountA,\n ownerTokenAccountB,\n });\n\n const poolKeys = propsPoolKeys ?? cpmmKeys;\n\n txBuilder.addInstruction({\n instructions: [\n makeSwapCpmmBaseInInstruction(\n cpmmPoolData.programId,\n this.scope.ownerPubKey,\n new PublicKey(poolKeys.authority),\n new PublicKey(poolKeys.config.id),\n cpmmPoolData.id,\n baseIn ? ownerTokenAccountA! : ownerTokenAccountB!,\n baseIn ? ownerTokenAccountB! : ownerTokenAccountA!,\n new PublicKey(poolKeys.vault[baseIn ? \"A\" : \"B\"]),\n new PublicKey(poolKeys.vault[baseIn ? \"B\" : \"A\"]),\n new PublicKey(baseIn ? cpmmMintAProgram : cpmmMintBProgram ?? TOKEN_PROGRAM_ID),\n new PublicKey(baseIn ? cpmmMintBProgram : cpmmMintAProgram ?? TOKEN_PROGRAM_ID),\n baseIn ? cpmmMintA : cpmmMintB,\n baseIn ? cpmmMintB : cpmmMintA,\n getPdaObservationId(cpmmPoolData.programId, cpmmPoolData.id).publicKey,\n\n inputAmount,\n cpmmComputInfo.swapResult.outputAmount,\n ),\n ],\n });\n\n const launchMintAProgram = getLaunchpadPoolMintAProgram(launchPoolInfo.mintProgramFlag);\n const launchTokenAccountA = this.scope.account.getAssociatedTokenAccount(launchPoolInfo.mintA, launchMintAProgram);\n let launchTokenAccountB = tokenAccountMap[launchPoolInfo.mintB.toBase58()];\n\n txBuilder.addInstruction({\n instructions: [\n createAssociatedTokenAccountIdempotentInstruction(\n this.scope.ownerPubKey,\n launchTokenAccountA,\n this.scope.ownerPubKey,\n launchPoolInfo.mintA,\n launchMintAProgram,\n ),\n ],\n });\n\n if (!launchTokenAccountB) {\n const mintBUseSol = launchPoolInfo.mintB.equals(WSOLMint);\n const { account, instructionParams } = await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: launchMintProgramB,\n mint: launchPoolInfo.mintB,\n notUseTokenAccount: mintBUseSol,\n owner: this.scope.ownerPubKey,\n skipCloseAccount: !mintBUseSol,\n createInfo: mintBUseSol\n ? {\n payer: this.scope.ownerPubKey!,\n amount: cpmmComputInfo.minAmountOut,\n }\n : undefined,\n associatedOnly: false,\n checkCreateATAOwner,\n });\n launchTokenAccountB = account!;\n instructionParams && txBuilder.addInstruction(instructionParams);\n }\n\n txBuilder.addInstruction({\n instructions: [\n buyExactInInstruction(\n launchPoolInfo.programId,\n this.scope.ownerPubKey,\n launchAuthProgramId,\n launchPoolInfo.configId,\n launchPoolInfo.platformId,\n new PublicKey(launchPoolId),\n launchTokenAccountA,\n launchTokenAccountB,\n launchPoolInfo.vaultA,\n launchPoolInfo.vaultB,\n launchPoolInfo.mintA,\n launchPoolInfo.mintB,\n launchMintAProgram,\n launchMintProgramB,\n\n getPdaPlatformVault(launchPoolInfo.programId, launchPoolInfo.platformId, launchPoolInfo.mintB).publicKey,\n getPdaCreatorVault(launchPoolInfo.programId, launchPoolInfo.creator, launchPoolInfo.mintB).publicKey,\n\n launchSwapInfo.amountB.lt(cpmmComputInfo.minAmountOut) ? launchSwapInfo.amountB : cpmmComputInfo.minAmountOut,\n minOutAmount,\n shareFeeRate,\n shareFeeReceiver,\n ),\n ],\n });\n\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n return txBuilder.versionBuild({\n txVersion,\n extInfo: {\n routes: [\n {\n mint: new PublicKey(inputMint),\n amount: inputAmount,\n decimal: cpmmPoolData[baseIn ? \"mintDecimalA\" : \"mintDecimalB\"],\n },\n {\n mint: baseIn ? cpmmMintB : cpmmMintA,\n amount: cpmmComputInfo.minAmountOut,\n decimal: cpmmPoolData[baseIn ? \"mintB\" : \"mintA\"].decimals,\n },\n {\n mint: launchPoolInfo.mintA,\n amount: outAmount,\n decimal: launchPoolInfo.mintDecimalsA,\n },\n ],\n outAmount,\n minOutAmount,\n },\n }) as Promise<\n MakeTxData<\n T,\n {\n routes: { mint: PublicKey; amount: BN; decimal: number }[];\n outAmount: BN;\n minOutAmount: BN;\n }\n >\n >;\n }\n\n public async computeCpmmToLaunchAmount({\n inputMint,\n inputAmount,\n cpmmPoolId,\n launchPoolId,\n slippage: propsSlippage,\n epochInfo,\n shareFeeRate = new BN(0),\n cpmmPoolData: propsCpmmPoolData,\n launchPoolInfo: propsLaunchPoolInfo,\n launchPlatformInfo: propsLaunchPlatformInfo,\n slot,\n mintInfo: propsMintInfo,\n }: {\n cpmmPoolId: string | PublicKey;\n launchPoolId: string | PublicKey;\n inputMint: string | PublicKey;\n inputAmount: BN;\n slippage: number;\n epochInfo?: EpochInfo;\n shareFeeRate?: BN;\n\n cpmmPoolData?: CpmmComputeData;\n\n launchPoolInfo?: LaunchpadPoolInfo & { programId: PublicKey; configInfo: LaunchpadConfigInfo };\n launchPlatformInfo?: Pick<LaunchpadPlatformInfo, \"feeRate\" | \"creatorFeeRate\">;\n slot?: number;\n mintInfo?: ApiV3Token;\n }): Promise<{\n cpmmPoolData: CpmmComputeData;\n cpmmComputInfo: {\n amountIn: BN;\n amountOut: BN;\n minAmountOut: BN;\n fee: BN;\n executionPrice: Decimal;\n priceImpact: Decimal;\n swapResult: SwapResult;\n };\n launchPoolInfo: LaunchpadPoolInfo & { programId: PublicKey; configInfo: LaunchpadConfigInfo };\n launchAuthProgramId: PublicKey;\n outAmount: BN;\n minOutAmount: BN;\n launchSwapInfo: SwapInfoReturn;\n launchMintTransferFeeConfig?: TransferFeeConfig;\n launchMintProgramB: PublicKey;\n launchMintTransferFeeConfigB?: TransferFeeConfig;\n }> {\n // split slippage for clmm swap and launch buy\n const slippage =\n propsSlippage > 0\n ? new Decimal(propsSlippage).div(2).toDecimalPlaces(4, Decimal.ROUND_DOWN).toNumber()\n : propsSlippage;\n\n const cpmmPoolData =\n propsCpmmPoolData ?? (await this.scope.cpmm.getPoolInfoFromRpc(cpmmPoolId.toString())).computePoolInfo;\n if (inputMint.toString() !== cpmmPoolData.mintA.address && inputMint.toString() !== cpmmPoolData.mintB.address)\n throw new Error(\"input mint does not match clmm pool mints, please check\");\n const baseIn = inputMint.toString() === cpmmPoolData.mintA.address;\n const tokenOut = cpmmPoolData[baseIn ? \"mintB\" : \"mintA\"];\n\n let launchPoolInfo = propsLaunchPoolInfo;\n if (!launchPoolInfo)\n launchPoolInfo = await this.scope.launchpad.getRpcPoolInfo({ poolId: new PublicKey(launchPoolId) });\n\n if (tokenOut.address !== launchPoolInfo.mintB.toBase58())\n throw new Error(`clmm swap mint(${tokenOut.address}) != launch pool mintB(${launchPoolInfo.mintB.toBase58()})`);\n\n let platformInfo = propsLaunchPlatformInfo;\n if (!platformInfo) {\n const data = await this.scope.connection.getAccountInfo(launchPoolInfo.platformId);\n platformInfo = PlatformConfig.decode(data!.data);\n }\n const mintInfo = propsMintInfo ?? (await this.scope.token.getTokenInfo(launchPoolInfo.mintA));\n const authProgramId = getPdaLaunchpadAuth(launchPoolInfo.programId).publicKey;\n\n const launchMintTransferFeeConfig = toTransferFeeConfig(mintInfo, epochInfo?.epoch);\n const launchMintProgramB = getMintBProgram(tokenOut);\n const launchMintTransferFeeConfigB = toTransferFeeConfig(tokenOut, epochInfo?.epoch);\n\n const cpmmComputeAmount = await this.scope.cpmm.computeSwapAmount({\n pool: cpmmPoolData,\n amountIn: inputAmount,\n outputMint: new PublicKey(tokenOut.address),\n slippage,\n });\n\n const launchBuyAmount = cpmmComputeAmount.minAmountOut;\n\n const launchSwapInfo = Curve.buyExactIn({\n poolInfo: launchPoolInfo,\n amountB: launchBuyAmount,\n protocolFeeRate: launchPoolInfo.configInfo.tradeFeeRate,\n platformFeeRate: platformInfo.feeRate,\n curveType: launchPoolInfo.configInfo.curveType,\n shareFeeRate,\n creatorFeeRate: platformInfo.creatorFeeRate,\n transferFeeConfigA: launchMintTransferFeeConfig,\n transferFeeConfigB: launchMintTransferFeeConfigB,\n slot: slot ?? (await this.scope.connection.getSlot()),\n });\n\n const outAmount = launchSwapInfo.amountA.amount.sub(launchSwapInfo.amountA.fee ?? new BN(0));\n const decimalAmountA = new Decimal(outAmount.toString());\n\n const SLIPPAGE_UNIT = new BN(10000);\n const multiplier = slippage\n ? new Decimal(SLIPPAGE_UNIT.sub(new BN(slippage * 10000)).toNumber() / SLIPPAGE_UNIT.toNumber()).clampedTo(0, 1)\n : new Decimal(1);\n\n return {\n cpmmPoolData,\n cpmmComputInfo: cpmmComputeAmount,\n\n launchPoolInfo,\n launchAuthProgramId: authProgramId,\n launchMintTransferFeeConfig,\n launchMintProgramB,\n launchMintTransferFeeConfigB,\n launchSwapInfo,\n outAmount: launchSwapInfo.amountA.amount.sub(launchSwapInfo.amountA.fee ?? new BN(0)),\n minOutAmount: new BN(decimalAmountA.mul(multiplier).toFixed(0)),\n };\n }\n\n public async computeCpClToLaunchAmount({\n inputMint,\n inputAmount,\n clmmPoolId,\n cpmmPoolId,\n launchPoolId,\n slippage: propsSlippage,\n epochInfo,\n shareFeeRate = new BN(0),\n cpmmPoolData: propsCpmmPoolData,\n clmmPoolData: propsClmmPoolData,\n launchPoolInfo: propsLaunchPoolInfo,\n launchPlatformInfo: propsLaunchPlatformInfo,\n slot,\n mintInfo: propsMintInfo,\n blockTimestamp,\n }: {\n clmmPoolId: string | PublicKey;\n cpmmPoolId: string | PublicKey;\n launchPoolId: string | PublicKey;\n inputMint: string | PublicKey;\n inputAmount: BN;\n slippage: number;\n epochInfo?: EpochInfo;\n shareFeeRate?: BN;\n\n cpmmPoolData?: CpmmComputeData;\n\n clmmPoolData?: {\n poolInfo: ApiV3PoolInfoConcentratedItem;\n poolKeys: ClmmKeys;\n computePoolInfo: ComputeClmmPoolInfo;\n tickData: ReturnTypeFetchMultiplePoolTickArrays;\n };\n launchPoolInfo?: LaunchpadPoolInfo & { programId: PublicKey; configInfo: LaunchpadConfigInfo };\n launchPlatformInfo?: Pick<LaunchpadPlatformInfo, \"feeRate\" | \"creatorFeeRate\">;\n slot?: number;\n mintInfo?: ApiV3Token;\n blockTimestamp: number;\n }): Promise<{\n clmmPoolData: {\n poolInfo: ApiV3PoolInfoConcentratedItem;\n poolKeys: ClmmKeys;\n computePoolInfo: ComputeClmmPoolInfo;\n tickData: ReturnTypeFetchMultiplePoolTickArrays;\n };\n clmmComputeAmount: { maxClmmAmountIn: BN; clmmAmountOut: BN; remainingAccounts: PublicKey[] };\n clmmComputeInfo: ReturnTypeComputeAmountOutBaseOut | ReturnTypeComputeAmountOutFormat;\n cpmmComputInfo: {\n amountIn: BN;\n amountOut: BN;\n minAmountOut: BN;\n fee: BN;\n executionPrice: Decimal;\n priceImpact: Decimal;\n swapResult: SwapResult;\n };\n launchPoolInfo: LaunchpadPoolInfo & { programId: PublicKey; configInfo: LaunchpadConfigInfo };\n launchAuthProgramId: PublicKey;\n outAmount: BN;\n minOutAmount: BN;\n launchSwapInfo: SwapInfoReturn;\n launchMintTransferFeeConfig?: TransferFeeConfig;\n launchMintProgramB: PublicKey;\n launchMintTransferFeeConfigB?: TransferFeeConfig;\n swapPoolType: \"clmm\" | \"cpmm\";\n }> {\n // split slippage for clmm swap and launch buy\n const slippage =\n propsSlippage > 0\n ? new Decimal(propsSlippage).div(2).toDecimalPlaces(4, Decimal.ROUND_DOWN).toNumber()\n : propsSlippage;\n const clmmPoolData = propsClmmPoolData ?? (await this.scope.clmm.getPoolInfoFromRpc(clmmPoolId.toString()));\n if (\n inputMint.toString() !== clmmPoolData.poolInfo.mintA.address &&\n inputMint.toString() !== clmmPoolData.poolInfo.mintB.address\n )\n throw new Error(\"input mint does not match clmm pool mints, please check\");\n const baseIn = inputMint.toString() === clmmPoolData.poolInfo.mintA.address;\n const tokenOut = clmmPoolData.poolInfo[baseIn ? \"mintB\" : \"mintA\"];\n\n let launchPoolInfo = propsLaunchPoolInfo;\n if (!launchPoolInfo)\n launchPoolInfo = await this.scope.launchpad.getRpcPoolInfo({ poolId: new PublicKey(launchPoolId) });\n\n if (tokenOut.address !== launchPoolInfo.mintB.toBase58())\n throw new Error(`clmm swap mint(${tokenOut.address}) != launch pool mintB(${launchPoolInfo.mintB.toBase58()})`);\n\n let platformInfo = propsLaunchPlatformInfo;\n if (!platformInfo) {\n const data = await this.scope.connection.getAccountInfo(launchPoolInfo.platformId);\n platformInfo = PlatformConfig.decode(data!.data);\n }\n const mintInfo = propsMintInfo ?? (await this.scope.token.getTokenInfo(launchPoolInfo.mintA));\n const authProgramId = getPdaLaunchpadAuth(launchPoolInfo.programId).publicKey;\n\n const launchMintTransferFeeConfig = toTransferFeeConfig(mintInfo, epochInfo?.epoch);\n const launchMintProgramB = getMintBProgram(tokenOut);\n const launchMintTransferFeeConfigB = toTransferFeeConfig(tokenOut, epochInfo?.epoch);\n\n const clmmComputeAmount = await PoolUtils.computeAmountOutFormat({\n poolInfo: clmmPoolData.computePoolInfo,\n tickArrayCache: clmmPoolData.tickData[clmmPoolId.toString()],\n amountIn: inputAmount,\n tokenOut,\n slippage,\n epochInfo: epochInfo ?? (await this.scope.fetchEpochInfo()),\n blockTimestamp,\n tickarrayBitmapExtension: clmmPoolData.computePoolInfo.exBitmapInfo,\n });\n\n const cpmmPoolData =\n propsCpmmPoolData ?? (await this.scope.cpmm.getPoolInfoFromRpc(cpmmPoolId.toString())).computePoolInfo;\n const cpmmComputeAmount = await this.scope.cpmm.computeSwapAmount({\n pool: cpmmPoolData,\n amountIn: inputAmount,\n outputMint: new PublicKey(tokenOut.address),\n slippage,\n });\n\n const [clmmAmount, cpmmAmount] = [clmmComputeAmount.minAmountOut.amount.raw, cpmmComputeAmount.minAmountOut];\n const swapPoolType = clmmAmount.gte(cpmmAmount) ? \"clmm\" : \"cpmm\";\n const launchBuyAmount = clmmAmount.gte(cpmmAmount) ? clmmAmount : cpmmAmount;\n\n const launchSwapInfo = Curve.buyExactIn({\n poolInfo: launchPoolInfo,\n amountB: launchBuyAmount,\n protocolFeeRate: launchPoolInfo.configInfo.tradeFeeRate,\n platformFeeRate: platformInfo.feeRate,\n curveType: launchPoolInfo.configInfo.curveType,\n shareFeeRate,\n creatorFeeRate: platformInfo.creatorFeeRate,\n transferFeeConfigA: launchMintTransferFeeConfig,\n transferFeeConfigB: launchMintTransferFeeConfigB,\n slot: slot ?? (await this.scope.connection.getSlot()),\n });\n\n const outAmount = launchSwapInfo.amountA.amount.sub(launchSwapInfo.amountA.fee ?? new BN(0));\n const decimalAmountA = new Decimal(outAmount.toString());\n\n const SLIPPAGE_UNIT = new BN(10000);\n const multiplier = slippage\n ? new Decimal(SLIPPAGE_UNIT.sub(new BN(slippage * 10000)).toNumber() / SLIPPAGE_UNIT.toNumber()).clampedTo(0, 1)\n : new Decimal(1);\n\n return {\n clmmPoolData,\n clmmComputeAmount: {\n maxClmmAmountIn: inputAmount,\n clmmAmountOut: launchBuyAmount,\n remainingAccounts: clmmComputeAmount.remainingAccounts,\n },\n clmmComputeInfo: clmmComputeAmount,\n cpmmComputInfo: cpmmComputeAmount,\n swapPoolType,\n\n launchPoolInfo,\n launchAuthProgramId: authProgramId,\n launchMintTransferFeeConfig,\n launchMintProgramB,\n launchMintTransferFeeConfigB,\n launchSwapInfo,\n outAmount: launchSwapInfo.amountA.amount.sub(launchSwapInfo.amountA.fee ?? new BN(0)),\n minOutAmount: new BN(decimalAmountA.mul(multiplier).toFixed(0)),\n };\n }\n\n // get all amm/clmm/cpmm pools data only with id and mint\n public async fetchRoutePoolBasicInfo(programIds?: { amm: PublicKey; clmm: PublicKey; cpmm: PublicKey }): Promise<{\n ammPools: BasicPoolInfo[];\n clmmPools: BasicPoolInfo[];\n cpmmPools: BasicPoolInfo[];\n }> {\n const { amm = AMM_V4, clmm = CLMM_PROGRAM_ID, cpmm = CREATE_CPMM_POOL_PROGRAM } = programIds || {};\n const ammPoolsData = await this.scope.connection.getProgramAccounts(amm, {\n dataSlice: { offset: liquidityStateV4Layout.offsetOf(\"baseMint\"), length: 64 },\n });\n\n const layoutAmm = struct([publicKey(\"baseMint\"), publicKey(\"quoteMint\")]);\n const ammData = ammPoolsData.map((data) => ({\n id: data.pubkey,\n version: 4,\n mintA: layoutAmm.decode(data.account.data).baseMint,\n mintB: layoutAmm.decode(data.account.data).quoteMint,\n }));\n\n const layout = struct([publicKey(\"mintA\"), publicKey(\"mintB\")]);\n const clmmPoolsData = await this.scope.connection.getProgramAccounts(clmm, {\n filters: [{ dataSize: PoolInfoLayout.span }],\n dataSlice: { offset: PoolInfoLayout.offsetOf(\"mintA\"), length: 64 },\n });\n\n const clmmData = clmmPoolsData.map((data) => {\n const clmm = layout.decode(data.account.data);\n return {\n id: data.pubkey,\n version: 6,\n mintA: clmm.mintA,\n mintB: clmm.mintB,\n };\n });\n\n const cpmmPools = await this.scope.connection.getProgramAccounts(cpmm, {\n dataSlice: { offset: CpmmPoolInfoLayout.offsetOf(\"mintA\"), length: 64 },\n });\n\n const cpmmData = cpmmPools.map((data) => {\n const clmm = layout.decode(data.account.data);\n return {\n id: data.pubkey,\n version: 7,\n mintA: clmm.mintA,\n mintB: clmm.mintB,\n };\n });\n\n return {\n clmmPools: clmmData,\n ammPools: ammData,\n cpmmPools: cpmmData,\n };\n }\n\n // get pools with in routes\n public getAllRoute({\n inputMint,\n outputMint,\n clmmPools,\n ammPools,\n cpmmPools,\n }: {\n inputMint: PublicKey;\n outputMint: PublicKey;\n clmmPools: BasicPoolInfo[];\n ammPools: BasicPoolInfo[];\n cpmmPools: BasicPoolInfo[];\n }): ReturnTypeGetAllRoute {\n inputMint = inputMint.toString() === PublicKey.default.toString() ? WSOLMint : inputMint;\n outputMint = outputMint.toString() === PublicKey.default.toString() ? WSOLMint : outputMint;\n\n const needSimulate: { [poolKey: string]: BasicPoolInfo } = {};\n const needTickArray: { [poolKey: string]: BasicPoolInfo } = {};\n const cpmmPoolList: { [poolKey: string]: BasicPoolInfo } = {};\n\n const directPath: BasicPoolInfo[] = [];\n\n const routePathDict: RoutePathType = {}; // {[route mint: string]: {in: [] , out: []}}\n\n for (const itemClmmPool of clmmPools ?? []) {\n if (\n (itemClmmPool.mintA.equals(inputMint) && itemClmmPool.mintB.equals(outputMint)) ||\n (itemClmmPool.mintA.equals(outputMint) && itemClmmPool.mintB.equals(inputMint))\n ) {\n directPath.push(itemClmmPool);\n needTickArray[itemClmmPool.id.toString()] = itemClmmPool;\n }\n\n if (itemClmmPool.mintA.equals(inputMint)) {\n const t = itemClmmPool.mintB.toString();\n if (routePathDict[t] === undefined)\n routePathDict[t] = {\n mintProgram: TOKEN_PROGRAM_ID, // to fetch later\n in: [],\n out: [],\n mDecimals: 0, // to fetch later\n };\n routePathDict[t].in.push(itemClmmPool);\n }\n if (itemClmmPool.mintB.equals(inputMint)) {\n const t = itemClmmPool.mintA.toString();\n if (routePathDict[t] === undefined)\n routePathDict[t] = {\n mintProgram: TOKEN_PROGRAM_ID, // to fetch later\n in: [],\n out: [],\n mDecimals: 0, // to fetch later\n };\n routePathDict[t].in.push(itemClmmPool);\n }\n if (itemClmmPool.mintA.equals(outputMint)) {\n const t = itemClmmPool.mintB.toString();\n if (routePathDict[t] === undefined)\n routePathDict[t] = {\n mintProgram: TOKEN_PROGRAM_ID, // to fetch later\n in: [],\n out: [],\n mDecimals: 0, // to fetch later\n };\n routePathDict[t].out.push(itemClmmPool);\n }\n if (itemClmmPool.mintB.equals(outputMint)) {\n const t = itemClmmPool.mintA.toString();\n if (routePathDict[t] === undefined)\n routePathDict[t] = {\n mintProgram: TOKEN_PROGRAM_ID, // to fetch later\n in: [],\n out: [],\n mDecimals: 0, // to fetch later\n };\n routePathDict[t].out.push(itemClmmPool);\n }\n }\n\n const addLiquidityPools: BasicPoolInfo[] = [];\n\n for (const itemAmmPool of ammPools) {\n if (\n (itemAmmPool.mintA.equals(inputMint) && itemAmmPool.mintB.equals(outputMint)) ||\n (itemAmmPool.mintA.equals(outputMint) && itemAmmPool.mintB.equals(inputMint))\n ) {\n directPath.push(itemAmmPool);\n needSimulate[itemAmmPool.id.toBase58()] = itemAmmPool;\n addLiquidityPools.push(itemAmmPool);\n }\n if (itemAmmPool.mintA.equals(inputMint)) {\n if (routePathDict[itemAmmPool.mintB.toBase58()] === undefined)\n routePathDict[itemAmmPool.mintB.toBase58()] = {\n mintProgram: TOKEN_PROGRAM_ID,\n in: [],\n out: [],\n mDecimals: 0, // to fetch later\n };\n routePathDict[itemAmmPool.mintB.toBase58()].in.push(itemAmmPool);\n }\n if (itemAmmPool.mintB.equals(inputMint)) {\n if (routePathDict[itemAmmPool.mintA.toBase58()] === undefined)\n routePathDict[itemAmmPool.mintA.toBase58()] = {\n mintProgram: TOKEN_PROGRAM_ID,\n in: [],\n out: [],\n mDecimals: 0, // to fetch later\n };\n routePathDict[itemAmmPool.mintA.toBase58()].in.push(itemAmmPool);\n }\n if (itemAmmPool.mintA.equals(outputMint)) {\n if (routePathDict[itemAmmPool.mintB.toBase58()] === undefined)\n routePathDict[itemAmmPool.mintB.toBase58()] = {\n mintProgram: TOKEN_PROGRAM_ID,\n in: [],\n out: [],\n mDecimals: 0, // to fetch later\n };\n routePathDict[itemAmmPool.mintB.toBase58()].out.push(itemAmmPool);\n }\n if (itemAmmPool.mintB.equals(outputMint)) {\n if (routePathDict[itemAmmPool.mintA.toBase58()] === undefined)\n routePathDict[itemAmmPool.mintA.toBase58()] = {\n mintProgram: TOKEN_PROGRAM_ID,\n in: [],\n out: [],\n mDecimals: 0, // to fetch later\n };\n routePathDict[itemAmmPool.mintA.toBase58()].out.push(itemAmmPool);\n }\n }\n\n for (const itemCpmmPool of cpmmPools) {\n if (\n (itemCpmmPool.mintA.equals(inputMint) && itemCpmmPool.mintB.equals(outputMint)) ||\n (itemCpmmPool.mintA.equals(outputMint) && itemCpmmPool.mintB.equals(inputMint))\n ) {\n directPath.push(itemCpmmPool);\n cpmmPoolList[itemCpmmPool.id.toBase58()] = itemCpmmPool;\n }\n if (itemCpmmPool.mintA.equals(inputMint)) {\n if (routePathDict[itemCpmmPool.mintB.toBase58()] === undefined)\n routePathDict[itemCpmmPool.mintB.toBase58()] = {\n mintProgram: TOKEN_PROGRAM_ID,\n in: [],\n out: [],\n mDecimals: 0, // to fetch later\n };\n routePathDict[itemCpmmPool.mintB.toBase58()].in.push(itemCpmmPool);\n }\n if (itemCpmmPool.mintB.equals(inputMint)) {\n if (routePathDict[itemCpmmPool.mintA.toBase58()] === undefined)\n routePathDict[itemCpmmPool.mintA.toBase58()] = {\n mintProgram: TOKEN_PROGRAM_ID,\n in: [],\n out: [],\n mDecimals: 0, // to fetch later\n };\n routePathDict[itemCpmmPool.mintA.toBase58()].in.push(itemCpmmPool);\n }\n if (itemCpmmPool.mintA.equals(outputMint)) {\n if (routePathDict[itemCpmmPool.mintB.toBase58()] === undefined)\n routePathDict[itemCpmmPool.mintB.toBase58()] = {\n mintProgram: TOKEN_PROGRAM_ID,\n in: [],\n out: [],\n mDecimals: 0, // to fetch later\n };\n routePathDict[itemCpmmPool.mintB.toBase58()].out.push(itemCpmmPool);\n }\n if (itemCpmmPool.mintB.equals(outputMint)) {\n if (routePathDict[itemCpmmPool.mintA.toBase58()] === undefined)\n routePathDict[itemCpmmPool.mintA.toBase58()] = {\n mintProgram: TOKEN_PROGRAM_ID,\n in: [],\n out: [],\n mDecimals: 0, // to fetch later\n };\n routePathDict[itemCpmmPool.mintA.toBase58()].out.push(itemCpmmPool);\n }\n }\n\n for (const t of Object.keys(routePathDict)) {\n if (\n routePathDict[t].in.length === 1 &&\n routePathDict[t].out.length === 1 &&\n routePathDict[t].in[0].id.equals(routePathDict[t].out[0].id)\n ) {\n delete routePathDict[t];\n continue;\n }\n if (routePathDict[t].in.length === 0 || routePathDict[t].out.length === 0) {\n delete routePathDict[t];\n continue;\n }\n\n const info = routePathDict[t];\n\n for (const infoIn of info.in) {\n for (const infoOut of info.out) {\n if (infoIn.version === 6 && needTickArray[infoIn.id.toString()] === undefined) {\n needTickArray[infoIn.id.toString()] = infoIn;\n } else if (infoIn.version === 7 && cpmmPoolList[infoIn.id.toString()] === undefined) {\n cpmmPoolList[infoIn.id.toString()] = infoIn;\n } else if (\n (infoIn.version === 4 || infoIn.version === 5) &&\n needSimulate[infoIn.id.toString()] === undefined\n ) {\n needSimulate[infoIn.id.toString()] = infoIn;\n }\n if (infoOut.version === 6 && needTickArray[infoOut.id.toString()] === undefined) {\n needTickArray[infoOut.id.toString()] = infoOut;\n } else if (infoOut.version === 7 && cpmmPoolList[infoOut.id.toString()] === undefined) {\n cpmmPoolList[infoOut.id.toString()] = infoOut;\n } else if (\n (infoOut.version === 4 || infoOut.version === 5) &&\n needSimulate[infoOut.id.toString()] === undefined\n ) {\n needSimulate[infoOut.id.toString()] = infoOut;\n }\n }\n }\n }\n\n return {\n directPath,\n addLiquidityPools,\n routePathDict,\n needSimulate: Object.values(needSimulate),\n needTickArray: Object.values(needTickArray),\n cpmmPoolList: Object.values(cpmmPoolList),\n };\n }\n\n // fetch pools detail info in route\n public async fetchSwapRoutesData({\n routes,\n inputMint,\n outputMint,\n }: {\n inputMint: string | PublicKey;\n outputMint: string | PublicKey;\n routes: ReturnTypeGetAllRoute;\n }): Promise<{\n mintInfos: ReturnTypeFetchMultipleMintInfos;\n ammPoolsRpcInfo: Record<string, AmmRpcData>;\n ammSimulateCache: Record<string, ComputeAmountOutParam[\"poolInfo\"]>;\n clmmPoolsRpcInfo: Record<string, ClmmParsedRpcData>;\n computeClmmPoolInfo: Record<string, ComputeClmmPoolInfo>;\n computePoolTickData: ReturnTypeFetchMultiplePoolTickArrays;\n computeCpmmData: Record<string, CpmmComputeData>;\n routePathDict: ComputeRoutePathType;\n }> {\n const mintSet = new Set([\n ...routes.needTickArray.map((p) => [p.mintA.toBase58(), p.mintB.toBase58()]).flat(),\n inputMint.toString(),\n outputMint.toString(),\n ]);\n\n console.log(\"fetching amm pools info, total: \", routes.needSimulate.length);\n const ammPoolsRpcInfo = await this.scope.liquidity.getRpcPoolInfos(routes.needSimulate.map((p) => p.id));\n const ammSimulateCache = toAmmComputePoolInfo(ammPoolsRpcInfo);\n\n let mintInfos: ReturnTypeFetchMultipleMintInfos = {};\n // amm doesn't support token2022 yet, so don't need to fetch mint info\n Object.values(ammSimulateCache).forEach((p) => {\n mintSet.delete(p.mintA.address);\n mintInfos[p.mintA.address] = {\n address: new PublicKey(p.mintA.address),\n programId: TOKEN_PROGRAM_ID,\n mintAuthority: null,\n supply: BigInt(0),\n decimals: p.mintA.decimals,\n isInitialized: true,\n freezeAuthority: null,\n tlvData: Buffer.from(\"0\", \"hex\"),\n feeConfig: undefined,\n };\n\n mintSet.delete(p.mintB.address);\n mintInfos[p.mintB.address] = {\n address: new PublicKey(p.mintB.address),\n programId: TOKEN_PROGRAM_ID,\n mintAuthority: null,\n supply: BigInt(0),\n decimals: p.mintB.decimals,\n isInitialized: true,\n freezeAuthority: null,\n tlvData: Buffer.from(\"0\", \"hex\"),\n feeConfig: undefined,\n };\n });\n\n console.log(\"fetching cpmm pools info, total: \", routes.cpmmPoolList.length);\n const cpmmPoolsRpcInfo = await this.scope.cpmm.getRpcPoolInfos(\n routes.cpmmPoolList.map((p) => p.id.toBase58()),\n true,\n );\n\n Object.values(cpmmPoolsRpcInfo).forEach((p) => {\n const [mintA, mintB] = [p.mintA.toBase58(), p.mintB.toBase58()];\n if (p.mintProgramA.equals(TOKEN_PROGRAM_ID)) {\n mintSet.delete(mintA);\n mintInfos[mintA] = {\n address: p.mintA,\n programId: p.mintProgramA,\n mintAuthority: null,\n supply: BigInt(0),\n decimals: p.mintDecimalA,\n isInitialized: true,\n freezeAuthority: null,\n tlvData: Buffer.from(\"0\", \"hex\"),\n feeConfig: undefined,\n };\n } else mintSet.add(mintA); // 2022, need to fetch fee config\n if (p.mintProgramB.equals(TOKEN_PROGRAM_ID)) {\n mintSet.delete(mintB);\n mintInfos[mintB] = {\n address: p.mintB,\n programId: p.mintProgramB,\n mintAuthority: null,\n supply: BigInt(0),\n decimals: p.mintDecimalB,\n isInitialized: true,\n freezeAuthority: null,\n tlvData: Buffer.from(\"0\", \"hex\"),\n feeConfig: undefined,\n };\n } else mintSet.add(mintB); // 2022, need to fetch fee config\n });\n\n console.log(\"fetching mints info, total: \", mintSet.size);\n const fetchMintInfoRes = await fetchMultipleMintInfos({\n connection: this.scope.connection,\n mints: Array.from(mintSet).map((m) => new PublicKey(m)),\n });\n\n mintInfos = {\n ...mintInfos,\n ...fetchMintInfoRes,\n };\n\n const computeCpmmData = this.scope.cpmm.toComputePoolInfos({\n pools: cpmmPoolsRpcInfo,\n mintInfos,\n });\n\n console.log(\"fetching clmm pools info, total:\", routes.needTickArray.length);\n const clmmPoolsRpcInfo = await this.scope.clmm.getRpcClmmPoolInfos({\n poolIds: routes.needTickArray.map((p) => p.id),\n });\n const { computeClmmPoolInfo, computePoolTickData } = await this.scope.clmm.getComputeClmmPoolInfos({\n clmmPoolsRpcInfo,\n mintInfos,\n });\n\n // update route pool mint info\n const routePathDict = Object.keys(routes.routePathDict).reduce((acc, cur) => {\n return {\n ...acc,\n [cur]: {\n ...routes.routePathDict[cur],\n mintProgram: mintInfos[cur].programId,\n mDecimals: mintInfos[cur].decimals,\n in: routes.routePathDict[cur].in.map(\n (p) =>\n ammSimulateCache[p.id.toBase58()] ||\n computeClmmPoolInfo[p.id.toBase58()] ||\n computeCpmmData[p.id.toBase58()],\n ),\n out: routes.routePathDict[cur].out.map(\n (p) =>\n ammSimulateCache[p.id.toBase58()] ||\n computeClmmPoolInfo[p.id.toBase58()] ||\n computeCpmmData[p.id.toBase58()],\n ),\n },\n };\n }, {} as ComputeRoutePathType);\n\n return {\n mintInfos,\n\n ammPoolsRpcInfo,\n ammSimulateCache,\n\n clmmPoolsRpcInfo,\n computeClmmPoolInfo,\n computePoolTickData,\n\n computeCpmmData,\n\n routePathDict,\n };\n }\n\n // compute amount from routes\n public getAllRouteComputeAmountOut({\n inputTokenAmount,\n outputToken: propOutputToken,\n directPath,\n routePathDict,\n simulateCache,\n tickCache,\n slippage,\n chainTime,\n epochInfo,\n feeConfig,\n blockTimestamp,\n }: {\n directPath: ComputePoolType[];\n routePathDict: ComputeRoutePathType;\n simulateCache: ReturnTypeFetchMultipleInfo;\n tickCache: ReturnTypeFetchMultiplePoolTickArrays;\n\n mintInfos: ReturnTypeFetchMultipleMintInfos;\n\n inputTokenAmount: TokenAmount;\n outputToken: ApiV3Token;\n slippage: number;\n chainTime: number;\n epochInfo: EpochInfo;\n\n feeConfig?: {\n feeBps: BN;\n feeAccount: PublicKey;\n };\n blockTimestamp: number;\n }): ComputeAmountOutLayout[] {\n const _amountInFee =\n feeConfig === undefined\n ? new BN(0)\n : inputTokenAmount.raw.mul(new BN(feeConfig.feeBps.toNumber())).div(new BN(10000));\n const _amoutIn = inputTokenAmount.raw.sub(_amountInFee);\n const amountIn = new TokenAmount(inputTokenAmount.token, _amoutIn);\n const _inFeeConfig =\n feeConfig === undefined\n ? undefined\n : {\n feeAmount: _amountInFee,\n feeAccount: feeConfig.feeAccount,\n };\n const outputToken = {\n ...propOutputToken,\n address: solToWSol(propOutputToken.address).toString(),\n };\n const outRoute: ComputeAmountOutLayout[] = [];\n for (const itemPool of directPath) {\n try {\n outRoute.push({\n ...this.computeAmountOut({\n itemPool,\n tickCache,\n simulateCache,\n chainTime,\n epochInfo,\n slippage,\n outputToken,\n amountIn,\n blockTimestamp,\n }),\n feeConfig: _inFeeConfig,\n });\n } catch (e: any) {\n this.logDebug(\"direct error\", itemPool.version, itemPool.id.toString(), e.message);\n /* empty */\n }\n }\n this.logDebug(\"direct done\");\n for (const [routeMint, info] of Object.entries(routePathDict)) {\n // const routeToken = new Token(info.mintProgram, routeMint, info.mDecimals);\n const routeToken = {\n chainId: 101,\n address: routeMint,\n programId: info.mintProgram.toBase58(),\n logoURI: \"\",\n symbol: \"\",\n name: \"\",\n decimals: info.mDecimals,\n tags: [],\n extensions: {},\n };\n const maxFirstIn = info.in\n .map((i) => {\n try {\n return {\n pool: i,\n data: this.computeAmountOut({\n itemPool: i,\n tickCache,\n simulateCache,\n chainTime,\n epochInfo,\n slippage,\n outputToken: routeToken,\n amountIn,\n blockTimestamp,\n }),\n };\n } catch (e: any) {\n this.logDebug(\"route in error\", i.version, i.id.toString(), e.message);\n return undefined;\n }\n })\n .sort((_a, _b) => {\n const a = _a === undefined ? ZERO : _a.data.amountOut.amount.raw.sub(_a.data.amountOut.fee?.raw ?? ZERO);\n const b = _b === undefined ? ZERO : _b.data.amountOut.amount.raw.sub(_b.data.amountOut.fee?.raw ?? ZERO);\n return a.lt(b) ? 1 : -1;\n })[0];\n if (maxFirstIn === undefined) continue;\n const routeAmountIn = new TokenAmount(\n toToken(routeToken),\n maxFirstIn.data.amountOut.amount.raw.sub(maxFirstIn.data.amountOut.fee?.raw ?? ZERO),\n );\n for (const iOutPool of info.out) {\n try {\n const outC = this.computeAmountOut({\n itemPool: iOutPool,\n tickCache,\n simulateCache,\n chainTime,\n epochInfo,\n slippage,\n outputToken,\n amountIn: routeAmountIn,\n blockTimestamp,\n });\n outRoute.push({\n ...outC,\n allTrade: maxFirstIn.data.allTrade && outC.allTrade ? true : false,\n amountIn: maxFirstIn.data.amountIn,\n amountOut: outC.amountOut,\n minAmountOut: outC.minAmountOut,\n currentPrice: undefined,\n executionPrice: new Decimal(\n new Price({\n baseToken: maxFirstIn.data.amountIn.amount.token,\n denominator: maxFirstIn.data.amountIn.amount.raw,\n quoteToken: outC.amountOut.amount.token,\n numerator: outC.amountOut.amount.raw.sub(outC.amountOut.fee?.raw ?? ZERO),\n }).toFixed(),\n ),\n priceImpact: new Decimal(maxFirstIn.data.priceImpact.add(outC.priceImpact).toFixed()),\n fee: [maxFirstIn.data.fee[0], outC.fee[0]],\n routeType: \"route\",\n poolInfoList: [maxFirstIn.pool, iOutPool],\n remainingAccounts: [maxFirstIn.data.remainingAccounts[0], outC.remainingAccounts[0]],\n minMiddleAmountFee: outC.amountOut.fee?.raw\n ? new TokenAmount(\n (maxFirstIn.data.amountOut.amount as TokenAmount).token,\n (maxFirstIn.data.amountOut.fee?.raw ?? ZERO).add(outC.amountOut.fee?.raw ?? ZERO),\n )\n : undefined,\n middleToken: (maxFirstIn.data.amountOut.amount as TokenAmount).token,\n poolReady: maxFirstIn.data.poolReady && outC.poolReady,\n poolType: [maxFirstIn.data.poolType, outC.poolType],\n feeConfig: _inFeeConfig,\n expirationTime: minExpirationTime(maxFirstIn.data.expirationTime, outC.expirationTime),\n });\n } catch (e: any) {\n this.logDebug(\"route out error\", iOutPool.version, iOutPool.id.toString(), e.message);\n /* empty */\n }\n }\n }\n\n return outRoute\n .filter((i) => {\n if (!i.allTrade)\n this.logDebug(`pool ${i.poolInfoList.map((p) => p.id.toString()).join(\",\")} filter out since not all trade`);\n return i.allTrade;\n })\n .sort((a, b) => (a.amountOut.amount.raw.sub(b.amountOut.amount.raw).gt(ZERO) ? -1 : 1));\n }\n\n public getAllRouteComputeAmountIn({\n outputTokenAmount,\n directPath,\n routePathDict,\n simulateCache,\n tickCache,\n slippage,\n chainTime,\n epochInfo,\n blockTimestamp,\n feeConfig,\n }: {\n directPath: ComputePoolType[];\n routePathDict: ComputeRoutePathType;\n simulateCache: ReturnTypeFetchMultipleInfo;\n tickCache: ReturnTypeFetchMultiplePoolTickArrays;\n\n mintInfos: ReturnTypeFetchMultipleMintInfos;\n\n outputTokenAmount: TokenAmount;\n inputToken: ApiV3Token;\n slippage: number;\n chainTime: number;\n epochInfo: EpochInfo;\n\n feeConfig?: {\n feeBps: BN;\n feeAccount: PublicKey;\n };\n blockTimestamp: number;\n }): ComputeAmountInLayout[] {\n const outputToken = toApiV3Token({\n address: solToWSol(outputTokenAmount.token.mint).toBase58(),\n decimals: outputTokenAmount.token.decimals,\n programId: outputTokenAmount.token.isToken2022 ? TOKEN_2022_PROGRAM_ID.toBase58() : TOKEN_PROGRAM_ID.toBase58(),\n extensions: {},\n });\n const inRoute: ComputeAmountInLayout[] = [];\n for (const itemPool of directPath) {\n try {\n const computeResult = this.computeAmountIn({\n itemPool,\n tickCache,\n simulateCache,\n chainTime,\n epochInfo,\n slippage,\n outputToken,\n amountOut: outputTokenAmount.raw,\n blockTimestamp,\n });\n const _amountInFee =\n feeConfig === undefined\n ? new BN(0)\n : computeResult.amountIn.amount.raw.mul(new BN(feeConfig.feeBps.toNumber())).div(new BN(10000));\n inRoute.push({\n ...computeResult,\n feeConfig:\n feeConfig === undefined\n ? undefined\n : {\n feeAmount: _amountInFee,\n feeAccount: feeConfig.feeAccount,\n },\n });\n } catch (e: any) {\n this.logDebug(\"direct error\", itemPool.version, itemPool.id.toString(), e.message);\n /* empty */\n }\n }\n this.logDebug(\"direct done\");\n for (const [routeMint, info] of Object.entries(routePathDict)) {\n // const routeToken = new Token(info.mintProgram, routeMint, info.mDecimals);\n const routeToken = {\n chainId: 101,\n address: routeMint,\n programId: info.mintProgram.toBase58(),\n logoURI: \"\",\n symbol: \"\",\n name: \"\",\n decimals: info.mDecimals,\n tags: [],\n extensions: {},\n };\n\n // intermdiate -> out\n const minIntermediateIn = info.out\n .map((i) => {\n try {\n return {\n pool: i,\n data: this.computeAmountIn({\n itemPool: i,\n tickCache,\n simulateCache,\n chainTime,\n epochInfo,\n slippage,\n outputToken,\n amountOut: outputTokenAmount.raw,\n blockTimestamp,\n }),\n };\n } catch (e: any) {\n this.logDebug(\"route in error\", i.version, i.id.toString(), e.message);\n return undefined;\n }\n })\n .sort((_a, _b) => {\n const a = _a === undefined ? ZERO : _a.data.amountIn.amount.raw.add(_a.data.amountIn.fee?.raw ?? ZERO);\n const b = _b === undefined ? ZERO : _b.data.amountIn.amount.raw.add(_b.data.amountIn.fee?.raw ?? ZERO);\n return a.lt(b) ? -1 : 1;\n })[0];\n if (minIntermediateIn === undefined) continue;\n const routeAmountIn = new TokenAmount(\n toToken(routeToken),\n minIntermediateIn.data.amountIn.amount.raw.add(minIntermediateIn.data.amountIn.fee?.raw ?? ZERO),\n );\n for (const iInPool of info.in) {\n try {\n // input -> intermdiate\n const inputToIntermediate = this.computeAmountIn({\n itemPool: iInPool,\n tickCache,\n simulateCache,\n chainTime,\n epochInfo,\n slippage,\n outputToken: routeToken,\n amountOut: routeAmountIn.raw,\n blockTimestamp,\n });\n const _amountInFee =\n feeConfig === undefined\n ? new BN(0)\n : inputToIntermediate.amountIn.amount.raw.mul(new BN(feeConfig.feeBps.toNumber())).div(new BN(10000));\n\n inRoute.push({\n ...inputToIntermediate,\n allTrade: inputToIntermediate.allTrade && minIntermediateIn.data.allTrade ? true : false,\n amountIn: inputToIntermediate.amountIn,\n amountOut: minIntermediateIn.data.amountOut,\n maxAmountIn: inputToIntermediate.maxAmountIn,\n currentPrice: undefined,\n executionPrice: new Decimal(\n new Price({\n baseToken: minIntermediateIn.data.amountIn.amount.token,\n denominator: minIntermediateIn.data.amountIn.amount.raw,\n quoteToken: inputToIntermediate.amountOut.amount.token,\n numerator: inputToIntermediate.amountOut.amount.raw.sub(inputToIntermediate.amountOut.fee?.raw ?? ZERO),\n }).toFixed(),\n ),\n priceImpact: new Decimal(minIntermediateIn.data.priceImpact.add(inputToIntermediate.priceImpact).toFixed()),\n fee: [inputToIntermediate.fee[0], minIntermediateIn.data.fee[0]],\n routeType: \"route\",\n poolInfoList: [minIntermediateIn.pool, iInPool],\n remainingAccounts: [minIntermediateIn.data.remainingAccounts[0], inputToIntermediate.remainingAccounts[0]],\n minMiddleAmountFee: inputToIntermediate.amountOut.fee?.raw\n ? new TokenAmount(\n (minIntermediateIn.data.amountOut.amount as TokenAmount).token,\n (minIntermediateIn.data.amountOut.fee?.raw ?? ZERO).add(\n inputToIntermediate.amountOut.fee?.raw ?? ZERO,\n ),\n )\n : undefined,\n middleToken: (minIntermediateIn.data.amountOut.amount as TokenAmount).token,\n poolReady: minIntermediateIn.data.poolReady && inputToIntermediate.poolReady,\n poolType: [minIntermediateIn.data.poolType, inputToIntermediate.poolType],\n feeConfig:\n feeConfig === undefined\n ? undefined\n : {\n feeAmount: _amountInFee,\n feeAccount: feeConfig.feeAccount,\n },\n expirationTime: minExpirationTime(\n minIntermediateIn.data.expirationTime,\n inputToIntermediate.expirationTime,\n ),\n });\n } catch (e: any) {\n this.logDebug(\"route out error\", iInPool.version, iInPool.id.toString(), e.message);\n /* empty */\n }\n }\n }\n\n return inRoute\n .filter((i) => {\n if (!i.allTrade)\n this.logDebug(`pool ${i.poolInfoList.map((p) => p.id.toString()).join(\",\")} filter out since not all trade`);\n return i.allTrade;\n })\n .sort((a, b) => (b.amountIn.amount.raw.sub(a.amountIn.amount.raw).gt(ZERO) ? -1 : 1));\n }\n\n /** trade related utils */\n\n private computeAmountOut({\n itemPool,\n tickCache,\n simulateCache,\n chainTime,\n epochInfo,\n slippage,\n outputToken,\n amountIn,\n blockTimestamp,\n }: {\n itemPool: ComputePoolType;\n tickCache: ReturnTypeFetchMultiplePoolTickArrays;\n simulateCache: ReturnTypeFetchMultipleInfo;\n chainTime: number;\n epochInfo: EpochInfo;\n amountIn: TokenAmount;\n outputToken: ApiV3Token;\n slippage: number;\n blockTimestamp: number;\n }): ComputeAmountOutAmmLayout {\n if (itemPool.version === 6) {\n const {\n allTrade,\n realAmountIn,\n amountOut,\n minAmountOut,\n expirationTime,\n currentPrice,\n executionPrice,\n priceImpact,\n fee,\n remainingAccounts,\n executionPriceX64,\n } = PoolUtils.computeAmountOutFormat({\n poolInfo: itemPool,\n tickarrayBitmapExtension: itemPool.exBitmapInfo,\n tickArrayCache: tickCache[itemPool.id.toString()],\n amountIn: amountIn.raw,\n tokenOut: outputToken,\n slippage,\n epochInfo,\n catchLiquidityInsufficient: true,\n blockTimestamp,\n });\n return {\n allTrade,\n amountIn: realAmountIn,\n amountOut,\n minAmountOut,\n currentPrice: new Decimal(currentPrice.toFixed()),\n executionPrice: new Decimal(executionPrice.toFixed()),\n priceImpact: new Decimal(priceImpact.toFixed()),\n fee: [fee],\n remainingAccounts: [remainingAccounts],\n routeType: \"amm\",\n poolInfoList: [itemPool],\n poolReady: itemPool.startTime < chainTime,\n poolType: \"CLMM\",\n slippage,\n clmmExPriceX64: [executionPriceX64],\n expirationTime: minExpirationTime(realAmountIn.expirationTime, expirationTime),\n };\n } else if (itemPool.version === 7) {\n const { allTrade, executionPrice, amountOut, minAmountOut, priceImpact, fee } = this.scope.cpmm.computeSwapAmount(\n {\n pool: itemPool,\n outputMint: outputToken.address,\n amountIn: amountIn.raw,\n slippage,\n },\n );\n\n return {\n allTrade,\n amountIn: { amount: amountIn, fee: undefined, expirationTime: undefined },\n amountOut: {\n amount: toTokenAmount({\n ...outputToken,\n amount: amountOut,\n }),\n fee: undefined,\n expirationTime: undefined,\n },\n minAmountOut: {\n amount: toTokenAmount({\n ...outputToken,\n amount: minAmountOut,\n }),\n fee: undefined,\n expirationTime: undefined,\n },\n currentPrice: itemPool.poolPrice,\n executionPrice,\n priceImpact,\n fee: [new TokenAmount(amountIn.token, fee)],\n remainingAccounts: [],\n routeType: \"amm\",\n poolInfoList: [itemPool],\n poolReady: itemPool.openTime.toNumber() < chainTime,\n poolType: \"CPMM\",\n slippage,\n clmmExPriceX64: [undefined],\n expirationTime: undefined,\n };\n } else {\n if (![1, 6, 7].includes(simulateCache[itemPool.id.toString()].status)) throw Error(\"swap error\");\n const { amountOut, minAmountOut, currentPrice, executionPrice, priceImpact, fee } =\n this.scope.liquidity.computeAmountOut({\n poolInfo: simulateCache[itemPool.id.toString()],\n amountIn: amountIn.raw,\n mintIn: amountIn.token.mint,\n mintOut: outputToken.address,\n slippage,\n });\n return {\n amountIn: { amount: amountIn, fee: undefined, expirationTime: undefined },\n amountOut: {\n amount: toTokenAmount({\n ...outputToken,\n amount: amountOut,\n }),\n fee: undefined,\n expirationTime: undefined,\n },\n minAmountOut: {\n amount: toTokenAmount({\n ...outputToken,\n amount: minAmountOut,\n }),\n fee: undefined,\n expirationTime: undefined,\n },\n currentPrice,\n executionPrice,\n priceImpact,\n fee: [new TokenAmount(amountIn.token, fee)],\n routeType: \"amm\",\n poolInfoList: [itemPool],\n remainingAccounts: [],\n poolReady: Number(simulateCache[itemPool.id as string].openTime) < chainTime,\n poolType: itemPool.version === 5 ? \"STABLE\" : undefined,\n expirationTime: undefined,\n allTrade: true,\n slippage,\n clmmExPriceX64: [undefined],\n };\n }\n }\n\n private computeAmountIn({\n itemPool,\n tickCache,\n simulateCache,\n chainTime,\n epochInfo,\n slippage,\n amountOut,\n outputToken,\n blockTimestamp,\n }: {\n itemPool: ComputePoolType;\n tickCache: ReturnTypeFetchMultiplePoolTickArrays;\n simulateCache: ReturnTypeFetchMultipleInfo;\n chainTime: number;\n epochInfo: EpochInfo;\n amountOut: BN;\n outputToken: ApiV3Token;\n slippage: number;\n blockTimestamp: number;\n }): ComputeAmountInAmmLayout {\n const inputToken = outputToken.address === itemPool.mintB.address ? itemPool.mintA : itemPool.mintB;\n if (itemPool.version === 6) {\n const {\n allTrade,\n realAmountOut,\n amountIn,\n maxAmountIn,\n expirationTime,\n currentPrice,\n executionPrice,\n priceImpact,\n fee,\n remainingAccounts,\n } = PoolUtils.computeAmountIn({\n poolInfo: itemPool,\n tickarrayBitmapExtension: itemPool.exBitmapInfo,\n tickArrayCache: tickCache[itemPool.id.toString()],\n amountOut,\n baseMint: new PublicKey(inputToken.address),\n slippage,\n epochInfo,\n blockTimestamp,\n });\n return {\n allTrade,\n amountOut: {\n amount: toTokenAmount({\n ...outputToken,\n amount: realAmountOut.amount,\n }),\n fee: realAmountOut.fee\n ? toTokenAmount({\n ...outputToken,\n amount: realAmountOut.fee,\n })\n : undefined,\n expirationTime: undefined,\n },\n amountIn: {\n amount: toTokenAmount({\n ...inputToken,\n amount: amountIn.amount,\n }),\n fee: amountIn.fee\n ? toTokenAmount({\n ...inputToken,\n amount: amountIn.fee,\n })\n : undefined,\n expirationTime: amountIn.expirationTime,\n },\n maxAmountIn: {\n amount: toTokenAmount({\n ...inputToken,\n amount: maxAmountIn.amount,\n }),\n fee: maxAmountIn.fee\n ? toTokenAmount({\n ...inputToken,\n amount: maxAmountIn.fee,\n })\n : undefined,\n expirationTime: maxAmountIn.expirationTime,\n },\n currentPrice: new Decimal(currentPrice.toFixed()),\n executionPrice: new Decimal(executionPrice.toFixed()),\n priceImpact: new Decimal(priceImpact.toFixed()),\n fee: [\n toTokenAmount({\n ...inputToken,\n amount: fee,\n }),\n ],\n remainingAccounts: [remainingAccounts],\n routeType: \"amm\",\n poolInfoList: [itemPool],\n poolReady: itemPool.startTime < chainTime,\n poolType: \"CLMM\",\n slippage,\n clmmExPriceX64: [decimalToX64(executionPrice)],\n expirationTime: minExpirationTime(realAmountOut.expirationTime, expirationTime),\n };\n } else if (itemPool.version === 7) {\n const {\n allTrade,\n executionPrice,\n amountIn,\n amountOut: realAmountOut,\n priceImpact,\n fee,\n } = this.scope.cpmm.computeSwapAmount({\n pool: itemPool,\n outputMint: outputToken.address,\n amountIn: amountOut,\n swapBaseIn: false,\n slippage,\n });\n\n return {\n allTrade,\n amountOut: {\n amount: toTokenAmount({\n ...outputToken,\n amount: realAmountOut,\n }),\n fee: undefined,\n expirationTime: undefined,\n },\n amountIn: {\n amount: toTokenAmount({\n ...inputToken,\n amount: amountIn,\n }),\n fee: undefined,\n expirationTime: undefined,\n },\n maxAmountIn: {\n amount: toTokenAmount({\n ...inputToken,\n amount: amountIn.mul(new BN((1 + slippage) * 10000)).div(new BN(10000)),\n }),\n fee: undefined,\n expirationTime: undefined,\n },\n currentPrice: itemPool.poolPrice,\n executionPrice,\n priceImpact,\n fee: [\n toTokenAmount({\n ...inputToken,\n amount: fee,\n }),\n ],\n remainingAccounts: [],\n routeType: \"amm\",\n poolInfoList: [itemPool],\n poolReady: itemPool.openTime.toNumber() < chainTime,\n poolType: \"CPMM\",\n slippage,\n clmmExPriceX64: [undefined],\n expirationTime: undefined,\n };\n } else {\n if (![1, 6, 7].includes(simulateCache[itemPool.id.toString()].status)) throw Error(\"swap error\");\n const { amountIn, maxAmountIn, currentPrice, executionPrice, priceImpact } = this.scope.liquidity.computeAmountIn(\n {\n poolInfo: simulateCache[itemPool.id.toString()],\n amountOut,\n mintIn: inputToken.address,\n mintOut: outputToken.address,\n slippage,\n },\n );\n return {\n amountOut: {\n amount: toTokenAmount({\n ...outputToken,\n amount: amountOut,\n }),\n fee: undefined,\n expirationTime: undefined,\n },\n amountIn: {\n amount: toTokenAmount({\n ...inputToken,\n amount: amountIn,\n }),\n fee: undefined,\n expirationTime: undefined,\n },\n maxAmountIn: {\n amount: toTokenAmount({\n ...inputToken,\n amount: maxAmountIn,\n }),\n fee: undefined,\n expirationTime: undefined,\n },\n currentPrice,\n executionPrice,\n priceImpact,\n fee: [\n toTokenAmount({\n ...inputToken,\n amount: BN_ZERO,\n }),\n ],\n routeType: \"amm\",\n poolInfoList: [itemPool],\n remainingAccounts: [],\n poolReady: Number(simulateCache[itemPool.id as string].openTime) < chainTime,\n poolType: itemPool.version === 5 ? \"STABLE\" : undefined,\n expirationTime: undefined,\n allTrade: true,\n slippage,\n clmmExPriceX64: [undefined],\n };\n }\n }\n\n public async computePoolToPoolKeys({\n pools,\n clmmRpcData = {},\n ammRpcData = {},\n }: {\n pools: ComputePoolType[];\n clmmRpcData?: Record<string, ClmmParsedRpcData>;\n ammRpcData?: Record<string, AmmRpcData>;\n }): Promise<PoolKeys[]> {\n const clmmFetchKeys = new Set(\n pools.filter((p) => p.version === 6 && !clmmRpcData[p.id.toString()]).map((p) => p.id.toString()),\n );\n if (clmmFetchKeys.size > 0) {\n const clmmData = await this.scope.clmm.getRpcClmmPoolInfos({ poolIds: Array.from(clmmFetchKeys) });\n Object.keys(clmmData).forEach((poolId) => {\n clmmRpcData[poolId] = clmmData[poolId];\n });\n }\n\n const ammFetchKeys = new Set(\n pools.filter((p) => p.version === 4 && !ammRpcData[p.id.toString()]).map((p) => p.id.toString()),\n );\n if (ammFetchKeys.size > 0) {\n const ammData = await this.scope.liquidity.getRpcPoolInfos(Array.from(ammFetchKeys));\n Object.keys(ammData).forEach((poolId) => {\n ammRpcData[poolId] = ammData[poolId];\n });\n }\n\n const ammMarketFetchKeys = new Set(\n pools.filter((p) => p.version === 4).map((p) => (p as ComputeAmountOutParam[\"poolInfo\"]).marketId),\n );\n const marketData: Record<\n string,\n {\n marketProgramId: string;\n marketId: string;\n marketAuthority: string;\n marketBaseVault: string;\n marketQuoteVault: string;\n marketBids: string;\n marketAsks: string;\n marketEventQueue: string;\n }\n > = {};\n if (ammMarketFetchKeys.size > 0) {\n const marketAccount = await getMultipleAccountsInfoWithCustomFlags(\n this.scope.connection,\n Array.from(ammMarketFetchKeys).map((p) => ({ pubkey: new PublicKey(p) })),\n );\n marketAccount.forEach((m) => {\n if (!m.accountInfo) return;\n const itemMarketInfo = MARKET_STATE_LAYOUT_V3.decode(m.accountInfo.data);\n marketData[m.pubkey.toBase58()] = {\n marketId: m.pubkey.toString(),\n marketProgramId: m.accountInfo.owner.toString(),\n marketAuthority: Market.getAssociatedAuthority({\n programId: m.accountInfo.owner,\n marketId: m.pubkey,\n }).publicKey.toString(),\n marketBaseVault: itemMarketInfo.baseVault.toString(),\n marketQuoteVault: itemMarketInfo.quoteVault.toString(),\n marketBids: itemMarketInfo.bids.toString(),\n marketAsks: itemMarketInfo.asks.toString(),\n marketEventQueue: itemMarketInfo.eventQueue.toString(),\n };\n });\n }\n\n const poolKeys: PoolKeys[] = [];\n pools.forEach((pool) => {\n if (pool.version === 6) {\n const rpcInfo = clmmRpcData[pool.id.toString()];\n const clmmKeys: ClmmKeys = {\n programId: pool.programId.toBase58(),\n id: pool.id.toBase58(),\n mintA: pool.mintA,\n mintB: pool.mintB,\n openTime: String(pool.startTime),\n vault: {\n A: rpcInfo.vaultA.toBase58(),\n B: rpcInfo.vaultB.toBase58(),\n },\n config: {\n ...pool.ammConfig,\n id: pool.ammConfig.id.toString(),\n defaultRange: 0,\n defaultRangePoint: [],\n },\n rewardInfos: [],\n observationId: pool.observationId.toBase58(),\n exBitmapAccount: pool.exBitmapAccount.toBase58(),\n };\n poolKeys.push(clmmKeys);\n } else if (pool.version === 4) {\n const rpcInfo = ammRpcData[pool.id.toString()];\n const ammKeys: AmmV4Keys = {\n programId: pool.programId,\n id: pool.id,\n mintA: pool.mintA,\n mintB: pool.mintB,\n openTime: String(pool.openTime),\n vault: {\n A: rpcInfo.baseVault.toBase58(),\n B: rpcInfo.quoteVault.toBase58(),\n },\n authority: getLiquidityAssociatedAuthority({ programId: new PublicKey(pool.programId) }).publicKey.toString(),\n openOrders: rpcInfo.openOrders.toBase58(),\n targetOrders: rpcInfo.targetOrders.toBase58(),\n mintLp: pool.lpMint,\n ...(marketData[pool.marketId] || {\n marketProgramId: rpcInfo.marketProgramId.toBase58(),\n marketId: rpcInfo.marketId.toBase58(),\n marketAuthority: PublicKey.default.toBase58(),\n marketBaseVault: PublicKey.default.toBase58(),\n marketQuoteVault: PublicKey.default.toBase58(),\n marketBids: PublicKey.default.toBase58(),\n marketAsks: PublicKey.default.toBase58(),\n marketEventQueue: PublicKey.default.toBase58(),\n }),\n };\n poolKeys.push(ammKeys);\n } else if (pool.version === 7) {\n poolKeys.push({\n observationId: pool.observationId.toBase58(),\n programId: pool.programId.toBase58(),\n id: pool.id.toBase58(),\n mintA: pool.mintA,\n mintB: pool.mintB,\n openTime: String(pool.openTime),\n authority: getPdaPoolAuthority(pool.programId).publicKey.toBase58(),\n vault: {\n A: pool.vaultA.toBase58(),\n B: pool.vaultB.toBase58(),\n },\n mintLp: toApiV3Token({\n address: pool.mintLp.toBase58(),\n programId: TOKEN_PROGRAM_ID.toBase58(),\n decimals: pool.lpDecimals,\n }),\n config: {\n id: pool.configId.toBase58(),\n ...pool.configInfo,\n protocolFeeRate: pool.configInfo.protocolFeeRate.toNumber(),\n tradeFeeRate: pool.configInfo.tradeFeeRate.toNumber(),\n fundFeeRate: pool.configInfo.fundFeeRate.toNumber(),\n createPoolFee: pool.configInfo.createPoolFee.toString(),\n },\n });\n }\n });\n return poolKeys;\n }\n}\n","import { METADATA_PROGRAM_ID, RENT_PROGRAM_ID } from \"@/common\";\nimport { publicKey, str, struct, u16, u64, u8 } from \"@/marshmallow\";\nimport { ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_2022_PROGRAM_ID, TOKEN_PROGRAM_ID } from \"@solana/spl-token\";\nimport { AccountMeta, PublicKey, SystemProgram, TransactionInstruction } from \"@solana/web3.js\";\nimport BN from \"bn.js\";\nimport { BondingCurveParam } from \"./layout\";\nimport { getPdaCpiEvent } from \"./pda\";\nimport { CpmmCreatorFeeOn } from \"./type\";\nexport const anchorDataBuf = {\n initialize: Buffer.from([175, 175, 109, 31, 13, 152, 155, 237]),\n initializeV2: Buffer.from([67, 153, 175, 39, 218, 16, 38, 32]),\n\n buyExactIn: Buffer.from([250, 234, 13, 123, 213, 156, 19, 236]),\n buyExactOut: Buffer.from([24, 211, 116, 40, 105, 3, 153, 56]),\n sellExactIn: Buffer.from([149, 39, 222, 155, 211, 124, 152, 26]),\n sellExactOut: Buffer.from([95, 200, 71, 34, 8, 9, 11, 166]),\n createVestingAccount: Buffer.from([129, 178, 2, 13, 217, 172, 230, 218]),\n claimVestedToken: Buffer.from([49, 33, 104, 30, 189, 157, 79, 35]),\n\n createPlatformConfig: Buffer.from([176, 90, 196, 175, 253, 113, 220, 20]),\n claimPlatformFee: Buffer.from([156, 39, 208, 135, 76, 237, 61, 72]),\n updatePlaformConfig: Buffer.from([195, 60, 76, 129, 146, 45, 67, 143]),\n initializeWithToken2022: Buffer.from([37, 190, 126, 222, 44, 154, 171, 17]),\n claimPlatformFeeFromVault: Buffer.from([117, 241, 198, 168, 248, 218, 80, 29]),\n claimCreatorFee: Buffer.from([26, 97, 138, 203, 132, 171, 141, 252]),\n\n updatePlatformCurveParam: Buffer.from([138, 144, 138, 250, 220, 128, 4, 57]),\n removePlatformCurveParam: Buffer.from([27, 30, 62, 169, 93, 224, 24, 145]),\n\n createPlatformVestingAccount: Buffer.from([146, 71, 173, 69, 98, 19, 15, 106]),\n\n createPlatformAllowConfig: Buffer.from([69, 71, 168, 7, 214, 250, 107, 102]),\n closePlatformAllowConfig: Buffer.from([82, 205, 36, 216, 16, 6, 240, 215]),\n};\n\nexport function initialize(\n programId: PublicKey,\n\n payer: PublicKey,\n creator: PublicKey,\n configId: PublicKey,\n platformId: PublicKey,\n auth: PublicKey,\n poolId: PublicKey,\n mintA: PublicKey,\n mintB: PublicKey,\n vaultA: PublicKey,\n vaultB: PublicKey,\n metadataId: PublicKey,\n\n decimals: number,\n name: string,\n symbol: string,\n uri: string,\n\n curveParam: ({ type: \"ConstantCurve\"; totalSellA: BN } | { type: \"FixedCurve\" } | { type: \"LinearCurve\" }) & {\n migrateType: \"amm\" | \"cpmm\";\n supply: BN;\n totalFundRaisingB: BN;\n },\n\n totalLockedAmount: BN,\n cliffPeriod: BN,\n unlockPeriod: BN,\n): TransactionInstruction {\n throw new Error(\"*** launchlab initialize has been deprecated, please use initializeV2 instead! ***\");\n\n const dataLyaout1 = struct([u8(\"decimals\"), str(\"name\"), str(\"symbol\"), str(\"uri\")]);\n const dataLyaout3 = struct([u64(\"totalLockedAmount\"), u64(\"cliffPeriod\"), u64(\"unlockPeriod\")]);\n\n const dataLayout21 = struct([u8(\"index\"), u64(\"supply\"), u64(\"totalFundRaisingB\"), u8(\"migrateType\")]);\n const dataLayout22 = struct([\n u8(\"index\"),\n u64(\"supply\"),\n u64(\"totalSellA\"),\n u64(\"totalFundRaisingB\"),\n u8(\"migrateType\"),\n ]);\n\n const keys: Array<AccountMeta> = [\n { pubkey: payer, isSigner: true, isWritable: true },\n { pubkey: creator, isSigner: false, isWritable: false },\n { pubkey: configId, isSigner: false, isWritable: false },\n { pubkey: platformId, isSigner: false, isWritable: false },\n { pubkey: auth, isSigner: false, isWritable: false },\n { pubkey: poolId, isSigner: false, isWritable: true },\n { pubkey: mintA, isSigner: true, isWritable: true },\n { pubkey: mintB, isSigner: false, isWritable: false },\n { pubkey: vaultA, isSigner: false, isWritable: true },\n { pubkey: vaultB, isSigner: false, isWritable: true },\n { pubkey: metadataId, isSigner: false, isWritable: true },\n\n { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: METADATA_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },\n { pubkey: RENT_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: getPdaCpiEvent(programId).publicKey, isSigner: false, isWritable: false },\n { pubkey: programId, isSigner: false, isWritable: false },\n ];\n\n const data1 = Buffer.alloc(\n Buffer.from(name, \"utf-8\").length +\n Buffer.from(symbol, \"utf-8\").length +\n Buffer.from(uri, \"utf-8\").length +\n 4 * 3 +\n 1,\n );\n const data3 = Buffer.alloc(dataLyaout3.span);\n\n const data2 = Buffer.alloc(curveParam.type === \"ConstantCurve\" ? dataLayout22.span : dataLayout21.span);\n\n dataLyaout1.encode({ decimals, name, symbol, uri }, data1);\n if (curveParam.type === \"ConstantCurve\") {\n // eslint-disable-next-line\n // @ts-ignore\n dataLayout22.encode({ index: 0, ...curveParam, migrateType: curveParam.migrateType === \"amm\" ? 0 : 1 }, data2);\n } else if (curveParam.type === \"FixedCurve\") {\n dataLayout21.encode({ index: 1, ...curveParam, migrateType: curveParam.migrateType === \"amm\" ? 0 : 1 }, data2);\n } else if (curveParam.type === \"LinearCurve\") {\n dataLayout21.encode({ index: 2, ...curveParam, migrateType: curveParam.migrateType === \"amm\" ? 0 : 1 }, data2);\n }\n\n dataLyaout3.encode({ totalLockedAmount, cliffPeriod, unlockPeriod }, data3);\n\n return new TransactionInstruction({\n keys,\n programId,\n data: Buffer.from([...anchorDataBuf.initialize, ...data1, ...data2, ...data3]),\n });\n}\n\nexport function initializeV2(\n programId: PublicKey,\n\n payer: PublicKey,\n creator: PublicKey,\n configId: PublicKey,\n platformId: PublicKey,\n auth: PublicKey,\n poolId: PublicKey,\n mintA: PublicKey,\n mintB: PublicKey,\n vaultA: PublicKey,\n vaultB: PublicKey,\n metadataId: PublicKey,\n mintProgramB: PublicKey,\n\n decimals: number,\n name: string,\n symbol: string,\n uri: string,\n\n curveParam: ({ type: \"ConstantCurve\"; totalSellA: BN } | { type: \"FixedCurve\" } | { type: \"LinearCurve\" }) & {\n migrateType: \"amm\" | \"cpmm\";\n supply: BN;\n totalFundRaisingB: BN;\n },\n\n totalLockedAmount: BN,\n cliffPeriod: BN,\n unlockPeriod: BN,\n\n cpmmCreatorFeeOn: CpmmCreatorFeeOn,\n\n platformAllowConfig?: PublicKey,\n): TransactionInstruction {\n const dataLyaout1 = struct([u8(\"decimals\"), str(\"name\"), str(\"symbol\"), str(\"uri\")]);\n const dataLyaout3 = struct([\n u64(\"totalLockedAmount\"),\n u64(\"cliffPeriod\"),\n u64(\"unlockPeriod\"),\n u8(\"cpmmCreatorFeeOn\"),\n ]);\n\n const dataLayout21 = struct([u8(\"index\"), u64(\"supply\"), u64(\"totalFundRaisingB\"), u8(\"migrateType\")]);\n const dataLayout22 = struct([\n u8(\"index\"),\n u64(\"supply\"),\n u64(\"totalSellA\"),\n u64(\"totalFundRaisingB\"),\n u8(\"migrateType\"),\n ]);\n\n const keys: Array<AccountMeta> = [\n { pubkey: payer, isSigner: true, isWritable: true },\n { pubkey: creator, isSigner: false, isWritable: false },\n { pubkey: configId, isSigner: false, isWritable: false },\n { pubkey: platformId, isSigner: false, isWritable: false },\n { pubkey: auth, isSigner: false, isWritable: false },\n { pubkey: poolId, isSigner: false, isWritable: true },\n { pubkey: mintA, isSigner: true, isWritable: true },\n { pubkey: mintB, isSigner: false, isWritable: false },\n { pubkey: vaultA, isSigner: false, isWritable: true },\n { pubkey: vaultB, isSigner: false, isWritable: true },\n { pubkey: metadataId, isSigner: false, isWritable: true },\n\n { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: mintProgramB, isSigner: false, isWritable: false },\n { pubkey: METADATA_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },\n { pubkey: RENT_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: getPdaCpiEvent(programId).publicKey, isSigner: false, isWritable: false },\n { pubkey: programId, isSigner: false, isWritable: false },\n ];\n\n if (platformAllowConfig) keys.push({ pubkey: platformAllowConfig, isSigner: false, isWritable: false });\n\n const data1 = Buffer.alloc(\n Buffer.from(name, \"utf-8\").length +\n Buffer.from(symbol, \"utf-8\").length +\n Buffer.from(uri, \"utf-8\").length +\n 4 * 3 +\n 1,\n );\n const data3 = Buffer.alloc(dataLyaout3.span);\n\n const data2 = Buffer.alloc(curveParam.type === \"ConstantCurve\" ? dataLayout22.span : dataLayout21.span);\n\n dataLyaout1.encode({ decimals, name, symbol, uri }, data1);\n if (curveParam.type === \"ConstantCurve\") {\n dataLayout22.encode({ index: 0, ...curveParam, migrateType: curveParam.migrateType === \"amm\" ? 0 : 1 }, data2);\n } else if (curveParam.type === \"FixedCurve\") {\n dataLayout21.encode({ index: 1, ...curveParam, migrateType: curveParam.migrateType === \"amm\" ? 0 : 1 }, data2);\n } else if (curveParam.type === \"LinearCurve\") {\n dataLayout21.encode({ index: 2, ...curveParam, migrateType: curveParam.migrateType === \"amm\" ? 0 : 1 }, data2);\n }\n\n dataLyaout3.encode({ totalLockedAmount, cliffPeriod, unlockPeriod, cpmmCreatorFeeOn }, data3);\n\n return new TransactionInstruction({\n keys,\n programId,\n data: Buffer.from([...anchorDataBuf.initializeV2, ...data1, ...data2, ...data3]),\n });\n}\n\nexport function initializeWithToken2022(\n programId: PublicKey,\n\n payer: PublicKey,\n creator: PublicKey,\n configId: PublicKey,\n platformId: PublicKey,\n auth: PublicKey,\n poolId: PublicKey,\n mintA: PublicKey,\n mintB: PublicKey,\n vaultA: PublicKey,\n vaultB: PublicKey,\n mintProgramB: PublicKey,\n\n decimals: number,\n name: string,\n symbol: string,\n uri: string,\n\n curveParam: ({ type: \"ConstantCurve\"; totalSellA: BN } | { type: \"FixedCurve\" } | { type: \"LinearCurve\" }) & {\n migrateType: \"amm\" | \"cpmm\";\n supply: BN;\n totalFundRaisingB: BN;\n },\n\n totalLockedAmount: BN,\n cliffPeriod: BN,\n unlockPeriod: BN,\n\n cpmmCreatorFeeOn: CpmmCreatorFeeOn,\n transferFeeExtensionParams?: { transferFeeBasePoints: number; maxinumFee: BN },\n\n platformAllowConfig?: PublicKey,\n): TransactionInstruction {\n const dataLyaout1 = struct([u8(\"decimals\"), str(\"name\"), str(\"symbol\"), str(\"uri\")]);\n const dataLyaout3 = struct([\n u64(\"totalLockedAmount\"),\n u64(\"cliffPeriod\"),\n u64(\"unlockPeriod\"),\n u8(\"cpmmCreatorFeeOn\"),\n u8(\"transferFeeExtensionParamsOption\"),\n struct([u16(\"transferFeeBasePoints\"), u64(\"maxinumFee\")]).replicate(\"transferFeeExtensionParams\"),\n ]);\n\n const dataLayout21 = struct([u8(\"index\"), u64(\"supply\"), u64(\"totalFundRaisingB\"), u8(\"migrateType\")]);\n const dataLayout22 = struct([\n u8(\"index\"),\n u64(\"supply\"),\n u64(\"totalSellA\"),\n u64(\"totalFundRaisingB\"),\n u8(\"migrateType\"),\n ]);\n\n const keys: Array<AccountMeta> = [\n { pubkey: payer, isSigner: true, isWritable: true },\n { pubkey: creator, isSigner: false, isWritable: false },\n { pubkey: configId, isSigner: false, isWritable: false },\n { pubkey: platformId, isSigner: false, isWritable: false },\n { pubkey: auth, isSigner: false, isWritable: false },\n { pubkey: poolId, isSigner: false, isWritable: true },\n { pubkey: mintA, isSigner: true, isWritable: true },\n { pubkey: mintB, isSigner: false, isWritable: false },\n { pubkey: vaultA, isSigner: false, isWritable: true },\n { pubkey: vaultB, isSigner: false, isWritable: true },\n\n { pubkey: TOKEN_2022_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: mintProgramB, isSigner: false, isWritable: false },\n { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },\n { pubkey: getPdaCpiEvent(programId).publicKey, isSigner: false, isWritable: false },\n { pubkey: programId, isSigner: false, isWritable: false },\n ];\n\n if (platformAllowConfig) keys.push({ pubkey: platformAllowConfig, isSigner: false, isWritable: false });\n\n const data1 = Buffer.alloc(\n Buffer.from(name, \"utf-8\").length +\n Buffer.from(symbol, \"utf-8\").length +\n Buffer.from(uri, \"utf-8\").length +\n 4 * 3 +\n 1,\n );\n const data3 = Buffer.alloc(dataLyaout3.span);\n\n const data2 = Buffer.alloc(curveParam.type === \"ConstantCurve\" ? dataLayout22.span : dataLayout21.span);\n\n dataLyaout1.encode({ decimals, name, symbol, uri }, data1);\n if (curveParam.type === \"ConstantCurve\") {\n dataLayout22.encode({ index: 0, ...curveParam, migrateType: curveParam.migrateType === \"amm\" ? 0 : 1 }, data2);\n } else if (curveParam.type === \"FixedCurve\") {\n dataLayout21.encode({ index: 1, ...curveParam, migrateType: curveParam.migrateType === \"amm\" ? 0 : 1 }, data2);\n } else if (curveParam.type === \"LinearCurve\") {\n dataLayout21.encode({ index: 2, ...curveParam, migrateType: curveParam.migrateType === \"amm\" ? 0 : 1 }, data2);\n }\n\n dataLyaout3.encode(\n {\n totalLockedAmount,\n cliffPeriod,\n unlockPeriod,\n cpmmCreatorFeeOn,\n transferFeeExtensionParamsOption: transferFeeExtensionParams ? 1 : 0,\n transferFeeExtensionParams: transferFeeExtensionParams ?? { transferFeeBasePoints: 0, maxinumFee: new BN(0) },\n },\n data3,\n );\n\n return new TransactionInstruction({\n keys,\n programId,\n data: Buffer.from([...anchorDataBuf.initializeWithToken2022, ...data1, ...data2, ...data3]),\n });\n}\n\nexport function buyExactInInstruction(\n programId: PublicKey,\n\n owner: PublicKey,\n auth: PublicKey,\n configId: PublicKey,\n platformId: PublicKey,\n poolId: PublicKey,\n userTokenAccountA: PublicKey,\n userTokenAccountB: PublicKey,\n vaultA: PublicKey,\n vaultB: PublicKey,\n mintA: PublicKey,\n mintB: PublicKey,\n tokenProgramA: PublicKey,\n tokenProgramB: PublicKey,\n\n platformClaimFeeVault: PublicKey,\n creatorClaimFeeVault: PublicKey,\n\n amountB: BN,\n minAmountA: BN,\n shareFeeRate?: BN,\n\n shareFeeReceiver?: PublicKey,\n): TransactionInstruction {\n const dataLayout = struct([u64(\"amountB\"), u64(\"minAmountA\"), u64(\"shareFeeRate\")]);\n\n const keys: Array<AccountMeta> = [\n { pubkey: owner, isSigner: true, isWritable: true },\n { pubkey: auth, isSigner: false, isWritable: false },\n { pubkey: configId, isSigner: false, isWritable: false },\n { pubkey: platformId, isSigner: false, isWritable: false },\n { pubkey: poolId, isSigner: false, isWritable: true },\n\n { pubkey: userTokenAccountA, isSigner: false, isWritable: true },\n { pubkey: userTokenAccountB, isSigner: false, isWritable: true },\n { pubkey: vaultA, isSigner: false, isWritable: true },\n { pubkey: vaultB, isSigner: false, isWritable: true },\n { pubkey: mintA, isSigner: false, isWritable: false },\n { pubkey: mintB, isSigner: false, isWritable: false },\n\n { pubkey: tokenProgramA, isSigner: false, isWritable: false },\n { pubkey: tokenProgramB, isSigner: false, isWritable: false },\n\n { pubkey: getPdaCpiEvent(programId).publicKey, isSigner: false, isWritable: false },\n { pubkey: programId, isSigner: false, isWritable: false },\n ];\n\n if (shareFeeReceiver) {\n keys.push({ pubkey: shareFeeReceiver, isSigner: false, isWritable: true });\n }\n\n keys.push({ pubkey: SystemProgram.programId, isSigner: false, isWritable: false });\n keys.push({ pubkey: platformClaimFeeVault, isSigner: false, isWritable: true });\n keys.push({ pubkey: creatorClaimFeeVault, isSigner: false, isWritable: true });\n\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode(\n {\n amountB,\n minAmountA,\n shareFeeRate: shareFeeRate ?? new BN(0),\n },\n data,\n );\n\n return new TransactionInstruction({\n keys,\n programId,\n data: Buffer.from([...anchorDataBuf.buyExactIn, ...data]),\n });\n}\n\nexport function buyExactOutInstruction(\n programId: PublicKey,\n\n owner: PublicKey,\n auth: PublicKey,\n configId: PublicKey,\n platformId: PublicKey,\n poolId: PublicKey,\n userTokenAccountA: PublicKey,\n userTokenAccountB: PublicKey,\n vaultA: PublicKey,\n vaultB: PublicKey,\n mintA: PublicKey,\n mintB: PublicKey,\n tokenProgramA: PublicKey,\n tokenProgramB: PublicKey,\n\n platformClaimFeeVault: PublicKey,\n creatorClaimFeeVault: PublicKey,\n\n amountA: BN,\n maxAmountB: BN,\n shareFeeRate?: BN,\n\n shareFeeReceiver?: PublicKey,\n): TransactionInstruction {\n const dataLayout = struct([u64(\"amountA\"), u64(\"maxAmountB\"), u64(\"shareFeeRate\")]);\n\n const keys: Array<AccountMeta> = [\n { pubkey: owner, isSigner: true, isWritable: true },\n { pubkey: auth, isSigner: false, isWritable: false },\n { pubkey: configId, isSigner: false, isWritable: false },\n { pubkey: platformId, isSigner: false, isWritable: false },\n { pubkey: poolId, isSigner: false, isWritable: true },\n\n { pubkey: userTokenAccountA, isSigner: false, isWritable: true },\n { pubkey: userTokenAccountB, isSigner: false, isWritable: true },\n { pubkey: vaultA, isSigner: false, isWritable: true },\n { pubkey: vaultB, isSigner: false, isWritable: true },\n { pubkey: mintA, isSigner: false, isWritable: false },\n { pubkey: mintB, isSigner: false, isWritable: false },\n\n { pubkey: tokenProgramA, isSigner: false, isWritable: false },\n { pubkey: tokenProgramB, isSigner: false, isWritable: false },\n\n { pubkey: getPdaCpiEvent(programId).publicKey, isSigner: false, isWritable: false },\n { pubkey: programId, isSigner: false, isWritable: false },\n ];\n\n if (shareFeeReceiver) {\n keys.push({ pubkey: shareFeeReceiver, isSigner: false, isWritable: true });\n }\n\n keys.push({ pubkey: SystemProgram.programId, isSigner: false, isWritable: false });\n keys.push({ pubkey: platformClaimFeeVault, isSigner: false, isWritable: true });\n keys.push({ pubkey: creatorClaimFeeVault, isSigner: false, isWritable: true });\n\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode(\n {\n amountA,\n maxAmountB,\n shareFeeRate: shareFeeRate ?? new BN(0),\n },\n data,\n );\n\n return new TransactionInstruction({\n keys,\n programId,\n data: Buffer.from([...anchorDataBuf.buyExactOut, ...data]),\n });\n}\n\nexport function sellExactInInstruction(\n programId: PublicKey,\n\n owner: PublicKey,\n auth: PublicKey,\n configId: PublicKey,\n platformId: PublicKey,\n poolId: PublicKey,\n userTokenAccountA: PublicKey,\n userTokenAccountB: PublicKey,\n vaultA: PublicKey,\n vaultB: PublicKey,\n mintA: PublicKey,\n mintB: PublicKey,\n tokenProgramA: PublicKey,\n tokenProgramB: PublicKey,\n\n platformClaimFeeVault: PublicKey,\n creatorClaimFeeVault: PublicKey,\n\n amountA: BN,\n minAmountB: BN,\n shareFeeRate?: BN,\n\n shareFeeReceiver?: PublicKey,\n): TransactionInstruction {\n const dataLayout = struct([u64(\"amountA\"), u64(\"minAmountB\"), u64(\"shareFeeRate\")]);\n\n const keys: Array<AccountMeta> = [\n { pubkey: owner, isSigner: true, isWritable: true },\n { pubkey: auth, isSigner: false, isWritable: false },\n { pubkey: configId, isSigner: false, isWritable: false },\n { pubkey: platformId, isSigner: false, isWritable: false },\n { pubkey: poolId, isSigner: false, isWritable: true },\n\n { pubkey: userTokenAccountA, isSigner: false, isWritable: true },\n { pubkey: userTokenAccountB, isSigner: false, isWritable: true },\n { pubkey: vaultA, isSigner: false, isWritable: true },\n { pubkey: vaultB, isSigner: false, isWritable: true },\n { pubkey: mintA, isSigner: false, isWritable: false },\n { pubkey: mintB, isSigner: false, isWritable: false },\n\n { pubkey: tokenProgramA, isSigner: false, isWritable: false },\n { pubkey: tokenProgramB, isSigner: false, isWritable: false },\n\n { pubkey: getPdaCpiEvent(programId).publicKey, isSigner: false, isWritable: false },\n { pubkey: programId, isSigner: false, isWritable: false },\n ];\n\n if (shareFeeReceiver) {\n keys.push({ pubkey: shareFeeReceiver, isSigner: false, isWritable: true });\n }\n\n keys.push({ pubkey: SystemProgram.programId, isSigner: false, isWritable: false });\n keys.push({ pubkey: platformClaimFeeVault, isSigner: false, isWritable: true });\n keys.push({ pubkey: creatorClaimFeeVault, isSigner: false, isWritable: true });\n\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode(\n {\n amountA,\n minAmountB,\n shareFeeRate: shareFeeRate ?? new BN(0),\n },\n data,\n );\n\n return new TransactionInstruction({\n keys,\n programId,\n data: Buffer.from([...anchorDataBuf.sellExactIn, ...data]),\n });\n}\n\nexport function sellExactOut(\n programId: PublicKey,\n\n owner: PublicKey,\n auth: PublicKey,\n configId: PublicKey,\n platformId: PublicKey,\n poolId: PublicKey,\n userTokenAccountA: PublicKey,\n userTokenAccountB: PublicKey,\n vaultA: PublicKey,\n vaultB: PublicKey,\n mintA: PublicKey,\n mintB: PublicKey,\n tokenProgramA: PublicKey,\n tokenProgramB: PublicKey,\n\n platformClaimFeeVault: PublicKey,\n creatorClaimFeeVault: PublicKey,\n\n amountB: BN,\n maxAmountA: BN,\n shareFeeRate?: BN,\n\n shareFeeReceiver?: PublicKey,\n): TransactionInstruction {\n const dataLayout = struct([u64(\"amountB\"), u64(\"maxAmountA\"), u64(\"shareFeeRate\")]);\n\n const keys: Array<AccountMeta> = [\n { pubkey: owner, isSigner: true, isWritable: true },\n { pubkey: auth, isSigner: false, isWritable: false },\n { pubkey: configId, isSigner: false, isWritable: false },\n { pubkey: platformId, isSigner: false, isWritable: false },\n { pubkey: poolId, isSigner: false, isWritable: true },\n\n { pubkey: userTokenAccountA, isSigner: false, isWritable: true },\n { pubkey: userTokenAccountB, isSigner: false, isWritable: true },\n { pubkey: vaultA, isSigner: false, isWritable: true },\n { pubkey: vaultB, isSigner: false, isWritable: true },\n { pubkey: mintA, isSigner: false, isWritable: false },\n { pubkey: mintB, isSigner: false, isWritable: false },\n\n { pubkey: tokenProgramA, isSigner: false, isWritable: false },\n { pubkey: tokenProgramB, isSigner: false, isWritable: false },\n\n { pubkey: getPdaCpiEvent(programId).publicKey, isSigner: false, isWritable: false },\n { pubkey: programId, isSigner: false, isWritable: false },\n ];\n\n if (shareFeeReceiver) {\n keys.push({ pubkey: shareFeeReceiver, isSigner: false, isWritable: true });\n }\n\n keys.push({ pubkey: SystemProgram.programId, isSigner: false, isWritable: false });\n keys.push({ pubkey: platformClaimFeeVault, isSigner: false, isWritable: true });\n keys.push({ pubkey: creatorClaimFeeVault, isSigner: false, isWritable: true });\n\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode(\n {\n amountB,\n maxAmountA,\n shareFeeRate: shareFeeRate ?? new BN(0),\n },\n data,\n );\n\n return new TransactionInstruction({\n keys,\n programId,\n data: Buffer.from([...anchorDataBuf.sellExactOut, ...data]),\n });\n}\n\nexport function claimVestedToken(\n programId: PublicKey,\n\n owner: PublicKey,\n auth: PublicKey,\n poolId: PublicKey,\n\n vestingRecord: PublicKey,\n\n userTokenAccountA: PublicKey,\n vaultA: PublicKey,\n mintA: PublicKey,\n tokenProgramA: PublicKey,\n): TransactionInstruction {\n const dataLayout = struct([]);\n\n const keys: Array<AccountMeta> = [\n { pubkey: owner, isSigner: true, isWritable: true },\n { pubkey: auth, isSigner: false, isWritable: false },\n { pubkey: poolId, isSigner: false, isWritable: true },\n\n { pubkey: vestingRecord, isSigner: false, isWritable: true },\n\n { pubkey: vaultA, isSigner: false, isWritable: true },\n { pubkey: userTokenAccountA, isSigner: false, isWritable: true },\n { pubkey: mintA, isSigner: false, isWritable: false },\n { pubkey: tokenProgramA, isSigner: false, isWritable: false },\n { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },\n { pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n ];\n\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode({}, data);\n\n return new TransactionInstruction({\n keys,\n programId,\n data: Buffer.from([...anchorDataBuf.claimVestedToken, ...data]),\n });\n}\n\nexport function createVestingAccount(\n programId: PublicKey,\n\n owner: PublicKey,\n beneficiary: PublicKey,\n poolId: PublicKey,\n\n vestingRecord: PublicKey,\n shareAmount: BN,\n): TransactionInstruction {\n const dataLayout = struct([u64(\"shareAmount\")]);\n\n const keys: Array<AccountMeta> = [\n { pubkey: owner, isSigner: true, isWritable: true },\n { pubkey: beneficiary, isSigner: false, isWritable: true },\n { pubkey: poolId, isSigner: false, isWritable: true },\n\n { pubkey: vestingRecord, isSigner: false, isWritable: true },\n\n { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },\n ];\n\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode({ shareAmount }, data);\n\n return new TransactionInstruction({\n keys,\n programId,\n data: Buffer.from([...anchorDataBuf.createVestingAccount, ...data]),\n });\n}\n\nexport function claimPlatformFee(\n programId: PublicKey,\n platformClaimFeeWallet: PublicKey,\n auth: PublicKey,\n poolId: PublicKey,\n platformId: PublicKey,\n vaultB: PublicKey,\n userTokenAccountB: PublicKey,\n mintB: PublicKey,\n tokenProgramB: PublicKey,\n): TransactionInstruction {\n const keys: Array<AccountMeta> = [\n { pubkey: platformClaimFeeWallet, isSigner: true, isWritable: true },\n { pubkey: auth, isSigner: false, isWritable: false },\n { pubkey: poolId, isSigner: false, isWritable: true },\n { pubkey: platformId, isSigner: false, isWritable: true },\n { pubkey: vaultB, isSigner: false, isWritable: true },\n { pubkey: userTokenAccountB, isSigner: false, isWritable: true },\n { pubkey: mintB, isSigner: false, isWritable: true },\n { pubkey: tokenProgramB, isSigner: false, isWritable: true },\n { pubkey: SystemProgram.programId, isSigner: false, isWritable: true },\n { pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: true },\n ];\n\n return new TransactionInstruction({\n keys,\n programId,\n data: anchorDataBuf.claimPlatformFee,\n });\n}\n\nexport function createPlatformConfig(\n programId: PublicKey,\n\n platformAdmin: PublicKey,\n platformClaimFeeWallet: PublicKey,\n platformLockNftWallet: PublicKey,\n platformVestingWallet: PublicKey,\n platformId: PublicKey,\n\n cpConfigId: PublicKey,\n\n transferFeeExtensionAuth: PublicKey,\n\n migrateCpLockNftScale: {\n platformScale: BN;\n creatorScale: BN;\n burnScale: BN;\n },\n feeRate: BN,\n creatorFeeRate: BN,\n name: string,\n web: string,\n img: string,\n platformVestingScale: BN,\n): TransactionInstruction {\n const dataLayout = struct([\n u64(\"platformScale\"),\n u64(\"creatorScale\"),\n u64(\"burnScale\"),\n\n u64(\"feeRate\"),\n str(\"name\"),\n str(\"web\"),\n str(\"img\"),\n u64(\"creatorFeeRate\"),\n\n u64(\"platformVestingScale\"),\n ]);\n\n const keys: Array<AccountMeta> = [\n { pubkey: platformAdmin, isSigner: true, isWritable: true },\n { pubkey: platformClaimFeeWallet, isSigner: false, isWritable: false },\n { pubkey: platformLockNftWallet, isSigner: false, isWritable: false },\n { pubkey: platformId, isSigner: false, isWritable: true },\n { pubkey: cpConfigId, isSigner: false, isWritable: true },\n { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },\n { pubkey: transferFeeExtensionAuth, isSigner: false, isWritable: false },\n { pubkey: platformVestingWallet, isSigner: false, isWritable: false },\n ];\n\n const data = Buffer.alloc(\n 8 * 6 +\n Buffer.from(name, \"utf-8\").length +\n Buffer.from(web, \"utf-8\").length +\n Buffer.from(img, \"utf-8\").length +\n 4 * 3,\n );\n dataLayout.encode(\n {\n platformScale: migrateCpLockNftScale.platformScale,\n creatorScale: migrateCpLockNftScale.creatorScale,\n burnScale: migrateCpLockNftScale.burnScale,\n feeRate,\n name,\n web,\n img,\n creatorFeeRate,\n platformVestingScale,\n },\n data,\n );\n\n return new TransactionInstruction({\n keys,\n programId,\n data: Buffer.from([...anchorDataBuf.createPlatformConfig, ...data]),\n });\n}\n\nexport function updatePlatformConfig(\n programId: PublicKey,\n\n platformAdmin: PublicKey,\n platformId: PublicKey,\n\n updateInfo:\n | { type: \"updateClaimFeeWallet\" | \"updateLockNftWallet\"; value: PublicKey }\n | { type: \"updateFeeRate\"; value: BN }\n | { type: \"updateName\" | \"updateImg\" | \"updateWeb\"; value: string }\n | { type: \"migrateCpLockNftScale\"; value: { platformScale: BN; creatorScale: BN; burnScale: BN } }\n | { type: \"updateCpConfigId\"; value: PublicKey }\n | { type: \"updateVestingWallet\"; value: PublicKey }\n | { type: \"updatePlatformVestingScale\"; value: BN }\n | { type: \"updatePlatformCpCreator\"; value: PublicKey }\n | { type: \"updateRestrictGlobalConfig\"; value: BN }\n | {\n type: \"updateAll\";\n value: {\n platformClaimFeeWallet: PublicKey;\n platformLockNftWallet: PublicKey;\n platformVestingWallet: PublicKey;\n cpConfigId: PublicKey;\n migrateCpLockNftScale: {\n platformScale: BN;\n creatorScale: BN;\n burnScale: BN;\n };\n feeRate: BN;\n name: string;\n web: string;\n img: string;\n transferFeeExtensionAuth: PublicKey;\n creatorFeeRate: BN;\n platformVestingScale: BN;\n };\n },\n): TransactionInstruction {\n const keys: Array<AccountMeta> = [\n { pubkey: platformAdmin, isSigner: true, isWritable: false },\n { pubkey: platformId, isSigner: false, isWritable: true },\n ];\n\n let data: Buffer;\n if (updateInfo.type === \"updateClaimFeeWallet\") {\n const dataLayout = struct([u8(\"index\"), publicKey(\"value\")]);\n data = Buffer.alloc(dataLayout.span);\n dataLayout.encode({ index: 0, value: updateInfo.value }, data);\n } else if (updateInfo.type === \"updateLockNftWallet\") {\n const dataLayout = struct([u8(\"index\"), publicKey(\"value\")]);\n data = Buffer.alloc(dataLayout.span);\n dataLayout.encode({ index: 1, value: updateInfo.value }, data);\n } else if (updateInfo.type === \"migrateCpLockNftScale\") {\n const dataLayout = struct([u8(\"index\"), u64(\"platformScale\"), u64(\"creatorScale\"), u64(\"burnScale\")]);\n data = Buffer.alloc(dataLayout.span);\n dataLayout.encode({ index: 2, ...updateInfo.value }, data);\n } else if (updateInfo.type === \"updateFeeRate\") {\n const dataLayout = struct([u8(\"index\"), u64(\"value\")]);\n data = Buffer.alloc(dataLayout.span);\n dataLayout.encode({ index: 3, value: updateInfo.value }, data);\n } else if (updateInfo.type === \"updateImg\" || updateInfo.type === \"updateName\" || updateInfo.type === \"updateWeb\") {\n const dataLayout = struct([u8(\"index\"), str(\"value\")]);\n data = Buffer.alloc(Buffer.from(updateInfo.value, \"utf-8\").length + 4 + 1 * 1);\n if (updateInfo.type === \"updateName\") dataLayout.encode({ index: 4, value: updateInfo.value }, data);\n else if (updateInfo.type === \"updateWeb\") dataLayout.encode({ index: 5, value: updateInfo.value }, data);\n else if (updateInfo.type === \"updateImg\") dataLayout.encode({ index: 6, value: updateInfo.value }, data);\n } else if (updateInfo.type === \"updateCpConfigId\") {\n keys.push({ pubkey: updateInfo.value, isSigner: false, isWritable: false });\n\n const dataLayout = struct([u8(\"index\")]);\n data = Buffer.alloc(dataLayout.span);\n dataLayout.encode({ index: 7 }, data);\n } else if (updateInfo.type === \"updateAll\") {\n keys.push({ pubkey: updateInfo.value.cpConfigId, isSigner: false, isWritable: false });\n\n const dataLayout = struct([\n u8(\"index\"),\n publicKey(\"platformClaimFeeWallet\"),\n publicKey(\"platformLockNftWallet\"),\n u64(\"platformScale\"),\n u64(\"creatorScale\"),\n u64(\"burnScale\"),\n\n u64(\"feeRate\"),\n str(\"name\"),\n str(\"web\"),\n str(\"img\"),\n publicKey(\"transferFeeExtensionAuth\"),\n u64(\"creatorFeeRate\"),\n u64(\"platformVestingScale\"),\n publicKey(\"platformVestingWallet\"),\n ]);\n data = Buffer.alloc(\n 1 +\n 32 +\n 32 +\n 32 +\n 8 * 5 +\n 4 * 3 +\n Buffer.from(updateInfo.value.name, \"utf-8\").length +\n Buffer.from(updateInfo.value.web, \"utf-8\").length +\n Buffer.from(updateInfo.value.img, \"utf-8\").length +\n 32 +\n 8,\n );\n dataLayout.encode(\n {\n index: 8,\n platformClaimFeeWallet: updateInfo.value.platformClaimFeeWallet,\n platformLockNftWallet: updateInfo.value.platformLockNftWallet,\n platformVestingWallet: updateInfo.value.platformVestingWallet,\n platformScale: updateInfo.value.migrateCpLockNftScale.platformScale,\n creatorScale: updateInfo.value.migrateCpLockNftScale.creatorScale,\n burnScale: updateInfo.value.migrateCpLockNftScale.burnScale,\n feeRate: updateInfo.value.feeRate,\n name: updateInfo.value.name,\n web: updateInfo.value.web,\n img: updateInfo.value.img,\n transferFeeExtensionAuth: updateInfo.value.transferFeeExtensionAuth,\n creatorFeeRate: updateInfo.value.creatorFeeRate,\n platformVestingScale: updateInfo.value.platformVestingScale,\n },\n data,\n );\n } else if (updateInfo.type === \"updateVestingWallet\") {\n const dataLayout = struct([u8(\"index\"), publicKey(\"value\")]);\n data = Buffer.alloc(dataLayout.span);\n dataLayout.encode({ index: 9, value: updateInfo.value }, data);\n } else if (updateInfo.type === \"updatePlatformVestingScale\") {\n const dataLayout = struct([u8(\"index\"), u64(\"value\")]);\n data = Buffer.alloc(dataLayout.span);\n dataLayout.encode({ index: 10, value: updateInfo.value }, data);\n } else if (updateInfo.type === \"updatePlatformCpCreator\") {\n const dataLayout = struct([u8(\"index\"), publicKey(\"value\")]);\n data = Buffer.alloc(dataLayout.span);\n dataLayout.encode({ index: 11, value: updateInfo.value }, data);\n } else if (updateInfo.type === \"updateRestrictGlobalConfig\") {\n const dataLayout = struct([u8(\"index\"), u64(\"value\")]);\n data = Buffer.alloc(dataLayout.span);\n dataLayout.encode({ index: 12, value: updateInfo.value }, data);\n } else {\n throw Error(\"updateInfo params type error\");\n }\n\n return new TransactionInstruction({\n keys,\n programId,\n data: Buffer.from([...anchorDataBuf.updatePlaformConfig, ...data]),\n });\n}\n\nexport function claimPlatformFeeFromVault(\n programId: PublicKey,\n platformId: PublicKey,\n platformClaimFeeWallet: PublicKey,\n platformClaimFeeAuth: PublicKey,\n platformClaimFeeVault: PublicKey,\n recipientTokenAccount: PublicKey,\n mintB: PublicKey,\n mintProgramB: PublicKey,\n): TransactionInstruction {\n const keys: Array<AccountMeta> = [\n { pubkey: platformClaimFeeWallet, isSigner: true, isWritable: true },\n { pubkey: platformClaimFeeAuth, isSigner: false, isWritable: false },\n { pubkey: platformId, isSigner: false, isWritable: false },\n { pubkey: platformClaimFeeVault, isSigner: false, isWritable: true },\n { pubkey: recipientTokenAccount, isSigner: false, isWritable: true },\n { pubkey: mintB, isSigner: false, isWritable: false },\n\n { pubkey: mintProgramB, isSigner: false, isWritable: false },\n { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },\n { pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n ];\n\n return new TransactionInstruction({\n keys,\n programId,\n data: anchorDataBuf.claimPlatformFeeFromVault,\n });\n}\n\nexport function claimCreatorFee(\n programId: PublicKey,\n\n creator: PublicKey,\n creatorClaimFeeAuth: PublicKey,\n creatorClaimFeeVault: PublicKey,\n recipientTokenAccount: PublicKey,\n mintB: PublicKey,\n mintProgramB: PublicKey,\n): TransactionInstruction {\n const keys: Array<AccountMeta> = [\n { pubkey: creator, isSigner: true, isWritable: true },\n { pubkey: creatorClaimFeeAuth, isSigner: false, isWritable: false },\n { pubkey: creatorClaimFeeVault, isSigner: false, isWritable: true },\n { pubkey: recipientTokenAccount, isSigner: false, isWritable: true },\n { pubkey: mintB, isSigner: false, isWritable: false },\n\n { pubkey: mintProgramB, isSigner: false, isWritable: false },\n { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },\n { pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n ];\n\n return new TransactionInstruction({\n keys,\n programId,\n data: anchorDataBuf.claimCreatorFee,\n });\n}\n\nconst u8Max = 255;\nconst u64Max = new BN(\"18446744073709551615\");\n\nexport function updatePlatformCurveParamInstruction(\n programId: PublicKey,\n\n platformAdmin: PublicKey,\n platformId: PublicKey,\n configId: PublicKey,\n\n index: number,\n params: Partial<ReturnType<typeof BondingCurveParam.decode>>,\n): TransactionInstruction {\n const keys: Array<AccountMeta> = [\n { pubkey: platformAdmin, isSigner: true, isWritable: true },\n { pubkey: platformId, isSigner: false, isWritable: true },\n { pubkey: configId, isSigner: false, isWritable: false },\n { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },\n ];\n\n const data = Buffer.alloc(1 * 2 + 8 * 6 + u8().span);\n u8().encode(index, data);\n BondingCurveParam.encode(\n {\n migrateType: params.migrateType ? params.migrateType : u8Max,\n migrateCpmmFeeOn: params.migrateCpmmFeeOn ? params.migrateCpmmFeeOn : u8Max,\n supply: params.supply ? params.supply : new BN(0),\n totalSellA: params.totalSellA ? params.totalSellA : new BN(0),\n totalFundRaisingB: params.totalFundRaisingB ? params.totalFundRaisingB : new BN(0),\n totalLockedAmount: params.totalLockedAmount ? params.totalLockedAmount : u64Max,\n cliffPeriod: params.cliffPeriod ? params.cliffPeriod : u64Max,\n unlockPeriod: params.unlockPeriod ? params.unlockPeriod : u64Max,\n },\n data,\n 1,\n );\n\n return new TransactionInstruction({\n keys,\n programId,\n data: Buffer.from([...anchorDataBuf.updatePlatformCurveParam, ...data]),\n });\n}\n\nexport function removePlatformCurveParamInstruction(\n programId: PublicKey,\n\n platformAdmin: PublicKey,\n platformId: PublicKey,\n index: number,\n): TransactionInstruction {\n const keys: Array<AccountMeta> = [\n { pubkey: platformAdmin, isSigner: true, isWritable: false },\n { pubkey: platformId, isSigner: false, isWritable: true },\n ];\n\n const data = Buffer.alloc(u8().span);\n u8().encode(index, data);\n\n return new TransactionInstruction({\n keys,\n programId,\n data: Buffer.from([...anchorDataBuf.removePlatformCurveParam, ...data, 1, 2]),\n });\n}\n\nexport function createPlatformVestingAccountIns(\n programId: PublicKey,\n\n platformVestingWallet: PublicKey,\n beneficiary: PublicKey,\n platformId: PublicKey,\n poolId: PublicKey,\n\n vestingRecord: PublicKey,\n): TransactionInstruction {\n const keys: Array<AccountMeta> = [\n { pubkey: platformVestingWallet, isSigner: true, isWritable: true },\n { pubkey: beneficiary, isSigner: false, isWritable: true },\n { pubkey: platformId, isSigner: false, isWritable: true },\n { pubkey: poolId, isSigner: false, isWritable: true },\n\n { pubkey: vestingRecord, isSigner: false, isWritable: true },\n\n { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },\n ];\n\n return new TransactionInstruction({\n keys,\n programId,\n data: anchorDataBuf.createPlatformVestingAccount,\n });\n}\n\nexport function createPlatformAllowConfigIns(\n programId: PublicKey,\n\n platformAdmin: PublicKey,\n platformId: PublicKey,\n globalConfigId: PublicKey,\n platformAllowConfig: PublicKey,\n): TransactionInstruction {\n const keys: Array<AccountMeta> = [\n { pubkey: platformAdmin, isSigner: true, isWritable: true },\n { pubkey: platformId, isSigner: false, isWritable: false },\n { pubkey: globalConfigId, isSigner: false, isWritable: false },\n { pubkey: platformAllowConfig, isSigner: false, isWritable: true },\n { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },\n ];\n\n return new TransactionInstruction({\n keys,\n programId,\n data: anchorDataBuf.createPlatformAllowConfig,\n });\n}\n\nexport function closePlatformAllowConfigIns(\n programId: PublicKey,\n\n platformAdmin: PublicKey,\n platformId: PublicKey,\n globalConfigId: PublicKey,\n platformAllowConfig: PublicKey,\n): TransactionInstruction {\n const keys: Array<AccountMeta> = [\n { pubkey: platformAdmin, isSigner: true, isWritable: true },\n { pubkey: platformId, isSigner: false, isWritable: false },\n { pubkey: globalConfigId, isSigner: false, isWritable: false },\n { pubkey: platformAllowConfig, isSigner: false, isWritable: true },\n ];\n\n return new TransactionInstruction({\n keys,\n programId,\n data: anchorDataBuf.closePlatformAllowConfig,\n });\n}\n","import { publicKey, seq, struct, u16, u64, u8, vec } from \"../../marshmallow\";\n\nexport const LaunchpadConfig = struct([\n u64(),\n u64(\"epoch\"),\n u8(\"curveType\"),\n u16(\"index\"),\n u64(\"migrateFee\"),\n u64(\"tradeFeeRate\"),\n\n u64(\"maxShareFeeRate\"),\n u64(\"minSupplyA\"),\n u64(\"maxLockRate\"),\n u64(\"minSellRateA\"),\n u64(\"minMigrateRateA\"),\n u64(\"minFundRaisingB\"),\n\n publicKey(\"mintB\"),\n publicKey(\"protocolFeeOwner\"),\n publicKey(\"migrateFeeOwner\"),\n publicKey(\"migrateToAmmWallet\"),\n publicKey(\"migrateToCpmmWallet\"),\n seq(u64(), 16),\n]);\n\nexport const VestingSchedule = struct([\n u64(\"totalLockedAmount\"),\n u64(\"cliffPeriod\"),\n u64(\"unlockPeriod\"),\n u64(\"startTime\"),\n u64(\"totalAllocatedShare\"),\n]);\n\nexport const LaunchpadPool = struct([\n u64(),\n u64(\"epoch\"),\n u8(\"bump\"),\n u8(\"status\"),\n u8(\"mintDecimalsA\"),\n u8(\"mintDecimalsB\"),\n u8(\"migrateType\"),\n\n u64(\"supply\"),\n u64(\"totalSellA\"),\n u64(\"virtualA\"),\n u64(\"virtualB\"),\n u64(\"realA\"),\n u64(\"realB\"),\n u64(\"totalFundRaisingB\"),\n u64(\"protocolFee\"),\n u64(\"platformFee\"),\n u64(\"migrateFee\"),\n\n VestingSchedule.replicate(\"vestingSchedule\"),\n\n publicKey(\"configId\"),\n publicKey(\"platformId\"),\n publicKey(\"mintA\"),\n publicKey(\"mintB\"),\n publicKey(\"vaultA\"),\n publicKey(\"vaultB\"),\n\n publicKey(\"creator\"),\n\n u8(\"mintProgramFlag\"),\n u8(\"cpmmCreatorFeeOn\"),\n\n u64('platformVestingShare'),\n\n seq(u8(), 54),\n]);\n\nexport const LaunchpadVesting = struct([\n u64(),\n u64(\"epoch\"),\n publicKey(\"poolId\"),\n publicKey(\"beneficiary\"),\n u64(\"claimedAmount\"),\n u64(\"tokenShareAmount\"),\n seq(u64(), 8),\n]);\n\nexport const BondingCurveParam = struct([\n u8('migrateType'),\n u8('migrateCpmmFeeOn'),\n u64('supply'),\n u64('totalSellA'),\n u64('totalFundRaisingB'),\n\n u64('totalLockedAmount'),\n u64('cliffPeriod'),\n u64('unlockPeriod'),\n]);\n\nexport const PlatformCurveParam = struct([\n u64(\"epoch\"),\n u8(\"index\"),\n publicKey(\"configId\"),\n\n BondingCurveParam.replicate(\"bondingCurveParam\"),\n seq(u64(), 50),\n]);\n\nexport const PlatformConfig = struct([\n u64(),\n u64(\"epoch\"),\n publicKey(\"platformClaimFeeWallet\"),\n publicKey(\"platformLockNftWallet\"),\n u64(\"platformScale\"),\n u64(\"creatorScale\"),\n u64(\"burnScale\"),\n u64(\"feeRate\"),\n seq(u8(), 64, \"name\"),\n seq(u8(), 256, \"web\"),\n seq(u8(), 256, \"img\"),\n publicKey(\"cpConfigId\"),\n u64(\"creatorFeeRate\"),\n publicKey(\"transferFeeExtensionAuth\"),\n\n publicKey('platformVestingWallet'),\n u64('platformVestingScale'),\n\n publicKey(\"platformCpCreator\"),\n\n u8(\"restrictGlobalConfig\"),\n seq(u8(), 107),\n\n vec(PlatformCurveParam, \"platformCurve\"),\n]);\n","import { PublicKey } from \"@solana/web3.js\";\nimport { findProgramAddress, ProgramAddress } from \"@/common\";\nimport { u16ToBytes, POOL_SEED, POOL_VAULT_SEED } from \"../clmm\";\n\nexport const AUTH_SEED = Buffer.from(\"vault_auth_seed\", \"utf8\");\nexport const CONFIG_SEED = Buffer.from(\"global_config\", \"utf8\");\nexport const POOL_VESTING_SEED = Buffer.from(\"pool_vesting\", \"utf8\");\nexport const PLATFORM_SEED = Buffer.from(\"platform_config\", \"utf8\");\nexport const PLATFORM_FEE_VAULT_AUTH_SEED = Buffer.from(\"platform_fee_vault_auth_seed\", \"utf8\");\nexport const CREATOR_FEE_VAULT_AUTH_SEED = Buffer.from(\"creator_fee_vault_auth_seed\", \"utf8\");\nexport const PLATFORM_GLOBAL_ACCESS_SEED = Buffer.from(\"platform_global_access\", \"utf8\");\nexport const PLATFORM_ALLOW_CONFIG_SEED = Buffer.from(\"platform_allow_config\", \"utf8\");\n\nexport function getPdaLaunchpadAuth(programId: PublicKey): ProgramAddress {\n return findProgramAddress([AUTH_SEED], programId);\n}\n\nexport function getPdaLaunchpadConfigId(\n programId: PublicKey,\n mintB: PublicKey,\n curveType: number,\n index: number,\n): ProgramAddress {\n return findProgramAddress([CONFIG_SEED, mintB.toBuffer(), u8ToBytes(curveType), u16ToBytes(index)], programId);\n}\n\nexport function getPdaLaunchpadPoolId(programId: PublicKey, mintA: PublicKey, mintB: PublicKey): ProgramAddress {\n return findProgramAddress([POOL_SEED, mintA.toBuffer(), mintB.toBuffer()], programId);\n}\n\nexport function getPdaLaunchpadVaultId(programId: PublicKey, poolId: PublicKey, mint: PublicKey): ProgramAddress {\n return findProgramAddress([POOL_VAULT_SEED, poolId.toBuffer(), mint.toBuffer()], programId);\n}\n\nexport function getPdaCpiEvent(programId: PublicKey): ProgramAddress {\n return findProgramAddress([Buffer.from(\"__event_authority\", \"utf8\")], programId);\n}\n\nfunction u8ToBytes(num: number) {\n const arr = new ArrayBuffer(1);\n const view = new DataView(arr);\n view.setUint8(0, num);\n return new Uint8Array(arr);\n}\n\n// export function u16ToBytes(num: number): Uint8Array<ArrayBuffer> {\n// const arr = new ArrayBuffer(2);\n// const view = new DataView(arr);\n// view.setUint16(0, num, false);\n// return new Uint8Array(arr);\n// }\n\nexport function getPdaPlatformId(programId: PublicKey, platformAdminWallet: PublicKey): ProgramAddress {\n return findProgramAddress([PLATFORM_SEED, platformAdminWallet.toBuffer()], programId);\n}\n\nexport function getPdaVestId(programId: PublicKey, poolId: PublicKey, owner: PublicKey): ProgramAddress {\n return findProgramAddress([POOL_VESTING_SEED, poolId.toBuffer(), owner.toBuffer()], programId);\n}\n\nexport function getPdaPlatformVault(programId: PublicKey, platformId: PublicKey, mintB: PublicKey): ProgramAddress {\n return findProgramAddress([platformId.toBuffer(), mintB.toBuffer()], programId);\n}\n\nexport function getPdaPlatformFeeVaultAuth(programId: PublicKey): ProgramAddress {\n return findProgramAddress([PLATFORM_FEE_VAULT_AUTH_SEED], programId);\n}\n\nexport function getPdaCreatorVault(programId: PublicKey, creator: PublicKey, mintB: PublicKey): ProgramAddress {\n return findProgramAddress([creator.toBuffer(), mintB.toBuffer()], programId);\n}\n\nexport function getPdaCreatorFeeVaultAuth(programId: PublicKey): ProgramAddress {\n return findProgramAddress([CREATOR_FEE_VAULT_AUTH_SEED], programId);\n}\n\nexport function getPdaPlatformConfigAccess(\n programId: PublicKey,\n platformId: PublicKey,\n configId: PublicKey,\n): ProgramAddress {\n return findProgramAddress([PLATFORM_GLOBAL_ACCESS_SEED, platformId.toBuffer(), configId.toBuffer()], programId);\n}\n\nexport function getPdaPlatformAllowConfig(\n programId: PublicKey,\n platformId: PublicKey,\n configId: PublicKey,\n): ProgramAddress {\n return findProgramAddress([PLATFORM_ALLOW_CONFIG_SEED, platformId.toBuffer(), configId.toBuffer()], programId);\n}\n","import { TOKEN_2022_PROGRAM_ID, TOKEN_PROGRAM_ID } from \"@solana/spl-token\";\nimport { PublicKey } from \"@solana/web3.js\";\n\n/**\n * Bit positions inside a launchpad pool's `mintProgramFlag`.\n *\n * The field is a bitfield, not a boolean: bit0 describes mintA and bit1 describes mintB, each\n * holding 0 for the legacy SPL Token program and 1 for Token-2022. Quote mints were legacy only\n * until token2022 quote support landed, so bit1 used to be constant 0.\n */\nexport enum LaunchpadMintProgramBit {\n MintA = 0,\n MintB = 1,\n}\n\nexport function getLaunchpadPoolMintProgram(mintProgramFlag: number, bit: LaunchpadMintProgramBit): PublicKey {\n return (mintProgramFlag >> bit) & 1 ? TOKEN_2022_PROGRAM_ID : TOKEN_PROGRAM_ID;\n}\n\nexport function getLaunchpadPoolMintAProgram(mintProgramFlag: number): PublicKey {\n return getLaunchpadPoolMintProgram(mintProgramFlag, LaunchpadMintProgramBit.MintA);\n}\n\nexport function getLaunchpadPoolMintBProgram(mintProgramFlag: number): PublicKey {\n return getLaunchpadPoolMintProgram(mintProgramFlag, LaunchpadMintProgramBit.MintB);\n}\n\n/** The reverse, for pool info the sdk predicts locally instead of reading from chain */\nexport function toLaunchpadMintProgramFlag({\n mintAProgram,\n mintBProgram,\n}: {\n mintAProgram: PublicKey;\n mintBProgram: PublicKey;\n}): number {\n return (\n (mintAProgram.equals(TOKEN_2022_PROGRAM_ID) ? 1 << LaunchpadMintProgramBit.MintA : 0) |\n (mintBProgram.equals(TOKEN_2022_PROGRAM_ID) ? 1 << LaunchpadMintProgramBit.MintB : 0)\n );\n}\n","import BN from \"bn.js\";\nimport Decimal from \"decimal.js\";\nimport { LaunchpadPool } from \"../layout\";\nimport { CurveBase, PoolBaseAmount } from \"./curveBase\";\nimport { ceilDivBN } from \"@/common\";\n\nexport class LaunchConstantProductCurve extends CurveBase {\n static getPoolInitPriceByPool({\n poolInfo,\n decimalA,\n decimalB,\n }: {\n poolInfo: ReturnType<typeof LaunchpadPool.decode> | PoolBaseAmount;\n decimalA: number;\n decimalB: number;\n }): Decimal {\n return new Decimal(poolInfo.virtualB.toString()).div(poolInfo.virtualA.toString()).mul(10 ** (decimalA - decimalB));\n }\n static getPoolInitPriceByInit({\n a,\n b,\n decimalA,\n decimalB,\n }: {\n a: BN;\n b: BN;\n decimalA: number;\n decimalB: number;\n }): Decimal {\n return new Decimal(b.toString()).div(a.toString()).mul(10 ** (decimalA - decimalB));\n }\n static getPoolPrice({\n poolInfo,\n decimalA,\n decimalB,\n }: {\n poolInfo: ReturnType<typeof LaunchpadPool.decode> | PoolBaseAmount;\n decimalA: number;\n decimalB: number;\n }): Decimal {\n return new Decimal(poolInfo.virtualB.add(poolInfo.realB).toString())\n .div(poolInfo.virtualA.sub(poolInfo.realA).toString())\n .mul(10 ** (decimalA - decimalB));\n }\n static getPoolEndPrice({\n supply,\n totalSell,\n totalLockedAmount,\n totalFundRaising,\n migrateFee,\n decimalA,\n decimalB,\n }: {\n supply: BN;\n totalSell: BN;\n totalLockedAmount: BN;\n totalFundRaising: BN;\n migrateFee: BN;\n decimalA: number;\n decimalB: number;\n }): Decimal {\n return new Decimal(totalFundRaising.sub(migrateFee).toString())\n .div(supply.sub(totalSell).sub(totalLockedAmount).toString())\n .mul(10 ** (decimalA - decimalB));\n }\n\n static getPoolEndPriceReal({\n poolInfo,\n decimalA,\n decimalB,\n }: {\n poolInfo: ReturnType<typeof LaunchpadPool.decode>;\n decimalA: number;\n decimalB: number;\n }): Decimal {\n const allSellToken = poolInfo.totalSellA.sub(poolInfo.realA);\n const buyAllTokenUseB = poolInfo.totalFundRaisingB.sub(poolInfo.realB);\n // allSellToken.isZero() ? new BN(0) : this.buyExactOut({\n // amount: poolInfo.totalSellA.sub(poolInfo.realA),\n // poolInfo,\n // })\n\n return new Decimal(poolInfo.virtualB.add(poolInfo.realB.add(buyAllTokenUseB)).toString())\n .div(poolInfo.virtualA.sub(poolInfo.realA.add(allSellToken)).toString())\n .mul(10 ** (decimalA - decimalB));\n }\n\n static getInitParam({\n supply,\n totalFundRaising,\n totalSell,\n totalLockedAmount,\n migrateFee,\n }: {\n supply: BN;\n totalSell: BN;\n totalLockedAmount: BN;\n totalFundRaising: BN;\n migrateFee: BN;\n }): {\n a: BN;\n b: BN;\n c: BN;\n } {\n if (supply.lte(totalSell)) throw Error(\"supply need gt total sell\");\n const supplyMinusSellLocked = supply.sub(totalSell).sub(totalLockedAmount);\n if (supplyMinusSellLocked.lte(new BN(0))) throw Error(\"supplyMinusSellLocked <= 0\");\n\n const tfMinusMf = totalFundRaising.sub(migrateFee);\n if (tfMinusMf.lte(new BN(0))) throw Error(\"tfMinusMf <= 0\");\n\n // const migratePriceX64 = tfMinusMf.mul(Q64).div(supplyMinusSellLocked)\n\n const numerator = tfMinusMf.mul(totalSell).mul(totalSell).div(supplyMinusSellLocked);\n const denominator = tfMinusMf.mul(totalSell).div(supplyMinusSellLocked).sub(totalFundRaising);\n const x0 = numerator.div(denominator);\n const y0 = totalFundRaising.mul(totalFundRaising).div(denominator);\n\n if (x0.lt(new BN(0)) || y0.lt(new BN(0))) throw Error(\"invalid input 0\");\n\n return {\n a: x0,\n b: y0,\n c: totalSell,\n };\n }\n\n static buyExactIn({\n poolInfo,\n amount,\n }: {\n poolInfo: ReturnType<typeof LaunchpadPool.decode> | PoolBaseAmount;\n amount: BN;\n }): BN {\n return this.getAmountOut({\n amountIn: amount,\n inputReserve: poolInfo.virtualB.add(poolInfo.realB),\n outputReserve: poolInfo.virtualA.sub(poolInfo.realA),\n });\n }\n\n static buyExactOut({\n poolInfo,\n amount,\n }: {\n poolInfo: ReturnType<typeof LaunchpadPool.decode> | PoolBaseAmount;\n amount: BN;\n }): BN {\n return this.getAmountIn({\n amountOut: amount,\n inputReserve: poolInfo.virtualB.add(poolInfo.realB),\n outputReserve: poolInfo.virtualA.sub(poolInfo.realA),\n });\n }\n\n static sellExactIn({\n poolInfo,\n amount,\n }: {\n poolInfo: ReturnType<typeof LaunchpadPool.decode> | PoolBaseAmount;\n amount: BN;\n }): BN {\n return this.getAmountOut({\n amountIn: amount,\n inputReserve: poolInfo.virtualA.sub(poolInfo.realA),\n outputReserve: poolInfo.virtualB.add(poolInfo.realB),\n });\n }\n\n static sellExactOut({\n poolInfo,\n amount,\n }: {\n poolInfo: ReturnType<typeof LaunchpadPool.decode> | PoolBaseAmount;\n amount: BN;\n }): BN {\n return this.getAmountIn({\n amountOut: amount,\n inputReserve: poolInfo.virtualA.sub(poolInfo.realA),\n outputReserve: poolInfo.virtualB.add(poolInfo.realB),\n });\n }\n\n static getAmountOut({\n amountIn,\n inputReserve,\n outputReserve,\n }: {\n amountIn: BN;\n inputReserve: BN;\n outputReserve: BN;\n }): BN {\n const numerator = amountIn.mul(outputReserve);\n const denominator = inputReserve.add(amountIn);\n const amountOut = numerator.div(denominator);\n return amountOut;\n }\n static getAmountIn({\n amountOut,\n inputReserve,\n outputReserve,\n }: {\n amountOut: BN;\n inputReserve: BN;\n outputReserve: BN;\n }): BN {\n const numerator = inputReserve.mul(amountOut);\n const denominator = outputReserve.sub(amountOut);\n const amountIn = ceilDivBN(numerator, denominator);\n return amountIn;\n }\n}\n","import { TransferFeeConfig } from \"@solana/spl-token\";\nimport BN from \"bn.js\";\nimport Decimal from \"decimal.js\";\nimport { GetTransferAmountFee } from \"@/raydium/type\";\nimport { getTransferAmountFeeFromPre, getTransferAmountFeeFromPost } from \"@/common\";\nimport { LaunchpadConfig, LaunchpadPool } from \"../layout\";\nimport { LaunchConstantProductCurve } from \"./constantProductCurve\";\nimport { CurveBase, PoolBaseAmount } from \"./curveBase\";\n// import { ceilDiv, FEE_RATE_DENOMINATOR_VALUE } from \"./fee\";\nimport { ceilDiv, FEE_RATE_DENOMINATOR_VALUE } from \"@/common\";\nimport { FixedPriceCurve } from \"./fixedPriceCurve\";\nimport { LinearPriceCurve } from \"./linearPriceCurve\";\n\nexport interface SwapInfoReturn {\n amountA: GetTransferAmountFee;\n amountB: BN;\n splitFee: ReturnType<typeof Curve.splitFee>;\n transferFeeB: BN | undefined;\n}\n\nexport class Curve {\n static getPoolCurvePointByPoolInfo({\n curveType,\n pointCount,\n poolInfo,\n }: {\n curveType: number;\n poolInfo: ReturnType<typeof LaunchpadPool.decode>;\n pointCount: number;\n }): {\n price: Decimal;\n totalSellSupply: number;\n }[] {\n return this.getPoolCurvePointByInit({\n curveType,\n pointCount,\n supply: poolInfo.supply,\n totalFundRaising: poolInfo.totalFundRaisingB,\n totalSell: poolInfo.totalSellA,\n totalLockedAmount: poolInfo.vestingSchedule.totalLockedAmount,\n migrateFee: poolInfo.migrateFee,\n decimalA: poolInfo.mintDecimalsA,\n decimalB: poolInfo.mintDecimalsB,\n });\n }\n static getPoolCurvePointByInit({\n curveType,\n pointCount,\n supply,\n totalFundRaising,\n totalSell,\n totalLockedAmount,\n migrateFee,\n decimalA,\n decimalB,\n }: {\n curveType: number;\n supply: BN;\n totalSell: BN;\n totalLockedAmount: BN;\n totalFundRaising: BN;\n migrateFee: BN;\n decimalA: number;\n decimalB: number;\n pointCount: number;\n }): {\n price: Decimal;\n totalSellSupply: number;\n }[] {\n if (pointCount < 3) throw Error(\"point count < 3\");\n\n const curve = this.getCurve(curveType);\n const initParam = curve.getInitParam({ supply, totalFundRaising, totalSell, totalLockedAmount, migrateFee });\n const initPrice = curve.getPoolInitPriceByInit({ ...initParam, decimalA, decimalB });\n\n const itemStepBuy = totalFundRaising.div(new BN(pointCount - 1));\n\n const zero = new BN(0);\n\n const returnPoints: { price: Decimal; totalSellSupply: number }[] = [{ price: initPrice, totalSellSupply: 0 }];\n const { a, b } = initParam;\n let realA = zero;\n let realB = zero;\n for (let i = 1; i < pointCount; i++) {\n const amountB = i !== pointCount - 1 ? itemStepBuy : totalFundRaising.sub(realB);\n const itemBuy = this.buyExactIn({\n poolInfo: {\n virtualA: a,\n virtualB: b,\n realA,\n realB,\n totalFundRaisingB: totalFundRaising,\n totalSellA: totalSell,\n },\n amountB,\n protocolFeeRate: zero,\n platformFeeRate: zero,\n curveType,\n shareFeeRate: zero,\n creatorFeeRate: zero,\n transferFeeConfigA: undefined,\n transferFeeConfigB: undefined,\n slot: 0,\n });\n realA = realA.add(itemBuy.amountA.amount);\n realB = realB.add(itemBuy.amountB);\n\n const nowPoolPrice = this.getPrice({\n poolInfo: { virtualA: a, virtualB: b, realA, realB },\n decimalA,\n decimalB,\n curveType,\n });\n returnPoints.push({\n price: nowPoolPrice,\n totalSellSupply: new Decimal(realA.toString()).div(10 ** decimalA).toNumber(),\n });\n }\n\n return returnPoints;\n }\n\n static getPoolInitPriceByPool({\n poolInfo,\n decimalA,\n decimalB,\n curveType,\n }: {\n poolInfo: ReturnType<typeof LaunchpadPool.decode> | PoolBaseAmount;\n decimalA: number;\n decimalB: number;\n curveType: number;\n }): Decimal {\n const curve = this.getCurve(curveType);\n return curve.getPoolInitPriceByPool({ poolInfo, decimalA, decimalB });\n }\n static getPoolInitPriceByInit({\n a,\n b,\n decimalA,\n decimalB,\n curveType,\n }: {\n a: BN;\n b: BN;\n decimalA: number;\n decimalB: number;\n curveType: number;\n }): Decimal {\n const curve = this.getCurve(curveType);\n return curve.getPoolInitPriceByInit({ a, b, decimalA, decimalB });\n }\n static getPrice({\n poolInfo,\n curveType,\n decimalA,\n decimalB,\n }: {\n poolInfo: ReturnType<typeof LaunchpadPool.decode> | { virtualA: BN; virtualB: BN; realA: BN; realB: BN };\n decimalA: number;\n decimalB: number;\n curveType: number;\n }): Decimal {\n const curve = this.getCurve(curveType);\n return curve.getPoolPrice({ poolInfo, decimalA, decimalB });\n }\n static getEndPrice({\n poolInfo,\n curveType,\n decimalA,\n decimalB,\n }: {\n poolInfo: ReturnType<typeof LaunchpadPool.decode>;\n curveType: number;\n decimalA: number;\n decimalB: number;\n }): Decimal {\n const curve = this.getCurve(curveType);\n return curve.getPoolPrice({ poolInfo, decimalA, decimalB });\n }\n static getPoolEndPriceReal({\n poolInfo,\n curveType,\n decimalA,\n decimalB,\n }: {\n poolInfo: ReturnType<typeof LaunchpadPool.decode>;\n curveType: number;\n decimalA: number;\n decimalB: number;\n }): Decimal {\n const curve = this.getCurve(curveType);\n return curve.getPoolEndPriceReal({ poolInfo, decimalA, decimalB });\n }\n\n static checkParam({\n supply,\n totalFundRaising,\n totalSell,\n totalLockedAmount,\n decimals,\n config,\n migrateType,\n }: {\n supply: BN;\n totalSell: BN;\n totalLockedAmount: BN;\n totalFundRaising: BN;\n decimals: number;\n config: ReturnType<typeof LaunchpadConfig.decode>;\n migrateType: \"amm\" | \"cpmm\";\n }): void {\n if (Number(decimals) !== 6) throw Error(\"decimals = 6\");\n const maxLockedA = supply.mul(config.maxLockRate).div(FEE_RATE_DENOMINATOR_VALUE);\n if (maxLockedA.lt(totalLockedAmount)) throw Error(\"total lock amount gte max lock amount\");\n\n if (supply.lt(config.minSupplyA.mul(new BN(10 ** decimals)))) throw Error(\"supply lt min supply\");\n\n const minSellA = supply.mul(config.minSellRateA).div(FEE_RATE_DENOMINATOR_VALUE);\n if (totalSell.lt(minSellA)) throw Error(\"invalid input\");\n if (totalFundRaising.lt(config.minFundRaisingB)) throw Error(\"total fund raising lt min fund raising\");\n\n const amountMigrate = supply.sub(totalSell).sub(totalLockedAmount);\n const minAmountMigrate = supply.mul(config.minMigrateRateA).div(FEE_RATE_DENOMINATOR_VALUE);\n\n if (amountMigrate.lt(minAmountMigrate)) throw Error(\"migrate lt min migrate amoount\");\n\n const migrateAmountA = supply.sub(totalSell).sub(totalLockedAmount);\n const liquidity = new BN(new Decimal(migrateAmountA.mul(totalFundRaising).toString()).sqrt().toFixed(0));\n\n if (migrateType === \"amm\") {\n const minLockLp = new BN(10).pow(new BN(decimals));\n if (liquidity.lte(minLockLp)) throw Error(\"check migrate lp error\");\n } else if (migrateType === \"cpmm\") {\n const minLockLp = new BN(100);\n if (liquidity.lte(minLockLp)) throw Error(\"check migrate lp error\");\n } else {\n throw Error(\"migrate type error\");\n }\n }\n\n /**\n * @returns Please note that amountA/B is subject to change\n */\n static buyExactIn({\n poolInfo,\n amountB,\n protocolFeeRate,\n platformFeeRate,\n curveType,\n shareFeeRate,\n creatorFeeRate,\n transferFeeConfigA,\n transferFeeConfigB,\n slot,\n }: {\n poolInfo: ReturnType<typeof LaunchpadPool.decode> | (PoolBaseAmount & { totalSellA: BN; totalFundRaisingB: BN });\n amountB: BN;\n protocolFeeRate: BN;\n platformFeeRate: BN;\n curveType: number;\n shareFeeRate: BN;\n creatorFeeRate: BN;\n\n transferFeeConfigA: TransferFeeConfig | undefined;\n transferFeeConfigB?: TransferFeeConfig | undefined;\n slot: number;\n }): SwapInfoReturn {\n const amountInInfoB = getTransferAmountFeeFromPre(amountB, transferFeeConfigB, slot);\n const vaultAmountInB = amountB.sub(amountInInfoB.fee ?? new BN(0));\n\n const feeRate = this.totalFeeRate({ protocolFeeRate, platformFeeRate, shareFeeRate, creatorFeeRate });\n const _totalFee = this.calculateFee({ amount: vaultAmountInB, feeRate });\n\n const amountLessFeeB = vaultAmountInB.sub(_totalFee);\n\n const curve = this.getCurve(curveType);\n\n const _amountA = curve.buyExactIn({ poolInfo, amount: amountLessFeeB });\n\n const remainingAmountA = poolInfo.totalSellA.sub(poolInfo.realA);\n\n let amountA: BN;\n let realAmountB: BN;\n let totalFee: BN;\n let transferFeeB: BN | undefined;\n if (_amountA.gt(remainingAmountA)) {\n amountA = remainingAmountA;\n\n const amountLessFeeB = curve.buyExactOut({\n poolInfo,\n amount: amountA,\n });\n\n const vaultRealAmountB = this.calculatePreFee({ postFeeAmount: amountLessFeeB, feeRate });\n totalFee = vaultRealAmountB.sub(amountLessFeeB);\n\n const realAmountInfoB = getTransferAmountFeeFromPost(vaultRealAmountB, transferFeeConfigB, slot);\n realAmountB = realAmountInfoB.amount;\n transferFeeB = realAmountInfoB.fee;\n } else {\n amountA = _amountA;\n realAmountB = amountB;\n totalFee = _totalFee;\n transferFeeB = amountInInfoB.fee;\n }\n\n const splitFee = this.splitFee({ totalFee, protocolFeeRate, platformFeeRate, shareFeeRate, creatorFeeRate });\n\n return {\n amountA: getTransferAmountFeeFromPre(amountA, transferFeeConfigA, slot),\n amountB: realAmountB,\n splitFee,\n transferFeeB,\n };\n }\n\n /**\n * @returns Please note that amountA/B is subject to change\n */\n static buyExactOut({\n poolInfo,\n amountA,\n protocolFeeRate,\n platformFeeRate,\n curveType,\n shareFeeRate,\n creatorFeeRate,\n transferFeeConfigA,\n transferFeeConfigB,\n slot,\n }: {\n poolInfo: ReturnType<typeof LaunchpadPool.decode> | (PoolBaseAmount & { totalSellA: BN; totalFundRaisingB: BN });\n amountA: BN;\n protocolFeeRate: BN;\n platformFeeRate: BN;\n curveType: number;\n shareFeeRate: BN;\n creatorFeeRate: BN;\n\n transferFeeConfigA: TransferFeeConfig | undefined;\n transferFeeConfigB?: TransferFeeConfig | undefined;\n slot: number;\n }): SwapInfoReturn {\n const remainingAmountA = poolInfo.totalSellA.sub(poolInfo.realA);\n\n const preAmountA = getTransferAmountFeeFromPost(amountA, transferFeeConfigA, slot);\n let realAmountA = preAmountA.fee ? preAmountA.amount.add(preAmountA.fee) : preAmountA.amount;\n if (amountA.gt(remainingAmountA)) {\n realAmountA = remainingAmountA;\n }\n\n const curve = this.getCurve(curveType);\n const amountInLessFeeB = curve.buyExactOut({ poolInfo, amount: realAmountA });\n\n const totalFeeRate = this.totalFeeRate({ protocolFeeRate, platformFeeRate, shareFeeRate, creatorFeeRate });\n\n const vaultAmountInB = this.calculatePreFee({ postFeeAmount: amountInLessFeeB, feeRate: totalFeeRate });\n const totalFee = vaultAmountInB.sub(amountInLessFeeB);\n\n const amountInInfoB = getTransferAmountFeeFromPost(vaultAmountInB, transferFeeConfigB, slot);\n\n const splitFee = this.splitFee({ totalFee, protocolFeeRate, platformFeeRate, shareFeeRate, creatorFeeRate });\n\n return { amountA: preAmountA, amountB: amountInInfoB.amount, splitFee, transferFeeB: amountInInfoB.fee };\n }\n\n static sellExactIn({\n poolInfo,\n amountA: _amountA,\n protocolFeeRate,\n platformFeeRate,\n curveType,\n shareFeeRate,\n creatorFeeRate,\n transferFeeConfigA,\n transferFeeConfigB,\n slot,\n }: {\n poolInfo: ReturnType<typeof LaunchpadPool.decode> | PoolBaseAmount;\n amountA: BN;\n protocolFeeRate: BN;\n platformFeeRate: BN;\n curveType: number;\n shareFeeRate: BN;\n creatorFeeRate: BN;\n\n transferFeeConfigA: TransferFeeConfig | undefined;\n transferFeeConfigB?: TransferFeeConfig | undefined;\n slot: number;\n }): SwapInfoReturn {\n const curve = this.getCurve(curveType);\n\n const amountInfoA = getTransferAmountFeeFromPre(_amountA, transferFeeConfigA, slot);\n const amountA = amountInfoA.fee ? amountInfoA.amount.sub(amountInfoA.fee) : amountInfoA.amount;\n\n const amountB = curve.sellExactIn({ poolInfo, amount: amountA });\n\n const totalFee = this.calculateFee({\n amount: amountB,\n feeRate: this.totalFeeRate({ protocolFeeRate, platformFeeRate, shareFeeRate, creatorFeeRate }),\n });\n\n const splitFee = this.splitFee({ totalFee, protocolFeeRate, platformFeeRate, shareFeeRate, creatorFeeRate });\n\n const vaultAmountOutB = amountB.sub(totalFee);\n const amountOutInfoB = getTransferAmountFeeFromPre(vaultAmountOutB, transferFeeConfigB, slot);\n\n return {\n amountA: amountInfoA,\n amountB: vaultAmountOutB.sub(amountOutInfoB.fee ?? new BN(0)),\n splitFee,\n transferFeeB: amountOutInfoB.fee,\n };\n }\n\n static sellExactOut({\n poolInfo,\n amountB,\n protocolFeeRate,\n platformFeeRate,\n curveType,\n shareFeeRate,\n creatorFeeRate,\n transferFeeConfigA,\n transferFeeConfigB,\n slot,\n }: {\n poolInfo: ReturnType<typeof LaunchpadPool.decode> | PoolBaseAmount;\n amountB: BN;\n protocolFeeRate: BN;\n platformFeeRate: BN;\n curveType: number;\n shareFeeRate: BN;\n creatorFeeRate: BN;\n\n transferFeeConfigA: TransferFeeConfig | undefined;\n transferFeeConfigB?: TransferFeeConfig | undefined;\n slot: number;\n }): SwapInfoReturn {\n const totalFeeRate = this.totalFeeRate({ protocolFeeRate, platformFeeRate, shareFeeRate, creatorFeeRate });\n\n const amountOutInfoB = getTransferAmountFeeFromPost(amountB, transferFeeConfigB, slot);\n const vaultAmountOutB = amountOutInfoB.amount;\n\n const amountOutWithFeeB = this.calculatePreFee({ postFeeAmount: vaultAmountOutB, feeRate: totalFeeRate });\n if (poolInfo.realB.lt(amountOutWithFeeB)) throw Error(\"Insufficient liquidity\");\n\n const totalFee = amountOutWithFeeB.sub(vaultAmountOutB);\n\n const curve = Curve.getCurve(curveType);\n const amountA = curve.sellExactOut({ poolInfo, amount: amountOutWithFeeB });\n\n if (amountA.gt(poolInfo.realA)) throw Error();\n\n const splitFee = this.splitFee({ totalFee, protocolFeeRate, platformFeeRate, shareFeeRate, creatorFeeRate });\n\n return {\n amountA: getTransferAmountFeeFromPost(amountA, transferFeeConfigA, slot),\n amountB,\n splitFee,\n transferFeeB: amountOutInfoB.fee,\n };\n }\n\n static splitFee({\n totalFee,\n protocolFeeRate,\n platformFeeRate,\n shareFeeRate,\n creatorFeeRate,\n }: {\n totalFee: BN;\n protocolFeeRate: BN;\n platformFeeRate: BN;\n shareFeeRate: BN;\n creatorFeeRate: BN;\n }): { platformFee: BN; shareFee: BN; protocolFee: BN; creatorFee: BN } {\n const totalFeeRate = this.totalFeeRate({ protocolFeeRate, platformFeeRate, shareFeeRate, creatorFeeRate });\n const platformFee = totalFeeRate.isZero() ? new BN(0) : totalFee.mul(platformFeeRate).div(totalFeeRate);\n const shareFee = totalFeeRate.isZero() ? new BN(0) : totalFee.mul(shareFeeRate).div(totalFeeRate);\n const creatorFee = totalFeeRate.isZero() ? new BN(0) : totalFee.mul(creatorFeeRate).div(totalFeeRate);\n\n const protocolFee = totalFee.sub(platformFee).sub(shareFee).sub(creatorFee);\n\n return { platformFee, shareFee, protocolFee, creatorFee };\n }\n\n static calculateFee({ amount, feeRate }: { amount: BN; feeRate: BN }): BN {\n return ceilDiv(amount, feeRate, FEE_RATE_DENOMINATOR_VALUE);\n }\n static calculatePreFee({ postFeeAmount, feeRate }: { postFeeAmount: BN; feeRate: BN }): BN {\n if (feeRate.isZero()) return postFeeAmount;\n\n const numerator = postFeeAmount.mul(FEE_RATE_DENOMINATOR_VALUE);\n const denominator = FEE_RATE_DENOMINATOR_VALUE.sub(feeRate);\n\n return numerator.add(denominator).sub(new BN(1)).div(denominator);\n }\n\n static totalFeeRate({\n protocolFeeRate,\n platformFeeRate,\n shareFeeRate,\n creatorFeeRate,\n }: {\n protocolFeeRate: BN;\n platformFeeRate: BN;\n shareFeeRate: BN;\n creatorFeeRate: BN;\n }): BN {\n const totalFeeRate = protocolFeeRate.add(platformFeeRate).add(shareFeeRate).add(creatorFeeRate);\n if (totalFeeRate.gt(new BN(1_000_000))) throw Error(\"total fee rate gt 1_000_000\");\n return protocolFeeRate.add(platformFeeRate).add(shareFeeRate).add(creatorFeeRate);\n }\n\n static getCurve(curveType: number): typeof CurveBase {\n switch (curveType) {\n case 0:\n return LaunchConstantProductCurve;\n case 1:\n return FixedPriceCurve;\n case 2:\n return LinearPriceCurve;\n }\n throw Error(\"find curve error\");\n }\n}\n","import BN from \"bn.js\";\nimport Decimal from \"decimal.js\";\nimport { LaunchpadPool } from \"../layout\";\nimport { CurveBase, PoolBaseAmount } from \"./curveBase\";\n// import { ceilDivBN } from \"./fee\";\nimport { ceilDivBN } from \"@/common\";\n\nexport class FixedPriceCurve extends CurveBase {\n static getPoolInitPriceByPool({\n poolInfo,\n decimalA,\n decimalB,\n }: {\n poolInfo: ReturnType<typeof LaunchpadPool.decode> | PoolBaseAmount;\n decimalA: number;\n decimalB: number;\n }): Decimal {\n return new Decimal(poolInfo.virtualB.toString()).div(poolInfo.virtualA.toString()).mul(10 ** (decimalA - decimalB));\n }\n static getPoolInitPriceByInit({\n a,\n b,\n decimalA,\n decimalB,\n }: {\n a: BN;\n b: BN;\n decimalA: number;\n decimalB: number;\n }): Decimal {\n return new Decimal(b.toString()).div(a.toString()).mul(10 ** (decimalA - decimalB));\n }\n static getPoolPrice({\n poolInfo,\n decimalA,\n decimalB,\n }: {\n poolInfo: ReturnType<typeof LaunchpadPool.decode> | { virtualA: BN; virtualB: BN; realA: BN; realB: BN };\n decimalA: number;\n decimalB: number;\n }): Decimal {\n return new Decimal(poolInfo.virtualB.toString()).div(poolInfo.virtualA.toString()).mul(10 ** (decimalA - decimalB));\n }\n static getPoolEndPrice({\n supply,\n totalSell,\n totalLockedAmount,\n totalFundRaising,\n migrateFee,\n decimalA,\n decimalB,\n }: {\n supply: BN;\n totalSell: BN;\n totalLockedAmount: BN;\n totalFundRaising: BN;\n migrateFee: BN;\n decimalA: number;\n decimalB: number;\n }): Decimal {\n return new Decimal(totalFundRaising.sub(migrateFee).toString())\n .div(supply.sub(totalSell).sub(totalLockedAmount).toString())\n .mul(10 ** (decimalA - decimalB));\n }\n static getPoolEndPriceReal({\n poolInfo,\n decimalA,\n decimalB,\n }: {\n poolInfo: ReturnType<typeof LaunchpadPool.decode>;\n decimalA: number;\n decimalB: number;\n }): Decimal {\n const allSellToken = poolInfo.totalSellA.sub(poolInfo.realA);\n const buyAllTokenUseB = poolInfo.totalFundRaisingB.sub(poolInfo.realB);\n\n return new Decimal(poolInfo.virtualB.add(poolInfo.realB).add(buyAllTokenUseB).toString())\n .div(poolInfo.virtualA.sub(poolInfo.realA).add(allSellToken).toString())\n .mul(10 ** (decimalA - decimalB));\n }\n\n static getInitParam({\n supply,\n totalFundRaising,\n totalSell,\n totalLockedAmount,\n migrateFee,\n }: {\n supply: BN;\n totalSell: BN;\n totalFundRaising: BN;\n totalLockedAmount: BN;\n migrateFee: BN;\n }) {\n const supplyMinusLocked = supply.sub(totalLockedAmount);\n\n if (supplyMinusLocked.lte(new BN(0))) throw Error(\"invalid input 1\");\n\n const denominator = new BN(2).mul(totalFundRaising).sub(migrateFee);\n const numerator = totalFundRaising.mul(supplyMinusLocked);\n const totalSellExpect = numerator.div(denominator);\n\n // if (!totalSell.eq(totalSellExpect)) throw Error('invalid input 2')\n\n if (totalSellExpect.lt(new BN(0)) || totalFundRaising.lt(new BN(0))) throw Error(\"invalid input 0\");\n\n return { a: totalSellExpect, b: totalFundRaising, c: totalSellExpect };\n }\n\n static buyExactIn({\n poolInfo,\n amount,\n }: {\n poolInfo: ReturnType<typeof LaunchpadPool.decode> | PoolBaseAmount;\n amount: BN;\n }): BN {\n return this.getAmountOut({ amountIn: amount, initInput: poolInfo.virtualB, initOutput: poolInfo.virtualA });\n }\n\n static buyExactOut({\n poolInfo,\n amount,\n }: {\n poolInfo: ReturnType<typeof LaunchpadPool.decode> | PoolBaseAmount;\n amount: BN;\n }): BN {\n return this.getAmountIn({ amountOut: amount, initInput: poolInfo.virtualB, initOutput: poolInfo.virtualA });\n }\n\n static sellExactIn({\n poolInfo,\n amount,\n }: {\n poolInfo: ReturnType<typeof LaunchpadPool.decode> | PoolBaseAmount;\n amount: BN;\n }): BN {\n return this.getAmountOut({ amountIn: amount, initInput: poolInfo.virtualA, initOutput: poolInfo.virtualB });\n }\n\n static sellExactOut({\n poolInfo,\n amount,\n }: {\n poolInfo: ReturnType<typeof LaunchpadPool.decode> | PoolBaseAmount;\n amount: BN;\n }): BN {\n return this.getAmountIn({ amountOut: amount, initInput: poolInfo.virtualA, initOutput: poolInfo.virtualB });\n }\n\n static getAmountOut({ amountIn, initInput, initOutput }: { amountIn: BN; initInput: BN; initOutput: BN }) {\n const numerator = initOutput.mul(amountIn);\n const amountOut = numerator.div(initInput);\n return amountOut;\n }\n\n static getAmountIn({ amountOut, initInput, initOutput }: { amountOut: BN; initInput: BN; initOutput: BN }) {\n const numerator = initInput.mul(amountOut);\n const amountIn = ceilDivBN(numerator, initOutput);\n return amountIn;\n }\n}\n","import { Q64, U64_MAX } from \"@/raydium/clmm\";\nimport BN from \"bn.js\";\nimport Decimal from \"decimal.js\";\nimport { LaunchpadPool } from \"../layout\";\nimport { CurveBase, PoolBaseAmount } from \"./curveBase\";\n// import { ceilDivBN } from \"./fee\";\nimport { ceilDivBN } from \"@/common\";\nimport { MathLaunch } from \"./func\";\n\nexport class LinearPriceCurve extends CurveBase {\n static getPoolInitPriceByPool({\n poolInfo,\n decimalA,\n decimalB,\n }: {\n poolInfo: ReturnType<typeof LaunchpadPool.decode> | PoolBaseAmount;\n decimalA: number;\n decimalB: number;\n }): Decimal {\n return new Decimal(0);\n }\n static getPoolInitPriceByInit({\n a,\n b,\n decimalA,\n decimalB,\n }: {\n a: BN;\n b: BN;\n decimalA: number;\n decimalB: number;\n }): Decimal {\n return new Decimal(0);\n }\n static getPoolPrice({\n poolInfo,\n decimalA,\n decimalB,\n }: {\n poolInfo: ReturnType<typeof LaunchpadPool.decode> | { virtualA: BN; virtualB: BN; realA: BN; realB: BN };\n decimalA: number;\n decimalB: number;\n }): Decimal {\n return new Decimal(poolInfo.virtualA.mul(poolInfo.realA).toString())\n .div(MathLaunch._Q64)\n .mul(10 ** (decimalA - decimalB));\n }\n static getPoolEndPrice({\n supply,\n totalSell,\n totalLockedAmount,\n totalFundRaising,\n migrateFee,\n decimalA,\n decimalB,\n }: {\n supply: BN;\n totalSell: BN;\n totalLockedAmount: BN;\n totalFundRaising: BN;\n migrateFee: BN;\n decimalA: number;\n decimalB: number;\n }): Decimal {\n return new Decimal(totalFundRaising.sub(migrateFee).toString())\n .div(supply.sub(totalSell).sub(totalLockedAmount).toString())\n .mul(10 ** (decimalA - decimalB));\n }\n static getPoolEndPriceReal({\n poolInfo,\n decimalA,\n decimalB,\n }: {\n poolInfo: ReturnType<typeof LaunchpadPool.decode>;\n decimalA: number;\n decimalB: number;\n }): Decimal {\n const allSellToken = poolInfo.totalSellA.sub(poolInfo.realA);\n const buyAllTokenUseB = poolInfo.totalFundRaisingB.sub(poolInfo.realB);\n\n return new Decimal(poolInfo.virtualB.add(poolInfo.realB).add(buyAllTokenUseB).toString())\n .div(poolInfo.virtualA.sub(poolInfo.realA).add(allSellToken).toString())\n .mul(10 ** (decimalA - decimalB));\n }\n\n static getInitParam({\n supply,\n totalFundRaising,\n totalSell,\n totalLockedAmount,\n migrateFee,\n }: {\n supply: BN;\n totalSell: BN;\n totalLockedAmount: BN;\n totalFundRaising: BN;\n migrateFee: BN;\n }) {\n const supplyMinusLocked = supply.sub(totalLockedAmount);\n if (supplyMinusLocked.lte(new BN(0))) throw Error(\"supplyMinusLocked need gt 0\");\n const denominator = totalFundRaising.mul(new BN(3)).sub(migrateFee);\n const numerator = totalFundRaising.mul(new BN(2)).mul(supplyMinusLocked);\n\n const totalSellExpect = numerator.div(denominator);\n\n // if (!totalSell.eq(totalSellExpect)) throw Error('invalid input')\n\n const totalSellSquared = totalSellExpect.mul(totalSellExpect);\n const a = totalFundRaising.mul(new BN(2)).mul(Q64).div(totalSellSquared);\n\n if (!a.gt(new BN(0))) throw Error(\"a need gt 0\");\n\n if (!U64_MAX.gt(a)) throw Error(\"a need lt u64 max\");\n\n if (a.lt(new BN(0)) || totalSellExpect.lt(new BN(0))) throw Error(\"invalid input 0\");\n\n return { a, b: new BN(0), c: totalSellExpect };\n }\n\n static buyExactIn({\n poolInfo,\n amount,\n }: {\n poolInfo: ReturnType<typeof LaunchpadPool.decode> | PoolBaseAmount;\n amount: BN;\n }): BN {\n const newQuote = poolInfo.realB.add(amount);\n const termInsideSqrt = new BN(2).mul(newQuote).mul(Q64).div(poolInfo.virtualA);\n const sqrtTerm = new BN(new Decimal(termInsideSqrt.toString()).sqrt().toFixed(0));\n const amountOut = sqrtTerm.sub(poolInfo.realA);\n\n return amountOut;\n }\n\n static buyExactOut({\n poolInfo,\n amount,\n }: {\n poolInfo: ReturnType<typeof LaunchpadPool.decode> | PoolBaseAmount;\n amount: BN;\n }): BN {\n const newBase = poolInfo.realA.add(amount);\n const newBaseSquared = newBase.mul(newBase);\n const newQuote = ceilDivBN(poolInfo.virtualA.mul(newBaseSquared), new BN(2).mul(Q64));\n return newQuote.sub(poolInfo.realB);\n }\n\n static sellExactIn({\n poolInfo,\n amount,\n }: {\n poolInfo: ReturnType<typeof LaunchpadPool.decode> | PoolBaseAmount;\n amount: BN;\n }): BN {\n const newBase = poolInfo.realA.sub(amount);\n const newBaseSquared = newBase.mul(newBase);\n const newQuote = ceilDivBN(poolInfo.virtualA.mul(newBaseSquared), new BN(2).mul(Q64));\n return poolInfo.realB.sub(newQuote);\n }\n\n static sellExactOut({\n poolInfo,\n amount,\n }: {\n poolInfo: ReturnType<typeof LaunchpadPool.decode> | PoolBaseAmount;\n amount: BN;\n }): BN {\n const newB = poolInfo.realB.sub(amount);\n const termInsideSqrt = new BN(2).mul(newB).mul(Q64).div(poolInfo.virtualA);\n\n const sqrtTerm = new BN(new Decimal(termInsideSqrt.toString()).sqrt().toFixed(0));\n\n const amountIn = poolInfo.realA.sub(sqrtTerm);\n\n return amountIn;\n }\n}\n","import BN from \"bn.js\";\nimport Decimal from \"decimal.js\";\n\n\nexport class MathLaunch {\n static _Q64 = new Decimal(new BN(1).shln(64).toString())\n\n static _multipler(decimals: number) {\n return new Decimal(10).pow(decimals)\n }\n\n static getPrice({priceX64, decimalA, decimalB}: {priceX64: BN, decimalA: number, decimalB: number}){\n const priceWithDecimals = new Decimal(priceX64.toString()).div(this._Q64)\n const price = priceWithDecimals.mul(this._multipler(decimalA)).div(this._multipler(decimalB))\n\n return price\n }\n\n static getPriceX64({price, decimalA, decimalB}: {price: Decimal, decimalA: number, decimalB: number}) {\n const priceWithDecimals = price.mul(this._multipler(decimalB)).div(this._multipler(decimalA))\n const priceX64 = new BN(priceWithDecimals.mul(this._Q64).toFixed(0))\n return priceX64\n }\n}\n\nexport function checkPoolToAmm({supply, totalFundRaisingB, totalLockedAmount, totalSellA, migrateType ,decimalsA}: {\n supply: BN, totalSellA: BN, totalLockedAmount: BN, totalFundRaisingB: BN, migrateType: 'amm' | 'cpmm', decimalsA: number,\n}) {\n const migrateAmountA = supply.sub(totalSellA).sub(totalLockedAmount)\n const liquidity = new BN(new Decimal(migrateAmountA.mul(totalFundRaisingB).toString()).sqrt().toFixed(0))\n\n if (migrateType === 'amm') {\n if (liquidity.gt(new BN(10).pow(new BN(decimalsA)))) return true\n } else if (migrateType === 'cpmm') {\n if (liquidity.gt(new BN(100))) return true\n } else {\n throw Error('migrate type error')\n }\n\n return false\n}\n","import ModuleBase, { ModuleBaseProps } from \"../moduleBase\";\nimport {\n TxVersion,\n MakeTxData,\n LAUNCHPAD_PROGRAM,\n getMultipleAccountsInfoWithCustomFlags,\n getATAAddress,\n MakeMultiTxData,\n} from \"@/common\";\nimport {\n BuyToken,\n BuyTokenExactOut,\n ClaimAllPlatformFee,\n ClaimCreatorFee,\n ClaimMultiCreatorFee,\n ClaimMultipleVaultPlatformFee,\n ClaimMultiVesting,\n ClaimPlatformFee,\n ClaimVaultPlatformFee,\n ClaimVesting,\n CpmmCreatorFeeOn,\n CreateLaunchPad,\n CreateMultipleVesting,\n CreatePlatform,\n CreatePlatformAllowConfig,\n CreatePlatformVestingAccount,\n CreateVesting,\n LaunchpadConfigInfo,\n LaunchpadPoolInfo,\n SellToken,\n SellTokenExactOut,\n UpdatePlatform,\n} from \"./type\";\nimport {\n getPdaCreatorFeeVaultAuth,\n getPdaCreatorVault,\n getPdaLaunchpadAuth,\n getPdaLaunchpadConfigId,\n getPdaLaunchpadPoolId,\n getPdaLaunchpadVaultId,\n getPdaPlatformAllowConfig,\n getPdaPlatformConfigAccess,\n getPdaPlatformFeeVaultAuth,\n getPdaPlatformId,\n getPdaPlatformVault,\n getPdaVestId,\n} from \"./pda\";\nimport {\n buyExactInInstruction,\n sellExactInInstruction,\n createPlatformConfig,\n updatePlatformConfig,\n claimPlatformFee,\n createVestingAccount,\n claimVestedToken,\n buyExactOutInstruction,\n initializeWithToken2022,\n sellExactOut,\n claimPlatformFeeFromVault,\n claimCreatorFee,\n initializeV2,\n createPlatformVestingAccountIns,\n createPlatformAllowConfigIns,\n closePlatformAllowConfigIns,\n} from \"./instrument\";\nimport {\n NATIVE_MINT,\n TOKEN_2022_PROGRAM_ID,\n TOKEN_PROGRAM_ID,\n TransferFeeConfig,\n createAssociatedTokenAccountIdempotentInstruction,\n createSyncNativeInstruction,\n getTransferFeeConfig,\n unpackMint,\n} from \"@solana/spl-token\";\nimport BN from \"bn.js\";\nimport { PublicKey, SystemProgram } from \"@solana/web3.js\";\nimport { getPdaMetadataKey } from \"../clmm\";\nimport { LaunchpadConfig, LaunchpadPool, PlatformConfig } from \"./layout\";\nimport { Curve, SwapInfoReturn } from \"./curve/curve\";\nimport { toLaunchpadMintProgramFlag } from \"./util\";\nimport Decimal from \"decimal.js\";\nimport { ApiV3Token } from \"@/api\";\n\nexport const LaunchpadPoolInitParam = {\n initPriceX64: new BN(\"515752397214619\"),\n supply: new BN(1_000_000_000_000_000),\n totalSellA: new BN(793_100_000_000_000),\n totalFundRaisingB: new BN(85_000_000_000),\n totalFundRaisingBUSD: new BN(12_500_000_000),\n totalLockedAmount: new BN(\"0\"),\n cliffPeriod: new BN(\"0\"),\n unlockPeriod: new BN(\"0\"),\n decimals: 6,\n virtualA: new BN(\"1073471847374405\"),\n virtualB: new BN(\"30050573465\"),\n realA: new BN(0),\n realB: new BN(0),\n protocolFee: new BN(0),\n platformId: new PublicKey(\"4Bu96XjU84XjPDSpveTVf6LYGCkfW5FK7SNkREWcEfV4\"),\n vestingSchedule: {\n totalLockedAmount: new BN(0),\n cliffPeriod: new BN(0),\n unlockPeriod: new BN(0),\n startTime: new BN(0),\n totalAllocatedShare: new BN(0),\n },\n};\n\nconst SLIPPAGE_UNIT = new BN(10000);\n\nexport const usdMintBSet = new Set([\n \"USDCoctVLVnvTXBEuP9s8hntucdJokbo17RwHuNXemT\",\n \"USD1ttGY1N17NEEHLmELoaybftRBUSErhqYiQzvEmuB\",\n]);\n\nexport interface SwapInfoReturnExt extends SwapInfoReturn {\n decimalOutAmount: Decimal;\n minDecimalOutAmount: Decimal;\n}\nexport default class LaunchpadModule extends ModuleBase {\n constructor(params: ModuleBaseProps) {\n super(params);\n }\n\n private async getMintBTokenInfo({\n mintB,\n mintBProgram,\n transferFeeConfigB,\n skipCheckMintB,\n }: {\n mintB: PublicKey;\n mintBProgram?: PublicKey;\n transferFeeConfigB?: TransferFeeConfig;\n skipCheckMintB?: boolean;\n }): Promise<{ mintBProgram: PublicKey; transferFeeConfigB: TransferFeeConfig | undefined }> {\n if (mintB.equals(NATIVE_MINT)) return { mintBProgram: TOKEN_PROGRAM_ID, transferFeeConfigB: undefined };\n if (transferFeeConfigB) return { mintBProgram: mintBProgram ?? TOKEN_2022_PROGRAM_ID, transferFeeConfigB };\n if (skipCheckMintB || mintBProgram?.equals(TOKEN_PROGRAM_ID))\n return { mintBProgram: mintBProgram ?? TOKEN_PROGRAM_ID, transferFeeConfigB: undefined };\n\n const mintInfo = await this.scope.connection.getAccountInfo(mintB);\n if (!mintInfo || !mintInfo.owner.equals(TOKEN_2022_PROGRAM_ID))\n return { mintBProgram: mintBProgram ?? TOKEN_PROGRAM_ID, transferFeeConfigB: undefined };\n\n return {\n mintBProgram: mintInfo.owner,\n transferFeeConfigB: getTransferFeeConfig(unpackMint(mintB, mintInfo, mintInfo.owner)) || undefined,\n };\n }\n\n public async createLaunchpad<T extends TxVersion>({\n programId = LAUNCHPAD_PROGRAM,\n authProgramId,\n platformId = LaunchpadPoolInitParam.platformId,\n mintA,\n decimals = 6,\n mintBDecimals = 9,\n name,\n symbol,\n uri,\n migrateType,\n configId,\n\n configInfo: propConfigInfo,\n txVersion,\n computeBudgetConfig,\n txTipConfig,\n feePayer,\n buyAmount,\n minMintAAmount,\n slippage,\n associatedOnly = true,\n checkCreateATAOwner = false,\n extraSigners,\n\n token2022,\n transferFeeExtensionParams,\n creatorFeeOn = CpmmCreatorFeeOn.OnlyTokenB,\n platformAllowConfig,\n mintBProgram: propsMintBProgram,\n transferFeeConfigB: propsTransferFeeConfigB,\n skipCheckMintB,\n ...extraConfigs\n }: CreateLaunchPad<T>): Promise<\n MakeMultiTxData<T, { address: LaunchpadPoolInfo & { poolId: PublicKey }; swapInfo: SwapInfoReturnExt }>\n > {\n const txBuilder = this.createTxBuilder(feePayer);\n authProgramId = authProgramId ?? getPdaLaunchpadAuth(programId).publicKey;\n\n token2022 = !!transferFeeExtensionParams;\n if (token2022) migrateType = \"cpmm\";\n let configInfo = propConfigInfo;\n if (!configInfo && configId) {\n const r = await this.scope.connection.getAccountInfo(configId);\n if (r) configInfo = LaunchpadConfig.decode(r.data);\n }\n\n if (!configInfo) this.logAndCreateError(\"config not found\");\n const mintB = configInfo!.mintB;\n const curType = configInfo!.curveType;\n\n const { mintBProgram, transferFeeConfigB } = await this.getMintBTokenInfo({\n mintB,\n mintBProgram: propsMintBProgram,\n transferFeeConfigB: propsTransferFeeConfigB,\n skipCheckMintB,\n });\n\n // const { publicKey: configId } = getPdaLaunchpadConfigId(programId, mintB, curType, configIndex);\n const { publicKey: poolId } = getPdaLaunchpadPoolId(programId, mintA, mintB);\n const { publicKey: vaultA } = getPdaLaunchpadVaultId(programId, poolId, mintA);\n const { publicKey: vaultB } = getPdaLaunchpadVaultId(programId, poolId, mintB);\n const { publicKey: metaId } = getPdaMetadataKey(mintA);\n\n this.logDebug(\n `create token: ${mintA.toBase58()}, mintB: ${mintB.toBase58()}, decimals A:${decimals}/B:${mintBDecimals}, config:${configId.toBase58()}`,\n );\n\n if (symbol.length > 10) this.logAndCreateError(\"Symbol length should shorter than 11\");\n if (!uri) this.logAndCreateError(\"uri should not empty\");\n\n const configs = await this.scope.api.fetchLaunchConfigs();\n const apiConfig = configs.find((c) => c.key.pubKey === configId.toBase58())!;\n\n const supply = extraConfigs?.supply ?? new BN(apiConfig.defaultParams.supplyInit);\n const totalSellA = extraConfigs?.totalSellA ?? new BN(apiConfig.defaultParams.totalSellA);\n\n const totalFundRaisingB = extraConfigs?.totalFundRaisingB ?? new BN(apiConfig.defaultParams.totalFundRaisingB);\n const totalLockedAmount = extraConfigs?.totalLockedAmount ?? new BN(0);\n\n // let defaultPlatformFeeRate = platformFeeRate;\n // let defaultPlatformVestingScale = platformVestingScale;\n // if (!platformFeeRate) {\n // const platformData = await this.scope.connection.getAccountInfo(platformId);\n // if (!platformData) this.logAndCreateError(\"platform id not found:\", platformId.toString());\n // const platform = PlatformConfig.decode(platformData!.data);\n // defaultPlatformVestingScale = platform.platformVestingScale;\n // defaultPlatformFeeRate = platform.feeRate;\n // }\n\n const platformData = await this.scope.connection.getAccountInfo(platformId);\n if (!platformData) this.logAndCreateError(\"platform id not found:\", platformId.toString());\n const platform = PlatformConfig.decode(platformData!.data);\n const defaultPlatformVestingScale = platform.platformVestingScale;\n const defaultPlatformFeeRate = platform.feeRate;\n\n const curve = Curve.getCurve(configInfo!.curveType);\n const initParam = curve.getInitParam({\n supply,\n totalFundRaising: totalFundRaisingB,\n totalSell: totalSellA,\n totalLockedAmount,\n migrateFee: configInfo!.migrateFee,\n });\n\n let mintBInfo: ApiV3Token | undefined;\n try {\n mintBInfo = await this.scope.token.getTokenInfo(mintB);\n } catch {\n this.logDebug(\"can not get mintB info from getTokenInfo\");\n }\n\n const poolInfo: LaunchpadPoolInfo = {\n epoch: new BN(896),\n bump: 254,\n status: 0,\n mintDecimalsA: decimals,\n mintDecimalsB: mintBInfo?.decimals ?? mintBDecimals,\n supply,\n totalSellA,\n mintA: new PublicKey(mintA),\n mintB,\n virtualA: initParam.a,\n virtualB: initParam.b,\n realA: LaunchpadPoolInitParam.realA,\n realB: LaunchpadPoolInitParam.realB,\n migrateFee: configInfo!.migrateFee,\n migrateType: migrateType === \"amm\" ? 0 : 1,\n protocolFee: LaunchpadPoolInitParam.protocolFee,\n platformFee: defaultPlatformFeeRate!,\n platformId,\n configId,\n vaultA,\n vaultB,\n creator: this.scope.ownerPubKey,\n totalFundRaisingB,\n vestingSchedule: {\n totalLockedAmount,\n cliffPeriod: new BN(0),\n unlockPeriod: new BN(0),\n startTime: new BN(0),\n totalAllocatedShare: new BN(0),\n },\n mintProgramFlag: toLaunchpadMintProgramFlag({\n mintAProgram: token2022 ? TOKEN_2022_PROGRAM_ID : TOKEN_PROGRAM_ID,\n mintBProgram,\n }),\n cpmmCreatorFeeOn: creatorFeeOn,\n platformVestingShare: defaultPlatformVestingScale ?? new BN(0),\n };\n\n const initCurve = Curve.getCurve(configInfo!.curveType);\n const { c } = initCurve.getInitParam({\n supply: poolInfo.supply,\n totalFundRaising: poolInfo.totalFundRaisingB,\n totalLockedAmount,\n totalSell: configInfo!.curveType === 0 ? poolInfo.totalSellA : new BN(0),\n migrateFee: configInfo!.migrateFee,\n });\n\n try {\n Curve.checkParam({\n supply: poolInfo.supply,\n totalFundRaising: poolInfo.totalFundRaisingB,\n totalSell: c,\n totalLockedAmount,\n decimals: poolInfo.mintDecimalsA,\n config: configInfo!,\n migrateType,\n });\n this.logDebug(\"check init params success\");\n } catch (e: any) {\n this.logAndCreateError(`check create mint params failed, ${e.message}`);\n }\n\n txBuilder.addInstruction({\n instructions: [\n token2022\n ? initializeWithToken2022(\n programId,\n feePayer ?? this.scope.ownerPubKey,\n this.scope.ownerPubKey,\n configId,\n platformId,\n authProgramId,\n poolId,\n mintA,\n mintB,\n vaultA,\n vaultB,\n mintBProgram,\n\n decimals,\n name,\n symbol,\n uri || \"https://\",\n\n {\n type:\n curType === 0\n ? \"ConstantCurve\"\n : curType === 1\n ? \"FixedCurve\"\n : curType === 2\n ? \"LinearCurve\"\n : \"ConstantCurve\",\n totalSellA,\n migrateType,\n supply,\n totalFundRaisingB,\n },\n totalLockedAmount,\n extraConfigs?.cliffPeriod ?? new BN(0),\n extraConfigs?.unlockPeriod ?? new BN(0),\n creatorFeeOn,\n transferFeeExtensionParams,\n platformAllowConfig ? getPdaPlatformAllowConfig(programId, platformId, configId).publicKey : undefined,\n )\n : initializeV2(\n programId,\n feePayer ?? this.scope.ownerPubKey,\n this.scope.ownerPubKey,\n configId,\n platformId,\n authProgramId,\n poolId,\n mintA,\n mintB,\n vaultA,\n vaultB,\n metaId,\n mintBProgram,\n\n decimals,\n name,\n symbol,\n uri || \"https://\",\n\n {\n type:\n curType === 0\n ? \"ConstantCurve\"\n : curType === 1\n ? \"FixedCurve\"\n : curType === 2\n ? \"LinearCurve\"\n : \"ConstantCurve\",\n totalSellA,\n migrateType,\n supply,\n totalFundRaisingB,\n },\n totalLockedAmount,\n extraConfigs?.cliffPeriod ?? new BN(0),\n extraConfigs?.unlockPeriod ?? new BN(0),\n creatorFeeOn,\n platformAllowConfig ? getPdaPlatformAllowConfig(programId, platformId, configId).publicKey : undefined,\n ),\n ],\n });\n\n const epoch = token2022 ? await this.scope.connection.getEpochInfo() : undefined;\n const fee = transferFeeExtensionParams\n ? {\n epoch: BigInt(epoch?.epoch || 0),\n maximumFee: BigInt(transferFeeExtensionParams?.maxinumFee.toString() ?? 0),\n transferFeeBasisPoints: transferFeeExtensionParams?.transferFeeBasePoints ?? 0,\n }\n : undefined;\n\n let swapInfo: SwapInfoReturn = {\n amountA: {\n amount: new BN(0),\n fee: undefined,\n expirationTime: undefined,\n },\n amountB: new BN(0),\n splitFee: {\n platformFee: new BN(0),\n shareFee: new BN(0),\n protocolFee: new BN(0),\n creatorFee: new BN(0),\n },\n transferFeeB: undefined,\n };\n let splitIns;\n if (extraSigners?.length) txBuilder.addInstruction({ signers: extraSigners });\n if (!extraConfigs.createOnly) {\n const { builder, extInfo } = await this.buyToken({\n programId,\n authProgramId,\n mintAProgram: token2022 ? TOKEN_2022_PROGRAM_ID : undefined,\n mintA,\n mintB,\n mintBProgram,\n transferFeeConfigB,\n skipCheckMintB: true,\n poolInfo,\n buyAmount,\n minMintAAmount,\n shareFeeRate: extraConfigs.shareFeeRate,\n shareFeeReceiver: extraConfigs.shareFeeReceiver,\n configInfo,\n platformFeeRate: defaultPlatformFeeRate,\n slippage,\n associatedOnly,\n checkCreateATAOwner,\n skipCheckMintA: !fee,\n transferFeeConfigA: fee\n ? {\n transferFeeConfigAuthority: authProgramId,\n withdrawWithheldAuthority: authProgramId,\n withheldAmount: BigInt(0),\n olderTransferFee: fee,\n newerTransferFee: fee,\n }\n : undefined,\n fromCreate: true,\n });\n txBuilder.addInstruction({ ...builder.AllTxData });\n swapInfo = { ...extInfo };\n splitIns =\n (this.scope.cluster === \"devnet\" || txVersion === TxVersion.LEGACY) && extraConfigs.shareFeeReceiver\n ? [builder.allInstructions[0]]\n : undefined;\n }\n\n txBuilder.addTipInstruction(txTipConfig);\n\n if (txVersion === TxVersion.V0)\n return txBuilder.sizeCheckBuildV0({\n computeBudgetConfig,\n swapInfo,\n splitIns,\n address: {\n ...poolInfo,\n poolId,\n },\n }) as Promise<\n MakeMultiTxData<T, { address: LaunchpadPoolInfo & { poolId: PublicKey }; swapInfo: SwapInfoReturnExt }>\n >;\n return txBuilder.sizeCheckBuild({\n computeBudgetConfig,\n swapInfo,\n splitIns,\n address: {\n ...poolInfo,\n poolId,\n },\n }) as Promise<\n MakeMultiTxData<T, { address: LaunchpadPoolInfo & { poolId: PublicKey }; swapInfo: SwapInfoReturnExt }>\n >;\n }\n\n public async buyToken<T extends TxVersion>({\n programId = LAUNCHPAD_PROGRAM,\n authProgramId,\n mintA,\n mintAProgram = TOKEN_PROGRAM_ID,\n mintB = NATIVE_MINT,\n poolInfo: propPoolInfo,\n\n configInfo: propConfigInfo,\n platformFeeRate,\n\n txVersion,\n computeBudgetConfig,\n txTipConfig,\n feePayer,\n buyAmount,\n minMintAAmount: propMinMintAAmount,\n slippage,\n\n shareFeeRate = new BN(0),\n shareFeeReceiver,\n\n associatedOnly = true,\n checkCreateATAOwner = false,\n fromCreate = false,\n transferFeeConfigA: propsTransferFeeConfigA,\n skipCheckMintA = false,\n mintBProgram: propsMintBProgram,\n transferFeeConfigB: propsTransferFeeConfigB,\n skipCheckMintB = false,\n }: BuyToken<T>): Promise<MakeTxData<T, SwapInfoReturnExt>> {\n if (buyAmount.lte(new BN(0))) this.logAndCreateError(\"buy amount should gt 0:\", buyAmount.toString());\n const txBuilder = this.createTxBuilder(feePayer);\n const { publicKey: poolId } = getPdaLaunchpadPoolId(programId, mintA, mintB);\n authProgramId = authProgramId ?? getPdaLaunchpadAuth(programId).publicKey;\n\n let transferFeeConfigA = propsTransferFeeConfigA;\n if (!skipCheckMintA) {\n if (!transferFeeConfigA) {\n const mintInfo = await this.scope.connection.getAccountInfo(mintA);\n if (mintInfo && mintInfo.owner.equals(TOKEN_2022_PROGRAM_ID)) {\n mintAProgram = mintInfo.owner;\n const onlineData = unpackMint(mintA, mintInfo, mintAProgram);\n transferFeeConfigA = getTransferFeeConfig(onlineData) || undefined;\n }\n } else {\n mintAProgram = TOKEN_2022_PROGRAM_ID;\n }\n }\n\n const { mintBProgram, transferFeeConfigB } = await this.getMintBTokenInfo({\n mintB,\n mintBProgram: propsMintBProgram,\n transferFeeConfigB: propsTransferFeeConfigB,\n skipCheckMintB,\n });\n\n const userTokenAccountA = this.scope.account.getAssociatedTokenAccount(mintA, mintAProgram);\n\n const isMintBSol = mintB.equals(NATIVE_MINT);\n const useAta = fromCreate && isMintBSol;\n let userTokenAccountB: PublicKey | null = useAta\n ? this.scope.account.getAssociatedTokenAccount(mintB, mintBProgram)\n : null;\n const mintBUseSOLBalance = isMintBSol;\n\n txBuilder.addInstruction({\n instructions: [\n createAssociatedTokenAccountIdempotentInstruction(\n this.scope.ownerPubKey,\n userTokenAccountA,\n this.scope.ownerPubKey,\n mintA,\n mintAProgram,\n ),\n ...(useAta\n ? [\n createAssociatedTokenAccountIdempotentInstruction(\n this.scope.ownerPubKey,\n userTokenAccountB!,\n this.scope.ownerPubKey,\n mintB,\n mintBProgram,\n ),\n SystemProgram.transfer({\n fromPubkey: this.scope.ownerPubKey,\n toPubkey: userTokenAccountB!,\n lamports: BigInt(buyAmount.toString()),\n }),\n createSyncNativeInstruction(userTokenAccountB!),\n ]\n : []),\n ],\n });\n\n if (!useAta) {\n const { account: _ownerTokenAccountB, instructionParams: _tokenAccountBInstruction } =\n await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: mintBProgram,\n mint: mintB,\n owner: this.scope.ownerPubKey,\n createInfo: mintBUseSOLBalance\n ? {\n payer: this.scope.ownerPubKey!,\n amount: buyAmount,\n }\n : undefined,\n skipCloseAccount: !mintBUseSOLBalance,\n notUseTokenAccount: mintBUseSOLBalance,\n associatedOnly: mintBUseSOLBalance ? false : associatedOnly,\n checkCreateATAOwner,\n });\n if (_ownerTokenAccountB) userTokenAccountB = _ownerTokenAccountB;\n txBuilder.addInstruction(_tokenAccountBInstruction || {});\n }\n if (!userTokenAccountB)\n this.logAndCreateError(\n `cannot found mintB(${mintB.toBase58()}) buy token accounts`,\n \"tokenAccounts\",\n this.scope.account.tokenAccounts,\n );\n let poolInfo = propPoolInfo;\n if (!poolInfo) {\n const poolData = await this.scope.connection.getAccountInfo(poolId, { commitment: \"processed\" });\n if (!poolData) this.logAndCreateError(\"cannot found pool:\", poolId.toBase58());\n poolInfo = LaunchpadPool.decode(poolData!.data);\n }\n\n let configInfo = propConfigInfo;\n const allData = await getMultipleAccountsInfoWithCustomFlags(\n this.scope.connection,\n [configInfo ? undefined : poolInfo.configId, poolInfo.platformId]\n .filter(Boolean)\n .map((key) => ({ pubkey: key! })),\n );\n if (!configInfo) {\n const data = allData.find((d) => d.pubkey.equals(poolInfo!.configId));\n if (!data || !data.accountInfo) this.logAndCreateError(\"config not found: \", poolInfo.configId.toBase58());\n configInfo = LaunchpadConfig.decode(data!.accountInfo!.data);\n }\n const platformData = allData.find((d) => d.pubkey.equals(poolInfo!.platformId));\n if (!platformData || !platformData.accountInfo)\n this.logAndCreateError(\"platform info not found: \", poolInfo.configId.toBase58());\n const platformInfo = PlatformConfig.decode(platformData!.accountInfo!.data);\n platformFeeRate = platformFeeRate || platformInfo.feeRate;\n\n const calculatedAmount = Curve.buyExactIn({\n poolInfo,\n amountB: buyAmount,\n protocolFeeRate: configInfo.tradeFeeRate,\n platformFeeRate,\n curveType: configInfo.curveType,\n shareFeeRate,\n creatorFeeRate: platformInfo.creatorFeeRate,\n transferFeeConfigA,\n transferFeeConfigB,\n slot: await this.scope.connection.getSlot(),\n });\n\n const decimalAmountA = new Decimal(calculatedAmount.amountA.amount.toString()).sub(\n calculatedAmount.amountA.fee?.toString() ?? 0,\n );\n\n const multiplier = slippage\n ? new Decimal(SLIPPAGE_UNIT.sub(slippage).toNumber() / SLIPPAGE_UNIT.toNumber()).clampedTo(0, 1)\n : new Decimal(1);\n\n const minMintAAmount =\n propMinMintAAmount ??\n (slippage\n ? new BN(decimalAmountA.mul(multiplier).toFixed(0))\n : calculatedAmount.amountA.amount.sub(calculatedAmount.amountA.fee ?? new BN(0)));\n\n if (calculatedAmount.amountB.lt(buyAmount)) {\n console.log(\n `maximum ${mintA.toBase58()} amount can buy is ${calculatedAmount.amountA.toString()}, input ${mintB.toBase58()} amount: ${calculatedAmount.amountB.toString()}`,\n );\n }\n\n const shareATA = shareFeeReceiver ? getATAAddress(shareFeeReceiver, mintB, mintBProgram).publicKey : undefined;\n if (shareATA) {\n txBuilder.addInstruction({\n instructions: [\n createAssociatedTokenAccountIdempotentInstruction(\n this.scope.ownerPubKey,\n shareATA,\n shareFeeReceiver!,\n mintB,\n mintBProgram,\n ),\n ],\n });\n }\n txBuilder.addInstruction({\n instructions: [\n buyExactInInstruction(\n programId,\n this.scope.ownerPubKey,\n authProgramId,\n poolInfo.configId,\n poolInfo.platformId,\n poolId,\n userTokenAccountA!,\n userTokenAccountB!,\n poolInfo.vaultA,\n poolInfo.vaultB,\n mintA,\n mintB,\n mintAProgram,\n mintBProgram,\n\n getPdaPlatformVault(programId, poolInfo.platformId, mintB).publicKey,\n getPdaCreatorVault(programId, poolInfo.creator, mintB).publicKey,\n\n calculatedAmount.amountB.lt(buyAmount) ? calculatedAmount.amountB : buyAmount,\n minMintAAmount,\n shareFeeRate,\n shareATA,\n ),\n ],\n });\n\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n return txBuilder.versionBuild<SwapInfoReturnExt>({\n txVersion,\n extInfo: {\n ...calculatedAmount,\n decimalOutAmount: decimalAmountA,\n minDecimalOutAmount: new Decimal(minMintAAmount.toString()),\n },\n }) as Promise<MakeTxData<T, SwapInfoReturnExt>>;\n }\n\n public async buyTokenExactOut<T extends TxVersion>({\n programId = LAUNCHPAD_PROGRAM,\n authProgramId,\n mintA,\n mintAProgram = TOKEN_PROGRAM_ID,\n mintB = NATIVE_MINT,\n poolInfo: propPoolInfo,\n\n configInfo: propConfigInfo,\n transferFeeConfigA: propsTransferFeeConfigA,\n platformFeeRate,\n\n txVersion,\n computeBudgetConfig,\n txTipConfig,\n feePayer,\n maxBuyAmount,\n outAmount,\n slippage,\n\n shareFeeRate = new BN(0),\n shareFeeReceiver,\n\n associatedOnly = true,\n checkCreateATAOwner = false,\n skipCheckMintA = false,\n mintBProgram: propsMintBProgram,\n transferFeeConfigB: propsTransferFeeConfigB,\n skipCheckMintB = false,\n }: BuyTokenExactOut<T>): Promise<MakeTxData<T, { outAmount: BN; maxSpentAmount: BN }>> {\n if (outAmount.lte(new BN(0))) this.logAndCreateError(\"out amount should gt 0:\", outAmount.toString());\n const txBuilder = this.createTxBuilder(feePayer);\n const { publicKey: poolId } = getPdaLaunchpadPoolId(programId, mintA, mintB);\n authProgramId = authProgramId ?? getPdaLaunchpadAuth(programId).publicKey;\n\n let poolInfo = propPoolInfo;\n if (!poolInfo) {\n const poolData = await this.scope.connection.getAccountInfo(poolId, { commitment: \"processed\" });\n if (!poolData) this.logAndCreateError(\"cannot found pool:\", poolId.toBase58());\n poolInfo = LaunchpadPool.decode(poolData!.data);\n }\n\n let configInfo = propConfigInfo;\n const allData = await getMultipleAccountsInfoWithCustomFlags(\n this.scope.connection,\n [configInfo ? undefined : poolInfo.configId, poolInfo.platformId]\n .filter(Boolean)\n .map((key) => ({ pubkey: key! })),\n );\n if (!configInfo) {\n const data = allData.find((d) => d.pubkey.equals(poolInfo!.configId));\n if (!data || !data.accountInfo) this.logAndCreateError(\"config not found: \", poolInfo.configId.toBase58());\n configInfo = LaunchpadConfig.decode(data!.accountInfo!.data);\n }\n const platformData = allData.find((d) => d.pubkey.equals(poolInfo!.platformId));\n if (!platformData || !platformData.accountInfo)\n this.logAndCreateError(\"platform info not found: \", poolInfo.configId.toBase58());\n const platformInfo = PlatformConfig.decode(platformData!.accountInfo!.data);\n platformFeeRate = platformFeeRate || platformInfo.feeRate;\n\n let transferFeeConfigA = propsTransferFeeConfigA;\n if (!skipCheckMintA) {\n if (!transferFeeConfigA) {\n const mintInfo = await this.scope.connection.getAccountInfo(mintA);\n if (mintInfo && mintInfo.owner.equals(TOKEN_2022_PROGRAM_ID)) {\n mintAProgram = mintInfo.owner;\n const onlineData = unpackMint(mintA, mintInfo, mintAProgram);\n transferFeeConfigA = getTransferFeeConfig(onlineData) || undefined;\n }\n } else {\n mintAProgram = TOKEN_2022_PROGRAM_ID;\n }\n }\n\n const { mintBProgram, transferFeeConfigB } = await this.getMintBTokenInfo({\n mintB,\n mintBProgram: propsMintBProgram,\n transferFeeConfigB: propsTransferFeeConfigB,\n skipCheckMintB,\n });\n\n const calculatedAmount = Curve.buyExactOut({\n poolInfo,\n amountA: outAmount,\n protocolFeeRate: configInfo.tradeFeeRate,\n platformFeeRate,\n curveType: configInfo.curveType,\n shareFeeRate,\n creatorFeeRate: platformInfo.creatorFeeRate,\n transferFeeConfigA,\n transferFeeConfigB,\n slot: await this.scope.connection.getSlot(),\n });\n\n const decimalAmountB = new Decimal(calculatedAmount.amountB.toString());\n const multiplier = slippage\n ? new Decimal(SLIPPAGE_UNIT.add(slippage).toNumber() / SLIPPAGE_UNIT.toNumber()).clampedTo(\n 0,\n Number.MIN_SAFE_INTEGER,\n )\n : new Decimal(1);\n\n const maxAmountB =\n maxBuyAmount ?? slippage ? new BN(decimalAmountB.mul(multiplier).toFixed(0)) : calculatedAmount.amountB;\n\n const userTokenAccountA = this.scope.account.getAssociatedTokenAccount(mintA, mintAProgram);\n let userTokenAccountB: PublicKey | null = null;\n\n const mintBUseSOLBalance = mintB.equals(NATIVE_MINT);\n\n txBuilder.addInstruction({\n instructions: [\n createAssociatedTokenAccountIdempotentInstruction(\n this.scope.ownerPubKey,\n userTokenAccountA,\n this.scope.ownerPubKey,\n mintA,\n mintAProgram,\n ),\n ],\n });\n\n const { account: _ownerTokenAccountB, instructionParams: _tokenAccountBInstruction } =\n await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: mintBProgram,\n mint: mintB,\n owner: this.scope.ownerPubKey,\n createInfo: mintBUseSOLBalance\n ? {\n payer: this.scope.ownerPubKey!,\n amount: calculatedAmount.amountB,\n }\n : undefined,\n skipCloseAccount: !mintBUseSOLBalance,\n notUseTokenAccount: mintBUseSOLBalance,\n associatedOnly: mintBUseSOLBalance ? false : associatedOnly,\n checkCreateATAOwner,\n });\n if (_ownerTokenAccountB) userTokenAccountB = _ownerTokenAccountB;\n txBuilder.addInstruction(_tokenAccountBInstruction || {});\n if (userTokenAccountB === undefined)\n this.logAndCreateError(\n `cannot found mintB(${mintB.toBase58()}) token accounts`,\n \"tokenAccounts\",\n this.scope.account.tokenAccounts,\n );\n\n const shareATA = shareFeeReceiver ? getATAAddress(shareFeeReceiver, mintB, mintBProgram).publicKey : undefined;\n if (shareATA) {\n txBuilder.addInstruction({\n instructions: [\n createAssociatedTokenAccountIdempotentInstruction(\n this.scope.ownerPubKey,\n shareATA,\n shareFeeReceiver!,\n mintB,\n mintBProgram,\n ),\n ],\n });\n }\n\n txBuilder.addInstruction({\n instructions: [\n buyExactOutInstruction(\n programId,\n\n this.scope.ownerPubKey,\n authProgramId,\n poolInfo.configId,\n poolInfo.platformId,\n poolId,\n userTokenAccountA!,\n userTokenAccountB!,\n poolInfo.vaultA,\n poolInfo.vaultB,\n mintA,\n mintB,\n mintAProgram,\n mintBProgram,\n\n getPdaPlatformVault(programId, poolInfo.platformId, mintB).publicKey,\n getPdaCreatorVault(programId, poolInfo.creator, mintB).publicKey,\n\n outAmount,\n maxAmountB,\n shareFeeRate,\n shareATA,\n ),\n ],\n });\n\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n\n return txBuilder.versionBuild<{ outAmount: BN; maxSpentAmount: BN }>({\n txVersion,\n extInfo: {\n maxSpentAmount: maxAmountB,\n outAmount,\n },\n }) as Promise<MakeTxData<T, { outAmount: BN; maxSpentAmount: BN }>>;\n }\n\n public async sellToken<T extends TxVersion>({\n programId = LAUNCHPAD_PROGRAM,\n authProgramId,\n mintAProgram = TOKEN_PROGRAM_ID,\n mintA,\n mintB = NATIVE_MINT,\n poolInfo: propPoolInfo,\n configInfo: propConfigInfo,\n platformFeeRate,\n txVersion,\n computeBudgetConfig,\n txTipConfig,\n feePayer,\n sellAmount,\n minAmountB: propMinAmountB,\n slippage,\n\n shareFeeRate = new BN(0),\n shareFeeReceiver,\n\n associatedOnly = true,\n checkCreateATAOwner = false,\n skipCheckMintA = false,\n mintBProgram: propsMintBProgram,\n transferFeeConfigB: propsTransferFeeConfigB,\n skipCheckMintB = false,\n }: SellToken<T>): Promise<MakeTxData<T, { outAmount: BN }>> {\n authProgramId = authProgramId ?? getPdaLaunchpadAuth(programId).publicKey;\n const txBuilder = this.createTxBuilder(feePayer);\n\n if (sellAmount.lte(new BN(0))) this.logAndCreateError(\"sell amount should be gt 0\");\n\n const { publicKey: poolId } = getPdaLaunchpadPoolId(programId, mintA, mintB);\n\n let transferFeeConfigA: TransferFeeConfig | undefined;\n if (!skipCheckMintA) {\n const mintInfo = await this.scope.connection.getAccountInfo(mintA);\n if (mintInfo && mintInfo.owner.equals(TOKEN_2022_PROGRAM_ID)) {\n mintAProgram = mintInfo.owner;\n const onlineData = unpackMint(mintA, mintInfo, mintAProgram);\n transferFeeConfigA = getTransferFeeConfig(onlineData) || undefined;\n }\n }\n\n const { mintBProgram, transferFeeConfigB } = await this.getMintBTokenInfo({\n mintB,\n mintBProgram: propsMintBProgram,\n transferFeeConfigB: propsTransferFeeConfigB,\n skipCheckMintB,\n });\n\n let userTokenAccountA: PublicKey | null = null;\n let userTokenAccountB: PublicKey | null = null;\n\n const mintBUseSOLBalance = mintB.equals(NATIVE_MINT);\n\n const { account: _ownerTokenAccountA, instructionParams: _tokenAccountAInstruction } =\n await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: mintAProgram,\n mint: mintA,\n owner: this.scope.ownerPubKey,\n\n createInfo: undefined,\n skipCloseAccount: true,\n notUseTokenAccount: false,\n associatedOnly,\n checkCreateATAOwner,\n });\n if (_ownerTokenAccountA) userTokenAccountA = _ownerTokenAccountA;\n txBuilder.addInstruction(_tokenAccountAInstruction || {});\n\n if (userTokenAccountA === undefined)\n this.logAndCreateError(\"cannot found mintA token accounts\", \"tokenAccounts\", this.scope.account.tokenAccounts);\n const { account: _ownerTokenAccountB, instructionParams: _tokenAccountBInstruction } =\n await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: mintBProgram,\n mint: mintB,\n owner: this.scope.ownerPubKey,\n\n createInfo: mintBUseSOLBalance\n ? {\n payer: this.scope.ownerPubKey!,\n amount: 0,\n }\n : undefined,\n skipCloseAccount: !mintBUseSOLBalance,\n notUseTokenAccount: mintBUseSOLBalance,\n associatedOnly: mintBUseSOLBalance ? false : associatedOnly,\n checkCreateATAOwner,\n });\n if (_ownerTokenAccountB) userTokenAccountB = _ownerTokenAccountB;\n txBuilder.addInstruction(_tokenAccountBInstruction || {});\n\n if (userTokenAccountB === undefined)\n this.logAndCreateError(\"cannot found mintB token accounts\", \"tokenAccounts\", this.scope.account.tokenAccounts);\n\n let poolInfo = propPoolInfo;\n if (!poolInfo) {\n const poolData = await this.scope.connection.getAccountInfo(poolId, { commitment: \"processed\" });\n if (!poolData) this.logAndCreateError(\"cannot found pool\", poolId.toBase58());\n poolInfo = LaunchpadPool.decode(poolData!.data);\n }\n let configInfo = propConfigInfo;\n const allData = await getMultipleAccountsInfoWithCustomFlags(\n this.scope.connection,\n [configInfo ? undefined : poolInfo.configId, poolInfo.platformId]\n .filter(Boolean)\n .map((key) => ({ pubkey: key! })),\n );\n if (!configInfo) {\n const data = allData.find((d) => d.pubkey.equals(poolInfo!.configId));\n if (!data || !data.accountInfo) this.logAndCreateError(\"config not found: \", poolInfo.configId.toBase58());\n configInfo = LaunchpadConfig.decode(data!.accountInfo!.data);\n }\n\n const platformData = allData.find((d) => d.pubkey.equals(poolInfo!.platformId));\n if (!platformData || !platformData.accountInfo)\n this.logAndCreateError(\"platform info not found: \", poolInfo.configId.toBase58());\n const platformInfo = PlatformConfig.decode(platformData!.accountInfo!.data);\n platformFeeRate = platformFeeRate || platformInfo.feeRate;\n\n const calculatedAmount = Curve.sellExactIn({\n poolInfo,\n amountA: sellAmount,\n protocolFeeRate: configInfo.tradeFeeRate,\n platformFeeRate,\n curveType: configInfo.curveType,\n shareFeeRate,\n creatorFeeRate: platformInfo.creatorFeeRate,\n transferFeeConfigA,\n transferFeeConfigB,\n slot: await this.scope.connection.getSlot(),\n });\n\n const decimalAmountB = new Decimal(calculatedAmount.amountB.toString());\n const multiplier = slippage\n ? new Decimal(SLIPPAGE_UNIT.sub(slippage).toNumber() / SLIPPAGE_UNIT.toNumber()).clampedTo(0, 1)\n : new Decimal(1);\n\n const minAmountB =\n propMinAmountB ?? (slippage ? new BN(decimalAmountB.mul(multiplier).toFixed(0)) : calculatedAmount.amountB);\n\n if (minAmountB.lte(new BN(0))) this.logAndCreateError(`out ${mintB.toBase58()} amount should be gt 0`);\n\n const shareATA = shareFeeReceiver ? getATAAddress(shareFeeReceiver, mintB, mintBProgram).publicKey : undefined;\n if (shareATA) {\n txBuilder.addInstruction({\n instructions: [\n createAssociatedTokenAccountIdempotentInstruction(\n this.scope.ownerPubKey,\n shareATA,\n shareFeeReceiver!,\n mintB,\n mintBProgram,\n ),\n ],\n });\n }\n\n txBuilder.addInstruction({\n instructions: [\n sellExactInInstruction(\n programId,\n this.scope.ownerPubKey,\n authProgramId,\n poolInfo.configId,\n poolInfo.platformId,\n poolId,\n userTokenAccountA!,\n userTokenAccountB!,\n poolInfo.vaultA,\n poolInfo.vaultB,\n mintA,\n mintB,\n mintAProgram,\n mintBProgram,\n\n getPdaPlatformVault(programId, poolInfo.platformId, mintB).publicKey,\n getPdaCreatorVault(programId, poolInfo.creator, mintB).publicKey,\n\n calculatedAmount.amountA.amount.lt(sellAmount) ? calculatedAmount.amountA.amount : sellAmount,\n minAmountB,\n shareFeeRate,\n shareATA,\n ),\n ],\n });\n\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n\n return txBuilder.versionBuild<{ outAmount: BN }>({\n txVersion,\n extInfo: {\n outAmount: minAmountB,\n },\n }) as Promise<MakeTxData<T, { outAmount: BN }>>;\n }\n\n public async sellTokenExactOut<T extends TxVersion>({\n programId = LAUNCHPAD_PROGRAM,\n authProgramId,\n mintAProgram = TOKEN_PROGRAM_ID,\n mintA,\n mintB = NATIVE_MINT,\n poolInfo: propPoolInfo,\n configInfo: propConfigInfo,\n platformFeeRate,\n txVersion,\n computeBudgetConfig,\n txTipConfig,\n feePayer,\n inAmount,\n maxSellAmount,\n slippage,\n\n shareFeeRate = new BN(0),\n shareFeeReceiver,\n\n associatedOnly = true,\n checkCreateATAOwner = false,\n skipCheckMintA = false,\n mintBProgram: propsMintBProgram,\n transferFeeConfigB: propsTransferFeeConfigB,\n skipCheckMintB = false,\n }: SellTokenExactOut<T>): Promise<MakeTxData<T, { maxSellAmount: BN }>> {\n authProgramId = authProgramId ?? getPdaLaunchpadAuth(programId).publicKey;\n const txBuilder = this.createTxBuilder(feePayer);\n\n if (maxSellAmount?.lte(new BN(0))) this.logAndCreateError(\"max sell amount should be gt 0\");\n\n const { publicKey: poolId } = getPdaLaunchpadPoolId(programId, mintA, mintB);\n\n let transferFeeConfigA: TransferFeeConfig | undefined;\n if (!skipCheckMintA) {\n const mintInfo = await this.scope.connection.getAccountInfo(mintA);\n if (mintInfo && mintInfo.owner.equals(TOKEN_2022_PROGRAM_ID)) {\n mintAProgram = mintInfo.owner;\n const onlineData = unpackMint(mintA, mintInfo, mintAProgram);\n transferFeeConfigA = getTransferFeeConfig(onlineData) || undefined;\n }\n }\n\n const { mintBProgram, transferFeeConfigB } = await this.getMintBTokenInfo({\n mintB,\n mintBProgram: propsMintBProgram,\n transferFeeConfigB: propsTransferFeeConfigB,\n skipCheckMintB,\n });\n\n let userTokenAccountA: PublicKey | null = null;\n let userTokenAccountB: PublicKey | null = null;\n\n const mintBUseSOLBalance = mintB.equals(NATIVE_MINT);\n\n const { account: _ownerTokenAccountA, instructionParams: _tokenAccountAInstruction } =\n await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: mintAProgram,\n mint: mintA,\n owner: this.scope.ownerPubKey,\n\n createInfo: undefined,\n skipCloseAccount: true,\n notUseTokenAccount: false,\n associatedOnly,\n checkCreateATAOwner,\n });\n if (_ownerTokenAccountA) userTokenAccountA = _ownerTokenAccountA;\n txBuilder.addInstruction(_tokenAccountAInstruction || {});\n\n if (userTokenAccountA === undefined)\n this.logAndCreateError(\"cannot found mintA token accounts\", \"tokenAccounts\", this.scope.account.tokenAccounts);\n\n const { account: _ownerTokenAccountB, instructionParams: _tokenAccountBInstruction } =\n await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: mintBProgram,\n mint: mintB,\n owner: this.scope.ownerPubKey,\n\n createInfo: mintBUseSOLBalance\n ? {\n payer: this.scope.ownerPubKey!,\n amount: 0,\n }\n : undefined,\n skipCloseAccount: !mintBUseSOLBalance,\n notUseTokenAccount: mintBUseSOLBalance,\n associatedOnly: mintBUseSOLBalance ? false : associatedOnly,\n checkCreateATAOwner,\n });\n if (_ownerTokenAccountB) userTokenAccountB = _ownerTokenAccountB;\n txBuilder.addInstruction(_tokenAccountBInstruction || {});\n\n if (userTokenAccountB === undefined)\n this.logAndCreateError(\"cannot found mintB token accounts\", \"tokenAccounts\", this.scope.account.tokenAccounts);\n\n let poolInfo = propPoolInfo;\n if (!poolInfo) {\n const poolData = await this.scope.connection.getAccountInfo(poolId, { commitment: \"processed\" });\n if (!poolData) this.logAndCreateError(\"cannot found pool\", poolId.toBase58());\n poolInfo = LaunchpadPool.decode(poolData!.data);\n }\n\n let configInfo = propConfigInfo;\n const allData = await getMultipleAccountsInfoWithCustomFlags(\n this.scope.connection,\n [configInfo ? undefined : poolInfo.configId, poolInfo.platformId]\n .filter(Boolean)\n .map((key) => ({ pubkey: key! })),\n );\n if (!configInfo) {\n const data = allData.find((d) => d.pubkey.equals(poolInfo!.configId));\n if (!data || !data.accountInfo) this.logAndCreateError(\"config not found: \", poolInfo.configId.toBase58());\n configInfo = LaunchpadConfig.decode(data!.accountInfo!.data);\n }\n\n const platformData = allData.find((d) => d.pubkey.equals(poolInfo!.platformId));\n if (!platformData || !platformData.accountInfo)\n this.logAndCreateError(\"platform info not found: \", poolInfo.configId.toBase58());\n const platformInfo = PlatformConfig.decode(platformData!.accountInfo!.data);\n platformFeeRate = platformFeeRate || platformInfo.feeRate;\n\n const calculatedAmount = Curve.sellExactOut({\n poolInfo,\n amountB: inAmount,\n protocolFeeRate: configInfo.tradeFeeRate,\n platformFeeRate,\n curveType: configInfo.curveType,\n shareFeeRate,\n creatorFeeRate: platformInfo.creatorFeeRate,\n transferFeeConfigA,\n transferFeeConfigB,\n slot: await this.scope.connection.getSlot(),\n });\n\n const decimalAmountA = new Decimal(calculatedAmount.amountA.amount.toString());\n const multiplier = slippage\n ? new Decimal(SLIPPAGE_UNIT.add(slippage).toNumber() / SLIPPAGE_UNIT.toNumber()).clampedTo(\n 0,\n Number.MAX_SAFE_INTEGER,\n )\n : new Decimal(1);\n\n const maxSellAmountA =\n maxSellAmount ?? slippage ? new BN(decimalAmountA.mul(multiplier).toFixed(0)) : calculatedAmount.amountA.amount;\n\n const shareATA = shareFeeReceiver ? getATAAddress(shareFeeReceiver, mintB, mintBProgram).publicKey : undefined;\n if (shareATA) {\n txBuilder.addInstruction({\n instructions: [\n createAssociatedTokenAccountIdempotentInstruction(\n this.scope.ownerPubKey,\n shareATA,\n shareFeeReceiver!,\n mintB,\n mintBProgram,\n ),\n ],\n });\n }\n\n txBuilder.addInstruction({\n instructions: [\n sellExactOut(\n programId,\n this.scope.ownerPubKey,\n authProgramId,\n poolInfo.configId,\n poolInfo.platformId,\n poolId,\n userTokenAccountA!,\n userTokenAccountB!,\n poolInfo.vaultA,\n poolInfo.vaultB,\n mintA,\n mintB,\n mintAProgram,\n mintBProgram,\n\n getPdaPlatformVault(programId, poolInfo.platformId, mintB).publicKey,\n getPdaCreatorVault(programId, poolInfo.creator, mintB).publicKey,\n\n inAmount,\n maxSellAmountA,\n\n shareFeeRate,\n shareATA,\n ),\n ],\n });\n\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n\n return txBuilder.versionBuild<{ maxSellAmount: BN }>({\n txVersion,\n extInfo: {\n maxSellAmount: maxSellAmountA,\n },\n }) as Promise<MakeTxData<T, { maxSellAmount: BN }>>;\n }\n\n public async createPlatformConfig<T extends TxVersion>({\n programId = LAUNCHPAD_PROGRAM,\n platformAdmin,\n platformClaimFeeWallet,\n platformLockNftWallet,\n platformVestingWallet,\n cpConfigId,\n migrateCpLockNftScale,\n transferFeeExtensionAuth,\n creatorFeeRate,\n feeRate,\n name,\n web,\n img,\n platformVestingScale = new BN(0), // max: 1_000_000 = 100%\n txVersion,\n computeBudgetConfig,\n txTipConfig,\n feePayer,\n }: CreatePlatform<T>): Promise<MakeTxData<T, { platformId: PublicKey }>> {\n const txBuilder = this.createTxBuilder(feePayer);\n\n const { publicKey: platformId } = getPdaPlatformId(programId, platformAdmin);\n\n txBuilder.addInstruction({\n instructions: [\n createPlatformConfig(\n programId,\n platformAdmin,\n platformClaimFeeWallet,\n platformLockNftWallet,\n platformVestingWallet,\n platformId,\n\n cpConfigId,\n\n transferFeeExtensionAuth,\n\n migrateCpLockNftScale,\n\n feeRate,\n creatorFeeRate,\n name,\n web,\n img,\n platformVestingScale,\n ),\n ],\n });\n\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n\n return txBuilder.versionBuild({\n txVersion,\n extInfo: {\n platformId,\n },\n }) as Promise<MakeTxData<T, { platformId: PublicKey }>>;\n }\n\n public async updatePlatformConfig<T extends TxVersion>({\n programId = LAUNCHPAD_PROGRAM,\n platformAdmin,\n platformId: propsPlatformId,\n updateInfo,\n txVersion,\n computeBudgetConfig,\n txTipConfig,\n feePayer,\n }: UpdatePlatform<T>): Promise<MakeTxData> {\n const txBuilder = this.createTxBuilder(feePayer);\n\n const platformId = propsPlatformId ?? getPdaPlatformId(programId, platformAdmin).publicKey;\n\n txBuilder.addInstruction({\n instructions: [updatePlatformConfig(programId, platformAdmin, platformId, updateInfo)],\n });\n\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n\n return txBuilder.versionBuild({\n txVersion,\n }) as Promise<MakeTxData>;\n }\n\n public async createPlatformVestingAccount<T extends TxVersion>({\n programId = LAUNCHPAD_PROGRAM,\n\n platformVestingWallet,\n beneficiary,\n platformId,\n poolId,\n vestingRecord: propsVestingRecord,\n\n txVersion,\n computeBudgetConfig,\n txTipConfig,\n feePayer,\n }: CreatePlatformVestingAccount<T>): Promise<MakeTxData<T>> {\n const txBuilder = this.createTxBuilder(feePayer);\n\n const vestingRecord = propsVestingRecord ?? getPdaVestId(programId, poolId, beneficiary).publicKey;\n\n txBuilder.addInstruction({\n instructions: [\n createPlatformVestingAccountIns(\n programId,\n platformVestingWallet,\n beneficiary,\n platformId,\n poolId,\n vestingRecord,\n ),\n ],\n });\n\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n return txBuilder.versionBuild({\n txVersion,\n }) as Promise<MakeTxData<T>>;\n }\n\n public async claimPlatformFee<T extends TxVersion>({\n programId = LAUNCHPAD_PROGRAM,\n authProgramId,\n platformId,\n poolId,\n platformClaimFeeWallet,\n\n mintB: propsMintB,\n vaultB: propsVaultB,\n mintBProgram: propsMintBProgram,\n\n txVersion,\n computeBudgetConfig,\n txTipConfig,\n feePayer,\n }: ClaimPlatformFee<T>): Promise<MakeTxData> {\n const txBuilder = this.createTxBuilder(feePayer);\n authProgramId = authProgramId ?? getPdaLaunchpadAuth(programId).publicKey;\n\n let mintB = propsMintB;\n let vaultB = propsVaultB;\n\n if (!mintB) {\n const poolData = await this.scope.connection.getAccountInfo(poolId, { commitment: \"processed\" });\n if (!poolData) this.logAndCreateError(\"cannot found pool:\", poolId.toBase58());\n const poolInfo = LaunchpadPool.decode(poolData!.data);\n\n const configData = await this.scope.connection.getAccountInfo(poolInfo.configId, { commitment: \"processed\" });\n if (!configData) this.logAndCreateError(\"cannot found config:\", poolInfo.configId.toBase58());\n const configInfo = LaunchpadConfig.decode(configData!.data);\n\n mintB = configInfo.mintB;\n vaultB = vaultB ?? poolInfo.vaultB;\n }\n\n if (!mintB || !vaultB) {\n this.logAndCreateError(\n \"cannot found mint info, mintB: \",\n mintB.toBase58(),\n \", vaultB: \",\n vaultB?.toBase58() ?? \"\",\n );\n }\n\n const { mintBProgram } = await this.getMintBTokenInfo({ mintB, mintBProgram: propsMintBProgram });\n\n const userTokenAccountB = getATAAddress(this.scope.ownerPubKey, mintB, mintBProgram).publicKey;\n txBuilder.addInstruction({\n instructions: [\n createAssociatedTokenAccountIdempotentInstruction(\n this.scope.ownerPubKey,\n userTokenAccountB,\n this.scope.ownerPubKey,\n mintB,\n mintBProgram,\n ),\n ],\n });\n\n txBuilder.addInstruction({\n instructions: [\n claimPlatformFee(\n programId,\n platformClaimFeeWallet,\n authProgramId,\n poolId,\n platformId,\n vaultB!,\n userTokenAccountB!,\n mintB,\n mintBProgram,\n ),\n ],\n });\n\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n\n return txBuilder.versionBuild({\n txVersion,\n }) as Promise<MakeTxData>;\n }\n\n public async claimAllPlatformFee<T extends TxVersion>({\n programId = LAUNCHPAD_PROGRAM,\n authProgramId,\n platformId,\n platformClaimFeeWallet,\n\n txVersion,\n computeBudgetConfig,\n txTipConfig,\n feePayer,\n }: ClaimAllPlatformFee<T>): Promise<MakeMultiTxData<T>> {\n const txBuilder = this.createTxBuilder(feePayer);\n authProgramId = authProgramId ?? getPdaLaunchpadAuth(programId).publicKey;\n\n const allPlatformPool = await this.scope.connection.getProgramAccounts(programId, {\n filters: [\n { dataSize: LaunchpadPool.span },\n { memcmp: { offset: LaunchpadPool.offsetOf(\"platformId\"), bytes: platformId.toString() } },\n ],\n });\n\n const pendingPools = allPlatformPool\n .map((data) => ({ poolId: data.pubkey, pool: LaunchpadPool.decode(data.account.data) }))\n .filter(({ pool }) => pool.platformFee.gt(new BN(0)));\n\n // the pools of one platform can be quoted in different mints, each on either token program\n const mintBPrograms: Record<string, PublicKey> = {};\n const mintBList = [...new Set(pendingPools.map(({ pool }) => pool.mintB.toBase58()))];\n if (mintBList.length) {\n const mintBData = await getMultipleAccountsInfoWithCustomFlags(\n this.scope.connection,\n mintBList.map((mint) => ({ pubkey: new PublicKey(mint) })),\n );\n mintBData.forEach((data) => {\n mintBPrograms[data.pubkey.toBase58()] = data.accountInfo?.owner ?? TOKEN_PROGRAM_ID;\n });\n }\n\n pendingPools.forEach(({ poolId, pool }) => {\n const mintBProgram = mintBPrograms[pool.mintB.toBase58()] ?? TOKEN_PROGRAM_ID;\n const userTokenAccountB = getATAAddress(this.scope.ownerPubKey, pool.mintB, mintBProgram).publicKey;\n txBuilder.addInstruction({\n instructions: [\n createAssociatedTokenAccountIdempotentInstruction(\n this.scope.ownerPubKey,\n userTokenAccountB,\n this.scope.ownerPubKey,\n pool.mintB,\n mintBProgram,\n ),\n ],\n });\n\n txBuilder.addInstruction({\n instructions: [\n claimPlatformFee(\n programId,\n platformClaimFeeWallet,\n authProgramId!,\n poolId,\n platformId,\n pool.vaultB,\n userTokenAccountB!,\n pool.mintB,\n mintBProgram,\n ),\n ],\n });\n });\n\n txBuilder.addTipInstruction(txTipConfig);\n\n if (txVersion === TxVersion.V0)\n return txBuilder.sizeCheckBuildV0({ computeBudgetConfig }) as Promise<MakeMultiTxData<T>>;\n\n return txBuilder.sizeCheckBuild({\n computeBudgetConfig,\n }) as Promise<MakeMultiTxData<T>>;\n }\n\n public async createVesting<T extends TxVersion>({\n programId = LAUNCHPAD_PROGRAM,\n poolId,\n beneficiary,\n shareAmount,\n txVersion,\n computeBudgetConfig,\n txTipConfig,\n feePayer,\n }: CreateVesting<T>): Promise<MakeTxData> {\n const txBuilder = this.createTxBuilder(feePayer);\n\n const poolInfo = await this.getRpcPoolInfo({ poolId });\n if (shareAmount.add(poolInfo.vestingSchedule.totalAllocatedShare).gt(poolInfo.vestingSchedule.totalLockedAmount))\n this.logAndCreateError(\"share amount exceed total locked amount\");\n\n const vestingRecord = getPdaVestId(programId, poolId, beneficiary).publicKey;\n txBuilder.addInstruction({\n instructions: [\n createVestingAccount(programId, this.scope.ownerPubKey, beneficiary, poolId, vestingRecord, shareAmount),\n ],\n });\n\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n\n return txBuilder.versionBuild({\n txVersion,\n }) as Promise<MakeTxData>;\n }\n\n public async createMultipleVesting<T extends TxVersion>({\n programId = LAUNCHPAD_PROGRAM,\n poolId,\n beneficiaryList,\n txVersion,\n computeBudgetConfig,\n feePayer,\n }: CreateMultipleVesting<T>): Promise<MakeMultiTxData<T>> {\n const txBuilder = this.createTxBuilder(feePayer);\n if (beneficiaryList.length === 0) this.logAndCreateError(\"beneficiaryList is null\");\n\n const poolInfo = await this.getRpcPoolInfo({ poolId });\n const allShareAmount = beneficiaryList.reduce(\n (acc, cur) => acc.add(cur.shareAmount),\n poolInfo.vestingSchedule.totalAllocatedShare,\n );\n\n if (allShareAmount.gt(poolInfo.vestingSchedule.totalLockedAmount))\n this.logAndCreateError(\"share amount exceed total locked amount\");\n\n beneficiaryList.forEach((beneficiary) => {\n const vestingRecord = getPdaVestId(programId, poolId, beneficiary.wallet).publicKey;\n txBuilder.addInstruction({\n instructions: [\n createVestingAccount(\n programId,\n this.scope.ownerPubKey,\n beneficiary.wallet,\n poolId,\n vestingRecord,\n beneficiary.shareAmount,\n ),\n ],\n });\n });\n\n if (txVersion === TxVersion.V0)\n return txBuilder.sizeCheckBuildV0({ computeBudgetConfig }) as Promise<MakeMultiTxData<T>>;\n return txBuilder.sizeCheckBuild({ computeBudgetConfig }) as Promise<MakeMultiTxData<T>>;\n }\n\n public async claimVesting<T extends TxVersion>({\n programId = LAUNCHPAD_PROGRAM,\n poolId,\n poolInfo: propsPoolInfo,\n vestingRecord: propsVestingRecord,\n txVersion,\n computeBudgetConfig,\n txTipConfig,\n feePayer,\n }: ClaimVesting<T>): Promise<MakeTxData> {\n const txBuilder = this.createTxBuilder(feePayer);\n\n const authProgramId = getPdaLaunchpadAuth(programId).publicKey;\n const vestingRecord = propsVestingRecord || getPdaVestId(programId, poolId, this.scope.ownerPubKey).publicKey;\n\n let poolInfo = propsPoolInfo;\n if (!poolInfo) {\n const r = await this.scope.connection.getAccountInfo(poolId);\n if (!r) this.logAndCreateError(\"pool not found\");\n poolInfo = LaunchpadPool.decode(r!.data);\n }\n\n const userTokenAccountA = getATAAddress(this.scope.ownerPubKey, poolInfo.mintA, TOKEN_PROGRAM_ID).publicKey;\n txBuilder.addInstruction({\n instructions: [\n createAssociatedTokenAccountIdempotentInstruction(\n this.scope.ownerPubKey,\n userTokenAccountA,\n this.scope.ownerPubKey,\n poolInfo.mintA,\n ),\n ],\n });\n\n txBuilder.addInstruction({\n instructions: [\n claimVestedToken(\n programId,\n this.scope.ownerPubKey,\n authProgramId,\n poolId,\n vestingRecord,\n userTokenAccountA!,\n poolInfo.vaultA,\n poolInfo.mintA,\n TOKEN_PROGRAM_ID,\n ),\n ],\n });\n\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n\n return txBuilder.versionBuild({\n txVersion,\n }) as Promise<MakeTxData>;\n }\n\n public async claimMultiVesting<T extends TxVersion>({\n programId = LAUNCHPAD_PROGRAM,\n poolIdList,\n poolsInfo: propsPoolsInfo = {},\n vestingRecords = {},\n txVersion,\n computeBudgetConfig,\n feePayer,\n }: ClaimMultiVesting<T>): Promise<MakeMultiTxData<T>> {\n const txBuilder = this.createTxBuilder(feePayer);\n\n let poolsInfo = { ...propsPoolsInfo };\n const authProgramId = getPdaLaunchpadAuth(programId).publicKey;\n const needFetchPools = poolIdList.filter((id) => !poolsInfo[id.toBase58()]);\n if (needFetchPools.length) {\n const fetchedPools = await this.getRpcPoolsInfo({ poolIdList: needFetchPools });\n poolsInfo = {\n ...poolsInfo,\n ...fetchedPools.poolInfoMap,\n };\n }\n\n poolIdList.forEach((poolId) => {\n const poolIdStr = poolId.toBase58();\n const poolInfo = poolsInfo[poolIdStr];\n if (!poolInfo) this.logAndCreateError(`pool info not found: ${poolIdStr}`);\n const vestingRecord =\n vestingRecords[poolIdStr] || getPdaVestId(programId, poolId, this.scope.ownerPubKey).publicKey;\n const userTokenAccountA = getATAAddress(this.scope.ownerPubKey, poolInfo.mintA, TOKEN_PROGRAM_ID).publicKey;\n txBuilder.addInstruction({\n instructions: [\n createAssociatedTokenAccountIdempotentInstruction(\n this.scope.ownerPubKey,\n userTokenAccountA,\n this.scope.ownerPubKey,\n poolInfo.mintA,\n ),\n ],\n });\n\n txBuilder.addInstruction({\n instructions: [\n claimVestedToken(\n programId,\n this.scope.ownerPubKey,\n authProgramId,\n poolId,\n vestingRecord,\n userTokenAccountA!,\n poolInfo.vaultA,\n poolInfo.mintA,\n TOKEN_PROGRAM_ID,\n ),\n ],\n });\n });\n\n if (txVersion === TxVersion.V0)\n return txBuilder.sizeCheckBuildV0({ computeBudgetConfig }) as Promise<MakeMultiTxData<T>>;\n return txBuilder.sizeCheckBuild({ computeBudgetConfig }) as Promise<MakeMultiTxData<T>>;\n }\n\n public async claimVaultPlatformFee<T extends TxVersion>({\n programId = LAUNCHPAD_PROGRAM,\n platformId,\n mintB,\n mintBProgram: propsMintBProgram,\n claimFeeWallet,\n txVersion,\n computeBudgetConfig,\n txTipConfig,\n feePayer,\n }: ClaimVaultPlatformFee<T>): Promise<MakeTxData> {\n const txBuilder = this.createTxBuilder(feePayer);\n\n const platformFeeVault = getPdaPlatformVault(programId, platformId, mintB).publicKey;\n const platformFeeAuth = getPdaPlatformFeeVaultAuth(programId).publicKey;\n const { mintBProgram } = await this.getMintBTokenInfo({ mintB, mintBProgram: propsMintBProgram });\n\n const userTokenAccount = this.scope.account.getAssociatedTokenAccount(mintB, mintBProgram);\n\n txBuilder.addInstruction({\n instructions: [\n createAssociatedTokenAccountIdempotentInstruction(\n this.scope.ownerPubKey,\n userTokenAccount,\n this.scope.ownerPubKey,\n mintB,\n mintBProgram,\n ),\n claimPlatformFeeFromVault(\n programId,\n platformId,\n claimFeeWallet ?? this.scope.ownerPubKey,\n platformFeeAuth,\n platformFeeVault,\n userTokenAccount,\n mintB,\n mintBProgram,\n ),\n ],\n });\n\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n\n return txBuilder.versionBuild({\n txVersion,\n }) as Promise<MakeTxData>;\n }\n\n public async claimMultipleVaultPlatformFee<T extends TxVersion>({\n programId = LAUNCHPAD_PROGRAM,\n platformList,\n unwrapSol = true,\n txVersion,\n computeBudgetConfig,\n feePayer,\n associatedOnly = true,\n checkCreateATAOwner = false,\n }: ClaimMultipleVaultPlatformFee<T>): Promise<MakeMultiTxData<T>> {\n const txBuilder = this.createTxBuilder(feePayer);\n\n // const platformFeeVault = getPdaPlatformVault(programId, platformId, mintB).publicKey;\n\n const tokenAccountRecord: Record<string, PublicKey> = {};\n\n platformList.forEach(async (platform) => {\n const platformFeeAuth = getPdaPlatformFeeVaultAuth(programId).publicKey;\n const platformFeeVault = getPdaPlatformVault(programId, platform.id, platform.mintB).publicKey;\n const useSolBalance = platform.mintB.equals(NATIVE_MINT) && unwrapSol;\n let userTokenAccount: PublicKey | undefined = tokenAccountRecord[platform.mintB.toBase58()];\n\n if (!userTokenAccount) {\n const { account: _userTokenAccount, instructionParams: _tokenAccountInstruction } =\n await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: platform.mintBProgram ?? TOKEN_PROGRAM_ID,\n mint: platform.mintB,\n owner: this.scope.ownerPubKey,\n createInfo: useSolBalance\n ? {\n payer: this.scope.ownerPubKey!,\n amount: 0,\n }\n : undefined,\n skipCloseAccount: !useSolBalance,\n notUseTokenAccount: useSolBalance,\n associatedOnly: useSolBalance ? false : associatedOnly,\n checkCreateATAOwner,\n });\n if (_userTokenAccount) userTokenAccount = _userTokenAccount;\n txBuilder.addInstruction(_tokenAccountInstruction || {});\n if (userTokenAccount === undefined)\n this.logAndCreateError(\n `cannot found platform ${platform.id.toBase58()} mintB(${platform.mintB.toBase58()}) token accounts`,\n \"tokenAccounts\",\n this.scope.account.tokenAccounts,\n );\n }\n\n txBuilder.addInstruction({\n instructions: [\n claimPlatformFeeFromVault(\n programId,\n platform.id,\n platform.claimFeeWallet ?? this.scope.ownerPubKey,\n platformFeeAuth,\n platformFeeVault,\n userTokenAccount!,\n platform.mintB,\n platform.mintBProgram ?? TOKEN_PROGRAM_ID,\n ),\n ],\n });\n });\n\n if (txVersion === TxVersion.V0)\n return txBuilder.sizeCheckBuildV0({ computeBudgetConfig }) as Promise<MakeMultiTxData<T>>;\n return txBuilder.sizeCheckBuild({ computeBudgetConfig }) as Promise<MakeMultiTxData<T>>;\n }\n\n public async claimCreatorFee<T extends TxVersion>({\n programId = LAUNCHPAD_PROGRAM,\n mintB,\n mintBProgram: propsMintBProgram,\n txVersion,\n computeBudgetConfig,\n txTipConfig,\n feePayer,\n }: ClaimCreatorFee<T>): Promise<MakeTxData> {\n const txBuilder = this.createTxBuilder(feePayer);\n\n const creatorFeeVault = getPdaCreatorVault(programId, this.scope.ownerPubKey, mintB).publicKey;\n const creatorFeeVaultAuth = getPdaCreatorFeeVaultAuth(programId).publicKey;\n const { mintBProgram } = await this.getMintBTokenInfo({ mintB, mintBProgram: propsMintBProgram });\n const userTokenAccount = this.scope.account.getAssociatedTokenAccount(mintB, mintBProgram);\n\n txBuilder.addInstruction({\n instructions: [\n createAssociatedTokenAccountIdempotentInstruction(\n this.scope.ownerPubKey,\n userTokenAccount,\n this.scope.ownerPubKey,\n mintB,\n mintBProgram,\n ),\n claimCreatorFee(\n programId,\n this.scope.ownerPubKey,\n creatorFeeVaultAuth,\n creatorFeeVault,\n userTokenAccount!,\n mintB,\n mintBProgram,\n ),\n ],\n });\n\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n\n return txBuilder.versionBuild({\n txVersion,\n }) as Promise<MakeTxData>;\n }\n\n public async claimMultipleCreatorFee<T extends TxVersion>({\n programId = LAUNCHPAD_PROGRAM,\n mintBList,\n txVersion,\n computeBudgetConfig,\n feePayer,\n }: ClaimMultiCreatorFee<T>): Promise<MakeMultiTxData<T>> {\n const txBuilder = this.createTxBuilder(feePayer);\n\n mintBList.forEach((mint) => {\n const mintB = mint.pubKey;\n const mintBProgram = mint.programId ?? TOKEN_PROGRAM_ID;\n const creatorFeeVault = getPdaCreatorVault(programId, this.scope.ownerPubKey, mintB).publicKey;\n const creatorFeeVaultAuth = getPdaCreatorFeeVaultAuth(programId).publicKey;\n const userTokenAccount = this.scope.account.getAssociatedTokenAccount(mintB, mintBProgram);\n\n txBuilder.addInstruction({\n instructions: [\n createAssociatedTokenAccountIdempotentInstruction(\n this.scope.ownerPubKey,\n userTokenAccount,\n this.scope.ownerPubKey,\n mintB,\n mintBProgram,\n ),\n claimCreatorFee(\n programId,\n this.scope.ownerPubKey,\n creatorFeeVaultAuth,\n creatorFeeVault,\n userTokenAccount!,\n mintB,\n mintBProgram,\n ),\n ],\n });\n });\n\n if (txVersion == TxVersion.V0)\n return txBuilder.sizeCheckBuildV0({ computeBudgetConfig }) as Promise<MakeMultiTxData<T>>;\n return txBuilder.sizeCheckBuild({ computeBudgetConfig }) as Promise<MakeMultiTxData<T>>;\n }\n\n public async createPlatformAllowConfig<T extends TxVersion>({\n programId = LAUNCHPAD_PROGRAM,\n platformAdmin,\n platformId,\n configInfo,\n txVersion,\n computeBudgetConfig,\n txTipConfig,\n feePayer,\n }: CreatePlatformAllowConfig<T>): Promise<MakeTxData<T>> {\n const txBuilder = this.createTxBuilder(feePayer);\n\n const { publicKey: globalConfigId } = getPdaLaunchpadConfigId(\n programId,\n new PublicKey(configInfo.mintB),\n configInfo.curveType,\n configInfo.index,\n );\n const { publicKey: platformAllowConfig } = getPdaPlatformAllowConfig(programId, platformId, globalConfigId);\n txBuilder.addInstruction({\n instructions: [\n createPlatformAllowConfigIns(programId, platformAdmin, platformId, globalConfigId, platformAllowConfig),\n ],\n });\n\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n\n return txBuilder.versionBuild({\n txVersion,\n extInfo: {\n platformId,\n },\n }) as Promise<MakeTxData<T, { platformId: PublicKey }>>;\n }\n\n public async closePlatformAllowConfig<T extends TxVersion>({\n programId = LAUNCHPAD_PROGRAM,\n platformAdmin,\n platformId,\n configInfo,\n txVersion,\n computeBudgetConfig,\n txTipConfig,\n feePayer,\n }: CreatePlatformAllowConfig<T>): Promise<MakeTxData<T>> {\n const txBuilder = this.createTxBuilder(feePayer);\n\n const { publicKey: globalConfigId } = getPdaLaunchpadConfigId(\n programId,\n new PublicKey(configInfo.mintB),\n configInfo.curveType,\n configInfo.index,\n );\n const { publicKey: platformAllowConfig } = getPdaPlatformAllowConfig(programId, platformId, globalConfigId);\n txBuilder.addInstruction({\n instructions: [\n closePlatformAllowConfigIns(programId, platformAdmin, platformId, globalConfigId, platformAllowConfig),\n ],\n });\n\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n txBuilder.addTipInstruction(txTipConfig);\n\n return txBuilder.versionBuild({\n txVersion,\n extInfo: {\n platformId,\n },\n }) as Promise<MakeTxData<T, { platformId: PublicKey }>>;\n }\n\n public async getRpcPoolInfo({\n poolId,\n }: {\n poolId: PublicKey;\n }): Promise<LaunchpadPoolInfo & { programId: PublicKey; configInfo: LaunchpadConfigInfo }> {\n const data = await this.getRpcPoolsInfo({ poolIdList: [poolId] });\n\n return data.poolInfoMap[poolId.toBase58()];\n }\n\n public async getRpcPoolsInfo({\n poolIdList,\n config,\n }: {\n poolIdList: PublicKey[];\n config?: { batchRequest?: boolean; chunkCount?: number };\n }): Promise<{\n poolInfoMap: Record<\n string,\n LaunchpadPoolInfo & {\n poolId: PublicKey;\n programId: PublicKey;\n configInfo: LaunchpadConfigInfo;\n }\n >;\n }> {\n const accounts = await getMultipleAccountsInfoWithCustomFlags(\n this.scope.connection,\n poolIdList.map((i) => ({ pubkey: i })),\n config,\n );\n\n const poolInfoMap: { [poolId: string]: LaunchpadPoolInfo & { poolId: PublicKey; programId: PublicKey } } = {};\n const configKeys: PublicKey[] = [];\n\n for (let i = 0; i < poolIdList.length; i++) {\n const item = accounts[i];\n\n if (item === null || !item.accountInfo) throw Error(\"fetch pool info error: \" + poolIdList[i].toBase58());\n const poolInfo = LaunchpadPool.decode(item.accountInfo.data);\n poolInfoMap[poolIdList[i].toBase58()] = {\n ...poolInfo,\n poolId: poolIdList[i],\n programId: item.accountInfo.owner,\n };\n configKeys.push(poolInfo.configId);\n }\n\n const configAccounts = await getMultipleAccountsInfoWithCustomFlags(\n this.scope.connection,\n configKeys.map((i) => ({ pubkey: i })),\n config,\n );\n\n const configInfoMap: { [poolId: string]: LaunchpadConfigInfo & { configId: PublicKey } } = {};\n\n for (let i = 0; i < configKeys.length; i++) {\n const item = configAccounts[i];\n if (item === null || !item.accountInfo) throw Error(\"fetch config info error: \" + configKeys[i].toBase58());\n const configInfo = LaunchpadConfig.decode(item.accountInfo.data);\n configInfoMap[configKeys[i].toBase58()] = {\n ...configInfo,\n configId: item.accountInfo.owner,\n };\n }\n\n return {\n poolInfoMap: Object.keys(poolInfoMap).reduce(\n (acc, cur) => ({\n ...acc,\n [cur]: {\n ...poolInfoMap[cur],\n configInfo: configInfoMap[poolInfoMap[cur].configId.toBase58()],\n },\n }),\n {},\n ),\n };\n }\n}\n","import { PublicKey } from \"@solana/web3.js\";\nimport { SERUM_PROGRAM_ID_V3 } from \"../../common/programId\";\nimport { SerumVersion } from \"./type\";\n\n// serum program id string => serum version\nexport const SERUM_PROGRAMID_TO_VERSION: {\n [key: string]: SerumVersion;\n} = {\n [SERUM_PROGRAM_ID_V3.toBase58()]: 3,\n};\n\n// serum version => serum program id\nexport const SERUM_VERSION_TO_PROGRAMID: { [key in SerumVersion]?: PublicKey } & {\n [K: number]: PublicKey;\n} = {\n 3: SERUM_PROGRAM_ID_V3,\n};\n","import { blob, GetStructureSchema, publicKey, struct, u64 } from \"../../marshmallow\";\n\n/* ================= state layouts ================= */\nexport const MARKET_STATE_LAYOUT_V3 = struct([\n blob(5),\n\n blob(8), // accountFlagsLayout('accountFlags'),\n\n publicKey(\"ownAddress\"),\n\n u64(\"vaultSignerNonce\"),\n\n publicKey(\"baseMint\"),\n publicKey(\"quoteMint\"),\n\n publicKey(\"baseVault\"),\n u64(\"baseDepositsTotal\"),\n u64(\"baseFeesAccrued\"),\n\n publicKey(\"quoteVault\"),\n u64(\"quoteDepositsTotal\"),\n u64(\"quoteFeesAccrued\"),\n\n u64(\"quoteDustThreshold\"),\n\n publicKey(\"requestQueue\"),\n publicKey(\"eventQueue\"),\n\n publicKey(\"bids\"),\n publicKey(\"asks\"),\n\n u64(\"baseLotSize\"),\n u64(\"quoteLotSize\"),\n\n u64(\"feeRateBps\"),\n\n u64(\"referrerRebatesAccrued\"),\n\n blob(7),\n]);\n\nexport type MarketStateLayoutV3 = typeof MARKET_STATE_LAYOUT_V3;\nexport type MarketStateLayout = MarketStateLayoutV3;\n\nexport type MarketStateV3 = GetStructureSchema<MarketStateLayoutV3>;\nexport type MarketState = MarketStateV3;\n\n/* ================= index ================= */\n// version => market state layout\nexport const MARKET_VERSION_TO_STATE_LAYOUT: {\n [version: number]: MarketStateLayout;\n} = {\n 3: MARKET_STATE_LAYOUT_V3,\n};\n","import { PublicKey } from \"@solana/web3.js\";\n\nimport { createLogger } from \"../../common/logger\";\n\nimport { SERUM_PROGRAMID_TO_VERSION, SERUM_VERSION_TO_PROGRAMID } from \"./id\";\nimport { MARKET_VERSION_TO_STATE_LAYOUT, MarketStateLayout } from \"./layout\";\n\nconst logger = createLogger(\"Serum\");\n\nexport class Market {\n /* ================= get version and program id ================= */\n static getProgramId(version: number): PublicKey {\n const programId = SERUM_VERSION_TO_PROGRAMID[version];\n if (!programId) logger.logWithError(\"invalid version\", \"version\", version);\n\n return programId;\n }\n\n static getVersion(programId: PublicKey): number {\n const programIdString = programId.toBase58();\n\n const version = SERUM_PROGRAMID_TO_VERSION[programIdString];\n if (!version) logger.logWithError(\"invalid program id\", \"programId\", programIdString);\n\n return version;\n }\n\n /* ================= get layout ================= */\n static getStateLayout(version: number): MarketStateLayout {\n const STATE_LAYOUT = MARKET_VERSION_TO_STATE_LAYOUT[version];\n if (!STATE_LAYOUT) logger.logWithError(!!STATE_LAYOUT, \"invalid version\", \"version\", version);\n\n return STATE_LAYOUT;\n }\n\n static getLayouts(version: number): { state: MarketStateLayout } {\n return { state: this.getStateLayout(version) };\n }\n\n /* ================= get key ================= */\n static getAssociatedAuthority({ programId, marketId }: { programId: PublicKey; marketId: PublicKey }): {\n publicKey: PublicKey;\n nonce: number;\n } {\n const seeds = [marketId.toBuffer()];\n\n let nonce = 0;\n let publicKey: PublicKey;\n\n while (nonce < 100) {\n try {\n const seedsWithNonce = seeds.concat(Buffer.from([nonce]), Buffer.alloc(7));\n publicKey = PublicKey.createProgramAddressSync(seedsWithNonce, programId);\n } catch (err) {\n if (err instanceof TypeError) {\n throw err;\n }\n nonce++;\n continue;\n }\n return { publicKey, nonce };\n }\n\n logger.logWithError(\"unable to find a viable program address nonce\", \"params\", {\n programId,\n marketId,\n });\n\n return { publicKey: PublicKey.default, nonce };\n }\n}\n","import { ASSOCIATED_TOKEN_PROGRAM_ID, TOKEN_2022_PROGRAM_ID, TOKEN_PROGRAM_ID } from \"@solana/spl-token\";\nimport { PublicKey, SystemProgram, TransactionInstruction } from \"@solana/web3.js\";\nimport BN from \"bn.js\";\n\nimport {\n ALL_PROGRAM_ID,\n InstructionType,\n LIQUIDITY_POOL_PROGRAM_ID_V5_MODEL,\n\n MEMO_PROGRAM_ID,\n\n accountMeta,\n getATAAddress,\n jsonInfo2PoolKeys,\n} from \"@/common\";\nimport { seq, struct, u128, u64, u8 } from \"../../marshmallow\";\nimport {\n BN_ONE,\n ClmmInstrument,\n MAX_SQRT_PRICE_X64,\n MIN_SQRT_PRICE_X64,\n getPdaExBitmapAccount\n} from \"../clmm\";\nimport { makeAMMSwapInstruction, makeAMMSwapV2Instruction } from \"../liquidity/instruction\";\n\nimport { AmmV4Keys, AmmV5Keys, ApiV3PoolInfoItem, ClmmKeys, CpmmKeys, PoolKeys } from \"../../api/type\";\nimport { makeSwapCpmmBaseInInstruction } from \"../../raydium/cpmm\";\nimport { ComputePoolType, MakeSwapInstructionParam, ReturnTypeMakeSwapInstruction } from \"./type\";\nexport function route1Instruction(\n programId: PublicKey,\n poolInfoA: ApiV3PoolInfoItem,\n poolKeyA: PoolKeys,\n poolKeyB: PoolKeys,\n\n userSourceToken: PublicKey,\n userRouteToken: PublicKey,\n // userDestinationToken: PublicKey,\n userPdaAccount: PublicKey,\n ownerWallet: PublicKey,\n\n inputMint: PublicKey,\n\n amountIn: BN,\n amountOut: BN,\n\n tickArrayA?: PublicKey[],\n // tickArrayB?: PublicKey[],\n): TransactionInstruction {\n const dataLayout = struct([u8(\"instruction\"), u64(\"amountIn\"), u64(\"amountOut\")]);\n\n const keys: { pubkey: PublicKey; isSigner: boolean; isWritable: boolean }[] = [\n { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },\n { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: new PublicKey(poolKeyA.programId), isSigner: false, isWritable: false },\n { pubkey: new PublicKey(poolKeyA.id), isSigner: false, isWritable: true },\n { pubkey: new PublicKey(poolKeyB.id), isSigner: false, isWritable: true },\n\n { pubkey: userSourceToken, isSigner: false, isWritable: true },\n { pubkey: userRouteToken, isSigner: false, isWritable: true },\n { pubkey: userPdaAccount, isSigner: false, isWritable: true },\n { pubkey: ownerWallet, isSigner: true, isWritable: false },\n ];\n\n if (poolInfoA.type === \"Concentrated\") {\n const poolKey = jsonInfo2PoolKeys(poolKeyA as ClmmKeys);\n keys.push(\n ...[\n { pubkey: poolKey.config.id, isSigner: false, isWritable: false },\n { pubkey: poolKey.id, isSigner: false, isWritable: true },\n {\n pubkey: poolKey.mintA.address.equals(inputMint) ? poolKey.vault.A : poolKey.vault.B,\n isSigner: false,\n isWritable: true,\n },\n {\n pubkey: poolKey.mintA.address.equals(inputMint) ? poolKey.vault.B : poolKey.vault.A,\n isSigner: false,\n isWritable: true,\n },\n // { pubkey: poolKey.observationId, isSigner: false, isWritable: true }, // to do\n { pubkey: poolKey.id, isSigner: false, isWritable: true },\n ...tickArrayA!.map((i) => ({ pubkey: i, isSigner: false, isWritable: true })),\n ],\n );\n } else if (poolInfoA.pooltype.includes(\"StablePool\")) {\n const poolKey = jsonInfo2PoolKeys(poolKeyA as AmmV5Keys);\n keys.push(\n ...[\n { pubkey: poolKey.authority, isSigner: false, isWritable: false },\n { pubkey: poolKey.marketProgramId, isSigner: false, isWritable: false },\n { pubkey: poolKey.id, isSigner: false, isWritable: true },\n { pubkey: new PublicKey(\"CDSr3ssLcRB6XYPJwAfFt18MZvEZp4LjHcvzBVZ45duo\"), isSigner: false, isWritable: false },\n { pubkey: poolKey.openOrders, isSigner: false, isWritable: true },\n { pubkey: poolKey.vault.A, isSigner: false, isWritable: true },\n { pubkey: poolKey.vault.B, isSigner: false, isWritable: true },\n { pubkey: poolKey.marketId, isSigner: false, isWritable: true },\n { pubkey: poolKey.marketBids, isSigner: false, isWritable: true },\n { pubkey: poolKey.marketAsks, isSigner: false, isWritable: true },\n { pubkey: poolKey.marketEventQueue, isSigner: false, isWritable: true },\n { pubkey: poolKey.id, isSigner: false, isWritable: true },\n { pubkey: poolKey.id, isSigner: false, isWritable: true },\n ],\n );\n } else {\n const poolKey = jsonInfo2PoolKeys(poolKeyA as AmmV4Keys);\n keys.push(\n ...[\n { pubkey: poolKey.authority, isSigner: false, isWritable: false },\n { pubkey: poolKey.marketProgramId, isSigner: false, isWritable: false },\n { pubkey: poolKey.marketAuthority, isSigner: false, isWritable: false },\n { pubkey: poolKey.openOrders, isSigner: false, isWritable: true },\n { pubkey: poolKey.vault.A, isSigner: false, isWritable: true },\n { pubkey: poolKey.vault.B, isSigner: false, isWritable: true },\n { pubkey: poolKey.marketId, isSigner: false, isWritable: true },\n { pubkey: poolKey.marketBids, isSigner: false, isWritable: true },\n { pubkey: poolKey.marketAsks, isSigner: false, isWritable: true },\n { pubkey: poolKey.marketEventQueue, isSigner: false, isWritable: true },\n ...(poolKey.marketProgramId.toString() === \"srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX\"\n ? [\n { pubkey: poolKey.marketBaseVault, isSigner: false, isWritable: true },\n { pubkey: poolKey.marketQuoteVault, isSigner: false, isWritable: true },\n ]\n : [\n { pubkey: poolKey.id, isSigner: false, isWritable: true },\n { pubkey: poolKey.id, isSigner: false, isWritable: true },\n ]),\n ],\n );\n }\n\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode(\n {\n instruction: 4,\n amountIn,\n amountOut,\n },\n data,\n );\n\n return new TransactionInstruction({\n keys,\n programId,\n data,\n });\n}\n\nexport function route2Instruction(\n programId: PublicKey,\n poolInfoB: ApiV3PoolInfoItem,\n poolKeyA: PoolKeys,\n poolKeyB: PoolKeys,\n\n // userSourceToken: PublicKey,\n userRouteToken: PublicKey,\n userDestinationToken: PublicKey,\n userPdaAccount: PublicKey,\n ownerWallet: PublicKey,\n\n routeMint: PublicKey,\n\n // tickArrayA?: PublicKey[],\n tickArrayB?: PublicKey[],\n): TransactionInstruction {\n const dataLayout = struct([u8(\"instruction\")]);\n\n const keys: { pubkey: PublicKey; isSigner: boolean; isWritable: boolean }[] = [\n { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },\n { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: new PublicKey(String(poolKeyB.programId)), isSigner: false, isWritable: false },\n { pubkey: new PublicKey(String(poolKeyB.id)), isSigner: false, isWritable: true },\n { pubkey: new PublicKey(String(poolKeyA.id)), isSigner: false, isWritable: true },\n\n { pubkey: userRouteToken, isSigner: false, isWritable: true },\n { pubkey: userDestinationToken, isSigner: false, isWritable: true },\n { pubkey: userPdaAccount, isSigner: false, isWritable: true },\n { pubkey: ownerWallet, isSigner: true, isWritable: false },\n ];\n\n if (poolInfoB.type === \"Concentrated\") {\n const poolKey = jsonInfo2PoolKeys(poolKeyB as ClmmKeys);\n keys.push(\n ...[\n { pubkey: poolKey.config.id, isSigner: false, isWritable: false },\n { pubkey: poolKey.id, isSigner: false, isWritable: true },\n {\n pubkey: poolKey.mintA.address.equals(routeMint) ? poolKey.vault.A : poolKey.vault.B,\n isSigner: false,\n isWritable: true,\n },\n {\n pubkey: poolKey.mintA.address.equals(routeMint) ? poolKey.vault.B : poolKey.vault.A,\n isSigner: false,\n isWritable: true,\n },\n // { pubkey: poolKey.observationId, isSigner: false, isWritable: true }, // to do\n { pubkey: poolKey.id, isSigner: false, isWritable: true },\n ...tickArrayB!.map((i) => ({ pubkey: i, isSigner: false, isWritable: true })),\n ],\n );\n } else if (poolInfoB.pooltype.includes(\"StablePool\")) {\n const poolKey = jsonInfo2PoolKeys(poolKeyB as AmmV5Keys);\n keys.push(\n ...[\n { pubkey: poolKey.authority, isSigner: false, isWritable: false },\n { pubkey: poolKey.marketProgramId, isSigner: false, isWritable: false },\n { pubkey: poolKey.id, isSigner: false, isWritable: true },\n { pubkey: new PublicKey(\"CDSr3ssLcRB6XYPJwAfFt18MZvEZp4LjHcvzBVZ45duo\"), isSigner: false, isWritable: false },\n { pubkey: poolKey.openOrders, isSigner: false, isWritable: true },\n { pubkey: poolKey.vault.A, isSigner: false, isWritable: true },\n { pubkey: poolKey.vault.B, isSigner: false, isWritable: true },\n { pubkey: poolKey.marketId, isSigner: false, isWritable: true },\n { pubkey: poolKey.marketBids, isSigner: false, isWritable: true },\n { pubkey: poolKey.marketAsks, isSigner: false, isWritable: true },\n { pubkey: poolKey.marketEventQueue, isSigner: false, isWritable: true },\n { pubkey: poolKey.id, isSigner: false, isWritable: true },\n { pubkey: poolKey.id, isSigner: false, isWritable: true },\n ],\n );\n } else {\n const poolKey = jsonInfo2PoolKeys(poolKeyB as AmmV4Keys);\n keys.push(\n ...[\n { pubkey: poolKey.authority, isSigner: false, isWritable: false },\n { pubkey: poolKey.marketProgramId, isSigner: false, isWritable: false },\n { pubkey: poolKey.marketAuthority, isSigner: false, isWritable: false },\n { pubkey: poolKey.openOrders, isSigner: false, isWritable: true },\n { pubkey: poolKey.vault.A, isSigner: false, isWritable: true },\n { pubkey: poolKey.vault.B, isSigner: false, isWritable: true },\n { pubkey: poolKey.marketId, isSigner: false, isWritable: true },\n { pubkey: poolKey.marketBids, isSigner: false, isWritable: true },\n { pubkey: poolKey.marketAsks, isSigner: false, isWritable: true },\n { pubkey: poolKey.marketEventQueue, isSigner: false, isWritable: true },\n ...(poolKey.marketProgramId.toString() === \"srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX\"\n ? [\n { pubkey: poolKey.marketBaseVault, isSigner: false, isWritable: true },\n { pubkey: poolKey.marketQuoteVault, isSigner: false, isWritable: true },\n ]\n : [\n { pubkey: poolKey.id, isSigner: false, isWritable: true },\n { pubkey: poolKey.id, isSigner: false, isWritable: true },\n ]),\n ],\n );\n }\n\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode(\n {\n instruction: 5,\n },\n data,\n );\n\n return new TransactionInstruction({\n keys,\n programId,\n data,\n });\n}\n\n/*\nfunction makeInnerInsKey(\n itemPool: ComputePoolType,\n itemPoolKey: PoolKeys,\n inMint: string,\n userInAccount: PublicKey,\n userOutAccount: PublicKey,\n remainingAccount: PublicKey[] | undefined,\n): accountMeta[] {\n if (itemPool.version === 4) {\n const poolKey = jsonInfo2PoolKeys(itemPoolKey as AmmV4Keys);\n\n return [\n { pubkey: poolKey.programId, isSigner: false, isWritable: false },\n { pubkey: userInAccount, isSigner: false, isWritable: true },\n { pubkey: userOutAccount, isSigner: false, isWritable: true },\n\n { pubkey: poolKey.id, isSigner: false, isWritable: true },\n { pubkey: poolKey.authority, isSigner: false, isWritable: false },\n { pubkey: poolKey.marketProgramId, isSigner: false, isWritable: false },\n { pubkey: poolKey.marketAuthority, isSigner: false, isWritable: true },\n\n { pubkey: poolKey.openOrders, isSigner: false, isWritable: true },\n { pubkey: poolKey.vault.A, isSigner: false, isWritable: true },\n { pubkey: poolKey.vault.B, isSigner: false, isWritable: true },\n { pubkey: poolKey.marketId, isSigner: false, isWritable: true },\n { pubkey: poolKey.marketBids, isSigner: false, isWritable: true },\n { pubkey: poolKey.marketAsks, isSigner: false, isWritable: true },\n { pubkey: poolKey.marketEventQueue, isSigner: false, isWritable: true },\n ...(poolKey.marketProgramId.toString() === \"srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX\"\n ? [\n { pubkey: poolKey.marketBaseVault, isSigner: false, isWritable: true },\n { pubkey: poolKey.marketQuoteVault, isSigner: false, isWritable: true },\n ]\n : [\n { pubkey: poolKey.id, isSigner: false, isWritable: true },\n { pubkey: poolKey.id, isSigner: false, isWritable: true },\n ]),\n ];\n } else if (itemPool.version === 5) {\n const poolKey = jsonInfo2PoolKeys(itemPoolKey as AmmV4Keys);\n\n return [\n { pubkey: poolKey.programId, isSigner: false, isWritable: false },\n { pubkey: userInAccount, isSigner: false, isWritable: true },\n { pubkey: userOutAccount, isSigner: false, isWritable: true },\n\n { pubkey: poolKey.id, isSigner: false, isWritable: true },\n { pubkey: poolKey.authority, isSigner: false, isWritable: false },\n { pubkey: poolKey.marketProgramId, isSigner: false, isWritable: false },\n { pubkey: poolKey.id, isSigner: false, isWritable: true },\n { pubkey: new PublicKey(\"CDSr3ssLcRB6XYPJwAfFt18MZvEZp4LjHcvzBVZ45duo\"), isSigner: false, isWritable: false },\n { pubkey: poolKey.openOrders, isSigner: false, isWritable: true },\n { pubkey: poolKey.vault.A, isSigner: false, isWritable: true },\n { pubkey: poolKey.vault.B, isSigner: false, isWritable: true },\n { pubkey: poolKey.marketId, isSigner: false, isWritable: true },\n { pubkey: poolKey.marketBids, isSigner: false, isWritable: true },\n { pubkey: poolKey.marketAsks, isSigner: false, isWritable: true },\n { pubkey: poolKey.marketEventQueue, isSigner: false, isWritable: true },\n { pubkey: poolKey.id, isSigner: false, isWritable: true },\n { pubkey: poolKey.id, isSigner: false, isWritable: true },\n ];\n } else if (itemPool.version === 6) {\n const pool = itemPool;\n const poolKey = jsonInfo2PoolKeys(itemPoolKey as ClmmKeys);\n const baseIn = pool.mintA.address === inMint;\n return [\n { pubkey: new PublicKey(String(itemPool.programId)), isSigner: false, isWritable: false },\n { pubkey: userInAccount, isSigner: false, isWritable: true },\n { pubkey: userOutAccount, isSigner: false, isWritable: true },\n { pubkey: poolKey.config.id, isSigner: false, isWritable: false },\n { pubkey: poolKey.id, isSigner: false, isWritable: true },\n { pubkey: baseIn ? poolKey.vault.A : poolKey.vault.B, isSigner: false, isWritable: true },\n { pubkey: baseIn ? poolKey.vault.B : poolKey.vault.A, isSigner: false, isWritable: true },\n { pubkey: itemPool.observationId, isSigner: false, isWritable: true },\n ...(poolKey.mintA.programId.equals(TOKEN_2022_PROGRAM_ID) || poolKey.mintB.programId.equals(TOKEN_2022_PROGRAM_ID)\n ? [\n { pubkey: TOKEN_2022_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: MEMO_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: baseIn ? poolKey.mintA.address : poolKey.mintB.address, isSigner: false, isWritable: false },\n { pubkey: baseIn ? poolKey.mintB.address : poolKey.mintA.address, isSigner: false, isWritable: false },\n ]\n : []),\n ...(remainingAccount ?? []).map((i) => ({ pubkey: i, isSigner: false, isWritable: true })),\n {\n pubkey: getPdaExBitmapAccount(new PublicKey(String(itemPool.programId)), new PublicKey(itemPool.id)).publicKey,\n isSigner: false,\n isWritable: true,\n },\n ];\n } else if (itemPool.version === 7) {\n const pool = itemPool;\n const poolKey = jsonInfo2PoolKeys(itemPoolKey as CpmmKeys);\n const baseIn = pool.mintA.address === inMint;\n return [\n { pubkey: new PublicKey(String(itemPool.programId)), isSigner: false, isWritable: false },\n { pubkey: userInAccount, isSigner: false, isWritable: true },\n { pubkey: userOutAccount, isSigner: false, isWritable: true },\n { pubkey: poolKey.config.id, isSigner: false, isWritable: false },\n { pubkey: poolKey.id, isSigner: false, isWritable: true },\n { pubkey: baseIn ? poolKey.vault.A : poolKey.vault.B, isSigner: false, isWritable: true },\n { pubkey: baseIn ? poolKey.vault.B : poolKey.vault.A, isSigner: false, isWritable: true },\n { pubkey: itemPool.observationId, isSigner: false, isWritable: true },\n ...(poolKey.mintA.programId.equals(TOKEN_2022_PROGRAM_ID) || poolKey.mintB.programId.equals(TOKEN_2022_PROGRAM_ID)\n ? [\n { pubkey: TOKEN_2022_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: MEMO_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: baseIn ? poolKey.mintA.address : poolKey.mintB.address, isSigner: false, isWritable: false },\n { pubkey: baseIn ? poolKey.mintB.address : poolKey.mintA.address, isSigner: false, isWritable: false },\n ]\n : []),\n ...(remainingAccount ?? []).map((i) => ({ pubkey: i, isSigner: false, isWritable: true })),\n {\n pubkey: getPdaExBitmapAccount(new PublicKey(String(itemPool.programId)), new PublicKey(itemPool.id)).publicKey,\n isSigner: false,\n isWritable: true,\n },\n ];\n } else {\n throw Error(\"make swap ins error\");\n }\n}\n*/\n\nexport function routeInstruction(\n programId: PublicKey,\n wallet: PublicKey,\n\n userSourceToken: PublicKey,\n userRouteToken: PublicKey,\n userDestinationToken: PublicKey,\n\n inputMint: string,\n routeMint: string,\n outputMint: string,\n\n poolInfoA: ComputePoolType,\n poolInfoB: ComputePoolType,\n\n poolKeyA: PoolKeys,\n poolKeyB: PoolKeys,\n\n amountIn: BN,\n amountOut: BN,\n\n remainingAccounts: (PublicKey[] | undefined)[],\n): TransactionInstruction {\n const clmmPriceLimit: BN[] = [];\n const keys = [\n accountMeta({ pubkey: TOKEN_PROGRAM_ID, isWritable: false }),\n accountMeta({ pubkey: TOKEN_2022_PROGRAM_ID, isWritable: false }),\n accountMeta({ pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isWritable: false }),\n accountMeta({ pubkey: SystemProgram.programId, isWritable: false }),\n accountMeta({ pubkey: wallet, isSigner: true }),\n ];\n\n keys.push(accountMeta({ pubkey: userSourceToken }));\n keys.push(accountMeta({ pubkey: userDestinationToken }));\n\n const poolInfos = [poolInfoA, poolInfoB];\n const poolKeys = [poolKeyA, poolKeyB];\n const routeMints = [inputMint, routeMint, outputMint];\n\n for (let index = 0; index < poolInfos.length; index++) {\n const _poolInfo = poolInfos[index];\n const inputIsA = routeMints[index] === _poolInfo.mintA.address;\n keys.push(accountMeta({ pubkey: new PublicKey(_poolInfo.programId), isWritable: false }));\n if (index === poolInfos.length - 1) {\n keys.push(accountMeta({ pubkey: userDestinationToken }));\n } else {\n keys.push(accountMeta({ pubkey: userRouteToken }));\n }\n keys.push(accountMeta({ pubkey: new PublicKey(routeMints[index]) }));\n keys.push(accountMeta({ pubkey: new PublicKey(routeMints[index + 1]) }));\n if (_poolInfo.version === 6) {\n const _poolKey = poolKeys[index] as ClmmKeys;\n\n keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.config.id) }));\n keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.id) }));\n keys.push(accountMeta({ pubkey: new PublicKey(inputIsA ? _poolKey.vault.A : _poolKey.vault.B) }));\n keys.push(accountMeta({ pubkey: new PublicKey(inputIsA ? _poolKey.vault.B : _poolKey.vault.A) }));\n keys.push(accountMeta({ pubkey: new PublicKey(_poolInfo.observationId) })); //todo\n keys.push(accountMeta({ pubkey: MEMO_PROGRAM_ID }));\n keys.push(\n accountMeta({\n pubkey: getPdaExBitmapAccount(new PublicKey(_poolInfo.programId), new PublicKey(_poolInfo.id)).publicKey,\n }),\n );\n clmmPriceLimit.push(clmmPriceLimitX64InsData(_poolInfo.sqrtPriceX64.toString(), inputIsA));\n for (const item of remainingAccounts[index] ?? []) {\n keys.push(accountMeta({ pubkey: new PublicKey(item) }));\n }\n } else if (_poolInfo.version === 5) {\n const _poolKey = poolKeys[index] as AmmV5Keys;\n keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.id) }));\n keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.authority), isWritable: false }));\n keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.marketProgramId) }));\n keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.marketAuthority) }));\n keys.push(accountMeta({ pubkey: LIQUIDITY_POOL_PROGRAM_ID_V5_MODEL, isWritable: false }));\n keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.openOrders) }));\n keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.vault.A) }));\n keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.vault.B) }));\n keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.id) }));\n keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.id) }));\n keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.id) }));\n keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.id) }));\n keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.id) }));\n keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.id) }));\n keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.marketId) }));\n keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.marketBids) }));\n keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.marketAsks) }));\n keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.marketEventQueue) }));\n keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.marketBaseVault) }));\n keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.marketQuoteVault) }));\n } else if (_poolInfo.version === 4) {\n const _poolKey = poolKeys[index] as AmmV4Keys;\n const isSupportIdOnly = _poolInfo.status !== 1;\n keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.id) }));\n keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.authority), isWritable: false }));\n keys.push(accountMeta({ pubkey: new PublicKey(isSupportIdOnly ? _poolKey.id : _poolKey.marketProgramId) }));\n keys.push(accountMeta({ pubkey: new PublicKey(isSupportIdOnly ? _poolKey.id : _poolKey.marketAuthority) }));\n keys.push(accountMeta({ pubkey: new PublicKey(isSupportIdOnly ? _poolKey.id : _poolKey.openOrders) }));\n keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.vault.A) }));\n keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.vault.B) }));\n keys.push(accountMeta({ pubkey: new PublicKey(isSupportIdOnly ? _poolKey.id : _poolKey.marketId) }));\n keys.push(accountMeta({ pubkey: new PublicKey(isSupportIdOnly ? _poolKey.id : _poolKey.marketBids) }));\n keys.push(accountMeta({ pubkey: new PublicKey(isSupportIdOnly ? _poolKey.id : _poolKey.marketAsks) }));\n keys.push(accountMeta({ pubkey: new PublicKey(isSupportIdOnly ? _poolKey.id : _poolKey.marketEventQueue) }));\n keys.push(accountMeta({ pubkey: new PublicKey(isSupportIdOnly ? _poolKey.id : _poolKey.marketBaseVault) }));\n keys.push(accountMeta({ pubkey: new PublicKey(isSupportIdOnly ? _poolKey.id : _poolKey.marketQuoteVault) }));\n } else if (_poolInfo.version === 7) {\n const _poolKey = poolKeys[index] as CpmmKeys;\n keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.authority) }));\n keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.config.id) }));\n keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.id) }));\n keys.push(accountMeta({ pubkey: new PublicKey(inputIsA ? _poolKey.vault.A : _poolKey.vault.B) }));\n keys.push(accountMeta({ pubkey: new PublicKey(inputIsA ? _poolKey.vault.B : _poolKey.vault.A) }));\n keys.push(accountMeta({ pubkey: new PublicKey(_poolInfo.observationId) }));\n } else throw Error(\"pool type error\");\n }\n\n const dataLayout = struct([\n u8(\"insId\"),\n u64(\"amountIn\"),\n u64(\"amountOut\"),\n seq(u128(), clmmPriceLimit.length, \"clmmPriceLimit\"),\n ]);\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode(\n {\n insId: 0,\n amountIn,\n amountOut,\n clmmPriceLimit,\n },\n data,\n );\n return new TransactionInstruction({\n keys,\n programId,\n data,\n });\n}\n\nfunction clmmPriceLimitX64InsData(x64Price: string | undefined, inputIsA: boolean): BN {\n if (x64Price) {\n if (inputIsA) {\n const _m = new BN(x64Price).div(new BN(25));\n return _m.gt(MIN_SQRT_PRICE_X64.add(BN_ONE)) ? _m : MIN_SQRT_PRICE_X64.add(BN_ONE);\n } else {\n const _m = new BN(x64Price).mul(new BN(25));\n return _m.lt(MAX_SQRT_PRICE_X64.sub(BN_ONE)) ? _m : MAX_SQRT_PRICE_X64.sub(BN_ONE);\n }\n } else {\n return inputIsA ? MIN_SQRT_PRICE_X64.add(BN_ONE) : MAX_SQRT_PRICE_X64.sub(BN_ONE);\n }\n}\n\nexport function makeSwapInstruction({\n routeProgram,\n ownerInfo,\n inputMint,\n swapInfo,\n}: MakeSwapInstructionParam): ReturnTypeMakeSwapInstruction {\n if (swapInfo.routeType === \"amm\") {\n if (swapInfo.poolInfo[0].version === 6) {\n const poolKeys = swapInfo.poolKey[0] as ClmmKeys;\n const _poolKey = jsonInfo2PoolKeys(poolKeys);\n const sqrtPriceLimitX64 = inputMint.equals(_poolKey.mintA.address)\n ? MIN_SQRT_PRICE_X64.add(BN_ONE)\n : MAX_SQRT_PRICE_X64.sub(BN_ONE);\n\n return ClmmInstrument.makeSwapBaseInInstructions({\n poolInfo: poolKeys,\n poolKeys,\n observationId: swapInfo.poolInfo[0].observationId,\n ownerInfo: {\n wallet: ownerInfo.wallet,\n tokenAccountA: _poolKey.mintA.address.equals(inputMint) ? ownerInfo.sourceToken : ownerInfo.destinationToken,\n tokenAccountB: _poolKey.mintA.address.equals(inputMint) ? ownerInfo.destinationToken : ownerInfo.sourceToken,\n },\n inputMint,\n amountIn: swapInfo.amountIn.amount.raw,\n amountOutMin: swapInfo.minAmountOut.amount.raw.sub(swapInfo.minAmountOut.fee?.raw ?? new BN(0)),\n sqrtPriceLimitX64,\n remainingAccounts: swapInfo.remainingAccounts[0] ?? [],\n });\n } else if (swapInfo.poolInfo[0].version === 7) {\n const poolInfo = swapInfo.poolInfo[0];\n const baseIn = inputMint.toString() === swapInfo.poolInfo[0].mintA.address;\n\n return {\n signers: [],\n instructions: [\n makeSwapCpmmBaseInInstruction(\n poolInfo.programId,\n ownerInfo.wallet,\n poolInfo.authority,\n poolInfo.configId,\n poolInfo.id,\n ownerInfo.sourceToken!,\n ownerInfo.destinationToken!,\n baseIn ? poolInfo.vaultA : poolInfo.vaultB,\n baseIn ? poolInfo.vaultB : poolInfo.vaultA,\n baseIn ? poolInfo.mintProgramA : poolInfo.mintProgramB,\n baseIn ? poolInfo.mintProgramB : poolInfo.mintProgramA,\n new PublicKey(poolInfo[baseIn ? \"mintA\" : \"mintB\"].address),\n new PublicKey(poolInfo[baseIn ? \"mintB\" : \"mintA\"].address),\n poolInfo.observationId,\n\n swapInfo.amountIn.amount.raw,\n swapInfo.minAmountOut.amount.raw,\n ),\n ],\n lookupTableAddress: [],\n instructionTypes: [baseIn ? InstructionType.CpmmSwapBaseIn : InstructionType.CpmmSwapBaseOut],\n address: {},\n };\n } else {\n const _poolKey = swapInfo.poolKey[0] as AmmV4Keys | AmmV5Keys;\n\n return {\n signers: [],\n instructions: [\n swapInfo.poolInfo[0].pooltype.includes(\"StablePool\")\n ? makeAMMSwapInstruction({\n poolKeys: _poolKey,\n version: swapInfo.poolInfo[0].pooltype.includes(\"StablePool\") ? 5 : 4,\n userKeys: {\n tokenAccountIn: ownerInfo.sourceToken,\n tokenAccountOut: ownerInfo.destinationToken,\n owner: ownerInfo.wallet,\n },\n amountIn: swapInfo.amountIn.amount.raw,\n amountOut: swapInfo.minAmountOut.amount.raw.sub(swapInfo.minAmountOut.fee?.raw ?? new BN(0)),\n fixedSide: \"in\",\n })\n : makeAMMSwapV2Instruction({\n poolKeys: _poolKey,\n version: swapInfo.poolInfo[0].pooltype.includes(\"StablePool\") ? 5 : 4,\n userKeys: {\n tokenAccountIn: ownerInfo.sourceToken,\n tokenAccountOut: ownerInfo.destinationToken,\n owner: ownerInfo.wallet,\n },\n amountIn: swapInfo.amountIn.amount.raw,\n amountOut: swapInfo.minAmountOut.amount.raw.sub(swapInfo.minAmountOut.fee?.raw ?? new BN(0)),\n fixedSide: \"in\",\n }),\n ],\n lookupTableAddress: _poolKey.lookupTableAccount ? [_poolKey.lookupTableAccount] : [],\n instructionTypes: [\n swapInfo.poolInfo[0].pooltype.includes(\"StablePool\")\n ? InstructionType.AmmV5SwapBaseIn\n : InstructionType.AmmV4SwapBaseIn,\n ],\n address: {},\n };\n }\n } else if (swapInfo.routeType === \"route\") {\n const poolInfo1 = swapInfo.poolInfo[0];\n const poolInfo2 = swapInfo.poolInfo[1];\n const poolKey1 = swapInfo.poolKey[0];\n const poolKey2 = swapInfo.poolKey[1];\n\n if (ownerInfo.routeToken === undefined) throw Error(\"owner route token account check error\");\n\n return {\n signers: [],\n instructions: [\n routeInstruction(\n routeProgram,\n ownerInfo.wallet,\n ownerInfo.sourceToken,\n ownerInfo.routeToken,\n ownerInfo.destinationToken,\n\n inputMint.toString(),\n swapInfo.middleToken.mint.toString(),\n swapInfo.outputMint.toString(),\n\n poolInfo1,\n poolInfo2,\n poolKey1,\n poolKey2,\n\n swapInfo.amountIn.amount.raw,\n swapInfo.minAmountOut.amount.raw.sub(swapInfo.minAmountOut.fee?.raw ?? new BN(0)),\n\n swapInfo.remainingAccounts,\n ),\n ],\n instructionTypes: [InstructionType.RouteSwap],\n lookupTableAddress: [poolKey1.lookupTableAccount, poolKey2.lookupTableAccount].filter(\n (a) => a !== undefined,\n ) as string[],\n address: {},\n };\n } else {\n throw Error(\"route type error\");\n }\n}\n\nexport interface ApiSwapV1Out {\n id: string;\n success: boolean;\n version: \"V0\" | \"V1\";\n openTime?: undefined;\n msg: undefined;\n data: {\n swapType: \"BaseIn\" | \"BaseOut\";\n inputMint: string;\n inputAmount: string;\n outputMint: string;\n outputAmount: string;\n otherAmountThreshold: string;\n slippageBps: number;\n priceImpactPct: number;\n routePlan: {\n poolId: string;\n inputMint: string;\n outputMint: string;\n feeMint: string;\n feeRate: number;\n feeAmount: string;\n remainingAccounts?: string[];\n lastPoolPriceX64?: string;\n }[];\n };\n}\n\nexport function swapBaseInAutoAccount({\n programId,\n wallet,\n amount,\n inputAccount,\n outputAccount,\n routeInfo,\n poolKeys,\n}: {\n programId: PublicKey;\n wallet: PublicKey;\n amount: BN;\n inputAccount: PublicKey;\n outputAccount: PublicKey;\n routeInfo: ApiSwapV1Out;\n poolKeys: PoolKeys[];\n}): TransactionInstruction {\n if (routeInfo.success === false) throw Error(\"route info error\");\n const clmmPriceLimit: BN[] = [];\n const keys = [\n accountMeta({ pubkey: TOKEN_PROGRAM_ID, isWritable: false }),\n accountMeta({ pubkey: TOKEN_2022_PROGRAM_ID, isWritable: false }),\n accountMeta({ pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isWritable: false }),\n accountMeta({ pubkey: SystemProgram.programId, isWritable: false }),\n accountMeta({ pubkey: wallet, isSigner: true }),\n ];\n const cacheAccount: { [mint: string]: PublicKey } = {\n [routeInfo.data.inputMint]: inputAccount,\n [routeInfo.data.outputMint]: outputAccount,\n };\n keys.push(accountMeta({ pubkey: cacheAccount[routeInfo.data.inputMint] }));\n keys.push(accountMeta({ pubkey: cacheAccount[routeInfo.data.outputMint] }));\n for (let index = 0; index < poolKeys.length; index++) {\n const _routeInfo = routeInfo.data.routePlan[index];\n const _poolKey = poolKeys[index];\n const inputIsA = _routeInfo.inputMint === _poolKey.mintA.address;\n keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.programId), isWritable: false }));\n if (index === poolKeys.length - 1) {\n keys.push(accountMeta({ pubkey: cacheAccount[_routeInfo.outputMint] }));\n } else {\n const mint = _routeInfo.outputMint;\n if (cacheAccount[mint] === undefined) {\n const ata = getATAAddress(\n wallet,\n new PublicKey(mint),\n _poolKey.programId === ALL_PROGRAM_ID.CLMM_PROGRAM_ID.toBase58() ||\n _poolKey.programId === ALL_PROGRAM_ID.CREATE_CPMM_POOL_PROGRAM.toBase58()\n ? new PublicKey(inputIsA ? _poolKey.mintB.programId : _poolKey.mintA.programId)\n : TOKEN_PROGRAM_ID,\n ).publicKey;\n cacheAccount[mint] = ata;\n }\n keys.push(accountMeta({ pubkey: cacheAccount[mint] }));\n }\n keys.push(accountMeta({ pubkey: new PublicKey(_routeInfo.inputMint) }));\n keys.push(accountMeta({ pubkey: new PublicKey(_routeInfo.outputMint) }));\n if (_poolKey.programId === ALL_PROGRAM_ID.CLMM_PROGRAM_ID.toBase58()) {\n const poolKey = _poolKey as ClmmKeys;\n\n keys.push(accountMeta({ pubkey: new PublicKey(poolKey.config.id) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolKey.id) }));\n keys.push(accountMeta({ pubkey: new PublicKey(inputIsA ? poolKey.vault.A : poolKey.vault.B) }));\n keys.push(accountMeta({ pubkey: new PublicKey(inputIsA ? poolKey.vault.B : poolKey.vault.A) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolKey.observationId) }));\n keys.push(accountMeta({ pubkey: MEMO_PROGRAM_ID, isWritable: false }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolKey.exBitmapAccount) }));\n clmmPriceLimit.push(clmmPriceLimitX64InsData(_routeInfo.lastPoolPriceX64, inputIsA));\n for (const item of _routeInfo.remainingAccounts ?? []) {\n keys.push(accountMeta({ pubkey: new PublicKey(item) }));\n }\n } else if (_poolKey.programId === ALL_PROGRAM_ID.AMM_STABLE.toBase58()) {\n const poolKey = _poolKey as AmmV5Keys;\n keys.push(accountMeta({ pubkey: new PublicKey(poolKey.id) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolKey.authority), isWritable: false }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolKey.marketProgramId), isWritable: false }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolKey.marketAuthority), isWritable: false }));\n keys.push(accountMeta({ pubkey: LIQUIDITY_POOL_PROGRAM_ID_V5_MODEL, isWritable: false }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolKey.openOrders) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolKey.vault.A) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolKey.vault.B) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolKey.marketId) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolKey.marketBids) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolKey.marketAsks) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolKey.marketEventQueue) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolKey.marketBaseVault) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolKey.marketQuoteVault) }));\n } else if (_poolKey.programId === ALL_PROGRAM_ID.AMM_V4.toBase58()) {\n const poolKey = _poolKey as AmmV4Keys;\n keys.push(accountMeta({ pubkey: new PublicKey(poolKey.id) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolKey.authority), isWritable: false }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolKey.id) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolKey.id) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolKey.id) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolKey.vault.A) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolKey.vault.B) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolKey.id) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolKey.id) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolKey.id) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolKey.id) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolKey.id) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolKey.id) }));\n // keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.marketProgramId), isWritable: false }))\n // keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.marketAuthority), isWritable: false }))\n // keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.openOrder) }))\n // keys.push(accountMeta({ pubkey: new PublicKey(poolKey.vault.A) }))\n // keys.push(accountMeta({ pubkey: new PublicKey(poolKey.vault.B) }))\n // keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.marketId) }))\n // keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.bids) }))\n // keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.asks) }))\n // keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.eventQueue) }))\n // keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.marketVaultA) }))\n // keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.marketVaultB) }))\n } else if (_poolKey.programId === ALL_PROGRAM_ID.CREATE_CPMM_POOL_PROGRAM.toBase58()) {\n const poolKey = _poolKey as CpmmKeys;\n keys.push(accountMeta({ pubkey: new PublicKey(poolKey.authority) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolKey.config.id) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolKey.id) }));\n keys.push(accountMeta({ pubkey: new PublicKey(inputIsA ? poolKey.vault.A : poolKey.vault.B) }));\n keys.push(accountMeta({ pubkey: new PublicKey(inputIsA ? poolKey.vault.B : poolKey.vault.A) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolKey.observationId) }));\n } else throw Error(\"pool type error\");\n }\n const dataLayout = struct([\n u8(\"insId\"),\n u64(\"amountIn\"),\n u64(\"amountOut\"),\n seq(u128(), clmmPriceLimit.length, \"clmmPriceLimit\"),\n ]);\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode(\n {\n insId: 0,\n amountIn: amount,\n amountOut: new BN(routeInfo.data.otherAmountThreshold),\n clmmPriceLimit,\n },\n data,\n );\n return new TransactionInstruction({\n keys,\n programId,\n data,\n });\n}\n\nexport function swapBaseOutAutoAccount({\n programId,\n wallet,\n inputAccount,\n outputAccount,\n routeInfo,\n poolKeys,\n}: {\n programId: PublicKey;\n wallet: PublicKey;\n inputAccount: PublicKey;\n outputAccount: PublicKey;\n routeInfo: ApiSwapV1Out;\n poolKeys: PoolKeys[];\n}): TransactionInstruction {\n if (routeInfo.success === false) throw Error(\"route info error\");\n const clmmPriceLimit: BN[] = [];\n const keys = [\n accountMeta({ pubkey: TOKEN_PROGRAM_ID, isWritable: false }),\n accountMeta({ pubkey: TOKEN_2022_PROGRAM_ID, isWritable: false }),\n accountMeta({ pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isWritable: false }),\n accountMeta({ pubkey: SystemProgram.programId, isWritable: false }),\n accountMeta({ pubkey: wallet, isSigner: true }),\n ];\n const cacheAccount: { [mint: string]: PublicKey } = {\n [routeInfo.data.inputMint]: inputAccount,\n [routeInfo.data.outputMint]: outputAccount,\n };\n for (let index = poolKeys.length - 1; index >= 0; index--) {\n const _routeInfo = routeInfo.data.routePlan[index];\n const _poolKey = poolKeys[index];\n const inputIsA = _routeInfo.inputMint === _poolKey.mintA.address;\n keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.programId) }));\n if (index === 0) {\n keys.push(accountMeta({ pubkey: cacheAccount[_routeInfo.inputMint] }));\n } else {\n const mint = _routeInfo.inputMint;\n if (cacheAccount[mint] === undefined) {\n const ata = getATAAddress(\n wallet,\n new PublicKey(mint),\n _poolKey.programId === ALL_PROGRAM_ID.CLMM_PROGRAM_ID.toBase58() ||\n _poolKey.programId === ALL_PROGRAM_ID.CREATE_CPMM_POOL_PROGRAM.toBase58()\n ? new PublicKey(inputIsA ? _poolKey.mintA.programId : _poolKey.mintB.programId)\n : TOKEN_PROGRAM_ID,\n ).publicKey;\n cacheAccount[mint] = ata;\n }\n keys.push(accountMeta({ pubkey: cacheAccount[mint] }));\n }\n if (index === poolKeys.length - 1) {\n keys.push(accountMeta({ pubkey: cacheAccount[_routeInfo.outputMint] }));\n } else {\n const mint = _routeInfo.outputMint;\n if (cacheAccount[mint] === undefined) {\n const ata = getATAAddress(\n wallet,\n new PublicKey(mint),\n _poolKey.programId === ALL_PROGRAM_ID.CLMM_PROGRAM_ID.toBase58() ||\n _poolKey.programId === ALL_PROGRAM_ID.CREATE_CPMM_POOL_PROGRAM.toBase58()\n ? new PublicKey(inputIsA ? _poolKey.mintB.programId : _poolKey.mintA.programId)\n : TOKEN_PROGRAM_ID,\n ).publicKey;\n cacheAccount[mint] = ata;\n }\n keys.push(accountMeta({ pubkey: cacheAccount[mint] }));\n }\n keys.push(accountMeta({ pubkey: new PublicKey(_routeInfo.inputMint) }));\n keys.push(accountMeta({ pubkey: new PublicKey(_routeInfo.outputMint) }));\n if (_poolKey.programId === ALL_PROGRAM_ID.CLMM_PROGRAM_ID.toBase58()) {\n const poolKey = _poolKey as ClmmKeys;\n keys.push(accountMeta({ pubkey: new PublicKey(poolKey.config.id) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolKey.id) }));\n keys.push(accountMeta({ pubkey: new PublicKey(inputIsA ? poolKey.vault.A : poolKey.vault.B) }));\n keys.push(accountMeta({ pubkey: new PublicKey(inputIsA ? poolKey.vault.B : poolKey.vault.A) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolKey.observationId) }));\n keys.push(accountMeta({ pubkey: MEMO_PROGRAM_ID, isWritable: false }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolKey.exBitmapAccount) }));\n clmmPriceLimit.push(clmmPriceLimitX64InsData(_routeInfo.lastPoolPriceX64, inputIsA));\n for (const item of _routeInfo.remainingAccounts ?? []) {\n keys.push(accountMeta({ pubkey: new PublicKey(item) }));\n }\n } else if (_poolKey.programId === ALL_PROGRAM_ID.AMM_STABLE.toBase58()) {\n const poolkey = _poolKey as AmmV5Keys;\n keys.push(accountMeta({ pubkey: new PublicKey(poolkey.id) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolkey.authority), isWritable: false }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolkey.marketProgramId), isWritable: false }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolkey.marketAuthority), isWritable: false }));\n keys.push(accountMeta({ pubkey: LIQUIDITY_POOL_PROGRAM_ID_V5_MODEL, isWritable: false }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolkey.openOrders) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolkey.vault.A) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolkey.vault.B) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolkey.marketId) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolkey.marketBids) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolkey.marketAsks) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolkey.marketEventQueue) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolkey.marketBaseVault) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolkey.marketQuoteVault) }));\n } else if (_poolKey.programId === ALL_PROGRAM_ID.AMM_V4.toBase58()) {\n const poolkey = _poolKey as AmmV4Keys;\n keys.push(accountMeta({ pubkey: new PublicKey(poolkey.id) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolkey.authority), isWritable: false }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolkey.id) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolkey.id) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolkey.id) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolkey.vault.A) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolkey.vault.B) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolkey.id) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolkey.id) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolkey.id) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolkey.id) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolkey.id) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolkey.id) }));\n // keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.marketProgramId), isWritable: false }))\n // keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.marketAuthority), isWritable: false }))\n // keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.openOrder) }))\n // keys.push(accountMeta({ pubkey: new PublicKey(poolKey.vault.A) }))\n // keys.push(accountMeta({ pubkey: new PublicKey(poolKey.vault.B) }))\n // keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.marketId) }))\n // keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.bids) }))\n // keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.asks) }))\n // keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.eventQueue) }))\n // keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.marketVaultA) }))\n // keys.push(accountMeta({ pubkey: new PublicKey(_poolKey.marketVaultB) }))\n } else if (_poolKey.programId === ALL_PROGRAM_ID.CREATE_CPMM_POOL_PROGRAM.toBase58()) {\n const poolkey = _poolKey as CpmmKeys;\n\n keys.push(accountMeta({ pubkey: new PublicKey(poolkey.authority) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolkey.config.id) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolkey.id) }));\n keys.push(accountMeta({ pubkey: new PublicKey(inputIsA ? poolkey.vault.A : poolkey.vault.B) }));\n keys.push(accountMeta({ pubkey: new PublicKey(inputIsA ? poolkey.vault.B : poolkey.vault.A) }));\n keys.push(accountMeta({ pubkey: new PublicKey(poolkey.observationId) }));\n } else throw Error(\"pool type error\");\n }\n const dataLayout = struct([\n u8(\"insId\"),\n u64(\"amountIn\"),\n u64(\"amountOut\"),\n seq(u128(), clmmPriceLimit.length, \"clmmPriceLimit\"),\n ]);\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode(\n {\n insId: 1,\n amountIn: new BN(routeInfo.data.otherAmountThreshold),\n amountOut: new BN(routeInfo.data.outputAmount),\n clmmPriceLimit,\n },\n data,\n );\n return new TransactionInstruction({\n keys,\n programId,\n data,\n });\n}\n","import { Connection, PublicKey, Signer, Transaction, TransactionInstruction } from \"@solana/web3.js\";\nimport { TOKEN_PROGRAM_ID } from \"@solana/spl-token\";\nimport BN from \"bn.js\";\nimport { findProgramAddress, forecastTransactionSize, getMultipleAccountsInfo } from \"@/common\";\nimport { blob, publicKey, seq, struct, u64, u8 } from \"@/marshmallow\";\nimport { Token } from \"@/module\";\nimport ModuleBase from \"../moduleBase\";\n\nexport interface SHOW_INFO {\n programId: PublicKey;\n poolId: PublicKey;\n ammId: PublicKey;\n ownerAccountId: PublicKey;\n snapshotLpAmount: BN;\n\n openTime: number;\n endTime: number;\n\n project: typeof Utils1216.VERSION_PROJECT[number];\n\n canClaim: boolean;\n canClaimErrorType: canClaimErrorType;\n\n tokenInfo: {\n mintAddress: PublicKey;\n mintVault: PublicKey;\n mintDecimals: number;\n perLpLoss: BN;\n debtAmount: BN;\n }[];\n}\n\nexport type canClaimErrorType = \"outOfOperationalTime\" | \"alreadyClaimIt\" | undefined;\n\nexport default class Utils1216 extends ModuleBase {\n static CLAIMED_NUM = 3;\n static POOL_LAYOUT = struct([\n blob(8),\n u8(\"bump\"),\n u8(\"status\"),\n u64(\"openTime\"),\n u64(\"endTime\"),\n publicKey(\"ammId\"),\n\n seq(\n struct([\n u8(\"mintDecimals\"),\n publicKey(\"mintAddress\"),\n publicKey(\"mintVault\"),\n u64(\"perLpLoss\"),\n u64(\"totalClaimedAmount\"),\n ]),\n Utils1216.CLAIMED_NUM,\n \"tokenInfo\",\n ),\n seq(u64(), 10, \"padding\"),\n ]);\n\n static OWNER_LAYOUT = struct([\n blob(8),\n u8(\"bump\"),\n u8(\"version\"),\n publicKey(\"poolId\"),\n publicKey(\"owner\"),\n u64(\"lpAmount\"),\n\n seq(\n struct([publicKey(\"mintAddress\"), u64(\"debtAmount\"), u64(\"claimedAmount\")]),\n Utils1216.CLAIMED_NUM,\n \"tokenInfo\",\n ),\n seq(u64(), 4, \"padding\"),\n ]);\n\n static DEFAULT_POOL_ID = [\n \"58oQChx4yWmvKdwLLZzBi4ChoCc2fqCUWBkwMihLYQo2\",\n \"6UmmUiYoBjSrhakAobJw8BvkmJtDVxaeBtbt7rxWo1mg\",\n \"AVs9TA4nWDzfPJE9gGVNJMVhcQy3V9PGazuz33BfG2RA\",\n \"DVa7Qmb5ct9RCpaU7UTpSaf3GVMYz17vNVU67XpdCRut\",\n \"7XawhbbxtsRcQA8KTkHT9f9nc6d69UwqCDh6U5EEbEmX\",\n \"6a1CsrpeZubDjEJE9s1CMVheB6HWM5d7m1cj2jkhyXhj\",\n \"EoNrn8iUhwgJySD1pHu8Qxm5gSQqLK3za4m8xzD2RuEb\",\n \"AceAyRTWt4PyB2pHqf2qhDgNZDtKVNaxgL8Ru3V4aN1P\",\n \"6tmFJbMk5yVHFcFy7X2K8RwHjKLr6KVFLYXpgpBNeAxB\",\n ].map((i) => new PublicKey(i));\n\n static SEED_CONFIG = {\n pool: {\n id: Buffer.from(\"pool_seed\", \"utf8\"),\n },\n owner: {\n id: Buffer.from(\"user_claim_seed\", \"utf8\"),\n },\n };\n\n static VERSION_PROJECT = [undefined, \"Francium\", \"Tulip\", \"Larix\"] as const;\n\n // pda\n static getPdaPoolId(\n programId: PublicKey,\n ammId: PublicKey,\n ): {\n publicKey: PublicKey;\n nonce: number;\n } {\n return findProgramAddress([Utils1216.SEED_CONFIG.pool.id, ammId.toBuffer()], programId);\n }\n\n static getPdaOwnerId(\n programId: PublicKey,\n poolId: PublicKey,\n owner: PublicKey,\n version: number,\n ): {\n publicKey: PublicKey;\n nonce: number;\n } {\n return findProgramAddress(\n [\n Utils1216.SEED_CONFIG.owner.id,\n poolId.toBuffer(),\n owner.toBuffer(),\n // new BN(version).toBuffer()\n Buffer.from(new BN(version).toArray()),\n ],\n programId,\n );\n }\n\n static async getAllInfo({\n connection,\n programId,\n poolIds,\n wallet,\n chainTime,\n }: {\n connection: Connection;\n programId: PublicKey;\n poolIds: PublicKey[];\n wallet: PublicKey;\n chainTime: number;\n }): Promise<SHOW_INFO[]> {\n if (poolIds.length === 0) return [];\n\n const allPoolPda = poolIds.map((id) => Utils1216.getPdaPoolId(programId, id).publicKey);\n\n const allOwnerPda: PublicKey[] = [];\n for (let itemVersion = 0; itemVersion < Utils1216.VERSION_PROJECT.length; itemVersion++) {\n allOwnerPda.push(\n ...allPoolPda.map((id) => Utils1216.getPdaOwnerId(programId, id, wallet, itemVersion).publicKey),\n );\n }\n\n const pdaInfo = await getMultipleAccountsInfo(connection, [...allPoolPda, ...allOwnerPda]);\n\n const info: SHOW_INFO[] = [];\n for (let index = 0; index < pdaInfo.length; index++) {\n const version = Math.floor(index / poolIds.length);\n const i = index % poolIds.length;\n\n const itemPoolId = allPoolPda[i];\n const itemOwnerId = allOwnerPda[index];\n const itemPoolInfoS = pdaInfo[i];\n const itemOwnerInfoS = pdaInfo[poolIds.length + index];\n if (!(itemPoolInfoS && itemOwnerInfoS)) continue;\n if (\n itemPoolInfoS.data.length !== Utils1216.POOL_LAYOUT.span ||\n itemOwnerInfoS.data.length !== Utils1216.OWNER_LAYOUT.span\n )\n continue;\n\n const itemPoolInfo = Utils1216.POOL_LAYOUT.decode(itemPoolInfoS.data);\n const itemOwnerInfo = Utils1216.OWNER_LAYOUT.decode(itemOwnerInfoS.data);\n\n const openTime = itemPoolInfo.openTime.toNumber();\n const endTime = itemPoolInfo.endTime.toNumber();\n\n const hasCanClaimToken =\n itemOwnerInfo.tokenInfo.map((i) => i.debtAmount.gt(new BN(0))).filter((i) => !i).length !== 3;\n const inCanClaimTime = chainTime > openTime && chainTime < endTime && itemPoolInfo.status === 1;\n\n const canClaim = hasCanClaimToken && inCanClaimTime;\n\n info.push({\n programId,\n poolId: itemPoolId,\n ammId: itemPoolInfo.ammId,\n ownerAccountId: itemOwnerId,\n snapshotLpAmount: itemOwnerInfo.lpAmount,\n\n project: Utils1216.VERSION_PROJECT[version],\n\n openTime,\n endTime,\n\n canClaim,\n canClaimErrorType: !hasCanClaimToken ? \"alreadyClaimIt\" : !inCanClaimTime ? \"outOfOperationalTime\" : undefined,\n\n tokenInfo: itemPoolInfo.tokenInfo.map((itemPoolToken, i) => ({\n mintAddress: itemPoolToken.mintAddress,\n mintVault: itemPoolToken.mintVault,\n mintDecimals: itemPoolToken.mintDecimals,\n perLpLoss: itemPoolToken.perLpLoss,\n debtAmount: itemOwnerInfo.tokenInfo[i].debtAmount.add(itemOwnerInfo.tokenInfo[i].claimedAmount),\n })),\n });\n }\n\n return info;\n }\n\n public async makeClaimTransaction({\n poolInfo,\n ownerInfo,\n feePayer,\n }: {\n connection: Connection;\n poolInfo: SHOW_INFO;\n ownerInfo: {\n wallet?: PublicKey;\n associatedOnly: boolean;\n };\n feePayer?: PublicKey;\n }): Promise<\n {\n transaction: Transaction;\n signer: Signer[];\n }[]\n > {\n if (!ownerInfo.wallet) this.scope.checkOwner();\n const txBuilder = this.createTxBuilder(feePayer);\n const wallet = ownerInfo.wallet || this.scope.ownerPubKey;\n\n const ownerVaultList: PublicKey[] = [];\n for (const itemToken of poolInfo.tokenInfo) {\n const { account, instructionParams } = await this.scope.account.getOrCreateTokenAccount({\n mint: itemToken.mintAddress,\n owner: this.scope.ownerPubKey,\n notUseTokenAccount: itemToken.mintAddress.equals(Token.WSOL.mint),\n createInfo: {\n payer: wallet,\n amount: 0,\n },\n skipCloseAccount: !itemToken.mintAddress.equals(Token.WSOL.mint),\n\n associatedOnly: itemToken.mintAddress.equals(Token.WSOL.mint) ? false : ownerInfo.associatedOnly,\n });\n instructionParams && txBuilder.addInstruction(instructionParams);\n ownerVaultList.push(account!);\n }\n\n txBuilder.addInstruction({\n instructions: [\n Utils1216.makeClaimInstruction({\n programId: poolInfo.programId,\n poolInfo,\n ownerInfo: {\n wallet,\n ownerPda: poolInfo.ownerAccountId,\n claimAddress: ownerVaultList,\n },\n }),\n ],\n });\n const { transaction, signers } = txBuilder.build();\n\n return [\n {\n transaction,\n signer: signers,\n },\n ];\n }\n\n public async makeClaimAllTransaction({\n poolInfos,\n ownerInfo,\n feePayer,\n }: {\n poolInfos: SHOW_INFO[];\n ownerInfo: {\n wallet?: PublicKey;\n associatedOnly: boolean;\n };\n feePayer?: PublicKey;\n }): Promise<\n {\n transaction: Transaction;\n signer: Signer[];\n }[]\n > {\n const txBuilder = this.createTxBuilder(feePayer);\n const wallet = ownerInfo.wallet || this.scope.ownerPubKey;\n\n const tempNewVault: { [mint: string]: PublicKey } = {};\n\n for (const poolInfo of poolInfos) {\n const ownerVaultList: PublicKey[] = [];\n for (const itemToken of poolInfo.tokenInfo) {\n const { account: tempVault, instructionParams } = await this.scope.account.getOrCreateTokenAccount({\n mint: itemToken.mintAddress,\n owner: this.scope.ownerPubKey,\n notUseTokenAccount: itemToken.mintAddress.equals(Token.WSOL.mint),\n createInfo: {\n payer: wallet,\n amount: 0,\n },\n skipCloseAccount: !itemToken.mintAddress.equals(Token.WSOL.mint),\n\n associatedOnly: itemToken.mintAddress.equals(Token.WSOL.mint) ? false : ownerInfo.associatedOnly,\n });\n instructionParams && txBuilder.addInstruction(instructionParams);\n\n if (tempVault) {\n tempNewVault[itemToken.mintAddress.toString()] = tempVault;\n ownerVaultList.push(tempVault);\n }\n }\n\n txBuilder.addInstruction({\n instructions: [\n Utils1216.makeClaimInstruction({\n programId: poolInfo.programId,\n poolInfo,\n ownerInfo: {\n wallet,\n ownerPda: poolInfo.ownerAccountId,\n claimAddress: ownerVaultList,\n },\n }),\n ],\n });\n }\n\n const { transaction, signers } = txBuilder.build();\n const instructions = txBuilder.allInstructions;\n\n if (forecastTransactionSize(instructions, [wallet, ...signers.map((s) => s.publicKey)])) {\n return [\n {\n transaction,\n signer: signers,\n },\n ];\n } else {\n return [\n {\n transaction: new Transaction().add(...instructions.slice(0, txBuilder.AllTxData.instructions.length - 1)),\n signer: signers,\n },\n {\n transaction: new Transaction().add(...instructions.slice(txBuilder.AllTxData.instructions.length - 1)),\n signer: [],\n },\n { transaction: new Transaction().add(...txBuilder.AllTxData.endInstructions), signer: [] },\n ];\n }\n }\n\n static makeClaimInstruction({\n programId,\n poolInfo,\n ownerInfo,\n }: {\n programId: PublicKey;\n\n poolInfo: SHOW_INFO;\n ownerInfo: {\n wallet: PublicKey;\n ownerPda: PublicKey;\n claimAddress: PublicKey[];\n };\n }): TransactionInstruction {\n const dataLayout = struct([]);\n\n const keys = [\n { pubkey: ownerInfo.wallet, isSigner: true, isWritable: true },\n { pubkey: poolInfo.poolId, isSigner: false, isWritable: true },\n { pubkey: ownerInfo.ownerPda, isSigner: false, isWritable: true },\n\n ...ownerInfo.claimAddress.map((i) => ({ pubkey: i, isSigner: false, isWritable: true })),\n ...poolInfo.tokenInfo.map(({ mintVault }) => ({ pubkey: mintVault, isSigner: false, isWritable: true })),\n\n { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n ];\n\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode({}, data);\n const aData = Buffer.from([...[10, 66, 208, 184, 161, 6, 191, 98], ...data]);\n\n return new TransactionInstruction({\n keys,\n programId,\n data: aData,\n });\n }\n}\n","import { PublicKey } from \"@solana/web3.js\";\nimport {\n getTransferFeeConfig,\n MintLayout,\n TOKEN_2022_PROGRAM_ID,\n TOKEN_PROGRAM_ID,\n unpackMint,\n} from \"@solana/spl-token\";\n\nimport { ApiV3Token, JupTokenType } from \"@/api/type\";\nimport ModuleBase, { ModuleBaseProps } from \"../moduleBase\";\nimport { LoadParams } from \"../type\";\n\nimport { SOL_INFO } from \"./constant\";\nimport { TokenInfo } from \"./type\";\nimport { toFeeConfig } from \"./utils\";\n\nexport default class TokenModule extends ModuleBase {\n private _tokenList: TokenInfo[] = [];\n private _tokenMap: Map<string, TokenInfo> = new Map();\n private _blackTokenMap: Set<string> = new Set();\n private _mintGroup: { official: Set<string>; jup: Set<string>; extra: Set<string> } = {\n official: new Set(),\n jup: new Set(),\n extra: new Set(),\n };\n private _whiteMap: Set<string> = new Set();\n private _extraTokenList: TokenInfo[] = [];\n\n constructor(params: ModuleBaseProps) {\n super(params);\n }\n\n public async load(params?: LoadParams & { type?: JupTokenType }): Promise<void> {\n this.checkDisabled();\n const { forceUpdate = false, type = JupTokenType.Strict } = params || {};\n const { mintList, blacklist, whiteList } = await this.scope.fetchV3TokenList(forceUpdate);\n const jup = await this.scope.fetchJupTokenList(forceUpdate);\n // reset all data\n this._tokenList = [];\n this._tokenMap = new Map();\n this._blackTokenMap = new Set(blacklist);\n this._mintGroup = { official: new Set(), jup: new Set(), extra: new Set() };\n this._whiteMap = new Set(whiteList);\n\n this._tokenMap.set(SOL_INFO.address, SOL_INFO);\n this._mintGroup.official.add(SOL_INFO.address);\n\n mintList.forEach((token) => {\n if (this._blackTokenMap.has(token.address)) return;\n this._tokenMap.set(token.address, {\n ...token,\n type: \"raydium\",\n priority: 2,\n programId:\n token.programId ??\n (token.tags.includes(\"token-2022\") ? TOKEN_2022_PROGRAM_ID.toBase58() : TOKEN_PROGRAM_ID.toBase58()),\n });\n this._mintGroup.official.add(token.address);\n });\n\n jup.forEach((token) => {\n if (this._blackTokenMap.has(token.address) || this._tokenMap.has(token.address)) return;\n this._tokenMap.set(token.address, {\n ...token,\n type: \"jupiter\",\n priority: 1,\n programId:\n token.programId ??\n (token.tags.includes(\"token-2022\") ? TOKEN_2022_PROGRAM_ID.toBase58() : TOKEN_PROGRAM_ID.toBase58()),\n tags: token.freezeAuthority ? [...(token.tags || []), \"hasFreeze\"] : token.tags,\n });\n this._mintGroup.jup.add(token.address);\n });\n\n this._extraTokenList.forEach((token) => {\n if (this._blackTokenMap.has(token.address) || this._tokenMap.has(token.address)) return;\n this._tokenMap.set(token.address, {\n ...token,\n type: \"extra\",\n priority: 1,\n programId:\n token.programId || token.tags.includes(\"token-2022\")\n ? TOKEN_2022_PROGRAM_ID.toBase58()\n : TOKEN_PROGRAM_ID.toBase58(),\n });\n this._mintGroup.extra.add(token.address);\n });\n\n this._tokenList = Array.from(this._tokenMap).map((data) => data[1]);\n }\n\n get tokenList(): TokenInfo[] {\n return this._tokenList;\n }\n get tokenMap(): Map<string, TokenInfo> {\n return this._tokenMap;\n }\n get blackTokenMap(): Set<string> {\n return this._blackTokenMap;\n }\n get mintGroup(): { official: Set<string>; jup: Set<string> } {\n return this._mintGroup;\n }\n get whiteListMap(): Set<string> {\n return this._whiteMap;\n }\n\n /** === util functions === */\n\n public async getTokenInfo(mint: string | PublicKey): Promise<ApiV3Token> {\n if (!mint) throw new Error(\"please input mint\");\n const mintStr = mint.toString();\n const info = this._tokenMap.get(mintStr);\n if (info) return info;\n if (mintStr.toLocaleUpperCase() === \"SOL\") return SOL_INFO;\n\n const apiTokenInfo = (await this.scope.api.getTokenInfo([mintStr]))[0];\n if (apiTokenInfo) {\n this._mintGroup.extra.add(mintStr);\n this._tokenMap.set(mintStr, { ...apiTokenInfo, priority: 2 });\n return apiTokenInfo;\n }\n\n const onlineInfo = await this.scope.connection.getAccountInfo(new PublicKey(mintStr));\n if (!onlineInfo) throw new Error(`mint address not found: ${mintStr}`);\n const data = MintLayout.decode(onlineInfo.data as any);\n const mintSymbol = mintStr.toString().substring(0, 6);\n const transferFeeConfig = getTransferFeeConfig(unpackMint(new PublicKey(mint), onlineInfo, onlineInfo.owner));\n const fullInfo = {\n chainId: 101,\n address: mintStr,\n programId: onlineInfo.owner.toBase58(),\n logoURI: \"\",\n symbol: mintSymbol,\n name: mintSymbol,\n decimals: data.decimals,\n tags: [],\n extensions: transferFeeConfig\n ? {\n feeConfig: toFeeConfig(transferFeeConfig),\n }\n : {},\n priority: 0,\n type: \"unknown\",\n };\n this._mintGroup.extra.add(mintStr);\n this._tokenMap.set(mintStr, fullInfo);\n return fullInfo;\n }\n}\n","/**\n * https://youmightnotneed.com/lodash/\n */\n\nexport function chunkArray<T>(arr: T[], chunkSize = 1, cache: T[][] = []): T[][] {\n const tmp = [...arr];\n if (chunkSize <= 0) return cache;\n while (tmp.length) cache.push(tmp.splice(0, chunkSize));\n return cache;\n}\n\nexport function intersection<T>(arr: T[], ...args: T[][]): T[] {\n return arr.filter((item) => args.every((arr) => arr.includes(item)));\n}\n\nexport function xor<T>(arr: T[], ...args: T[][]): T[] {\n return arr.filter((item) => args.every((arr) => !arr.includes(item)));\n}\n\nexport function uniq<T>(arr: T[]): T[] {\n return [...new Set(arr)];\n}\n"],"mappings":"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","names":[]}