UNPKG

test-raydium-sdk-v2

Version:

An SDK for building applications on top of Raydium.

1 lines 689 kB
{"version":3,"sources":["../../../src/raydium/clmm/clmm.ts","../../../node_modules/decimal.js/decimal.mjs","../../../src/common/logger.ts","../../../src/common/utility.ts","../../../src/module/amount.ts","../../../src/common/bignumber.ts","../../../src/module/token.ts","../../../src/common/pubKey.ts","../../../src/raydium/token/constant.ts","../../../src/module/fraction.ts","../../../src/module/formatter.ts","../../../src/module/price.ts","../../../src/module/currency.ts","../../../src/module/percent.ts","../../../src/common/txTool/txTool.ts","../../../src/common/txTool/txType.ts","../../../src/common/txTool/txUtils.ts","../../../src/common/txTool/lookupTable.ts","../../../src/common/accountInfo.ts","../../../src/common/lodash.ts","../../../src/common/programId.ts","../../../src/common/pda.ts","../../../src/common/transfer.ts","../../../src/raydium/moduleBase.ts","../../../src/raydium/clmm/utils/constants.ts","../../../src/raydium/clmm/utils/math.ts","../../../src/raydium/clmm/utils/util.ts","../../../src/raydium/clmm/utils/pda.ts","../../../src/raydium/clmm/utils/pool.ts","../../../src/raydium/clmm/utils/tick.ts","../../../src/marshmallow/index.ts","../../../src/marshmallow/buffer-layout.ts","../../../src/raydium/clmm/utils/tickarrayBitmap.ts","../../../src/raydium/clmm/layout.ts","../../../src/raydium/clmm/utils/tickQuery.ts","../../../src/raydium/clmm/utils/position.ts","../../../src/raydium/clmm/instrument.ts","../../../src/raydium/account/util.ts","../../../src/raydium/account/layout.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"],"sourcesContent":["import { PublicKey } from \"@solana/web3.js\";\nimport Decimal from \"decimal.js\";\nimport { InstructionType, WSOLMint, getTransferAmountFee } from \"@/common\";\nimport { Percent } from \"@/module/percent\";\nimport { ApiV3PoolInfoConcentratedItem, ClmmKeys } from \"@/api/type\";\nimport { MakeTxData, MakeMultiTxData } from \"@/common/txTool/txTool\";\nimport { TxVersion } from \"@/common/txTool/txType\";\nimport { getATAAddress } from \"@/common\";\nimport ModuleBase, { ModuleBaseProps } from \"../moduleBase\";\nimport { mockV3CreatePoolInfo, MAX_SQRT_PRICE_X64, MIN_SQRT_PRICE_X64, ONE } from \"./utils/constants\";\nimport { SqrtPriceMath } from \"./utils/math\";\nimport { PoolUtils } from \"./utils/pool\";\nimport {\n CreateConcentratedPool,\n IncreasePositionFromLiquidity,\n IncreasePositionFromBase,\n DecreaseLiquidity,\n OpenPositionFromBase,\n OpenPositionFromLiquidity,\n InitRewardParams,\n InitRewardsParams,\n SetRewardParams,\n SetRewardsParams,\n CollectRewardParams,\n CollectRewardsParams,\n ManipulateLiquidityExtInfo,\n ReturnTypeComputeAmountOutBaseOut,\n OpenPositionFromLiquidityExtInfo,\n OpenPositionFromBaseExtInfo,\n ClosePositionExtInfo,\n InitRewardExtInfo,\n HarvestAllRewardsParams,\n} from \"./type\";\nimport { ClmmInstrument } from \"./instrument\";\nimport { LoadParams, MakeTransaction, ReturnTypeFetchMultipleMintInfos } from \"../type\";\nimport { MathUtil } from \"./utils/math\";\nimport { TickArray } from \"./utils/tick\";\nimport { getPdaOperationAccount } from \"./utils/pda\";\nimport { ClmmPositionLayout, OperationLayout } from \"./layout\";\nimport BN from \"bn.js\";\n\nexport class Clmm extends ModuleBase {\n constructor(params: ModuleBaseProps) {\n super(params);\n }\n\n public async load(params?: LoadParams): Promise<void> {\n await this.scope.token.load(params);\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 startTime,\n computeBudgetConfig,\n forerunCreate,\n txVersion,\n } = props;\n const txBuilder = this.createTxBuilder();\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 = SqrtPriceMath.priceToSqrtPriceX64(initPrice, mintA.decimals, mintB.decimals);\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 startTime,\n forerunCreate,\n });\n\n txBuilder.addInstruction(insInfo);\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n\n return txBuilder.versionBuild<{\n mockPoolInfo: ApiV3PoolInfoConcentratedItem;\n address: ClmmKeys;\n forerunCreate?: boolean;\n }>({\n txVersion,\n extInfo: {\n address: {\n ...insInfo.address,\n programId: programId.toString(),\n id: insInfo.address.poolId.toString(),\n mintA,\n mintB,\n openTime: startTime.toNumber(),\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 id: insInfo.address.poolId.toString(),\n mintA,\n mintB,\n feeRate: ammConfig.tradeFeeRate,\n openTime: startTime.toNumber(),\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 ...mockV3CreatePoolInfo,\n },\n forerunCreate,\n },\n }) as Promise<MakeTxData<T, { mockPoolInfo: ApiV3PoolInfoConcentratedItem; address: ClmmKeys }>>;\n }\n\n public async openPositionFromBase<T extends TxVersion>({\n poolInfo,\n poolKeys: propPoolKeys,\n ownerInfo,\n tickLower,\n tickUpper,\n base,\n baseAmount,\n otherAmountMax,\n associatedOnly = true,\n checkCreateATAOwner = false,\n withMetadata = \"create\",\n getEphemeralSigners,\n computeBudgetConfig,\n txVersion,\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();\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\", this.scope.account.tokenAccounts);\n\n const poolKeys = propPoolKeys || ((await this.scope.api.fetchPoolKeysById({ id: poolInfo.id })) as ClmmKeys);\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 withMetadata,\n getEphemeralSigners,\n });\n\n txBuilder.addInstruction(insInfo);\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n return txBuilder.versionBuild<OpenPositionFromBaseExtInfo>({ txVersion, extInfo: insInfo.address }) as Promise<\n MakeTxData<T, OpenPositionFromBaseExtInfo>\n >;\n }\n\n public async openPositionFromLiquidity<T extends TxVersion>({\n poolInfo,\n poolKeys: propPoolKeys,\n ownerInfo,\n amountMaxA,\n amountMaxB,\n tickLower,\n tickUpper,\n liquidity,\n associatedOnly = true,\n checkCreateATAOwner = false,\n withMetadata = \"create\",\n txVersion,\n getEphemeralSigners,\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();\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: mintAUseSOLBalance\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: mintBUseSOLBalance\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.scope.api.fetchPoolKeysById({ id: poolInfo.id })) as ClmmKeys);\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 withMetadata,\n getEphemeralSigners,\n });\n txBuilder.addInstruction(makeOpenPositionInstructions);\n\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 ownerPosition,\n amountMaxA,\n amountMaxB,\n liquidity,\n ownerInfo,\n associatedOnly = true,\n checkCreateATAOwner = false,\n computeBudgetConfig,\n txVersion,\n } = props;\n const txBuilder = this.createTxBuilder();\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\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: mintAUseSOLBalance\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\n const { account: _ownerTokenAccountB, instructionParams: _tokenAccountBInstruction } =\n await this.scope.account.getOrCreateTokenAccount({\n mint: new PublicKey(poolInfo.mintB.address),\n owner: this.scope.ownerPubKey,\n\n createInfo: mintBUseSOLBalance\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 = (await this.scope.api.fetchPoolKeysById({ id: poolInfo.id })) as ClmmKeys;\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 });\n txBuilder.addInstruction(ins);\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n\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 txVersion,\n } = props;\n const txBuilder = this.createTxBuilder();\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: mintAUseSOLBalance\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 mint: new PublicKey(poolInfo.mintB.address),\n owner: this.scope.ownerPubKey,\n\n createInfo: mintBUseSOLBalance\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.scope.api.fetchPoolKeysById({ id: poolInfo.id })) as ClmmKeys;\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 });\n txBuilder.addInstruction(ins);\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n\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 ownerPosition,\n ownerInfo,\n amountMinA,\n amountMinB,\n liquidity,\n associatedOnly = true,\n checkCreateATAOwner = false,\n computeBudgetConfig,\n txVersion,\n } = props;\n if (this.scope.availability.removeConcentratedPosition === false)\n this.logAndCreateError(\"remove position feature disabled in your region\");\n const txBuilder = this.createTxBuilder();\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 rewardAccounts: PublicKey[] = [];\n for (const itemReward of poolInfo.rewardDefaultInfos) {\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 poolKeys = (await this.scope.api.fetchPoolKeysById({ id: poolInfo.id })) as ClmmKeys;\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 });\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 });\n txBuilder.addInstruction({\n endInstructions: closeInsInfo.instructions,\n endInstructionTypes: closeInsInfo.instructionTypes,\n });\n extInfo = { ...extInfo, ...closeInsInfo.address };\n }\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n\n return txBuilder.versionBuild<ManipulateLiquidityExtInfo>({\n txVersion,\n extInfo: { address: extInfo },\n }) as Promise<MakeTxData<T, ManipulateLiquidityExtInfo>>;\n }\n\n public async closePosition<T extends TxVersion>({\n poolInfo,\n ownerPosition,\n txVersion,\n }: {\n poolInfo: ApiV3PoolInfoConcentratedItem;\n ownerPosition: ClmmPositionLayout;\n txVersion: T;\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();\n const poolKeys = (await this.scope.api.fetchPoolKeysById({ id: poolInfo.id })) as ClmmKeys;\n const ins = ClmmInstrument.closePositionInstructions({\n poolInfo,\n poolKeys,\n ownerInfo: { wallet: this.scope.ownerPubKey },\n ownerPosition,\n });\n\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 }: 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();\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.address),\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.scope.api.fetchPoolKeysById({ id: poolInfo.id })) as ClmmKeys;\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: MathUtil.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 ownerInfo,\n rewardInfos,\n associatedOnly = true,\n checkCreateATAOwner = false,\n computeBudgetConfig,\n txVersion,\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();\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 = (await this.scope.api.fetchPoolKeysById({ id: poolInfo.id })) as ClmmKeys;\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: MathUtil.decimalToX64(rewardInfo.perSecond),\n },\n });\n address = {\n ...address,\n ...insInfo.address,\n };\n txBuilder.addInstruction(insInfo);\n }\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\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 txVersion,\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();\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.sub(rewardInfo.endTime - rewardInfo.openTime).toFixed(0)).gte(\n rewardInfo.perSecond.sub(rewardInfo.endTime - rewardInfo.openTime),\n )\n ? rewardInfo.perSecond.sub(rewardInfo.endTime - rewardInfo.openTime).toFixed(0)\n : rewardInfo.perSecond\n .sub(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.scope.api.fetchPoolKeysById({ id: poolInfo.id })) as ClmmKeys;\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: MathUtil.decimalToX64(rewardInfo.perSecond),\n },\n });\n\n txBuilder.addInstruction(insInfo);\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\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 ownerInfo,\n rewardInfos,\n associatedOnly = true,\n checkCreateATAOwner = false,\n computeBudgetConfig,\n txVersion,\n }: SetRewardsParams<T>): Promise<MakeTxData<T, { address: Record<string, PublicKey> }>> {\n const txBuilder = this.createTxBuilder();\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.sub(rewardInfo.endTime - rewardInfo.openTime).toFixed(0)).gte(\n rewardInfo.perSecond.sub(rewardInfo.endTime - rewardInfo.openTime),\n )\n ? rewardInfo.perSecond.sub(rewardInfo.endTime - rewardInfo.openTime).toFixed(0)\n : rewardInfo.perSecond\n .sub(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 = (await this.scope.api.fetchPoolKeysById({ id: poolInfo.id })) as ClmmKeys;\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: MathUtil.decimalToX64(rewardInfo.perSecond),\n },\n });\n txBuilder.addInstruction(insInfo);\n address = {\n ...address,\n ...insInfo.address,\n };\n }\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\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({\n poolInfo,\n ownerInfo,\n rewardMint,\n associatedOnly = true,\n checkCreateATAOwner = false,\n }: CollectRewardParams): Promise<MakeTransaction> {\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();\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.scope.api.fetchPoolKeysById({ id: poolInfo.id })) as ClmmKeys;\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\n return txBuilder.build<{ address: Record<string, PublicKey> }>({ address: insInfo.address });\n }\n\n public async collectRewards({\n poolInfo,\n ownerInfo,\n rewardMints,\n associatedOnly = true,\n checkCreateATAOwner = false,\n }: CollectRewardsParams): Promise<MakeTransaction> {\n const txBuilder = this.createTxBuilder();\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.scope.api.fetchPoolKeysById({ id: poolInfo.id })) as ClmmKeys;\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\n return txBuilder.build<{ address: Record<string, PublicKey> }>({ address });\n }\n\n public async harvestAllRewards<T extends TxVersion = TxVersion.LEGACY>({\n allPoolInfo,\n allPositions,\n ownerInfo,\n associatedOnly = true,\n checkCreateATAOwner = false,\n programId,\n txVersion,\n computeBudgetConfig,\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 txBuilder = this.createTxBuilder();\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\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 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: true,\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 }\n\n let ownerTokenAccountB = ownerMintToAccount[poolInfo.mintB.address];\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: true,\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 }\n\n ownerMintToAccount[poolInfo.mintA.address] = ownerTokenAccountA;\n ownerMintToAccount[poolInfo.mintB.address] = ownerTokenAccountB;\n\n const rewardAccounts: PublicKey[] = [];\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.scope.api.fetchPoolKeysById({ id: poolInfo.id })) as ClmmKeys;\n\n for (const itemPosition of allPositions[itemInfo.id]) {\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 });\n txBuilder.addInstruction(insData);\n }\n }\n\n if (txVersion === TxVersion.V0) return txBuilder.sizeCheckBuildV0() as Promise<MakeMultiTxData<T>>;\n return txBuilder.sizeCheckBuild() 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 computeAmountIn({\n poolInfo,\n tickArrayCache,\n baseMint,\n token2022Infos,\n amountOut,\n slippage,\n priceLimit = new Decimal(0),\n }: {\n poolInfo: ApiV3PoolInfoConcentratedItem;\n tickArrayCache: { [key: string]: TickArray };\n baseMint: PublicKey;\n token2022Infos: ReturnTypeFetchMultipleMintInfos;\n amountOut: BN;\n slippage: number;\n priceLimit?: Decimal;\n }): Promise<ReturnTypeComputeAmountOutBaseOut> {\n const epochInfo = await this.scope.fetchEpochInfo();\n\n let sqrtPriceLimitX64: BN;\n if (priceLimit.equals(new Decimal(0))) {\n sqrtPriceLimitX64 =\n baseMint.toString() === poolInfo.mintB.address ? MIN_SQRT_PRICE_X64.add(ONE) : MAX_SQRT_PRICE_X64.sub(ONE);\n } else {\n sqrtPriceLimitX64 = SqrtPriceMath.priceToSqrtPriceX64(\n priceLimit,\n poolInfo.mintA.decimals,\n poolInfo.mintB.decimals,\n );\n }\n\n const realAmountOut = getTransferAmountFee(\n amountOut,\n token2022Infos[baseMint.toString()]?.feeConfig,\n