UNPKG

test-raydium-sdk-v2

Version:

An SDK for building applications on top of Raydium.

1,097 lines (965 loc) 33.8 kB
import { PublicKey, SystemProgram, SYSVAR_RENT_PUBKEY, SYSVAR_CLOCK_PUBKEY, TransactionInstruction, Connection, } from "@solana/web3.js"; import { createAssociatedTokenAccountInstruction, TOKEN_PROGRAM_ID, ASSOCIATED_TOKEN_PROGRAM_ID, } from "@solana/spl-token"; import BN from "bn.js"; import { struct, u8, u64, u32, bool } from "@/marshmallow"; import { FormatFarmKeyOut } from "@/api/type"; import { getATAAddress } from "@/common/pda"; import { createLogger } from "@/common/logger"; import { parseBigNumberish } from "@/common/bignumber"; import { accountMeta, commonSystemAccountMeta, SOLMint, RENT_PROGRAM_ID, INSTRUCTION_PROGRAM_ID, } from "@/common/pubKey"; import { InstructionType } from "@/common/txTool/txType"; import { InstructionReturn } from "../type"; import { associatedLedgerAccountLayout, farmRewardLayout, withdrawRewardLayout, farmLedgerLayoutV3_2, farmAddRewardLayout, } from "./layout"; import { FarmRewardInfoConfig, RewardInfoKey, RewardType } from "./type"; import { getRegistrarAddress, getVotingTokenMint, getVotingMintAuthority, getVoterAddress, getVoterWeightRecordAddress, getTokenOwnerRecordAddress, } from "./pda"; import { dwLayout, farmRewardRestartLayout } from "./layout"; import { getAssociatedLedgerAccount, getDepositEntryIndex } from "./util"; import { poolTypeV6 } from "./config"; const logger = createLogger("Raydium_farm_instruction"); const anchorDataBuf = { voterStakeRegistryCreateVoter: Buffer.from([6, 24, 245, 52, 243, 255, 148, 25]), // CreateVoter voterStakeRegistryCreateDepositEntry: Buffer.from([185, 131, 167, 186, 159, 125, 19, 67]), // CreateDepositEntry voterStakeRegistryDeposit: Buffer.from([242, 35, 198, 137, 82, 225, 242, 182]), // Deposit voterStakeRegistryWithdraw: Buffer.from([183, 18, 70, 156, 148, 109, 161, 34]), // Withdraw voterStakeRegistryUpdateVoterWeightRecord: Buffer.from([45, 185, 3, 36, 109, 190, 115, 169]), // UpdateVoterWeightRecord }; export function createAssociatedLedgerAccountInstruction(params: { version: number; id: PublicKey; programId: PublicKey; ledger: PublicKey; owner: PublicKey; }): InstructionReturn { const { version, id, ledger, programId, owner } = params; const instruction = { 3: 9, 5: 10 }[version]; if (!instruction) logger.logWithError(`invalid farm pool version: ${version}`); const data = Buffer.alloc(associatedLedgerAccountLayout.span); associatedLedgerAccountLayout.encode( { instruction: instruction!, }, data, ); const keys = [ accountMeta({ pubkey: id }), accountMeta({ pubkey: ledger }), accountMeta({ pubkey: owner, isWritable: false }), accountMeta({ pubkey: SystemProgram.programId, isWritable: false }), accountMeta({ pubkey: SYSVAR_RENT_PUBKEY, isWritable: false }), ]; return { instruction: new TransactionInstruction({ programId, keys, data, }), instructionType: InstructionType.FarmV3CreateLedger, }; } interface CreateFarmInstruction { farmId: PublicKey; farmAuthority: PublicKey; lpVault: PublicKey; lpMint: PublicKey; lockVault: PublicKey; lockMint: PublicKey; lockUserAccount?: PublicKey; programId: PublicKey; owner: PublicKey; rewardInfo: RewardInfoKey[]; rewardInfoConfig: FarmRewardInfoConfig[]; nonce: number; } export function makeCreateFarmInstruction(params: CreateFarmInstruction): InstructionReturn { const data = Buffer.alloc(farmRewardLayout.span); farmRewardLayout.encode( { instruction: 0, nonce: new BN(params.nonce), rewardTimeInfo: params.rewardInfoConfig, }, data, ); const keys = [ ...commonSystemAccountMeta, accountMeta({ pubkey: params.farmId }), accountMeta({ pubkey: params.farmAuthority, isWritable: false }), accountMeta({ pubkey: params.lpVault }), accountMeta({ pubkey: params.lpMint, isWritable: false }), accountMeta({ pubkey: params.lockVault }), accountMeta({ pubkey: params.lockMint, isWritable: false }), accountMeta({ pubkey: params.lockUserAccount ?? SOLMint }), accountMeta({ pubkey: params.owner, isWritable: false, isSigner: true }), ]; for (const item of params.rewardInfo) { keys.push( ...[ accountMeta({ pubkey: item.rewardMint, isWritable: false }), accountMeta({ pubkey: item.rewardVault }), accountMeta({ pubkey: item.userRewardToken }), ], ); } return { instruction: new TransactionInstruction({ programId: params.programId, keys, data }), instructionType: InstructionType.FarmV6Create, }; } interface CreatorWithdrawFarmRewardInstruction { id: PublicKey; programId: PublicKey; authority: PublicKey; lpVault: PublicKey; rewardVault: PublicKey; userRewardToken: PublicKey; owner: PublicKey; } export function makeCreatorWithdrawFarmRewardInstruction( params: CreatorWithdrawFarmRewardInstruction, ): InstructionReturn { const data = Buffer.alloc(withdrawRewardLayout.span); withdrawRewardLayout.encode({ instruction: 5 }, data); const keys = [ accountMeta({ pubkey: TOKEN_PROGRAM_ID, isWritable: false }), accountMeta({ pubkey: params.id }), accountMeta({ pubkey: params.authority, isWritable: false }), accountMeta({ pubkey: params.lpVault, isWritable: false }), accountMeta({ pubkey: params.rewardVault }), accountMeta({ pubkey: params.userRewardToken }), accountMeta({ pubkey: params.owner, isWritable: false, isSigner: true }), ]; return { instruction: new TransactionInstruction({ programId: params.programId, keys, data }), instructionType: InstructionType.FarmV6CreatorWithdraw, }; } export function voterStakeRegistryDeposit( programId: PublicKey, registrar: PublicKey, voter: PublicKey, voterVault: PublicKey, depositToken: PublicKey, depositAuthority: PublicKey, userStakerInfoV2: PublicKey, pool: PublicKey, votingMint: PublicKey, votingMintAuthority: PublicKey, stakeProgramId: PublicKey, depositEntryIndex: number, amount: BN, ): TransactionInstruction { const dataLayout = struct([u8("depositEntryIndex"), u64("amount")]); const keys = [ { pubkey: registrar, isSigner: false, isWritable: false }, { pubkey: voter, isSigner: false, isWritable: true }, { pubkey: voterVault, isSigner: false, isWritable: true }, { pubkey: depositToken, isSigner: false, isWritable: true }, { pubkey: depositAuthority, isSigner: false, isWritable: false }, { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, { pubkey: userStakerInfoV2, isSigner: false, isWritable: true }, { pubkey: pool, isSigner: false, isWritable: false }, { pubkey: votingMint, isSigner: false, isWritable: true }, { pubkey: votingMintAuthority, isSigner: false, isWritable: false }, { pubkey: stakeProgramId, isSigner: false, isWritable: false }, { pubkey: INSTRUCTION_PROGRAM_ID, isSigner: false, isWritable: false }, ]; const data = Buffer.alloc(dataLayout.span); dataLayout.encode( { depositEntryIndex, amount, }, data, ); const aData = Buffer.from([...anchorDataBuf.voterStakeRegistryDeposit, ...data]); return new TransactionInstruction({ keys, programId, data: aData, }); } export function voterStakeRegistryUpdateVoterWeightRecord( programId: PublicKey, registrar: PublicKey, voter: PublicKey, voterWeightRecord: PublicKey, ): TransactionInstruction { const dataLayout = struct([]); const keys = [ { pubkey: registrar, isSigner: false, isWritable: false }, { pubkey: voter, isSigner: false, isWritable: false }, { pubkey: voterWeightRecord, isSigner: false, isWritable: true }, { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, ]; const data = Buffer.alloc(dataLayout.span); dataLayout.encode({}, data); const aData = Buffer.from([...anchorDataBuf.voterStakeRegistryUpdateVoterWeightRecord, ...data]); return new TransactionInstruction({ keys, programId, data: aData, }); } export function voterStakeRegistryWithdraw( programId: PublicKey, registrar: PublicKey, voter: PublicKey, voterAuthority: PublicKey, tokenOwnerRecord: PublicKey, voterWeightRecord: PublicKey, vault: PublicKey, destination: PublicKey, userStakerInfoV2: PublicKey, pool: PublicKey, votingMint: PublicKey, votingMintAuthority: PublicKey, stakeProgramId: PublicKey, depositEntryIndex: number, amount: BN, ): TransactionInstruction { const dataLayout = struct([u8("depositEntryIndex"), u64("amount")]); const keys = [ { pubkey: registrar, isSigner: false, isWritable: false }, { pubkey: voter, isSigner: false, isWritable: true }, { pubkey: voterAuthority, isSigner: true, isWritable: false }, { pubkey: tokenOwnerRecord, isSigner: false, isWritable: false }, { pubkey: voterWeightRecord, isSigner: false, isWritable: true }, { pubkey: vault, isSigner: false, isWritable: true }, { pubkey: destination, isSigner: false, isWritable: true }, { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, { pubkey: userStakerInfoV2, isSigner: false, isWritable: true }, { pubkey: pool, isSigner: false, isWritable: false }, { pubkey: votingMint, isSigner: false, isWritable: true }, { pubkey: votingMintAuthority, isSigner: false, isWritable: false }, { pubkey: stakeProgramId, isSigner: false, isWritable: false }, { pubkey: INSTRUCTION_PROGRAM_ID, isSigner: false, isWritable: false }, ]; const data = Buffer.alloc(dataLayout.span); dataLayout.encode( { depositEntryIndex, amount, }, data, ); const aData = Buffer.from([...anchorDataBuf.voterStakeRegistryWithdraw, ...data]); return new TransactionInstruction({ keys, programId, data: aData, }); } export function governanceCreateTokenOwnerRecord( programId: PublicKey, realm: PublicKey, governingTokenOwner: PublicKey, governingTokenMint: PublicKey, payer: PublicKey, tokenOwnerRecordAddress: PublicKey, ): TransactionInstruction { const dataLayout = struct([u8("ins")]); const keys = [ { pubkey: realm, isSigner: false, isWritable: false }, { pubkey: governingTokenOwner, isSigner: false, isWritable: false }, { pubkey: tokenOwnerRecordAddress, isSigner: false, isWritable: true }, { pubkey: governingTokenMint, isSigner: false, isWritable: false }, { pubkey: payer, isSigner: true, isWritable: true }, { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, ]; const data = Buffer.alloc(dataLayout.span); dataLayout.encode({ ins: 23 }, data); return new TransactionInstruction({ keys, programId, data, }); } export function voterStakeRegistryCreateVoter( programId: PublicKey, registrar: PublicKey, voter: PublicKey, voterWeightRecord: PublicKey, voterAuthority: PublicKey, payer: PublicKey, voterBump: number, voterWeightRecordBump: number, ): TransactionInstruction { const dataLayout = struct([u8("voterBump"), u8("voterWeightRecordBump")]); const keys = [ { pubkey: registrar, isSigner: false, isWritable: false }, { pubkey: voter, isSigner: false, isWritable: true }, { pubkey: voterAuthority, isSigner: true, isWritable: false }, { pubkey: voterWeightRecord, isSigner: false, isWritable: true }, { pubkey: payer, isSigner: true, isWritable: true }, { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, { pubkey: RENT_PROGRAM_ID, isSigner: false, isWritable: false }, { pubkey: INSTRUCTION_PROGRAM_ID, isSigner: false, isWritable: false }, ]; const data = Buffer.alloc(dataLayout.span); dataLayout.encode({ voterBump, voterWeightRecordBump }, data); const aData = Buffer.from([...anchorDataBuf.voterStakeRegistryCreateVoter, ...data]); return new TransactionInstruction({ keys, programId, data: aData, }); } export function voterStakeRegistryCreateDepositEntry( programId: PublicKey, registrar: PublicKey, voter: PublicKey, voterVault: PublicKey, voterAuthority: PublicKey, payer: PublicKey, depositMint: PublicKey, depositEntryIndex: number, kind: number, startTs: BN | undefined, periods: number, allowClawback: boolean, ): TransactionInstruction { const dataLayout = struct([ u8("depositEntryIndex"), u8("kind"), u8("option"), u64("startTs"), u32("periods"), bool("allowClawback"), ]); const keys = [ { pubkey: registrar, isSigner: false, isWritable: false }, { pubkey: voter, isSigner: false, isWritable: true }, { pubkey: voterVault, isSigner: false, isWritable: true }, { pubkey: voterAuthority, isSigner: true, isWritable: false }, { pubkey: payer, isSigner: true, isWritable: true }, { pubkey: depositMint, isSigner: false, isWritable: false }, { pubkey: SystemProgram.programId, isSigner: false, isWritable: false }, { pubkey: TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, { pubkey: ASSOCIATED_TOKEN_PROGRAM_ID, isSigner: false, isWritable: false }, { pubkey: RENT_PROGRAM_ID, isSigner: false, isWritable: false }, ]; const data = Buffer.alloc(dataLayout.span); dataLayout.encode( { depositEntryIndex, kind, option: startTs === undefined ? 0 : 1, startTs: startTs!, periods, allowClawback, }, data, ); const aData = Buffer.from([...anchorDataBuf.voterStakeRegistryCreateDepositEntry, ...data]); return new TransactionInstruction({ keys, programId, data: aData, }); } export async function makeDepositTokenInstruction({ connection, programId, governanceProgramId, voteWeightAddinProgramId, realm, communityTokenMint, owner, poolId, tokenProgram, }: { connection: Connection; programId: PublicKey; governanceProgramId: PublicKey; voteWeightAddinProgramId: PublicKey; realm: PublicKey; communityTokenMint: PublicKey; owner: PublicKey; poolId: PublicKey; tokenProgram?: PublicKey; }): Promise<TransactionInstruction[]> { const registrar = getRegistrarAddress(voteWeightAddinProgramId, realm, communityTokenMint).publicKey; const ownerPda = getAssociatedLedgerAccount({ programId, poolId, owner, version: 3 }); const ownerAccountInfo = await connection.getAccountInfo(ownerPda); if (ownerAccountInfo === null) { throw Error("user is not staker"); } const ownerInfo = farmLedgerLayoutV3_2.decode(ownerAccountInfo.data); const mintAmount = ownerInfo.deposited.sub(ownerInfo.voteLockedBalance); console.log("amount", mintAmount.toString()); if (mintAmount.eq(new BN(0))) { throw Error("user do not has new stake amount"); } const votingMint = getVotingTokenMint(programId, poolId).publicKey; const votingMintAuthority = getVotingMintAuthority(programId, poolId).publicKey; const { publicKey: voter, nonce: voterBump } = getVoterAddress(voteWeightAddinProgramId, registrar, owner); const voterVault = getATAAddress(voter, votingMint, tokenProgram).publicKey; const { publicKey: voterWeightRecord, nonce: voterWeightRecordBump } = getVoterWeightRecordAddress( voteWeightAddinProgramId, registrar, owner, ); const tokenOwnerRecordAddress = getTokenOwnerRecordAddress( governanceProgramId, realm, communityTokenMint, owner, ).publicKey; const instructions: TransactionInstruction[] = []; const depositToken = getATAAddress(owner, votingMint, tokenProgram).publicKey; const depositTokenAccountInfo = await connection.getAccountInfo(depositToken); if (depositTokenAccountInfo === null) { instructions.push(createAssociatedTokenAccountInstruction(owner, depositToken, owner, votingMint)); } const voterAccountInfo = await connection.getAccountInfo(voter); if (voterAccountInfo === null) { const createTokenOwnerRecodeIns = governanceCreateTokenOwnerRecord( governanceProgramId, realm, owner, communityTokenMint, owner, tokenOwnerRecordAddress, ); instructions.push( createTokenOwnerRecodeIns, voterStakeRegistryCreateVoter( voteWeightAddinProgramId, registrar, voter, voterWeightRecord, owner, owner, voterBump, voterWeightRecordBump, ), ); } const { index: depositEntryIndex, isInit: depositEntryInit } = await getDepositEntryIndex( connection, registrar, voter, votingMint, ); if (!depositEntryInit) { instructions.push( voterStakeRegistryCreateDepositEntry( voteWeightAddinProgramId, registrar, voter, voterVault, owner, owner, votingMint, depositEntryIndex, 0, undefined, 0, false, ), ); } instructions.push( voterStakeRegistryDeposit( voteWeightAddinProgramId, registrar, voter, voterVault, depositToken, owner, ownerPda, poolId, votingMint, votingMintAuthority, programId, depositEntryIndex, mintAmount, ), voterStakeRegistryUpdateVoterWeightRecord(voteWeightAddinProgramId, registrar, voter, voterWeightRecord), ); return instructions; } export async function makeWithdrawTokenInstruction({ connection, programId, governanceProgramId, voteWeightAddinProgramId, realm, communityTokenMint, owner, poolId, tokenProgram, }: { connection: Connection; programId: PublicKey; governanceProgramId: PublicKey; voteWeightAddinProgramId: PublicKey; realm: PublicKey; communityTokenMint: PublicKey; owner: PublicKey; poolId: PublicKey; tokenProgram?: PublicKey; }): Promise<TransactionInstruction[]> { const registrar = getRegistrarAddress(voteWeightAddinProgramId, realm, communityTokenMint).publicKey; const ownerPda = getAssociatedLedgerAccount({ programId, poolId, owner, version: 3 }); const ownerAccountInfo = await connection.getAccountInfo(ownerPda); if (ownerAccountInfo === null) { throw Error("user is not staker"); } const ownerInfo = farmLedgerLayoutV3_2.decode(ownerAccountInfo.data); if (ownerInfo.voteLockedBalance.eq(new BN(0))) { throw Error("user has vote locked balance = 0"); } const votingMint = getVotingTokenMint(programId, poolId).publicKey; const votingMintAuthority = getVotingMintAuthority(programId, poolId).publicKey; const { publicKey: voter } = getVoterAddress(voteWeightAddinProgramId, registrar, owner); const voterVault = getATAAddress(voter, votingMint, tokenProgram).publicKey; const { publicKey: voterWeightRecord } = getVoterWeightRecordAddress(voteWeightAddinProgramId, registrar, owner); const tokenOwnerRecordAddress = getTokenOwnerRecordAddress( governanceProgramId, realm, communityTokenMint, owner, ).publicKey; const instructions: TransactionInstruction[] = []; const { index: depositEntryIndex, isInit: depositEntryInit } = await getDepositEntryIndex( connection, registrar, voter, votingMint, ); if (!depositEntryInit) throw Error("deposit entry index check error"); instructions.push( voterStakeRegistryWithdraw( voteWeightAddinProgramId, registrar, voter, owner, tokenOwnerRecordAddress, voterWeightRecord, voterVault, getATAAddress(owner, votingMint, tokenProgram).publicKey, ownerPda, poolId, votingMint, votingMintAuthority, programId, depositEntryIndex, ownerInfo.voteLockedBalance, ), ); return instructions; } export function makeRestartRewardInstruction({ payer, rewardVault, userRewardTokenPub, farmKeys, rewardInfo, }: { payer: PublicKey; rewardVault: PublicKey; userRewardTokenPub: PublicKey; farmKeys: { id: PublicKey; programId: PublicKey; lpVault: PublicKey; }; rewardInfo: { openTime: number; endTime: number; perSecond: string; }; }): TransactionInstruction { const data = Buffer.alloc(farmRewardRestartLayout.span); farmRewardRestartLayout.encode( { instruction: 3, rewardReopenTime: parseBigNumberish(rewardInfo.openTime), rewardEndTime: parseBigNumberish(rewardInfo.endTime), rewardPerSecond: parseBigNumberish(rewardInfo.perSecond), }, data, ); const keys = [ accountMeta({ pubkey: TOKEN_PROGRAM_ID, isWritable: false }), accountMeta({ pubkey: farmKeys.id }), accountMeta({ pubkey: farmKeys.lpVault, isWritable: false }), accountMeta({ pubkey: rewardVault }), accountMeta({ pubkey: userRewardTokenPub! }), accountMeta({ pubkey: payer, isWritable: false, isSigner: true }), ]; return new TransactionInstruction({ programId: farmKeys.programId, keys, data }); } export function makeAddNewRewardInstruction({ payer, userRewardTokenPub, farmKeys, rewardVault, rewardInfo, }: { payer: PublicKey; userRewardTokenPub: PublicKey; rewardVault: PublicKey; farmKeys: { id: PublicKey; programId: PublicKey; authority: PublicKey; }; rewardInfo: { mint: PublicKey; openTime: number; endTime: number; perSecond: string; rewardType: RewardType; }; }): TransactionInstruction { const data = Buffer.alloc(farmAddRewardLayout.span); farmAddRewardLayout.encode( { instruction: 4, isSet: new BN(1), rewardPerSecond: parseBigNumberish(rewardInfo.perSecond), rewardOpenTime: parseBigNumberish(rewardInfo.openTime), rewardEndTime: parseBigNumberish(rewardInfo.endTime), rewardType: parseBigNumberish(poolTypeV6[rewardInfo.rewardType]), }, data, ); const keys = [ ...commonSystemAccountMeta, accountMeta({ pubkey: farmKeys.id }), accountMeta({ pubkey: farmKeys.authority, isWritable: false }), accountMeta({ pubkey: rewardInfo.mint, isWritable: false }), accountMeta({ pubkey: rewardVault }), accountMeta({ pubkey: userRewardTokenPub! }), accountMeta({ pubkey: payer, isWritable: false, isSigner: true }), ]; return new TransactionInstruction({ programId: farmKeys.programId, keys, data }); } export function makeDepositWithdrawInstruction(params: { instruction: number; amount: BN; farmInfo: { id: string; programId: string }; farmKeys: FormatFarmKeyOut; lpAccount: PublicKey; owner: PublicKey; rewardAccounts: PublicKey[]; deposit?: boolean; version: 3 | 5 | 6; }): TransactionInstruction { const { farmInfo, farmKeys, version, lpAccount, rewardAccounts, owner, instruction, amount, deposit } = params; const [programId, id] = [new PublicKey(farmInfo.programId), new PublicKey(farmInfo.id)]; const ledgerAddress = getAssociatedLedgerAccount({ programId, poolId: id, owner, version, }); const data = Buffer.alloc(dwLayout.span); dwLayout.encode( { instruction, amount, }, data, ); const keys = version === 6 ? [ accountMeta({ pubkey: TOKEN_PROGRAM_ID, isWritable: false }), ...(deposit ? [accountMeta({ pubkey: SystemProgram.programId, isWritable: false })] : []), accountMeta({ pubkey: id }), accountMeta({ pubkey: new PublicKey(farmKeys.authority), isWritable: false }), accountMeta({ pubkey: new PublicKey(farmKeys.lpVault) }), accountMeta({ pubkey: ledgerAddress }), accountMeta({ pubkey: owner, isWritable: false, isSigner: true }), accountMeta({ pubkey: lpAccount }), ] : [ accountMeta({ pubkey: id }), accountMeta({ pubkey: new PublicKey(farmKeys.authority), isWritable: false }), accountMeta({ pubkey: ledgerAddress }), accountMeta({ pubkey: owner, isWritable: false, isSigner: true }), accountMeta({ pubkey: lpAccount }), accountMeta({ pubkey: new PublicKey(farmKeys.lpVault) }), accountMeta({ pubkey: rewardAccounts[0] }), accountMeta({ pubkey: new PublicKey(farmKeys.rewardInfos[0].vault) }), // system accountMeta({ pubkey: SYSVAR_CLOCK_PUBKEY, isWritable: false }), accountMeta({ pubkey: TOKEN_PROGRAM_ID, isWritable: false }), ]; if (version === 5) { for (let index = 1; index < farmKeys.rewardInfos.length; index++) { keys.push(accountMeta({ pubkey: rewardAccounts[index] })); keys.push(accountMeta({ pubkey: new PublicKey(farmKeys.rewardInfos[index].vault) })); } } if (version === 6) { for (let index = 0; index < farmKeys.rewardInfos.length; index++) { keys.push(accountMeta({ pubkey: new PublicKey(farmKeys.rewardInfos[index].vault) })); keys.push(accountMeta({ pubkey: rewardAccounts[index] })); } } return new TransactionInstruction({ programId, keys, data }); } interface DepositWithdrawParams { amount: BN; farmInfo: { id: string; programId: string }; farmKeys: FormatFarmKeyOut; lpAccount: PublicKey; owner: PublicKey; rewardAccounts: PublicKey[]; userAuxiliaryLedgers?: PublicKey[]; } export function makeWithdrawInstructionV6(params: DepositWithdrawParams): TransactionInstruction { const { farmInfo, farmKeys, lpAccount, rewardAccounts, owner, amount } = params; const [programId, id] = [new PublicKey(farmInfo.programId), new PublicKey(farmInfo.id)]; const ledgerAddress = getAssociatedLedgerAccount({ programId, poolId: id, owner, version: 6, }); const data = Buffer.alloc(dwLayout.span); dwLayout.encode( { instruction: 2, amount: parseBigNumberish(amount), }, data, ); const keys = [ accountMeta({ pubkey: TOKEN_PROGRAM_ID, isWritable: false }), accountMeta({ pubkey: id }), accountMeta({ pubkey: new PublicKey(farmKeys.authority), isWritable: false }), accountMeta({ pubkey: new PublicKey(farmKeys.lpVault) }), accountMeta({ pubkey: ledgerAddress }), accountMeta({ pubkey: owner, isWritable: false, isSigner: true }), accountMeta({ pubkey: lpAccount }), ]; for (let index = 0; index < farmKeys.rewardInfos.length; index++) { keys.push(accountMeta({ pubkey: new PublicKey(farmKeys.rewardInfos[index].vault) })); keys.push(accountMeta({ pubkey: rewardAccounts[index] })); } return new TransactionInstruction({ programId, keys, data }); } export function makeWithdrawInstructionV5(params: DepositWithdrawParams): TransactionInstruction { const { farmInfo, farmKeys, lpAccount, rewardAccounts, owner, amount, userAuxiliaryLedgers } = params; const [programId, id] = [new PublicKey(farmInfo.programId), new PublicKey(farmInfo.id)]; const ledgerAddress = getAssociatedLedgerAccount({ programId, poolId: id, owner, version: 5, }); const data = Buffer.alloc(dwLayout.span); dwLayout.encode( { instruction: 12, amount: parseBigNumberish(amount), }, data, ); const keys = [ accountMeta({ pubkey: id }), accountMeta({ pubkey: new PublicKey(farmKeys.authority), isWritable: false }), accountMeta({ pubkey: ledgerAddress }), accountMeta({ pubkey: owner, isWritable: false, isSigner: true }), accountMeta({ pubkey: lpAccount }), accountMeta({ pubkey: new PublicKey(farmKeys.lpVault) }), accountMeta({ pubkey: rewardAccounts[0] }), accountMeta({ pubkey: new PublicKey(farmKeys.rewardInfos[0].vault) }), // system accountMeta({ pubkey: SYSVAR_CLOCK_PUBKEY, isWritable: false }), accountMeta({ pubkey: TOKEN_PROGRAM_ID, isWritable: false }), ]; for (let index = 1; index < farmKeys.rewardInfos.length; index++) { keys.push(accountMeta({ pubkey: rewardAccounts[index] })); keys.push(accountMeta({ pubkey: new PublicKey(farmKeys.rewardInfos[index].vault) })); } if (userAuxiliaryLedgers) { for (const auxiliaryLedger of userAuxiliaryLedgers) { keys.push(accountMeta({ pubkey: auxiliaryLedger })); } } return new TransactionInstruction({ programId, keys, data }); } export function makeWithdrawInstructionV3(params: DepositWithdrawParams): TransactionInstruction { const { farmInfo, farmKeys, lpAccount, rewardAccounts, owner, amount, userAuxiliaryLedgers } = params; const [programId, id] = [new PublicKey(farmInfo.programId), new PublicKey(farmInfo.id)]; const ledgerAddress = getAssociatedLedgerAccount({ programId, poolId: id, owner, version: 3, }); const data = Buffer.alloc(dwLayout.span); dwLayout.encode( { instruction: 11, amount: parseBigNumberish(amount), }, data, ); const keys = [ accountMeta({ pubkey: id }), accountMeta({ pubkey: new PublicKey(farmKeys.authority), isWritable: false }), accountMeta({ pubkey: ledgerAddress }), accountMeta({ pubkey: owner, isWritable: false, isSigner: true }), accountMeta({ pubkey: lpAccount }), accountMeta({ pubkey: new PublicKey(farmKeys.lpVault) }), accountMeta({ pubkey: rewardAccounts[0] }), accountMeta({ pubkey: new PublicKey(farmKeys.rewardInfos[0].vault) }), // system accountMeta({ pubkey: SYSVAR_CLOCK_PUBKEY, isWritable: false }), accountMeta({ pubkey: TOKEN_PROGRAM_ID, isWritable: false }), ]; if (userAuxiliaryLedgers) { for (const auxiliaryLedger of userAuxiliaryLedgers) { keys.push(accountMeta({ pubkey: auxiliaryLedger })); } } return new TransactionInstruction({ programId, keys, data }); } export function makeDepositInstructionV3(params: DepositWithdrawParams): TransactionInstruction { const { farmInfo, farmKeys, lpAccount, rewardAccounts, owner, amount, userAuxiliaryLedgers } = params; const [programId, id] = [new PublicKey(farmInfo.programId), new PublicKey(farmInfo.id)]; const ledgerAddress = getAssociatedLedgerAccount({ programId, poolId: id, owner, version: 3, }); const data = Buffer.alloc(dwLayout.span); dwLayout.encode( { instruction: 10, amount: parseBigNumberish(amount), }, data, ); const keys = [ accountMeta({ pubkey: id }), accountMeta({ pubkey: new PublicKey(farmKeys.authority), isWritable: false }), accountMeta({ pubkey: ledgerAddress }), accountMeta({ pubkey: owner, isWritable: false, isSigner: true }), accountMeta({ pubkey: lpAccount }), accountMeta({ pubkey: new PublicKey(farmKeys.lpVault) }), accountMeta({ pubkey: rewardAccounts[0] }), accountMeta({ pubkey: new PublicKey(farmKeys.rewardInfos[0].vault) }), // system accountMeta({ pubkey: SYSVAR_CLOCK_PUBKEY, isWritable: false }), accountMeta({ pubkey: TOKEN_PROGRAM_ID, isWritable: false }), ]; if (userAuxiliaryLedgers) { for (const auxiliaryLedger of userAuxiliaryLedgers) { keys.push(accountMeta({ pubkey: auxiliaryLedger })); } } return new TransactionInstruction({ programId, keys, data }); } export function makeDepositInstructionV5(params: DepositWithdrawParams): TransactionInstruction { const { farmInfo, farmKeys, lpAccount, rewardAccounts, owner, amount, userAuxiliaryLedgers } = params; const [programId, id] = [new PublicKey(farmInfo.programId), new PublicKey(farmInfo.id)]; const ledgerAddress = getAssociatedLedgerAccount({ programId, poolId: id, owner, version: 5, }); const data = Buffer.alloc(dwLayout.span); dwLayout.encode( { instruction: 11, amount: parseBigNumberish(amount), }, data, ); const keys = [ accountMeta({ pubkey: id }), accountMeta({ pubkey: new PublicKey(farmKeys.authority), isWritable: false }), accountMeta({ pubkey: ledgerAddress }), accountMeta({ pubkey: owner, isWritable: false, isSigner: true }), accountMeta({ pubkey: lpAccount }), accountMeta({ pubkey: new PublicKey(farmKeys.lpVault) }), accountMeta({ pubkey: rewardAccounts[0] }), accountMeta({ pubkey: new PublicKey(farmKeys.rewardInfos[0].vault) }), // system accountMeta({ pubkey: SYSVAR_CLOCK_PUBKEY, isWritable: false }), accountMeta({ pubkey: TOKEN_PROGRAM_ID, isWritable: false }), ]; for (let index = 1; index < farmKeys.rewardInfos.length; index++) { keys.push(accountMeta({ pubkey: rewardAccounts[index] })); keys.push(accountMeta({ pubkey: new PublicKey(farmKeys.rewardInfos[index].vault) })); } if (userAuxiliaryLedgers) { for (const auxiliaryLedger of userAuxiliaryLedgers) { keys.push(accountMeta({ pubkey: auxiliaryLedger })); } } return new TransactionInstruction({ programId, keys, data }); } export function makeDepositInstructionV6(params: DepositWithdrawParams): TransactionInstruction { const { farmInfo, farmKeys, lpAccount, rewardAccounts, owner, amount } = params; const [programId, id] = [new PublicKey(farmInfo.programId), new PublicKey(farmInfo.id)]; const ledgerAddress = getAssociatedLedgerAccount({ programId, poolId: id, owner, version: 6, }); const data = Buffer.alloc(dwLayout.span); dwLayout.encode( { instruction: 1, amount: parseBigNumberish(amount), }, data, ); const keys = [ accountMeta({ pubkey: TOKEN_PROGRAM_ID, isWritable: false }), accountMeta({ pubkey: SystemProgram.programId, isWritable: false }), accountMeta({ pubkey: id }), accountMeta({ pubkey: new PublicKey(farmKeys.authority), isWritable: false }), accountMeta({ pubkey: new PublicKey(farmKeys.lpVault) }), accountMeta({ pubkey: ledgerAddress }), accountMeta({ pubkey: owner, isWritable: false, isSigner: true }), accountMeta({ pubkey: lpAccount }), ]; for (let index = 0; index < farmKeys.rewardInfos.length; index++) { keys.push(accountMeta({ pubkey: new PublicKey(farmKeys.rewardInfos[index].vault) })); keys.push(accountMeta({ pubkey: rewardAccounts[index] })); } return new TransactionInstruction({ programId, keys, data }); }