@raydium-io/raydium-sdk-v2
Version:
An SDK for building applications on top of Raydium.
1 lines • 1.29 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/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/ido/ido.ts","../../../src/raydium/ido/instruction.ts","../../../src/raydium/ido/layout.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 funct