UNPKG

test-rrr-sdk

Version:

An SDK for building applications on top of Raydium.

1 lines 428 kB
{"version":3,"sources":["../../../src/raydium/farm/instruction.ts","../../../src/common/accountInfo.ts","../../../src/common/logger.ts","../../../src/common/bignumber.ts","../../../node_modules/decimal.js/decimal.mjs","../../../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/common/utility.ts","../../../src/common/pda.ts","../../../src/common/txTool/txUtils.ts","../../../src/common/txTool/txType.ts","../../../src/common/programId.ts","../../../src/common/transfer.ts","../../../src/common/txTool/lookupTable.ts","../../../src/common/txTool/txTool.ts","../../../src/common/fee.ts","../../../src/marshmallow/index.ts","../../../src/marshmallow/buffer-layout.ts","../../../src/raydium/farm/config.ts","../../../src/raydium/farm/layout.ts","../../../src/raydium/farm/pda.ts","../../../src/raydium/farm/util.ts","../../../src/raydium/account/layout.ts"],"sourcesContent":["import {\n Connection,\n PublicKey,\n SystemProgram,\n SYSVAR_CLOCK_PUBKEY,\n SYSVAR_RENT_PUBKEY,\n TransactionInstruction,\n} from \"@solana/web3.js\";\nimport BN from \"bn.js\";\nimport {\n ASSOCIATED_TOKEN_PROGRAM_ID,\n createAssociatedTokenAccountInstruction,\n TOKEN_PROGRAM_ID,\n} from \"@solana/spl-token\";\n\nimport { FormatFarmKeyOut } from \"@/api/type\";\nimport { parseBigNumberish } from \"@/common\";\nimport { createLogger } from \"@/common/logger\";\nimport { getATAAddress } from \"@/common/pda\";\nimport {\n accountMeta,\n commonSystemAccountMeta,\n INSTRUCTION_PROGRAM_ID,\n RENT_PROGRAM_ID,\n SOLMint,\n} from \"@/common/pubKey\";\nimport { InstructionType } from \"@/common/txTool/txType\";\nimport { bool, struct, u32, u64, u8 } from \"../../marshmallow\";\nimport { InstructionReturn } from \"../type\";\nimport { poolTypeV6 } from \"./config\";\nimport {\n associatedLedgerAccountLayout,\n dwLayout,\n farmAddRewardLayout,\n farmLedgerLayoutV3_2,\n farmRewardLayout,\n farmRewardRestartLayout,\n withdrawRewardLayout,\n} from \"./layout\";\nimport {\n getRegistrarAddress,\n getTokenOwnerRecordAddress,\n getVoterAddress,\n getVoterWeightRecordAddress,\n getVotingMintAuthority,\n getVotingTokenMint,\n} from \"./pda\";\nimport { FarmRewardInfoConfig, RewardInfoKey, RewardType } from \"./type\";\nimport { getAssociatedLedgerAccount, getDepositEntryIndex } from \"./util\";\n\nconst logger = createLogger(\"Raydium_farm_instruction\");\n\nconst anchorDataBuf = {\n voterStakeRegistryCreateVoter: Buffer.from([6, 24, 245, 52, 243, 255, 148, 25]), // CreateVoter\n voterStakeRegistryCreateDepositEntry: Buffer.from([185, 131, 167, 186, 159, 125, 19, 67]), // CreateDepositEntry\n voterStakeRegistryDeposit: Buffer.from([242, 35, 198, 137, 82, 225, 242, 182]), // Deposit\n voterStakeRegistryWithdraw: Buffer.from([183, 18, 70, 156, 148, 109, 161, 34]), // Withdraw\n voterStakeRegistryUpdateVoterWeightRecord: Buffer.from([45, 185, 3, 36, 109, 190, 115, 169]), // UpdateVoterWeightRecord\n};\n\nexport function createAssociatedLedgerAccountInstruction(params: {\n version: number;\n id: PublicKey;\n programId: PublicKey;\n ledger: PublicKey;\n owner: PublicKey;\n}): InstructionReturn {\n const { version, id, ledger, programId, owner } = params;\n const instruction = { 3: 9, 5: 10 }[version];\n if (!instruction) logger.logWithError(`invalid farm pool version: ${version}`);\n\n const data = Buffer.alloc(associatedLedgerAccountLayout.span);\n associatedLedgerAccountLayout.encode(\n {\n instruction: instruction!,\n },\n data,\n );\n\n const keys = [\n accountMeta({ pubkey: id }),\n accountMeta({ pubkey: ledger }),\n accountMeta({ pubkey: owner, isWritable: false }),\n accountMeta({ pubkey: SystemProgram.programId, isWritable: false }),\n accountMeta({ pubkey: SYSVAR_RENT_PUBKEY, isWritable: false }),\n ];\n\n return {\n instruction: new TransactionInstruction({\n programId,\n keys,\n data,\n }),\n instructionType: InstructionType.FarmV3CreateLedger,\n };\n}\n\ninterface CreateFarmInstruction {\n farmId: PublicKey;\n farmAuthority: PublicKey;\n lpVault: PublicKey;\n lpMint: PublicKey;\n lockVault: PublicKey;\n lockMint: PublicKey;\n lockUserAccount?: PublicKey;\n programId: PublicKey;\n owner: PublicKey;\n rewardInfo: RewardInfoKey[];\n rewardInfoConfig: FarmRewardInfoConfig[];\n nonce: number;\n}\nexport function makeCreateFarmInstruction(params: CreateFarmInstruction): InstructionReturn {\n const data = Buffer.alloc(farmRewardLayout.span);\n farmRewardLayout.encode(\n {\n instruction: 0,\n nonce: new BN(params.nonce),\n rewardTimeInfo: params.rewardInfoConfig,\n },\n data,\n );\n\n const keys = [\n ...commonSystemAccountMeta,\n accountMeta({ pubkey: params.farmId }),\n accountMeta({ pubkey: params.farmAuthority, isWritable: false }),\n accountMeta({ pubkey: params.lpVault }),\n accountMeta({ pubkey: params.lpMint, isWritable: false }),\n accountMeta({ pubkey: params.lockVault }),\n accountMeta({ pubkey: params.lockMint, isWritable: false }),\n accountMeta({ pubkey: params.lockUserAccount ?? SOLMint }),\n accountMeta({ pubkey: params.owner, isWritable: false, isSigner: true }),\n ];\n\n for (const item of params.rewardInfo) {\n keys.push(\n ...[\n accountMeta({ pubkey: item.rewardMint, isWritable: false }),\n accountMeta({ pubkey: item.rewardVault }),\n accountMeta({ pubkey: item.userRewardToken }),\n ],\n );\n }\n\n return {\n instruction: new TransactionInstruction({ programId: params.programId, keys, data }),\n instructionType: InstructionType.FarmV6Create,\n };\n}\n\ninterface CreatorWithdrawFarmRewardInstruction {\n id: PublicKey;\n programId: PublicKey;\n authority: PublicKey;\n lpVault: PublicKey;\n rewardVault: PublicKey;\n userRewardToken: PublicKey;\n owner: PublicKey;\n}\n\nexport function makeCreatorWithdrawFarmRewardInstruction(\n params: CreatorWithdrawFarmRewardInstruction,\n): InstructionReturn {\n const data = Buffer.alloc(withdrawRewardLayout.span);\n withdrawRewardLayout.encode({ instruction: 5 }, data);\n\n const keys = [\n accountMeta({ pubkey: TOKEN_PROGRAM_ID, isWritable: false }),\n accountMeta({ pubkey: params.id }),\n accountMeta({ pubkey: params.authority, isWritable: false }),\n accountMeta({ pubkey: params.lpVault, isWritable: false }),\n accountMeta({ pubkey: params.rewardVault }),\n accountMeta({ pubkey: params.userRewardToken }),\n accountMeta({ pubkey: params.owner, isWritable: false, isSigner: true }),\n ];\n\n return {\n instruction: new TransactionInstruction({ programId: params.programId, keys, data }),\n instructionType: InstructionType.FarmV6CreatorWithdraw,\n };\n}\n\nexport function voterStakeRegistryDeposit(\n programId: PublicKey,\n registrar: PublicKey,\n voter: PublicKey,\n voterVault: PublicKey,\n depositToken: PublicKey,\n depositAuthority: PublicKey,\n\n userStakerInfoV2: PublicKey,\n pool: PublicKey,\n votingMint: PublicKey,\n votingMintAuthority: PublicKey,\n stakeProgramId: PublicKey,\n\n depositEntryIndex: number,\n amount: BN,\n): TransactionInstruction {\n const dataLayout = struct([u8(\"depositEntryIndex\"), u64(\"amount\")]);\n\n const keys = [\n { pubkey: registrar, isSigner: false, isWritable: false },\n { pubkey: voter, isSigner: false, isWritable: true },\n { pubkey: voterVault, isSigner: false, isWritable: true },\n { pubkey: depositToken, isSigner: false, isWritable: true },\n { pubkey: depositAuthority, isSigner: false, isWritable: false },\n { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n\n { pubkey: userStakerInfoV2, isSigner: false, isWritable: true },\n { pubkey: pool, isSigner: false, isWritable: false },\n { pubkey: votingMint, isSigner: false, isWritable: true },\n\n { pubkey: votingMintAuthority, isSigner: false, isWritable: false },\n { pubkey: stakeProgramId, isSigner: false, isWritable: false },\n { pubkey: INSTRUCTION_PROGRAM_ID, isSigner: false, isWritable: false },\n ];\n\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode(\n {\n depositEntryIndex,\n amount,\n },\n data,\n );\n const aData = Buffer.from([...anchorDataBuf.voterStakeRegistryDeposit, ...data]);\n\n return new TransactionInstruction({\n keys,\n programId,\n data: aData,\n });\n}\n\nexport function voterStakeRegistryUpdateVoterWeightRecord(\n programId: PublicKey,\n registrar: PublicKey,\n voter: PublicKey,\n voterWeightRecord: PublicKey,\n): TransactionInstruction {\n const dataLayout = struct([]);\n\n const keys = [\n { pubkey: registrar, isSigner: false, isWritable: false },\n { pubkey: voter, isSigner: false, isWritable: false },\n { pubkey: voterWeightRecord, isSigner: false, isWritable: true },\n { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },\n ];\n\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode({}, data);\n const aData = Buffer.from([...anchorDataBuf.voterStakeRegistryUpdateVoterWeightRecord, ...data]);\n\n return new TransactionInstruction({\n keys,\n programId,\n data: aData,\n });\n}\n\nexport function voterStakeRegistryWithdraw(\n programId: PublicKey,\n registrar: PublicKey,\n voter: PublicKey,\n voterAuthority: PublicKey,\n tokenOwnerRecord: PublicKey,\n voterWeightRecord: PublicKey,\n vault: PublicKey,\n destination: PublicKey,\n\n userStakerInfoV2: PublicKey,\n pool: PublicKey,\n votingMint: PublicKey,\n votingMintAuthority: PublicKey,\n stakeProgramId: PublicKey,\n\n depositEntryIndex: number,\n amount: BN,\n): TransactionInstruction {\n const dataLayout = struct([u8(\"depositEntryIndex\"), u64(\"amount\")]);\n\n const keys = [\n { pubkey: registrar, isSigner: false, isWritable: false },\n { pubkey: voter, isSigner: false, isWritable: true },\n { pubkey: voterAuthority, isSigner: true, isWritable: false },\n { pubkey: tokenOwnerRecord, isSigner: false, isWritable: false },\n\n { pubkey: voterWeightRecord, isSigner: false, isWritable: true },\n { pubkey: vault, isSigner: false, isWritable: true },\n { pubkey: destination, isSigner: false, isWritable: true },\n { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n\n { pubkey: userStakerInfoV2, isSigner: false, isWritable: true },\n { pubkey: pool, isSigner: false, isWritable: false },\n { pubkey: votingMint, isSigner: false, isWritable: true },\n\n { pubkey: votingMintAuthority, isSigner: false, isWritable: false },\n { pubkey: stakeProgramId, isSigner: false, isWritable: false },\n { pubkey: INSTRUCTION_PROGRAM_ID, isSigner: false, isWritable: false },\n ];\n\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode(\n {\n depositEntryIndex,\n amount,\n },\n data,\n );\n const aData = Buffer.from([...anchorDataBuf.voterStakeRegistryWithdraw, ...data]);\n\n return new TransactionInstruction({\n keys,\n programId,\n data: aData,\n });\n}\n\nexport function governanceCreateTokenOwnerRecord(\n programId: PublicKey,\n realm: PublicKey,\n governingTokenOwner: PublicKey,\n governingTokenMint: PublicKey,\n payer: PublicKey,\n tokenOwnerRecordAddress: PublicKey,\n): TransactionInstruction {\n const dataLayout = struct([u8(\"ins\")]);\n\n const keys = [\n { pubkey: realm, isSigner: false, isWritable: false },\n { pubkey: governingTokenOwner, isSigner: false, isWritable: false },\n\n { pubkey: tokenOwnerRecordAddress, isSigner: false, isWritable: true },\n\n { pubkey: governingTokenMint, isSigner: false, isWritable: false },\n\n { pubkey: payer, isSigner: true, isWritable: true },\n\n { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },\n ];\n\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode({ ins: 23 }, data);\n\n return new TransactionInstruction({\n keys,\n programId,\n data,\n });\n}\n\nexport function voterStakeRegistryCreateVoter(\n programId: PublicKey,\n registrar: PublicKey,\n voter: PublicKey,\n voterWeightRecord: PublicKey,\n voterAuthority: PublicKey,\n payer: PublicKey,\n\n voterBump: number,\n voterWeightRecordBump: number,\n): TransactionInstruction {\n const dataLayout = struct([u8(\"voterBump\"), u8(\"voterWeightRecordBump\")]);\n\n const keys = [\n { pubkey: registrar, isSigner: false, isWritable: false },\n { pubkey: voter, isSigner: false, isWritable: true },\n { pubkey: voterAuthority, isSigner: true, isWritable: false },\n { pubkey: voterWeightRecord, isSigner: false, isWritable: true },\n { pubkey: payer, isSigner: true, isWritable: true },\n { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },\n { pubkey: RENT_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: INSTRUCTION_PROGRAM_ID, isSigner: false, isWritable: false },\n ];\n\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode({ voterBump, voterWeightRecordBump }, data);\n const aData = Buffer.from([...anchorDataBuf.voterStakeRegistryCreateVoter, ...data]);\n\n return new TransactionInstruction({\n keys,\n programId,\n data: aData,\n });\n}\n\nexport function voterStakeRegistryCreateDepositEntry(\n programId: PublicKey,\n registrar: PublicKey,\n voter: PublicKey,\n voterVault: PublicKey,\n voterAuthority: PublicKey,\n payer: PublicKey,\n depositMint: PublicKey,\n\n depositEntryIndex: number,\n kind: number,\n startTs: BN | undefined,\n periods: number,\n allowClawback: boolean,\n): TransactionInstruction {\n const dataLayout = struct([\n u8(\"depositEntryIndex\"),\n u8(\"kind\"),\n u8(\"option\"),\n u64(\"startTs\"),\n u32(\"periods\"),\n bool(\"allowClawback\"),\n ]);\n\n const keys = [\n { pubkey: registrar, isSigner: false, isWritable: false },\n { pubkey: voter, isSigner: false, isWritable: true },\n { pubkey: voterVault, isSigner: false, isWritable: true },\n { pubkey: voterAuthority, isSigner: true, isWritable: false },\n { pubkey: payer, isSigner: true, isWritable: true },\n { pubkey: depositMint, isSigner: false, isWritable: false },\n { pubkey: SystemProgram.programId, isSigner: false, isWritable: false },\n { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false },\n { pubkey: RENT_PROGRAM_ID, isSigner: false, isWritable: false },\n ];\n\n const data = Buffer.alloc(dataLayout.span);\n dataLayout.encode(\n {\n depositEntryIndex,\n kind,\n option: startTs === undefined ? 0 : 1,\n startTs: startTs!,\n periods,\n allowClawback,\n },\n data,\n );\n const aData = Buffer.from([...anchorDataBuf.voterStakeRegistryCreateDepositEntry, ...data]);\n\n return new TransactionInstruction({\n keys,\n programId,\n data: aData,\n });\n}\n\nexport async function makeDepositTokenInstruction({\n connection,\n programId,\n governanceProgramId,\n voteWeightAddinProgramId,\n realm,\n communityTokenMint,\n owner,\n poolId,\n tokenProgram,\n}: {\n connection: Connection;\n programId: PublicKey;\n governanceProgramId: PublicKey;\n voteWeightAddinProgramId: PublicKey;\n realm: PublicKey;\n communityTokenMint: PublicKey;\n owner: PublicKey;\n poolId: PublicKey;\n tokenProgram?: PublicKey;\n}): Promise<TransactionInstruction[]> {\n const registrar = getRegistrarAddress(voteWeightAddinProgramId, realm, communityTokenMint).publicKey;\n const ownerPda = getAssociatedLedgerAccount({ programId, poolId, owner, version: 3 });\n const ownerAccountInfo = await connection.getAccountInfo(ownerPda);\n if (ownerAccountInfo === null) {\n throw Error(\"user is not staker\");\n }\n const ownerInfo = farmLedgerLayoutV3_2.decode(ownerAccountInfo.data);\n const mintAmount = ownerInfo.deposited.sub(ownerInfo.voteLockedBalance);\n console.log(\"amount\", mintAmount.toString());\n if (mintAmount.eq(new BN(0))) {\n throw Error(\"user do not has new stake amount\");\n }\n\n const votingMint = getVotingTokenMint(programId, poolId).publicKey;\n const votingMintAuthority = getVotingMintAuthority(programId, poolId).publicKey;\n const { publicKey: voter, nonce: voterBump } = getVoterAddress(voteWeightAddinProgramId, registrar, owner);\n const voterVault = getATAAddress(voter, votingMint, tokenProgram).publicKey;\n\n const { publicKey: voterWeightRecord, nonce: voterWeightRecordBump } = getVoterWeightRecordAddress(\n voteWeightAddinProgramId,\n registrar,\n owner,\n );\n\n const tokenOwnerRecordAddress = getTokenOwnerRecordAddress(\n governanceProgramId,\n realm,\n communityTokenMint,\n owner,\n ).publicKey;\n\n const instructions: TransactionInstruction[] = [];\n\n const depositToken = getATAAddress(owner, votingMint, tokenProgram).publicKey;\n const depositTokenAccountInfo = await connection.getAccountInfo(depositToken);\n if (depositTokenAccountInfo === null) {\n instructions.push(createAssociatedTokenAccountInstruction(owner, depositToken, owner, votingMint));\n }\n const voterAccountInfo = await connection.getAccountInfo(voter);\n if (voterAccountInfo === null) {\n const createTokenOwnerRecodeIns = governanceCreateTokenOwnerRecord(\n governanceProgramId,\n realm,\n owner,\n communityTokenMint,\n owner,\n tokenOwnerRecordAddress,\n );\n\n instructions.push(\n createTokenOwnerRecodeIns,\n voterStakeRegistryCreateVoter(\n voteWeightAddinProgramId,\n registrar,\n voter,\n voterWeightRecord,\n owner,\n owner,\n voterBump,\n voterWeightRecordBump,\n ),\n );\n }\n\n const { index: depositEntryIndex, isInit: depositEntryInit } = await getDepositEntryIndex(\n connection,\n registrar,\n voter,\n votingMint,\n );\n if (!depositEntryInit) {\n instructions.push(\n voterStakeRegistryCreateDepositEntry(\n voteWeightAddinProgramId,\n registrar,\n voter,\n voterVault,\n owner,\n owner,\n votingMint,\n\n depositEntryIndex,\n 0,\n undefined,\n 0,\n false,\n ),\n );\n }\n\n instructions.push(\n voterStakeRegistryDeposit(\n voteWeightAddinProgramId,\n registrar,\n voter,\n voterVault,\n depositToken,\n owner,\n\n ownerPda,\n poolId,\n votingMint,\n votingMintAuthority,\n programId,\n\n depositEntryIndex,\n mintAmount,\n ),\n voterStakeRegistryUpdateVoterWeightRecord(voteWeightAddinProgramId, registrar, voter, voterWeightRecord),\n );\n\n return instructions;\n}\n\nexport async function makeWithdrawTokenInstruction({\n connection,\n programId,\n governanceProgramId,\n voteWeightAddinProgramId,\n realm,\n communityTokenMint,\n owner,\n poolId,\n tokenProgram,\n}: {\n connection: Connection;\n programId: PublicKey;\n\n governanceProgramId: PublicKey;\n voteWeightAddinProgramId: PublicKey;\n realm: PublicKey;\n communityTokenMint: PublicKey;\n owner: PublicKey;\n poolId: PublicKey;\n tokenProgram?: PublicKey;\n}): Promise<TransactionInstruction[]> {\n const registrar = getRegistrarAddress(voteWeightAddinProgramId, realm, communityTokenMint).publicKey;\n const ownerPda = getAssociatedLedgerAccount({ programId, poolId, owner, version: 3 });\n const ownerAccountInfo = await connection.getAccountInfo(ownerPda);\n if (ownerAccountInfo === null) {\n throw Error(\"user is not staker\");\n }\n const ownerInfo = farmLedgerLayoutV3_2.decode(ownerAccountInfo.data);\n if (ownerInfo.voteLockedBalance.eq(new BN(0))) {\n throw Error(\"user has vote locked balance = 0\");\n }\n\n const votingMint = getVotingTokenMint(programId, poolId).publicKey;\n const votingMintAuthority = getVotingMintAuthority(programId, poolId).publicKey;\n const { publicKey: voter } = getVoterAddress(voteWeightAddinProgramId, registrar, owner);\n const voterVault = getATAAddress(voter, votingMint, tokenProgram).publicKey;\n const { publicKey: voterWeightRecord } = getVoterWeightRecordAddress(voteWeightAddinProgramId, registrar, owner);\n\n const tokenOwnerRecordAddress = getTokenOwnerRecordAddress(\n governanceProgramId,\n realm,\n communityTokenMint,\n owner,\n ).publicKey;\n\n const instructions: TransactionInstruction[] = [];\n\n const { index: depositEntryIndex, isInit: depositEntryInit } = await getDepositEntryIndex(\n connection,\n registrar,\n voter,\n votingMint,\n );\n if (!depositEntryInit) throw Error(\"deposit entry index check error\");\n\n instructions.push(\n voterStakeRegistryWithdraw(\n voteWeightAddinProgramId,\n registrar,\n voter,\n owner,\n tokenOwnerRecordAddress,\n voterWeightRecord,\n voterVault,\n getATAAddress(owner, votingMint, tokenProgram).publicKey,\n ownerPda,\n poolId,\n votingMint,\n votingMintAuthority,\n programId,\n\n depositEntryIndex,\n ownerInfo.voteLockedBalance,\n ),\n );\n\n return instructions;\n}\n\nexport function makeRestartRewardInstruction({\n payer,\n rewardVault,\n userRewardTokenPub,\n farmKeys,\n rewardInfo,\n}: {\n payer: PublicKey;\n rewardVault: PublicKey;\n userRewardTokenPub: PublicKey;\n farmKeys: {\n id: PublicKey;\n programId: PublicKey;\n lpVault: PublicKey;\n };\n rewardInfo: {\n openTime: number;\n endTime: number;\n perSecond: string;\n };\n}): TransactionInstruction {\n const data = Buffer.alloc(farmRewardRestartLayout.span);\n farmRewardRestartLayout.encode(\n {\n instruction: 3,\n rewardReopenTime: parseBigNumberish(rewardInfo.openTime),\n rewardEndTime: parseBigNumberish(rewardInfo.endTime),\n rewardPerSecond: parseBigNumberish(rewardInfo.perSecond),\n },\n data,\n );\n\n const keys = [\n accountMeta({ pubkey: TOKEN_PROGRAM_ID, isWritable: false }),\n accountMeta({ pubkey: farmKeys.id }),\n accountMeta({ pubkey: farmKeys.lpVault, isWritable: false }),\n accountMeta({ pubkey: rewardVault }),\n accountMeta({ pubkey: userRewardTokenPub! }),\n accountMeta({ pubkey: payer, isWritable: false, isSigner: true }),\n ];\n\n return new TransactionInstruction({ programId: farmKeys.programId, keys, data });\n}\n\nexport function makeAddNewRewardInstruction({\n payer,\n userRewardTokenPub,\n farmKeys,\n rewardVault,\n rewardInfo,\n}: {\n payer: PublicKey;\n userRewardTokenPub: PublicKey;\n rewardVault: PublicKey;\n farmKeys: {\n id: PublicKey;\n programId: PublicKey;\n authority: PublicKey;\n };\n rewardInfo: {\n mint: PublicKey;\n openTime: number;\n endTime: number;\n perSecond: string;\n rewardType: RewardType;\n };\n}): TransactionInstruction {\n const data = Buffer.alloc(farmAddRewardLayout.span);\n farmAddRewardLayout.encode(\n {\n instruction: 4,\n isSet: new BN(1),\n rewardPerSecond: parseBigNumberish(rewardInfo.perSecond),\n rewardOpenTime: parseBigNumberish(rewardInfo.openTime),\n rewardEndTime: parseBigNumberish(rewardInfo.endTime),\n rewardType: parseBigNumberish(poolTypeV6[rewardInfo.rewardType]),\n },\n data,\n );\n\n const keys = [\n ...commonSystemAccountMeta,\n accountMeta({ pubkey: farmKeys.id }),\n accountMeta({ pubkey: farmKeys.authority, isWritable: false }),\n accountMeta({ pubkey: rewardInfo.mint, isWritable: false }),\n accountMeta({ pubkey: rewardVault }),\n accountMeta({ pubkey: userRewardTokenPub! }),\n accountMeta({ pubkey: payer, isWritable: false, isSigner: true }),\n ];\n\n return new TransactionInstruction({ programId: farmKeys.programId, keys, data });\n}\n\nexport function makeDepositWithdrawInstruction(params: {\n instruction: number;\n amount: BN;\n farmInfo: { id: string; programId: string };\n farmKeys: FormatFarmKeyOut;\n lpAccount: PublicKey;\n owner: PublicKey;\n rewardAccounts: PublicKey[];\n deposit?: boolean;\n version: 3 | 5 | 6;\n}): TransactionInstruction {\n const { farmInfo, farmKeys, version, lpAccount, rewardAccounts, owner, instruction, amount, deposit } = params;\n\n const [programId, id] = [new PublicKey(farmInfo.programId), new PublicKey(farmInfo.id)];\n\n const ledgerAddress = getAssociatedLedgerAccount({\n programId,\n poolId: id,\n owner,\n version,\n });\n\n const data = Buffer.alloc(dwLayout.span);\n dwLayout.encode(\n {\n instruction,\n amount,\n },\n data,\n );\n\n const keys =\n version === 6\n ? [\n accountMeta({ pubkey: TOKEN_PROGRAM_ID, isWritable: false }),\n ...(deposit ? [accountMeta({ pubkey: SystemProgram.programId, isWritable: false })] : []),\n accountMeta({ pubkey: id }),\n accountMeta({ pubkey: new PublicKey(farmKeys.authority), isWritable: false }),\n accountMeta({ pubkey: new PublicKey(farmKeys.lpVault) }),\n accountMeta({ pubkey: ledgerAddress }),\n accountMeta({ pubkey: owner, isWritable: false, isSigner: true }),\n accountMeta({ pubkey: lpAccount }),\n ]\n : [\n accountMeta({ pubkey: id }),\n accountMeta({ pubkey: new PublicKey(farmKeys.authority), isWritable: false }),\n accountMeta({ pubkey: ledgerAddress }),\n accountMeta({ pubkey: owner, isWritable: false, isSigner: true }),\n accountMeta({ pubkey: lpAccount }),\n accountMeta({ pubkey: new PublicKey(farmKeys.lpVault) }),\n accountMeta({ pubkey: rewardAccounts[0] }),\n accountMeta({ pubkey: new PublicKey(farmKeys.rewardInfos[0].vault) }),\n // system\n accountMeta({ pubkey: SYSVAR_CLOCK_PUBKEY, isWritable: false }),\n accountMeta({ pubkey: TOKEN_PROGRAM_ID, isWritable: false }),\n ];\n\n if (version === 5) {\n for (let index = 1; index < farmKeys.rewardInfos.length; index++) {\n keys.push(accountMeta({ pubkey: rewardAccounts[index] }));\n keys.push(accountMeta({ pubkey: new PublicKey(farmKeys.rewardInfos[index].vault) }));\n }\n }\n\n if (version === 6) {\n for (let index = 0; index < farmKeys.rewardInfos.length; index++) {\n keys.push(accountMeta({ pubkey: new PublicKey(farmKeys.rewardInfos[index].vault) }));\n keys.push(accountMeta({ pubkey: rewardAccounts[index] }));\n }\n }\n\n return new TransactionInstruction({ programId, keys, data });\n}\n\ninterface DepositWithdrawParams {\n amount: BN;\n farmInfo: { id: string; programId: string };\n farmKeys: FormatFarmKeyOut;\n lpAccount: PublicKey;\n owner: PublicKey;\n rewardAccounts: PublicKey[];\n userAuxiliaryLedgers?: PublicKey[];\n}\n\nexport function makeWithdrawInstructionV6(params: DepositWithdrawParams): TransactionInstruction {\n const { farmInfo, farmKeys, lpAccount, rewardAccounts, owner, amount } = params;\n const [programId, id] = [new PublicKey(farmInfo.programId), new PublicKey(farmInfo.id)];\n\n const ledgerAddress = getAssociatedLedgerAccount({\n programId,\n poolId: id,\n owner,\n version: 6,\n });\n\n const data = Buffer.alloc(dwLayout.span);\n dwLayout.encode(\n {\n instruction: 2,\n amount: parseBigNumberish(amount),\n },\n data,\n );\n\n const keys = [\n accountMeta({ pubkey: TOKEN_PROGRAM_ID, isWritable: false }),\n\n accountMeta({ pubkey: id }),\n\n accountMeta({ pubkey: new PublicKey(farmKeys.authority), isWritable: false }),\n accountMeta({ pubkey: new PublicKey(farmKeys.lpVault) }),\n accountMeta({ pubkey: ledgerAddress }),\n accountMeta({ pubkey: owner, isWritable: false, isSigner: true }),\n accountMeta({ pubkey: lpAccount }),\n ];\n\n for (let index = 0; index < farmKeys.rewardInfos.length; index++) {\n keys.push(accountMeta({ pubkey: new PublicKey(farmKeys.rewardInfos[index].vault) }));\n keys.push(accountMeta({ pubkey: rewardAccounts[index] }));\n }\n\n return new TransactionInstruction({ programId, keys, data });\n}\n\nexport function makeWithdrawInstructionV5(params: DepositWithdrawParams): TransactionInstruction {\n const { farmInfo, farmKeys, lpAccount, rewardAccounts, owner, amount, userAuxiliaryLedgers } = params;\n const [programId, id] = [new PublicKey(farmInfo.programId), new PublicKey(farmInfo.id)];\n\n const ledgerAddress = getAssociatedLedgerAccount({\n programId,\n poolId: id,\n owner,\n version: 5,\n });\n\n const data = Buffer.alloc(dwLayout.span);\n dwLayout.encode(\n {\n instruction: 12,\n amount: parseBigNumberish(amount),\n },\n data,\n );\n\n const keys = [\n accountMeta({ pubkey: id }),\n accountMeta({ pubkey: new PublicKey(farmKeys.authority), isWritable: false }),\n accountMeta({ pubkey: ledgerAddress }),\n accountMeta({ pubkey: owner, isWritable: false, isSigner: true }),\n accountMeta({ pubkey: lpAccount }),\n accountMeta({ pubkey: new PublicKey(farmKeys.lpVault) }),\n accountMeta({ pubkey: rewardAccounts[0] }),\n accountMeta({ pubkey: new PublicKey(farmKeys.rewardInfos[0].vault) }),\n // system\n accountMeta({ pubkey: SYSVAR_CLOCK_PUBKEY, isWritable: false }),\n accountMeta({ pubkey: TOKEN_PROGRAM_ID, isWritable: false }),\n ];\n\n for (let index = 1; index < farmKeys.rewardInfos.length; index++) {\n keys.push(accountMeta({ pubkey: rewardAccounts[index] }));\n keys.push(accountMeta({ pubkey: new PublicKey(farmKeys.rewardInfos[index].vault) }));\n }\n\n if (userAuxiliaryLedgers) {\n for (const auxiliaryLedger of userAuxiliaryLedgers) {\n keys.push(accountMeta({ pubkey: auxiliaryLedger }));\n }\n }\n\n return new TransactionInstruction({ programId, keys, data });\n}\n\nexport function makeWithdrawInstructionV4(params: DepositWithdrawParams): TransactionInstruction {\n const { farmInfo, farmKeys, lpAccount, rewardAccounts, owner, amount, userAuxiliaryLedgers } = params;\n const [programId, id] = [new PublicKey(farmInfo.programId), new PublicKey(farmInfo.id)];\n\n const dataLayout = struct([u8('instruction'), u64('amount')])\n\n const keys = [\n accountMeta({ pubkey: id }),\n accountMeta({ pubkey: new PublicKey(farmKeys.authority), isWritable: false }),\n accountMeta({ pubkey: userAuxiliaryLedgers![0] }),\n accountMeta({ pubkey: owner, isSigner: true, isWritable: false }),\n accountMeta({ pubkey: lpAccount }),\n accountMeta({ pubkey: new PublicKey(farmKeys.lpVault) }),\n accountMeta({ pubkey: rewardAccounts[0] }),\n accountMeta({ pubkey: new PublicKey(farmKeys.rewardInfos[0].vault) }),\n accountMeta({ pubkey: SYSVAR_CLOCK_PUBKEY, isWritable: false }),\n accountMeta({ pubkey: TOKEN_PROGRAM_ID, isWritable: false }),\n accountMeta({ pubkey: rewardAccounts[1] }),\n accountMeta({ pubkey: new PublicKey(farmKeys.rewardInfos[1].vault) }),\n ]\n\n const data = Buffer.alloc(dataLayout.span)\n dataLayout.encode(\n {\n instruction: 2,\n amount\n },\n data\n )\n\n return new TransactionInstruction({\n keys,\n programId,\n data\n })\n}\n\nexport function makeWithdrawInstructionV3(params: DepositWithdrawParams): TransactionInstruction {\n const { farmInfo, farmKeys, lpAccount, rewardAccounts, owner, amount, userAuxiliaryLedgers } = params;\n const [programId, id] = [new PublicKey(farmInfo.programId), new PublicKey(farmInfo.id)];\n\n const ledgerAddress = getAssociatedLedgerAccount({\n programId,\n poolId: id,\n owner,\n version: 3,\n });\n\n const data = Buffer.alloc(dwLayout.span);\n dwLayout.encode(\n {\n instruction: 11,\n amount: parseBigNumberish(amount),\n },\n data,\n );\n\n const keys = [\n accountMeta({ pubkey: id }),\n accountMeta({ pubkey: new PublicKey(farmKeys.authority), isWritable: false }),\n accountMeta({ pubkey: ledgerAddress }),\n accountMeta({ pubkey: owner, isWritable: false, isSigner: true }),\n accountMeta({ pubkey: lpAccount }),\n accountMeta({ pubkey: new PublicKey(farmKeys.lpVault) }),\n accountMeta({ pubkey: rewardAccounts[0] }),\n accountMeta({ pubkey: new PublicKey(farmKeys.rewardInfos[0].vault) }),\n // system\n accountMeta({ pubkey: SYSVAR_CLOCK_PUBKEY, isWritable: false }),\n accountMeta({ pubkey: TOKEN_PROGRAM_ID, isWritable: false }),\n ];\n\n if (userAuxiliaryLedgers) {\n for (const auxiliaryLedger of userAuxiliaryLedgers) {\n keys.push(accountMeta({ pubkey: auxiliaryLedger }));\n }\n }\n\n return new TransactionInstruction({ programId, keys, data });\n}\n\nexport function makeDepositInstructionV3(params: DepositWithdrawParams): TransactionInstruction {\n const { farmInfo, farmKeys, lpAccount, rewardAccounts, owner, amount, userAuxiliaryLedgers } = params;\n const [programId, id] = [new PublicKey(farmInfo.programId), new PublicKey(farmInfo.id)];\n\n const ledgerAddress = getAssociatedLedgerAccount({\n programId,\n poolId: id,\n owner,\n version: 3,\n });\n\n const data = Buffer.alloc(dwLayout.span);\n dwLayout.encode(\n {\n instruction: 10,\n amount: parseBigNumberish(amount),\n },\n data,\n );\n\n const keys = [\n accountMeta({ pubkey: id }),\n accountMeta({ pubkey: new PublicKey(farmKeys.authority), isWritable: false }),\n accountMeta({ pubkey: ledgerAddress }),\n accountMeta({ pubkey: owner, isWritable: false, isSigner: true }),\n accountMeta({ pubkey: lpAccount }),\n accountMeta({ pubkey: new PublicKey(farmKeys.lpVault) }),\n accountMeta({ pubkey: rewardAccounts[0] }),\n accountMeta({ pubkey: new PublicKey(farmKeys.rewardInfos[0].vault) }),\n // system\n accountMeta({ pubkey: SYSVAR_CLOCK_PUBKEY, isWritable: false }),\n accountMeta({ pubkey: TOKEN_PROGRAM_ID, isWritable: false }),\n ];\n\n if (userAuxiliaryLedgers) {\n for (const auxiliaryLedger of userAuxiliaryLedgers) {\n keys.push(accountMeta({ pubkey: auxiliaryLedger }));\n }\n }\n\n return new TransactionInstruction({ programId, keys, data });\n}\n\nexport function makeDepositInstructionV5(params: DepositWithdrawParams): TransactionInstruction {\n const { farmInfo, farmKeys, lpAccount, rewardAccounts, owner, amount, userAuxiliaryLedgers } = params;\n const [programId, id] = [new PublicKey(farmInfo.programId), new PublicKey(farmInfo.id)];\n\n const ledgerAddress = getAssociatedLedgerAccount({\n programId,\n poolId: id,\n owner,\n version: 5,\n });\n\n const data = Buffer.alloc(dwLayout.span);\n dwLayout.encode(\n {\n instruction: 11,\n amount: parseBigNumberish(amount),\n },\n data,\n );\n\n const keys = [\n accountMeta({ pubkey: id }),\n accountMeta({ pubkey: new PublicKey(farmKeys.authority), isWritable: false }),\n accountMeta({ pubkey: ledgerAddress }),\n accountMeta({ pubkey: owner, isWritable: false, isSigner: true }),\n accountMeta({ pubkey: lpAccount }),\n accountMeta({ pubkey: new PublicKey(farmKeys.lpVault) }),\n accountMeta({ pubkey: rewardAccounts[0] }),\n accountMeta({ pubkey: new PublicKey(farmKeys.rewardInfos[0].vault) }),\n // system\n accountMeta({ pubkey: SYSVAR_CLOCK_PUBKEY, isWritable: false }),\n accountMeta({ pubkey: TOKEN_PROGRAM_ID, isWritable: false }),\n ];\n\n for (let index = 1; index < farmKeys.rewardInfos.length; index++) {\n keys.push(accountMeta({ pubkey: rewardAccounts[index] }));\n keys.push(accountMeta({ pubkey: new PublicKey(farmKeys.rewardInfos[index].vault) }));\n }\n\n if (userAuxiliaryLedgers) {\n for (const auxiliaryLedger of userAuxiliaryLedgers) {\n keys.push(accountMeta({ pubkey: auxiliaryLedger }));\n }\n }\n\n return new TransactionInstruction({ programId, keys, data });\n}\n\nexport function makeDepositInstructionV6(params: DepositWithdrawParams): TransactionInstruction {\n const { farmInfo, farmKeys, lpAccount, rewardAccounts, owner, amount } = params;\n const [programId, id] = [new PublicKey(farmInfo.programId), new PublicKey(farmInfo.id)];\n\n const ledgerAddress = getAssociatedLedgerAccount({\n programId,\n poolId: id,\n owner,\n version: 6,\n });\n\n const data = Buffer.alloc(dwLayout.span);\n dwLayout.encode(\n {\n instruction: 1,\n amount: parseBigNumberish(amount),\n },\n data,\n );\n\n const keys = [\n accountMeta({ pubkey: TOKEN_PROGRAM_ID, isWritable: false }),\n accountMeta({ pubkey: SystemProgram.programId, isWritable: false }),\n accountMeta({ pubkey: id }),\n accountMeta({ pubkey: new PublicKey(farmKeys.authority), isWritable: false }),\n accountMeta({ pubkey: new PublicKey(farmKeys.lpVault) }),\n accountMeta({ pubkey: ledgerAddress }),\n accountMeta({ pubkey: owner, isWritable: false, isSigner: true }),\n accountMeta({ pubkey: lpAccount }),\n ];\n\n for (let index = 0; index < farmKeys.rewardInfos.length; index++) {\n keys.push(accountMeta({ pubkey: new PublicKey(farmKeys.rewardInfos[index].vault) }));\n keys.push(accountMeta({ pubkey: rewardAccounts[index] }));\n }\n\n return new TransactionInstruction({ programId, keys, data });\n}\n","import { AccountInfo, Commitment, Connection, PublicKey } from \"@solana/web3.js\";\nimport { ReturnTypeFetchMultipleMintInfos } from \"../raydium/type\";\nimport { WSOLMint, chunkArray, solToWSol } from \"./\";\nimport { createLogger } from \"./logger\";\nimport { MINT_SIZE, TOKEN_PROGRAM_ID, getTransferFeeConfig, unpackMint } from \"@solana/spl-token\";\n\ninterface MultipleAccountsJsonRpcResponse {\n jsonrpc: string;\n id: string;\n error?: {\n code: number;\n message: string;\n };\n result: {\n context: { slot: number };\n value: { data: Array<string>; executable: boolean; lamports: number; owner: string; rentEpoch: number }[];\n };\n}\n\nexport interface GetMultipleAccountsInfoConfig {\n batchRequest?: boolean;\n commitment?: Commitment;\n chunkCount?: number;\n}\n\nconst logger = createLogger(\"Raydium_accountInfo_util\");\n\nexport async function getMultipleAccountsInfo(\n connection: Connection,\n publicKeys: PublicKey[],\n config?: GetMultipleAccountsInfoConfig,\n): Promise<(AccountInfo<Buffer> | null)[]> {\n const {\n batchRequest,\n commitment = \"confirmed\",\n chunkCount = 100,\n } = {\n batchRequest: false,\n ...config,\n };\n\n const chunkedKeys = chunkArray(publicKeys, chunkCount);\n let results: (AccountInfo<Buffer> | null)[][] = new Array(chunkedKeys.length).fill([]);\n\n if (batchRequest) {\n const batch = chunkedKeys.map((keys) => {\n const args = connection._buildArgs([keys.map((key) => key.toBase58())], commitment, \"base64\");\n return {\n methodName: \"getMultipleAccounts\",\n args,\n };\n });\n\n const _batch = chunkArray(batch, 10);\n\n const unsafeResponse: MultipleAccountsJsonRpcResponse[] = await (\n await Promise.all(_batch.map(async (i) => await (connection as any)._rpcBatchRequest(i)))\n ).flat();\n results = unsafeResponse.map((unsafeRes: MultipleAccountsJsonRpcResponse) => {\n if (unsafeRes.error)\n logger.logWithError(`failed to get info for multiple accounts, RPC_ERROR, ${unsafeRes.error.message}`);\n\n return unsafeRes.result.value.map((accountInfo) => {\n if (accountInfo) {\n const { data, executable, lamports, owner, rentEpoch } = accountInfo;\n\n if (data.length !== 2 && data[1] !== \"base64\") logger.logWithError(`info must be base64 encoded, RPC_ERROR`);\n\n return {\n data: Buffer.from(data[0], \"base64\"),\n executable,\n lamports,\n owner: new PublicKey(owner),\n rentEpoch,\n };\n }\n return null;\n });\n });\n } else {\n try {\n results = (await Promise.all(\n chunkedKeys.map((keys) => connection.getMultipleAccountsInfo(keys, commitment)),\n )) as (AccountInfo<Buffer> | null)[][];\n } catch (error) {\n if (error instanceof Error) {\n logger.logWithError(`failed to get info for multiple accounts, RPC_ERROR, ${error.message}`);\n }\n }\n }\n\n return results.flat();\n}\n\nexport async function getMultipleAccountsInfoWithCustomFlags<T extends { pubkey: PublicKey }>(\n connection: Connection,\n publicKeysWithCustomFlag: T[],\n config?: GetMultipleAccountsInfoConfig,\n): Promise<({ accountInfo: AccountInfo<Buffer> | null } & T)[]> {\n const multipleAccountsInfo = await getMultipleAccountsInfo(\n connection,\n publicKeysWithCustomFlag.map((o) => o.pubkey),\n config,\n );\n\n return publicKeysWithCustomFlag.map((o, idx) => ({ ...o, accountInfo: multipleAccountsInfo[idx] }));\n}\n\nexport enum AccountType {\n Uninitialized,\n Mint,\n Account,\n}\nexport const ACCOUNT_TYPE_SIZE = 1;\n\nexport async function fetchMultipleMintInfos({\n connection,\n mints,\n config,\n}: {\n connection: Connection;\n mints: PublicKey[];\n config?: { batchRequest?: boolean };\n}): Promise<ReturnTypeFetchMultipleMintInfos> {\n if (mints.length === 0) return {};\n const mintInfos = await getMultipleAccountsInfoWithCustomFlags(\n connection,\n mints.map((i) => ({ pubkey: solToWSol(i) })),\n config,\n );\n\n const mintK: ReturnTypeFetchMultipleMintInfos = {};\n for (const i of mintInfos) {\n if (!i.accountInfo || i.accountInfo.data.length < MINT_SIZE) {\n console.log(\"invalid mint account\", i.pubkey.toBase58());\n continue;\n }\n const t = unpackMint(i.pubkey, i.accountInfo, i.accountInfo?.owner);\n mintK[i.pubkey.toString()] = {\n ...t,\n programId: i.accountInfo?.owner || TOKEN_PROGRAM_ID,\n feeConfig: getTransferFeeConfig(t) ?? undefined,\n };\n }\n mintK[PublicKey.default.toBase58()] = mintK[WSOLMint.toBase58()];\n\n return mintK;\n}\n","import { get, set } from \"lodash\";\n\nexport type ModuleName = \"Common.Api\";\n\nexport enum LogLevel {\n Error,\n Warning,\n Info,\n Debug,\n}\nexport class Logger {\n private logLevel: LogLevel;\n private name: string;\n constructor(params: { name: string; logLevel?: LogLevel }) {\n this.logLevel = params.logLevel !== undefined ? params.logLevel : LogLevel.Error;\n this.name = params.name;\n }\n\n set level(logLevel: LogLevel) {\n this.logLevel = logLevel;\n }\n get time(): string {\n return Date.now().toString();\n }\n get moduleName(): string {\n return this.name;\n }\n\n private isLogLevel(level: LogLevel): boolean {\n return level <= this.logLevel;\n }\n\n public error(...props): Logger {\n if (!this.isLogLevel(LogLevel.Error)) return this;\n console.error(this.time, this.name, \"sdk logger error\", ...props);\n return this;\n }\n\n public logWithError(...props): Logger {\n // this.error(...props)\n const msg = props.map((arg) => (typeof arg === \"object\" ? JSON.stringify(arg) : arg)).join(\", \");\n throw new Error(msg);\n }\n\n public warning(...props): Logger {\n if (!this.isLogLevel(LogLevel.Warning)) return this;\n console.warn(this.time, this.name, \"sdk logger warning\", ...props);\n return this;\n }\n\n public info(...props): Logger {\n if (!this.isLogLevel(LogLevel.Info)) return this;\n console.info(this.time, this.name, \"sdk logger info\", ...props);\n return this;\n }\n\n public debug(...props): Logger {\n if (!this.isLogLevel(LogLevel.Debug)) return this;\n console.debug(this.time, this.name, \"sdk logger debug\", ...props);\n return this;\n }\n}\n\nconst moduleLoggers: { [key in ModuleName]?: Logger } = {};\nconst moduleLevels: { [key in ModuleName]?: LogLevel } = {};\n\nexport function createLogger(moduleName: string): Logger {\n let logger = get(moduleLoggers, moduleName);\n if (!logger) {\n // default level is error\n const logLevel = get(moduleLevels, moduleName);\n\n logger = new Logger({ name: moduleName, logLevel });\n set(moduleLoggers, moduleName, logger);\n }\n\n return logger;\n}\n\nexport function setLoggerLevel(moduleName: string, level: LogLevel): void {\n set(moduleLevels, moduleName, level);\n\n const logger = get(moduleLoggers, moduleName);\n if (logger) logger.level = level;\n}\n","import BN from \"bn.js\";\nimport Decimal from \"decimal.js\";\nimport { CurrencyAmount, TokenAmount } from \"../module/amount\";\nimport { Currency } from \"../module/currency\";\nimport { Fraction } from \"../module/fraction\";\nimport { Percent } from \"../module/percent\";\nimport { Price } from \"../module/price\";\nimport { Token } from \"../module/token\";\nimport { SplToken, TokenJson } from \"../raydium/token/type\";\nimport { ReplaceType } from \"../raydium/type\";\nimport { parseBigNumberish } from \"./constant\";\nimport { mul } from \"./fractionUtil\";\nimport { notInnerObject } from \"./utility\";\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\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\nexport function ceilDiv(tokenAmount: BN, feeNumerator: BN, feeDenominator: BN): BN {\n return tokenAmount.mul(feeNumerator).add(feeDenominator).sub(new BN(1)).div(feeDenominator);\n}\n\nexport function floorDiv(tokenAmount: BN, feeNumerator: BN, feeDenominator: BN): BN {\n return tokenAmount.mul(feeNumerator).div(feeDenominator);\n}\n\n/**\n * @example\n * toPercent(3.14) // => Percent { 314.00% }\n * toPercent(3.14, { alreadyDecimaled: true }) // => Percent {3.14%}\n */\nexport function toPercent(\n n: Numberish,\n options?: { /* usually used for backend data */ alreadyDecimaled?: boolean },\n): Percent {\n const { numerator, denominator } = parseNumberInfo(n);\n return new Percent(new BN(numerator), new BN(denominator).mul(options?.alreadyDecimaled ? new BN(100) : new BN(1)));\n}\n\nexport function toTokenPrice(params: {\n token: TokenJson | Token | SplToken;\n numberPrice: Numberish;\n decimalDone?: boolean;\n}): Price {\n const { token, numberPrice, decimalDone } = params;\n const usdCurrency = new Token({ mint: \"\", decimals: 6, symbol: \"usd\", name: \"usd\", skipMint: true });\n const { numerator, denominator } = parseNumberInfo(numberPrice);\n const parsedNumerator = decimalDone ? new BN(numerator).mul(BN_TEN.pow(new BN(token.decimals))) : numerator;\n const parsedDenominator = new BN(denominator).mul(BN_TEN.pow(new BN(usdCurrency.decimals)));\n\n return new Price({\n baseToken: usdCurrency,\n denominator: parsedDenominator.toString(),\n quoteToken: new Token({ ...token, skipMint: true, mint: \"\" }),\n numerator: parsedNumerator.toString(),\n });\n}\n\nexport function toUsdCurrency(amount: Numberish): CurrencyAmount {\n const usdCurrency = new Currency({ decimals: 6, symbol: \"usd\", name: \"usd\" });\n const amountBigNumber = toBN(mul(amount, 10 ** usdCurrency.decimals)!);\n return new CurrencyAmount(usdCurrency, amountBigNumber);\n}\n\ne