UNPKG

test-raydium-sdk-v2

Version:

An SDK for building applications on top of Raydium.

1 lines 776 kB
{"version":3,"sources":["../../../src/raydium/liquidity/liquidity.ts","../../../src/module/amount.ts","../../../src/common/bignumber.ts","../../../node_modules/decimal.js/decimal.mjs","../../../src/module/token.ts","../../../src/common/pubKey.ts","../../../src/raydium/token/constant.ts","../../../src/common/logger.ts","../../../src/module/fraction.ts","../../../src/module/formatter.ts","../../../src/module/price.ts","../../../src/module/currency.ts","../../../src/module/percent.ts","../../../src/common/utility.ts","../../../src/marshmallow/index.ts","../../../src/marshmallow/buffer-layout.ts","../../../src/raydium/token/layout.ts","../../../src/raydium/token/utils.ts","../../../src/common/pda.ts","../../../src/common/txTool/txUtils.ts","../../../src/common/txTool/txType.ts","../../../src/common/txTool/txTool.ts","../../../src/common/txTool/lookupTable.ts","../../../src/common/accountInfo.ts","../../../src/common/lodash.ts","../../../src/common/programId.ts","../../../src/common/transfer.ts","../../../src/raydium/moduleBase.ts","../../../src/raydium/liquidity/instruction.ts","../../../src/raydium/liquidity/layout.ts","../../../src/raydium/liquidity/stable.ts","../../../src/raydium/clmm/instrument.ts","../../../src/raydium/clmm/utils/tick.ts","../../../src/raydium/clmm/utils/util.ts","../../../src/raydium/clmm/utils/pda.ts","../../../src/raydium/clmm/utils/constants.ts","../../../src/raydium/clmm/utils/tickQuery.ts","../../../src/raydium/clmm/utils/math.ts","../../../src/raydium/clmm/utils/pool.ts","../../../src/raydium/clmm/utils/tickarrayBitmap.ts","../../../src/raydium/clmm/utils/position.ts","../../../src/raydium/clmm/layout.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","../../../src/raydium/liquidity/utils.ts","../../../src/raydium/liquidity/serum.ts","../../../src/raydium/liquidity/constant.ts","../../../src/raydium/farm/config.ts","../../../src/raydium/farm/layout.ts","../../../src/raydium/farm/util.ts","../../../src/raydium/farm/instruction.ts"],"sourcesContent":["import { PublicKey } from \"@solana/web3.js\";\nimport { NATIVE_MINT, TOKEN_PROGRAM_ID } from \"@solana/spl-token\";\nimport {\n ApiV3PoolInfoConcentratedItem,\n ApiV3PoolInfoStandardItem,\n AmmV4Keys,\n AmmV5Keys,\n ClmmKeys,\n FormatFarmInfoOutV6,\n} from \"@/api/type\";\nimport { Token, TokenAmount, Percent } from \"@/module\";\nimport { solToWSol } from \"@/common/pubKey\";\nimport { toToken } from \"../token\";\nimport { BN_ZERO, BN_ONE, divCeil } from \"@/common/bignumber\";\nimport { getATAAddress } from \"@/common/pda\";\nimport { InstructionType, TxVersion } from \"@/common/txTool/txType\";\nimport { MakeMultiTxData, MakeTxData } from \"@/common/txTool/txTool\";\n\nimport ModuleBase, { ModuleBaseProps } from \"../moduleBase\";\nimport { AmountSide, AddLiquidityParams, RemoveParams, CreatePoolParam, CreatePoolAddress } from \"./type\";\nimport { makeAddLiquidityInstruction } from \"./instruction\";\nimport { ComputeBudgetConfig } from \"../type\";\nimport { removeLiquidityInstruction, createPoolV4InstructionV2 } from \"./instruction\";\nimport { ClmmInstrument } from \"../clmm/instrument\";\nimport { getAssociatedPoolKeys, getAssociatedConfigId } from \"./utils\";\nimport { createPoolFeeLayout } from \"./layout\";\nimport {\n FARM_PROGRAM_TO_VERSION,\n makeWithdrawInstructionV3,\n makeWithdrawInstructionV5,\n makeWithdrawInstructionV6,\n} from \"@/raydium/farm\";\n\nimport BN from \"bn.js\";\nimport Decimal from \"decimal.js\";\n\nexport default class LiquidityModule extends ModuleBase {\n constructor(params: ModuleBaseProps) {\n super(params);\n }\n\n public async load(): Promise<void> {\n this.checkDisabled();\n }\n\n public computePairAmount({\n poolInfo,\n amount,\n // anotherToken,\n slippage,\n baseIn,\n }: {\n poolInfo: ApiV3PoolInfoStandardItem;\n amount: string | Decimal;\n // anotherToken: Token;\n slippage: Percent;\n baseIn?: boolean;\n }): { anotherAmount: TokenAmount; maxAnotherAmount: TokenAmount; liquidity: BN } {\n const inputAmount = new BN(new Decimal(amount).mul(10 ** poolInfo[baseIn ? \"mintA\" : \"mintB\"].decimals).toFixed(0));\n const _anotherToken = toToken(poolInfo[baseIn ? \"mintB\" : \"mintA\"]);\n\n const [baseReserve, quoteReserve] = [\n new BN(new Decimal(poolInfo.mintAmountA).mul(10 ** poolInfo.mintA.decimals).toString()),\n new BN(new Decimal(poolInfo.mintAmountB).mul(10 ** poolInfo.mintB.decimals).toString()),\n ];\n this.logDebug(\"baseReserve:\", baseReserve.toString(), \"quoteReserve:\", quoteReserve.toString());\n\n this.logDebug(\n \"tokenIn:\",\n baseIn ? poolInfo.mintA.symbol : poolInfo.mintB.symbol,\n \"amountIn:\",\n inputAmount.toString(),\n \"anotherToken:\",\n baseIn ? poolInfo.mintB.symbol : poolInfo.mintA.symbol,\n \"slippage:\",\n `${slippage.toSignificant()}%`,\n );\n\n // input is fixed\n const input = baseIn ? \"base\" : \"quote\";\n this.logDebug(\"input side:\", input);\n\n // round up\n let amountRaw = BN_ZERO;\n if (!inputAmount.isZero()) {\n amountRaw =\n input === \"base\"\n ? divCeil(inputAmount.mul(quoteReserve), baseReserve)\n : divCeil(inputAmount.mul(baseReserve), quoteReserve);\n }\n\n const liquidity = divCeil(\n inputAmount.mul(new BN(poolInfo.lpAmount).mul(new BN(10).pow(new BN(poolInfo.lpMint.decimals)))),\n new BN(input === \"base\" ? poolInfo.mintAmountA : poolInfo.mintAmountB).mul(\n new BN(10).pow(new BN(poolInfo[input === \"base\" ? \"mintA\" : \"mintB\"].decimals)),\n ),\n );\n\n const _slippage = new Percent(BN_ONE).add(slippage);\n const slippageAdjustedAmount = _slippage.mul(amountRaw).quotient;\n\n const _anotherAmount = new TokenAmount(_anotherToken, amountRaw);\n const _maxAnotherAmount = new TokenAmount(_anotherToken, slippageAdjustedAmount);\n this.logDebug(\"anotherAmount:\", _anotherAmount.toFixed(), \"maxAnotherAmount:\", _maxAnotherAmount.toFixed());\n\n return {\n anotherAmount: _anotherAmount,\n maxAnotherAmount: _maxAnotherAmount,\n liquidity,\n };\n }\n\n public async addLiquidity<T extends TxVersion>(params: AddLiquidityParams<T>): Promise<MakeTxData<T>> {\n const { poolInfo, amountInA: _amountInA, amountInB: _amountInB, fixedSide, config, txVersion } = params;\n\n if (this.scope.availability.addStandardPosition === false)\n this.logAndCreateError(\"add liquidity feature disabled in your region\");\n\n const amountInA = this.scope.mintToTokenAmount({\n mint: solToWSol(poolInfo.mintA.address),\n amount: _amountInA.toString(),\n });\n const amountInB = this.scope.mintToTokenAmount({\n mint: solToWSol(poolInfo.mintB.address),\n amount: _amountInB.toString(),\n });\n\n this.logDebug(\"amountInA:\", amountInA, \"amountInB:\", amountInB);\n if (amountInA.isZero() || amountInB.isZero())\n this.logAndCreateError(\"amounts must greater than zero\", \"amountInA & amountInB\", {\n amountInA: amountInA.toFixed(),\n amountInB: amountInB.toFixed(),\n });\n const { account } = this.scope;\n const { bypassAssociatedCheck, checkCreateATAOwner } = {\n // default\n ...{ bypassAssociatedCheck: false, checkCreateATAOwner: false },\n // custom\n ...config,\n };\n const [tokenA, tokenB] = [amountInA.token, amountInB.token];\n const tokenAccountA = await account.getCreatedTokenAccount({\n mint: tokenA.mint,\n associatedOnly: false,\n });\n const tokenAccountB = await account.getCreatedTokenAccount({\n mint: tokenB.mint,\n associatedOnly: false,\n });\n if (!tokenAccountA && !tokenAccountB)\n this.logAndCreateError(\"cannot found target token accounts\", \"tokenAccounts\", account.tokenAccounts);\n\n const lpTokenAccount = await account.getCreatedTokenAccount({\n mint: new PublicKey(poolInfo.lpMint.address),\n });\n\n const tokens = [tokenA, tokenB];\n const _tokenAccounts = [tokenAccountA, tokenAccountB];\n const rawAmounts = [amountInA.raw, amountInB.raw];\n\n // handle amount a & b and direction\n const sideA = amountInA.token.mint.toBase58() === poolInfo.mintA.address ? \"base\" : \"quote\";\n let _fixedSide: AmountSide = \"base\";\n if (![\"quote\", \"base\"].includes(sideA)) this.logAndCreateError(\"invalid fixedSide\", \"fixedSide\", fixedSide);\n if (sideA === \"quote\") {\n tokens.reverse();\n _tokenAccounts.reverse();\n rawAmounts.reverse();\n _fixedSide = fixedSide === \"a\" ? \"quote\" : \"base\";\n } else if (sideA === \"base\") {\n _fixedSide = fixedSide === \"a\" ? \"base\" : \"quote\";\n }\n\n const [baseToken, quoteToken] = tokens;\n const [baseTokenAccount, quoteTokenAccount] = _tokenAccounts;\n const [baseAmountRaw, quoteAmountRaw] = rawAmounts;\n\n const poolKeys = await this.scope.api.fetchPoolKeysById({ id: poolInfo.id });\n\n const txBuilder = this.createTxBuilder();\n\n const { tokenAccount: _baseTokenAccount, ...baseInstruction } = await account.handleTokenAccount({\n side: \"in\",\n amount: baseAmountRaw,\n mint: baseToken.mint,\n tokenAccount: baseTokenAccount,\n bypassAssociatedCheck,\n checkCreateATAOwner,\n });\n txBuilder.addInstruction(baseInstruction);\n const { tokenAccount: _quoteTokenAccount, ...quoteInstruction } = await account.handleTokenAccount({\n side: \"in\",\n amount: quoteAmountRaw,\n mint: quoteToken.mint,\n tokenAccount: quoteTokenAccount,\n bypassAssociatedCheck,\n checkCreateATAOwner,\n });\n txBuilder.addInstruction(quoteInstruction);\n const { tokenAccount: _lpTokenAccount, ...lpInstruction } = await account.handleTokenAccount({\n side: \"out\",\n amount: 0,\n mint: new PublicKey(poolInfo.lpMint.address),\n tokenAccount: lpTokenAccount,\n bypassAssociatedCheck,\n checkCreateATAOwner,\n });\n txBuilder.addInstruction(lpInstruction);\n txBuilder.addInstruction({\n instructions: [\n makeAddLiquidityInstruction({\n poolInfo,\n poolKeys: poolKeys as AmmV4Keys | AmmV5Keys,\n userKeys: {\n baseTokenAccount: _baseTokenAccount!,\n quoteTokenAccount: _quoteTokenAccount!,\n lpTokenAccount: _lpTokenAccount!,\n owner: this.scope.ownerPubKey,\n },\n baseAmountIn: baseAmountRaw,\n quoteAmountIn: quoteAmountRaw,\n fixedSide: _fixedSide,\n }),\n ],\n instructionTypes: [\n poolInfo.pooltype.includes(\"StablePool\")\n ? InstructionType.AmmV5AddLiquidity\n : InstructionType.AmmV4AddLiquidity,\n ],\n lookupTableAddress: poolKeys.lookupTableAccount ? [poolKeys.lookupTableAccount] : [],\n });\n if (txVersion === TxVersion.V0) (await txBuilder.buildV0()) as MakeTxData<T>;\n return txBuilder.build() as MakeTxData<T>;\n }\n\n public async removeLiquidity<T extends TxVersion>(params: RemoveParams<T>): Promise<Promise<MakeTxData<T>>> {\n if (this.scope.availability.removeStandardPosition === false)\n this.logAndCreateError(\"remove liquidity feature disabled in your region\");\n const { poolInfo, amountIn, config, txVersion } = params;\n const poolKeys = (await this.scope.api.fetchPoolKeysById({ id: poolInfo.id })) as AmmV4Keys | AmmV5Keys;\n const [baseMint, quoteMint, lpMint] = [\n new PublicKey(poolInfo.mintA.address),\n new PublicKey(poolInfo.mintB.address),\n new PublicKey(poolInfo.lpMint.address),\n ];\n this.logDebug(\"amountIn:\", amountIn);\n if (amountIn.isZero()) this.logAndCreateError(\"amount must greater than zero\", \"amountIn\", amountIn.toString());\n\n const { account } = this.scope;\n const lpTokenAccount = await account.getCreatedTokenAccount({\n mint: lpMint,\n associatedOnly: false,\n });\n if (!lpTokenAccount) this.logAndCreateError(\"cannot found lpTokenAccount\", \"tokenAccounts\", account.tokenAccounts);\n\n const baseTokenAccount = await account.getCreatedTokenAccount({\n mint: baseMint,\n });\n const quoteTokenAccount = await account.getCreatedTokenAccount({\n mint: quoteMint,\n });\n\n const txBuilder = this.createTxBuilder();\n const { bypassAssociatedCheck, checkCreateATAOwner } = {\n // default\n ...{ bypassAssociatedCheck: false, checkCreateATAOwner: false },\n // custom\n ...config,\n };\n\n const { tokenAccount: _baseTokenAccount, ...baseInstruction } = await account.handleTokenAccount({\n side: \"out\",\n amount: 0,\n mint: baseMint,\n tokenAccount: baseTokenAccount,\n bypassAssociatedCheck,\n checkCreateATAOwner,\n });\n txBuilder.addInstruction(baseInstruction);\n const { tokenAccount: _quoteTokenAccount, ...quoteInstruction } = await account.handleTokenAccount({\n side: \"out\",\n amount: 0,\n mint: quoteMint,\n tokenAccount: quoteTokenAccount,\n bypassAssociatedCheck,\n checkCreateATAOwner,\n });\n txBuilder.addInstruction(quoteInstruction);\n\n txBuilder.addInstruction({\n instructions: [\n removeLiquidityInstruction({\n poolInfo,\n poolKeys,\n userKeys: {\n lpTokenAccount: lpTokenAccount!,\n baseTokenAccount: _baseTokenAccount!,\n quoteTokenAccount: _quoteTokenAccount!,\n owner: this.scope.ownerPubKey,\n },\n amountIn,\n }),\n ],\n lookupTableAddress: poolKeys.lookupTableAccount ? [poolKeys.lookupTableAccount] : [],\n instructionTypes: [\n poolInfo.pooltype.includes(\"StablePool\")\n ? InstructionType.AmmV5RemoveLiquidity\n : InstructionType.AmmV4RemoveLiquidity,\n ],\n });\n if (txVersion === TxVersion.V0) return (await txBuilder.buildV0()) as MakeTxData<T>;\n return txBuilder.build() as MakeTxData<T>;\n }\n\n public async removeAllLpAndCreateClmmPosition<T extends TxVersion>({\n poolInfo,\n clmmPoolInfo,\n removeLpAmount,\n createPositionInfo,\n farmInfo,\n userFarmLpAmount,\n base,\n computeBudgetConfig,\n payer,\n tokenProgram = TOKEN_PROGRAM_ID,\n checkCreateATAOwner = true,\n getEphemeralSigners,\n txVersion,\n }: {\n poolInfo: ApiV3PoolInfoStandardItem;\n clmmPoolInfo: ApiV3PoolInfoConcentratedItem;\n removeLpAmount: BN;\n createPositionInfo: {\n tickLower: number;\n tickUpper: number;\n baseAmount: BN;\n otherAmountMax: BN;\n };\n farmInfo?: FormatFarmInfoOutV6;\n userFarmLpAmount?: BN;\n base: \"MintA\" | \"MintB\";\n payer?: PublicKey;\n computeBudgetConfig?: ComputeBudgetConfig;\n tokenProgram?: PublicKey;\n checkCreateATAOwner?: boolean;\n txVersion?: T;\n getEphemeralSigners?: (k: number) => any;\n }): Promise<MakeMultiTxData<T>> {\n if (\n this.scope.availability.removeStandardPosition === false ||\n this.scope.availability.createConcentratedPosition === false\n )\n this.logAndCreateError(\"remove liquidity or create position feature disabled in your region\");\n\n if (\n !(poolInfo.mintA.address === clmmPoolInfo.mintA.address || poolInfo.mintA.address === clmmPoolInfo.mintB.address)\n )\n throw Error(\"mint check error\");\n if (\n !(poolInfo.mintB.address === clmmPoolInfo.mintA.address || poolInfo.mintB.address === clmmPoolInfo.mintB.address)\n )\n throw Error(\"mint check error\");\n\n const txBuilder = this.createTxBuilder();\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n const mintToAccount: { [mint: string]: PublicKey } = {};\n for (const item of this.scope.account.tokenAccountRawInfos) {\n if (\n mintToAccount[item.accountInfo.mint.toString()] === undefined ||\n getATAAddress(this.scope.ownerPubKey, item.accountInfo.mint, TOKEN_PROGRAM_ID).publicKey.equals(item.pubkey)\n ) {\n mintToAccount[item.accountInfo.mint.toString()] = item.pubkey;\n }\n }\n\n const lpTokenAccount = mintToAccount[poolInfo.lpMint.address];\n if (lpTokenAccount === undefined) throw Error(\"find lp account error in trade accounts\");\n\n const amountIn = removeLpAmount.add(userFarmLpAmount ?? new BN(0));\n const mintBaseUseSOLBalance = poolInfo.mintA.address === Token.WSOL.mint.toString();\n const mintQuoteUseSOLBalance = poolInfo.mintB.address === Token.WSOL.mint.toString();\n\n const { account: baseTokenAccount, instructionParams: ownerTokenAccountBaseInstruction } =\n await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: TOKEN_PROGRAM_ID,\n mint: new PublicKey(poolInfo.mintA.address),\n owner: this.scope.ownerPubKey,\n\n createInfo: mintBaseUseSOLBalance\n ? {\n payer: this.scope.ownerPubKey,\n }\n : undefined,\n skipCloseAccount: !mintBaseUseSOLBalance,\n notUseTokenAccount: mintBaseUseSOLBalance,\n associatedOnly: true,\n checkCreateATAOwner,\n });\n txBuilder.addInstruction(ownerTokenAccountBaseInstruction || {});\n if (baseTokenAccount === undefined) throw new Error(\"base token account not found\");\n\n const { account: quoteTokenAccount, instructionParams: ownerTokenAccountQuoteInstruction } =\n await this.scope.account.getOrCreateTokenAccount({\n tokenProgram: TOKEN_PROGRAM_ID,\n mint: new PublicKey(poolInfo.mintB.address),\n owner: this.scope.ownerPubKey,\n createInfo: mintQuoteUseSOLBalance\n ? {\n payer: this.scope.ownerPubKey!,\n amount: 0,\n }\n : undefined,\n skipCloseAccount: !mintQuoteUseSOLBalance,\n notUseTokenAccount: mintQuoteUseSOLBalance,\n associatedOnly: true,\n checkCreateATAOwner,\n });\n txBuilder.addInstruction(ownerTokenAccountQuoteInstruction || {});\n if (quoteTokenAccount === undefined) throw new Error(\"quote token account not found\");\n\n mintToAccount[poolInfo.mintA.address] = baseTokenAccount;\n mintToAccount[poolInfo.mintB.address] = quoteTokenAccount;\n\n if (farmInfo !== undefined && !userFarmLpAmount?.isZero()) {\n const rewardTokenAccounts: PublicKey[] = [];\n for (const item of farmInfo.rewardInfos) {\n const rewardIsWsol = item.mint.address === Token.WSOL.mint.toString();\n if (mintToAccount[item.mint.address]) rewardTokenAccounts.push(mintToAccount[item.mint.address]);\n else {\n const { account: farmRewardAccount, instructionParams: ownerTokenAccountFarmInstruction } =\n await this.scope.account.getOrCreateTokenAccount({\n mint: new PublicKey(item.mint.address),\n tokenProgram,\n owner: this.scope.ownerPubKey,\n skipCloseAccount: !rewardIsWsol,\n createInfo: {\n payer: payer || this.scope.ownerPubKey,\n },\n associatedOnly: true,\n checkCreateATAOwner,\n });\n if (!farmRewardAccount) this.logAndCreateError(\"farm reward account not found:\", item.mint.address);\n ownerTokenAccountFarmInstruction && txBuilder.addInstruction(ownerTokenAccountFarmInstruction);\n rewardTokenAccounts.push(farmRewardAccount!);\n }\n }\n const farmKeys = (await this.scope.api.fetchFarmKeysById({ ids: farmInfo.id }))[0];\n const insParams = {\n amount: userFarmLpAmount!,\n owner: this.scope.ownerPubKey,\n farmInfo,\n farmKeys,\n lpAccount: lpTokenAccount,\n rewardAccounts: rewardTokenAccounts,\n };\n const version = FARM_PROGRAM_TO_VERSION[farmInfo.programId];\n const newInstruction =\n version === 6\n ? makeWithdrawInstructionV6(insParams)\n : version === 5\n ? makeWithdrawInstructionV5(insParams)\n : makeWithdrawInstructionV3(insParams);\n const insType = {\n 3: InstructionType.FarmV3Withdraw,\n 5: InstructionType.FarmV5Withdraw,\n 6: InstructionType.FarmV6Withdraw,\n };\n txBuilder.addInstruction({\n instructions: [newInstruction],\n instructionTypes: [insType[version]],\n });\n }\n\n const poolKeys = (await this.scope.api.fetchPoolKeysById({ id: poolInfo.id })) as AmmV4Keys | AmmV5Keys;\n\n const removeIns = removeLiquidityInstruction({\n poolInfo,\n poolKeys,\n userKeys: {\n lpTokenAccount,\n baseTokenAccount,\n quoteTokenAccount,\n owner: this.scope.ownerPubKey,\n },\n amountIn,\n });\n\n txBuilder.addInstruction({\n instructions: [removeIns],\n instructionTypes: [\n !poolInfo.pooltype.includes(\"StablePool\")\n ? InstructionType.AmmV4RemoveLiquidity\n : InstructionType.AmmV5RemoveLiquidity,\n ],\n lookupTableAddress: poolKeys.lookupTableAccount ? [poolKeys.lookupTableAccount] : [],\n });\n\n const [tokenAccountA, tokenAccountB] =\n poolInfo.mintA.address === clmmPoolInfo.mintA.address\n ? [baseTokenAccount, quoteTokenAccount]\n : [quoteTokenAccount, baseTokenAccount];\n\n const clmmPoolKeys = (await this.scope.api.fetchPoolKeysById({ id: clmmPoolInfo.id })) as ClmmKeys;\n\n const createPositionIns = await ClmmInstrument.openPositionFromBaseInstructions({\n poolInfo: clmmPoolInfo,\n poolKeys: clmmPoolKeys,\n ownerInfo: {\n feePayer: this.scope.ownerPubKey,\n wallet: this.scope.ownerPubKey,\n tokenAccountA,\n tokenAccountB,\n },\n withMetadata: \"create\",\n ...createPositionInfo,\n base,\n getEphemeralSigners,\n });\n\n txBuilder.addInstruction({\n instructions: [...createPositionIns.instructions],\n signers: createPositionIns.signers,\n instructionTypes: [...createPositionIns.instructionTypes],\n lookupTableAddress: clmmPoolKeys.lookupTableAccount ? [clmmPoolKeys.lookupTableAccount] : [],\n });\n\n if (txVersion === TxVersion.V0) return txBuilder.sizeCheckBuildV0() as Promise<MakeMultiTxData<T>>;\n return txBuilder.sizeCheckBuild() as Promise<MakeMultiTxData<T>>;\n }\n\n // calComputeBudget\n public async createPoolV4<T extends TxVersion>({\n programId,\n marketInfo,\n baseMintInfo,\n quoteMintInfo,\n baseAmount,\n quoteAmount,\n startTime,\n ownerInfo,\n associatedOnly = false,\n checkCreateATAOwner = false,\n tokenProgram,\n txVersion,\n feeDestinationId,\n computeBudgetConfig,\n }: CreatePoolParam<T>): Promise<MakeTxData<T, { address: CreatePoolAddress }>> {\n const payer = ownerInfo.feePayer || this.scope.owner?.publicKey;\n const mintAUseSOLBalance = ownerInfo.useSOLBalance && baseMintInfo.mint.equals(NATIVE_MINT);\n const mintBUseSOLBalance = ownerInfo.useSOLBalance && quoteMintInfo.mint.equals(NATIVE_MINT);\n\n const txBuilder = this.createTxBuilder();\n\n const { account: ownerTokenAccountBase, instructionParams: ownerTokenAccountBaseInstruction } =\n await this.scope.account.getOrCreateTokenAccount({\n mint: baseMintInfo.mint,\n owner: this.scope.ownerPubKey,\n createInfo: mintAUseSOLBalance\n ? {\n payer: payer!,\n amount: baseAmount,\n }\n : undefined,\n notUseTokenAccount: mintAUseSOLBalance,\n skipCloseAccount: !mintAUseSOLBalance,\n associatedOnly: mintAUseSOLBalance ? false : associatedOnly,\n checkCreateATAOwner,\n });\n txBuilder.addInstruction(ownerTokenAccountBaseInstruction || {});\n\n const { account: ownerTokenAccountQuote, instructionParams: ownerTokenAccountQuoteInstruction } =\n await this.scope.account.getOrCreateTokenAccount({\n mint: quoteMintInfo.mint,\n owner: this.scope.ownerPubKey,\n createInfo: mintBUseSOLBalance\n ? {\n payer: payer!,\n amount: quoteAmount,\n }\n : undefined,\n\n notUseTokenAccount: mintBUseSOLBalance,\n skipCloseAccount: !mintBUseSOLBalance,\n associatedOnly: mintBUseSOLBalance ? false : associatedOnly,\n checkCreateATAOwner,\n });\n txBuilder.addInstruction(ownerTokenAccountQuoteInstruction || {});\n\n if (ownerTokenAccountBase === undefined || ownerTokenAccountQuote === undefined)\n throw Error(\"you don't has some token account\");\n\n const poolInfo = getAssociatedPoolKeys({\n version: 4,\n marketVersion: 3,\n marketId: marketInfo.marketId,\n baseMint: baseMintInfo.mint,\n quoteMint: quoteMintInfo.mint,\n baseDecimals: baseMintInfo.decimals,\n quoteDecimals: quoteMintInfo.decimals,\n programId,\n marketProgramId: marketInfo.programId,\n });\n\n const createPoolKeys = {\n programId,\n ammId: poolInfo.id,\n ammAuthority: poolInfo.authority,\n ammOpenOrders: poolInfo.openOrders,\n lpMint: poolInfo.lpMint,\n coinMint: poolInfo.baseMint,\n pcMint: poolInfo.quoteMint,\n coinVault: poolInfo.baseVault,\n pcVault: poolInfo.quoteVault,\n withdrawQueue: poolInfo.withdrawQueue,\n ammTargetOrders: poolInfo.targetOrders,\n poolTempLp: poolInfo.lpVault,\n marketProgramId: poolInfo.marketProgramId,\n marketId: poolInfo.marketId,\n ammConfigId: poolInfo.configId,\n feeDestinationId,\n };\n\n const { instruction, instructionType } = createPoolV4InstructionV2({\n ...createPoolKeys,\n userWallet: this.scope.ownerPubKey,\n userCoinVault: ownerTokenAccountBase,\n userPcVault: ownerTokenAccountQuote,\n userLpVault: getATAAddress(this.scope.ownerPubKey, poolInfo.lpMint, tokenProgram).publicKey,\n\n nonce: poolInfo.nonce,\n openTime: startTime,\n coinAmount: baseAmount,\n pcAmount: quoteAmount,\n });\n\n txBuilder.addInstruction({\n instructions: [instruction],\n instructionTypes: [instructionType],\n });\n\n txBuilder.addCustomComputeBudget(computeBudgetConfig);\n\n return txBuilder.versionBuild({\n txVersion,\n extInfo: {\n address: createPoolKeys,\n },\n }) as Promise<MakeTxData<T, { address: CreatePoolAddress }>>;\n }\n\n public async getCreatePoolFee({ programId }: { programId: PublicKey }): Promise<BN> {\n const configId = getAssociatedConfigId({ programId });\n\n const account = await this.scope.connection.getAccountInfo(configId, { dataSlice: { offset: 536, length: 8 } });\n if (account === null) throw Error(\"get config account error\");\n\n return createPoolFeeLayout.decode(account.data).fee;\n }\n}\n","import _Big from \"big.js\";\nimport BN from \"bn.js\";\n\nimport { BigNumberish, BN_TEN, parseBigNumberish, Rounding } from \"../common/bignumber\";\nimport { createLogger, Logger } from \"../common/logger\";\n\nimport toFormat, { WrappedBig } from \"./formatter\";\nimport { Fraction } from \"./fraction\";\nimport { Token } from \"./token\";\nimport { Currency } from \"./currency\";\n\nconst logger = createLogger(\"Raydium_amount\");\n\nconst Big = toFormat(_Big);\ntype Big = WrappedBig;\n\nexport function splitNumber(num: string, decimals: number): [string, string] {\n let integral = \"0\";\n let fractional = \"0\";\n\n if (num.includes(\".\")) {\n const splited = num.split(\".\");\n if (splited.length === 2) {\n [integral, fractional] = splited;\n fractional = fractional.padEnd(decimals, \"0\");\n } else {\n logger.logWithError(`invalid number string, num: ${num}`);\n }\n } else {\n integral = num;\n }\n\n // fix decimals is 0\n return [integral, fractional.slice(0, decimals) || fractional];\n}\n\nexport class TokenAmount extends Fraction {\n public readonly token: Token;\n protected logger: Logger;\n\n public constructor(token: Token, amount: BigNumberish, isRaw = true, name?: string) {\n let parsedAmount = new BN(0);\n const multiplier = BN_TEN.pow(new BN(token.decimals));\n\n if (isRaw) {\n parsedAmount = parseBigNumberish(amount);\n } else {\n let integralAmount = new BN(0);\n let fractionalAmount = new BN(0);\n\n // parse fractional string\n if (typeof amount === \"string\" || typeof amount === \"number\" || typeof amount === \"bigint\") {\n const [integral, fractional] = splitNumber(amount.toString(), token.decimals);\n integralAmount = parseBigNumberish(integral);\n fractionalAmount = parseBigNumberish(fractional);\n }\n\n integralAmount = integralAmount.mul(multiplier);\n parsedAmount = integralAmount.add(fractionalAmount);\n }\n\n super(parsedAmount, multiplier);\n this.logger = createLogger(name || \"TokenAmount\");\n this.token = token;\n }\n\n public get raw(): BN {\n return this.numerator;\n }\n public isZero(): boolean {\n return this.raw.isZero();\n }\n public gt(other: TokenAmount): boolean {\n if (!this.token.equals(other.token)) this.logger.logWithError(\"gt token not equals\");\n return this.raw.gt(other.raw);\n }\n\n /**\n * a less than b\n */\n public lt(other: TokenAmount): boolean {\n if (!this.token.equals(other.token)) this.logger.logWithError(\"lt token not equals\");\n return this.raw.lt(other.raw);\n }\n\n public add(other: TokenAmount): TokenAmount {\n if (!this.token.equals(other.token)) this.logger.logWithError(\"add token not equals\");\n return new TokenAmount(this.token, this.raw.add(other.raw));\n }\n\n public subtract(other: TokenAmount): TokenAmount {\n if (!this.token.equals(other.token)) this.logger.logWithError(\"sub token not equals\");\n return new TokenAmount(this.token, this.raw.sub(other.raw));\n }\n\n public toSignificant(\n significantDigits = this.token.decimals,\n format?: object,\n rounding: Rounding = Rounding.ROUND_DOWN,\n ): string {\n return super.toSignificant(significantDigits, format, rounding);\n }\n\n /**\n * To fixed\n *\n * @example\n * ```\n * 1 -> 1.000000000\n * 1.234 -> 1.234000000\n * 1.123456789876543 -> 1.123456789\n * ```\n */\n public toFixed(\n decimalPlaces = this.token.decimals,\n format?: object,\n rounding: Rounding = Rounding.ROUND_DOWN,\n ): string {\n if (decimalPlaces > this.token.decimals) this.logger.logWithError(\"decimals overflow\");\n return super.toFixed(decimalPlaces, format, rounding);\n }\n\n /**\n * To exact\n *\n * @example\n * ```\n * 1 -> 1\n * 1.234 -> 1.234\n * 1.123456789876543 -> 1.123456789\n * ```\n */\n public toExact(format: object = { groupSeparator: \"\" }): string {\n Big.DP = this.token.decimals;\n return new Big(this.numerator.toString()).div(this.denominator.toString()).toFormat(format);\n }\n}\n\nexport class CurrencyAmount extends Fraction {\n public readonly currency: Currency;\n protected logger: Logger;\n\n public constructor(currency: Currency, amount: BigNumberish, isRaw = true, name?: string) {\n let parsedAmount = new BN(0);\n const multiplier = BN_TEN.pow(new BN(currency.decimals));\n\n if (isRaw) {\n parsedAmount = parseBigNumberish(amount);\n } else {\n let integralAmount = new BN(0);\n let fractionalAmount = new BN(0);\n\n // parse fractional string\n if (typeof amount === \"string\" || typeof amount === \"number\" || typeof amount === \"bigint\") {\n const [integral, fractional] = splitNumber(amount.toString(), currency.decimals);\n integralAmount = parseBigNumberish(integral);\n fractionalAmount = parseBigNumberish(fractional);\n }\n\n integralAmount = integralAmount.mul(multiplier);\n parsedAmount = integralAmount.add(fractionalAmount);\n }\n\n super(parsedAmount, multiplier);\n this.logger = createLogger(name || \"TokenAmount\");\n this.currency = currency;\n }\n\n public get raw(): BN {\n return this.numerator;\n }\n\n public isZero(): boolean {\n return this.raw.isZero();\n }\n\n /**\n * a greater than b\n */\n public gt(other: CurrencyAmount): boolean {\n if (!this.currency.equals(other.currency)) this.logger.logWithError(\"gt currency not equals\");\n return this.raw.gt(other.raw);\n }\n\n /**\n * a less than b\n */\n public lt(other: CurrencyAmount): boolean {\n if (!this.currency.equals(other.currency)) this.logger.logWithError(\"lt currency not equals\");\n return this.raw.lt(other.raw);\n }\n\n public add(other: CurrencyAmount): CurrencyAmount {\n if (!this.currency.equals(other.currency)) this.logger.logWithError(\"add currency not equals\");\n return new CurrencyAmount(this.currency, this.raw.add(other.raw));\n }\n\n public sub(other: CurrencyAmount): CurrencyAmount {\n if (!this.currency.equals(other.currency)) this.logger.logWithError(\"sub currency not equals\");\n return new CurrencyAmount(this.currency, this.raw.sub(other.raw));\n }\n\n public toSignificant(\n significantDigits = this.currency.decimals,\n format?: object,\n rounding: Rounding = Rounding.ROUND_DOWN,\n ): string {\n return super.toSignificant(significantDigits, format, rounding);\n }\n\n /**\n * To fixed\n *\n * @example\n * ```\n * 1 -> 1.000000000\n * 1.234 -> 1.234000000\n * 1.123456789876543 -> 1.123456789\n * ```\n */\n public toFixed(\n decimalPlaces = this.currency.decimals,\n format?: object,\n rounding: Rounding = Rounding.ROUND_DOWN,\n ): string {\n if (decimalPlaces > this.currency.decimals) this.logger.logWithError(\"decimals overflow\");\n\n return super.toFixed(decimalPlaces, format, rounding);\n }\n\n /**\n * To exact\n *\n * @example\n * ```\n * 1 -> 1\n * 1.234 -> 1.234\n * 1.123456789876543 -> 1.123456789\n * ```\n */\n public toExact(format: object = { groupSeparator: \"\" }): string {\n Big.DP = this.currency.decimals;\n return new Big(this.numerator.toString()).div(this.denominator.toString()).toFormat(format);\n }\n}\n","import BN from \"bn.js\";\nimport Decimal from \"decimal.js\";\nimport { Token } from \"../module/token\";\nimport { Price } from \"../module/price\";\nimport { Currency } from \"../module/currency\";\nimport { TokenAmount, CurrencyAmount } from \"../module/amount\";\nimport { Fraction } from \"../module/fraction\";\nimport { Percent } from \"../module/percent\";\nimport { SplToken, TokenJson } from \"../raydium/token/type\";\nimport { ReplaceType } from \"../raydium/type\";\nimport { createLogger } from \"./logger\";\nimport { mul } from \"./fractionUtil\";\nimport { notInnerObject } from \"./utility\";\n\nexport enum Rounding {\n ROUND_DOWN,\n ROUND_HALF_UP,\n ROUND_UP,\n}\n\nexport const BN_ZERO = new BN(0);\nexport const BN_ONE = new BN(1);\nexport const BN_TWO = new BN(2);\nexport const BN_THREE = new BN(3);\nexport const BN_FIVE = new BN(5);\nexport const BN_TEN = new BN(10);\nexport const BN_100 = new BN(100);\nexport const BN_1000 = new BN(1000);\nexport const BN_10000 = new BN(10000);\nexport type BigNumberish = BN | string | number | bigint;\nexport type Numberish = number | string | bigint | Fraction | BN;\n\nconst MAX_SAFE = 0x1fffffffffffff;\n\nexport function parseBigNumberish(value: BigNumberish): BN {\n const logger = createLogger(\"Raydium_parseBigNumberish\");\n // BN\n if (value instanceof BN) {\n return value;\n }\n\n if (typeof value === \"string\") {\n if (value.match(/^-?[0-9]+$/)) {\n return new BN(value);\n }\n logger.logWithError(`invalid BigNumberish string: ${value}`);\n }\n\n if (typeof value === \"number\") {\n if (value % 1) {\n logger.logWithError(`BigNumberish number underflow: ${value}`);\n }\n\n if (value >= MAX_SAFE || value <= -MAX_SAFE) {\n logger.logWithError(`BigNumberish number overflow: ${value}`);\n }\n\n return new BN(String(value));\n }\n\n if (typeof value === \"bigint\") {\n return new BN(value.toString());\n }\n logger.error(`invalid BigNumberish value: ${value}`);\n return new BN(0); // never reach, because logWithError will throw error\n}\n\nexport function tenExponential(shift: BigNumberish): BN {\n return BN_TEN.pow(parseBigNumberish(shift));\n}\n\n/**\n *\n * @example\n * getIntInfo(0.34) => { numerator: '34', denominator: '100'}\n * getIntInfo('0.34') //=> { numerator: '34', denominator: '100'}\n */\nexport function parseNumberInfo(n: Numberish | undefined): {\n denominator: string;\n numerator: string;\n sign?: string;\n int?: string;\n dec?: string;\n} {\n if (n === undefined) return { denominator: \"1\", numerator: \"0\" };\n if (n instanceof BN) {\n return { numerator: n.toString(), denominator: \"1\" };\n }\n\n if (n instanceof Fraction) {\n return { denominator: n.denominator.toString(), numerator: n.numerator.toString() };\n }\n\n const s = String(n);\n const [, sign = \"\", int = \"\", dec = \"\"] = s.replace(\",\", \"\").match(/(-?)(\\d*)\\.?(\\d*)/) ?? [];\n const denominator = \"1\" + \"0\".repeat(dec.length);\n const numerator = sign + (int === \"0\" ? \"\" : int) + dec || \"0\";\n return { denominator, numerator, sign, int, dec };\n}\n\n// round up\nexport function divCeil(a: BN, b: BN): BN {\n // eslint-disable-next-line @typescript-eslint/ban-ts-comment\n // @ts-ignore\n const dm = a.divmod(b);\n\n // Fast case - exact division\n if (dm.mod.isZero()) return dm.div;\n\n // Round up\n return dm.div.isNeg() ? dm.div.isubn(1) : dm.div.iaddn(1);\n}\n\nexport function shakeFractionDecimal(n: Fraction): string {\n const [, sign = \"\", int = \"\"] = n.toFixed(2).match(/(-?)(\\d*)\\.?(\\d*)/) ?? [];\n return `${sign}${int}`;\n}\n\nexport function toBN(n: Numberish, decimal: BigNumberish = 0): BN {\n if (n instanceof BN) return n;\n return new BN(shakeFractionDecimal(toFraction(n).mul(BN_TEN.pow(new BN(String(decimal))))));\n}\n\nexport function toFraction(value: Numberish): Fraction {\n // to complete math format(may have decimal), not int\n if (value instanceof Percent) return new Fraction(value.numerator, value.denominator);\n\n if (value instanceof Price) return value.adjusted;\n\n // to complete math format(may have decimal), not BN\n if (value instanceof TokenAmount)\n try {\n return toFraction(value.toExact());\n } catch {\n return new Fraction(BN_ZERO);\n }\n\n // do not ideal with other fraction value\n if (value instanceof Fraction) return value;\n\n // wrap to Fraction\n const n = String(value);\n const details = parseNumberInfo(n);\n return new Fraction(details.numerator, details.denominator);\n}\n\n/**\n * @example\n * toPercent(3.14) // => Percent { 314.00% }\n * toPercent(3.14, { alreadyDecimaled: true }) // => Percent {3.14%}\n */\nexport function toPercent(\n n: Numberish,\n options?: { /* usually used for backend data */ alreadyDecimaled?: boolean },\n): Percent {\n const { numerator, denominator } = parseNumberInfo(n);\n return new Percent(new BN(numerator), new BN(denominator).mul(options?.alreadyDecimaled ? new BN(100) : new BN(1)));\n}\n\nexport function toTokenPrice(params: {\n token: TokenJson | Token | SplToken;\n numberPrice: Numberish;\n decimalDone?: boolean;\n}): Price {\n const { token, numberPrice, decimalDone } = params;\n const usdCurrency = new Token({ mint: \"\", decimals: 6, symbol: \"usd\", name: \"usd\", skipMint: true });\n const { numerator, denominator } = parseNumberInfo(numberPrice);\n const parsedNumerator = decimalDone ? new BN(numerator).mul(BN_TEN.pow(new BN(token.decimals))) : numerator;\n const parsedDenominator = new BN(denominator).mul(BN_TEN.pow(new BN(usdCurrency.decimals)));\n\n return new Price({\n baseToken: usdCurrency,\n denominator: parsedDenominator.toString(),\n quoteToken: new Token({ ...token, skipMint: true, mint: \"\" }),\n numerator: parsedNumerator.toString(),\n });\n}\n\nexport function toUsdCurrency(amount: Numberish): CurrencyAmount {\n const usdCurrency = new Currency({ decimals: 6, symbol: \"usd\", name: \"usd\" });\n const amountBigNumber = toBN(mul(amount, 10 ** usdCurrency.decimals)!);\n return new CurrencyAmount(usdCurrency, amountBigNumber);\n}\n\nexport function toTotalPrice(amount: Numberish | undefined, price: Price | undefined): CurrencyAmount {\n if (!price || !amount) return toUsdCurrency(0);\n return toUsdCurrency(mul(amount, price)!);\n}\n\nexport function decimalToFraction(n: Decimal | undefined): Fraction | undefined {\n if (n == null) return undefined;\n const { numerator, denominator } = parseNumberInfo(n.toString());\n return new Fraction(numerator, denominator);\n}\n\nexport function isDecimal(val: unknown): boolean {\n return val instanceof Decimal;\n}\n\nexport function recursivelyDecimalToFraction<T>(info: T): ReplaceType<T, Decimal, Fraction> {\n // @ts-expect-error no need type for inner code\n return isDecimal(info)\n ? decimalToFraction(info as any)\n : Array.isArray(info)\n ? info.map((k) => recursivelyDecimalToFraction(k))\n : notInnerObject(info)\n ? Object.fromEntries(Object.entries(info as any).map(([k, v]) => [k, recursivelyDecimalToFraction(v)]))\n : info;\n}\n","/*\r\n * decimal.js v10.3.1\r\n * An arbitrary-precision Decimal type for JavaScript.\r\n * https://github.com/MikeMcl/decimal.js\r\n * Copyright (c) 2021 Michael Mclaughlin <M8ch88l@gmail.com>\r\n * MIT Licence\r\n */\r\n\r\n\r\n// ----------------------------------- EDITABLE DEFAULTS ------------------------------------ //\r\n\r\n\r\n // The maximum exponent magnitude.\r\n // The limit on the value of `toExpNeg`, `toExpPos`, `minE` and `maxE`.\r\nvar EXP_LIMIT = 9e15, // 0 to 9e15\r\n\r\n // The limit on the value of `precision`, and on the value of the first argument to\r\n // `toDecimalPlaces`, `toExponential`, `toFixed`, `toPrecision` and `toSignificantDigits`.\r\n MAX_DIGITS = 1e9, // 0 to 1e9\r\n\r\n // Base conversion alphabet.\r\n NUMERALS = '0123456789abcdef',\r\n\r\n // The natural logarithm of 10 (1025 digits).\r\n LN10 = '2.3025850929940456840179914546843642076011014886287729760333279009675726096773524802359972050895982983419677840422862486334095254650828067566662873690987816894829072083255546808437998948262331985283935053089653777326288461633662222876982198867465436674744042432743651550489343149393914796194044002221051017141748003688084012647080685567743216228355220114804663715659121373450747856947683463616792101806445070648000277502684916746550586856935673420670581136429224554405758925724208241314695689016758940256776311356919292033376587141660230105703089634572075440370847469940168269282808481184289314848524948644871927809676271275775397027668605952496716674183485704422507197965004714951050492214776567636938662976979522110718264549734772662425709429322582798502585509785265383207606726317164309505995087807523710333101197857547331541421808427543863591778117054309827482385045648019095610299291824318237525357709750539565187697510374970888692180205189339507238539205144634197265287286965110862571492198849978748873771345686209167058',\r\n\r\n // Pi (1025 digits).\r\n PI = '3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337867831652712019091456485669234603486104543266482133936072602491412737245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094330572703657595919530921861173819326117931051185480744623799627495673518857527248912279381830119491298336733624406566430860213949463952247371907021798609437027705392171762931767523846748184676694051320005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235420199561121290219608640344181598136297747713099605187072113499999983729780499510597317328160963185950244594553469083026425223082533446850352619311881710100031378387528865875332083814206171776691473035982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989380952572010654858632789',\r\n\r\n\r\n // The initial configuration properties of the Decimal constructor.\r\n DEFAULTS = {\r\n\r\n // These values must be integers within the stated ranges (inclusive).\r\n // Most of these values can be changed at run-time using the `Decimal.config` method.\r\n\r\n // The maximum number of significant digits of the result of a calculation or base conversion.\r\n // E.g. `Decimal.config({ precision: 20 });`\r\n precision: 20, // 1 to MAX_DIGITS\r\n\r\n // The rounding mode used when rounding to `precision`.\r\n //\r\n // ROUND_UP 0 Away from zero.\r\n // ROUND_DOWN 1 Towards zero.\r\n // ROUND_CEIL 2 Towards +Infinity.\r\n // ROUND_FLOOR 3 Towards -Infinity.\r\n // ROUND_HALF_UP 4 Towards nearest neighbour. If equidistant, up.\r\n // ROUND_HALF_DOWN 5 Towards nearest neighbour. If equidistant, down.\r\n // ROUND_HALF_EVEN 6 Towards nearest neighbour. If equidistant, towards even neighbour.\r\n // ROUND_HALF_CEIL 7 Towards nearest neighbour. If equidistant, towards +Infinity.\r\n // ROUND_HALF_FLOOR 8 Towards nearest neighbour. If equidistant, towards -Infinity.\r\n //\r\n // E.g.\r\n // `Decimal.rounding = 4;`\r\n // `Decimal.rounding = Decimal.ROUND_HALF_UP;`\r\n rounding: 4, // 0 to 8\r\n\r\n // The modulo mode used when calculating the modulus: a mod n.\r\n // The quotient (q = a / n) is calculated according to the corresponding rounding mode.\r\n // The remainder (r) is calculated as: r = a - n * q.\r\n //\r\n // UP 0 The remainder is positive if the dividend is negative, else is negative.\r\n // DOWN 1 The remainder has the same sign as the dividend (JavaScript %).\r\n // FLOOR 3 The remainder has the same sign as the divisor (Python %).\r\n // HALF_EVEN 6 The IEEE 754 remainder function.\r\n // EUCLID 9 Euclidian division. q = sign(n) * floor(a / abs(n)). Always positive.\r\n //\r\n // Truncated division (1), floored division (3), the IEEE 754 remainder (6), and Euclidian\r\n // division (9) are commonly used for the modulus operation. The other rounding modes can also\r\n // be used, but they may not give useful results.\r\n modulo: 1, // 0 to 9\r\n\r\n // The exponent value at and beneath which `toString` returns exponential notation.\r\n // JavaScript numbers: -7\r\n toExpNeg: -7, // 0 to -EXP_LIMIT\r\n\r\n // The exponent value at and above which `toString` returns exponential notation.\r\n // JavaScript numbers: 21\r\n toExpPos: 21, // 0 to EXP_LIMIT\r\n\r\n // The minimum exponent value, beneath which underflow to zero occurs.\r\n // JavaScript numbers: -324 (5e-324)\r\n minE: -EXP_LIMIT, // -1 to -EXP_LIMIT\r\n\r\n // The maximum exponent value, above which overflow to Infinity occurs.\r\n // JavaScript numbers: 308 (1.7976931348623157e+308)\r\n maxE: EXP_LIMIT, // 1 to EXP_LIMIT\r\n\r\n // Whether to use cryptographically-secure random number generation, if available.\r\n crypto: false // true/false\r\n },\r\n\r\n\r\n// ----------------------------------- END OF EDITABLE DEFAULTS ------------------------------- //\r\n\r\n\r\n inexact, quadrant,\r\n external = true,\r\n\r\n decimalError = '[DecimalError] ',\r\n invalidArgument = decimalError + 'Invalid argument: ',\r\n precisionLimitExceeded = decimalError + 'Precision limit exceeded',\r\n cryptoUnavailable = decimalError + 'crypto unavailable',\r\n tag = '[object Decimal]',\r\n\r\n mathfloor = Math.floor,\r\n mathpow = Math.pow,\r\n\r\n isBinary = /^0b([01]+(\\.[01]*)?|\\.[01]+)(p[+-]?\\d+)?$/i,\r\n isHex = /^0x([0-9a-f]+(\\.[0-9a-f]*)?|\\.[0-9a-f]+)(p[+-]?\\d+)?$/i,\r\n isOctal = /^0o([0-7]+(\\.[0-7]*)?|\\.[0-7]+)(p[+-]?\\d+)?$/i,\r\n isDecimal = /^(\\d+(\\.\\d*)?|\\.\\d+)(e[+-]?\\d+)?$/i,\r\n\r\n BASE = 1e7,\r\n LOG_BASE = 7,\r\n MAX_SAFE_INTEGER = 9007199254740991,\r\n\r\n LN10_PRECISION = LN10.length - 1,\r\n PI_PRECISION = PI.length - 1,\r\n\r\n // Decimal.prototype object\r\n P = { toStringTag: tag };\r\n\r\n\r\n// Decimal prototype methods\r\n\r\n\r\n/*\r\n * absoluteValue abs\r\n * ceil\r\n * clampedTo clamp\r\n * comparedTo cmp\r\n * cosine cos\r\n * cubeRoot cbrt\r\n * decimalPlaces dp\r\n * dividedBy div\r\n * dividedToIntegerBy divToInt\r\n * equals eq\r\n * floor\r\n * greaterThan gt\r\n * greaterThanOrEqualTo gte\r\n * hyperbolicCosine cosh\r\n * hyperbolicSine sinh\r\n * hyperbolicTangent tanh\r\n * inverseCosine acos\r\n * inverseHyperbolicCosine acosh\r\n * inverseHyperbolicSine asinh\r\n * inverseHyperbolicTangent atanh\r\n * inverseSine asin\r\n * inverseTangent atan\r\n * isFinite\r\n * isInteger isInt\r\n * isNaN\r\n * isNegative isNeg\r\n * isPositive isPos\r\n * isZero\r\n * lessThan lt\r\n * l