UNPKG

@raydium-io/raydium-sdk-v2

Version:

An SDK for building applications on top of Raydium.

1 lines 1.3 MB
{"version":3,"sources":["../../../../src/raydium/clmm/libraries/pool.ts","../../../../src/marshmallow/index.ts","../../../../src/marshmallow/buffer-layout.ts","../../../../src/raydium/clmm/libraries/constants.ts","../../../../src/raydium/clmm/layout.ts","../../../../src/raydium/clmm/libraries/bigNum.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","../../../../src/raydium/account/layout.ts","../../../../src/raydium/farm/farm.ts","../../../../src/common/pda.ts","../../../../src/common/programId.ts","../../../../src/raydium/clmm/clmm.ts","../../../../src/raydium/token/utils.ts","../../../../src/raydium/token/layout.ts","../../../../src/raydium/clmm/instrument.ts","../../../../src/raydium/clmm/libraries/utils.ts","../../../../src/raydium/clmm/libraries/pda.ts","../../../../src/raydium/clmm/libraries/limitOrder.ts","../../../../src/raydium/clmm/libraries/liquidityMath.ts","../../../../src/raydium/clmm/libraries/sqrtPriceMath.ts","../../../../src/raydium/clmm/libraries/position.ts","../../../../src/raydium/clmm/libraries/swapMath.ts","../../../../src/raydium/clmm/libraries/swapSimulator.ts","../../../../src/raydium/farm/config.ts","../../../../src/raydium/farm/layout.ts","../../../../src/raydium/farm/instruction.ts","../../../../src/raydium/farm/util.ts","../../../../src/common/utility.ts","../../../../src/raydium/liquidity/liquidity.ts","../../../../src/common/transfer.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","../../../../src/raydium/clmm/libraries/tickArrayUtil.ts"],"sourcesContent":["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 if (tickIndex % tickSpacing == 0 || tickIndex >= 0) {\n return tickIndex / tickSpacing;\n } else {\n return tickIndex / tickSpacing - 1;\n }\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 } 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\";\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(pool: ComputeClmmPoolInfo): ApiV3PoolInfoConcentratedItem {\n return {\n ...pool,\n type: \"Concentrated\",\n programId: pool.programId.toString(),\n id: pool.id.toString(),\n rewardDefaultInfos: [],\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, { 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 ])