/** * This code was AUTOGENERATED using the Codama library. * Please DO NOT EDIT THIS FILE, instead use visitors * to add features, then rerun Codama to update it. * * @see https://github.com/codama-idl/codama */ import { combineCodec, getStructDecoder, getStructEncoder, getU64Decoder, getU64Encoder, getU8Decoder, getU8Encoder, SOLANA_ERROR__PROGRAM_CLIENTS__INSUFFICIENT_ACCOUNT_METAS, SolanaError, transformEncoder, type AccountMeta, type AccountSignerMeta, type Address, type FixedSizeCodec, type FixedSizeDecoder, type FixedSizeEncoder, type Instruction, type InstructionWithAccounts, type InstructionWithData, type ReadonlyAccount, type ReadonlySignerAccount, type ReadonlyUint8Array, type TransactionSigner, type WritableAccount, } from "@solana/kit"; import { getAccountMetaFactory, getAddressFromResolvedInstructionAccount, type ResolvedInstructionAccount, } from "@solana/program-client-core"; import { findWithdrawAuthorityPda } from "../pdas/index.ts"; import { SPL_STAKE_POOL_PROGRAM_ADDRESS } from "../programs/index.ts"; export const REDELEGATE_DISCRIMINATOR = 22; export function getRedelegateDiscriminatorBytes(): ReadonlyUint8Array { return getU8Encoder().encode(REDELEGATE_DISCRIMINATOR); } export type RedelegateInstruction< TProgram extends string = typeof SPL_STAKE_POOL_PROGRAM_ADDRESS, TAccountStakePool extends string | AccountMeta = string, TAccountStaker extends string | AccountMeta = string, TAccountWithdrawAuthority extends string | AccountMeta = string, TAccountValidatorList extends string | AccountMeta = string, TAccountReserveStake extends string | AccountMeta = string, TAccountSourceCanonicalStake extends string | AccountMeta = string, TAccountSourceTransientStake extends string | AccountMeta = string, TAccountEphemeralStake extends string | AccountMeta = string, TAccountDestinationTransientStake extends string | AccountMeta = string, TAccountDestinationStake extends string | AccountMeta = string, TAccountDestinationVote extends string | AccountMeta = string, TAccountClockSysvar extends string | AccountMeta = "SysvarC1ock11111111111111111111111111111111", TAccountStakeHistorySysvar extends string | AccountMeta = "SysvarStakeHistory1111111111111111111111111", TAccountStakeConfigSysvar extends string | AccountMeta = "StakeConfig11111111111111111111111111111111", TAccountSystemProgram extends string | AccountMeta = "11111111111111111111111111111111", TAccountStakeProgram extends string | AccountMeta = "Stake11111111111111111111111111111111111111", TRemainingAccounts extends readonly AccountMeta[] = [], > = Instruction & InstructionWithData & InstructionWithAccounts< [ TAccountStakePool extends string ? ReadonlyAccount : TAccountStakePool, TAccountStaker extends string ? ReadonlySignerAccount & AccountSignerMeta : TAccountStaker, TAccountWithdrawAuthority extends string ? ReadonlyAccount : TAccountWithdrawAuthority, TAccountValidatorList extends string ? WritableAccount : TAccountValidatorList, TAccountReserveStake extends string ? WritableAccount : TAccountReserveStake, TAccountSourceCanonicalStake extends string ? WritableAccount : TAccountSourceCanonicalStake, TAccountSourceTransientStake extends string ? WritableAccount : TAccountSourceTransientStake, TAccountEphemeralStake extends string ? WritableAccount : TAccountEphemeralStake, TAccountDestinationTransientStake extends string ? WritableAccount : TAccountDestinationTransientStake, TAccountDestinationStake extends string ? ReadonlyAccount : TAccountDestinationStake, TAccountDestinationVote extends string ? ReadonlyAccount : TAccountDestinationVote, TAccountClockSysvar extends string ? ReadonlyAccount : TAccountClockSysvar, TAccountStakeHistorySysvar extends string ? ReadonlyAccount : TAccountStakeHistorySysvar, TAccountStakeConfigSysvar extends string ? ReadonlyAccount : TAccountStakeConfigSysvar, TAccountSystemProgram extends string ? ReadonlyAccount : TAccountSystemProgram, TAccountStakeProgram extends string ? ReadonlyAccount : TAccountStakeProgram, ...TRemainingAccounts, ] >; export type RedelegateInstructionData = { discriminator: number; lamports: bigint; sourceTransientStakeSeed: bigint; ephemeralStakeSeed: bigint; destinationTransientStakeSeed: bigint; }; export type RedelegateInstructionDataArgs = { lamports: number | bigint; sourceTransientStakeSeed: number | bigint; ephemeralStakeSeed: number | bigint; destinationTransientStakeSeed: number | bigint; }; export function getRedelegateInstructionDataEncoder(): FixedSizeEncoder { return transformEncoder( getStructEncoder([ ["discriminator", getU8Encoder()], ["lamports", getU64Encoder()], ["sourceTransientStakeSeed", getU64Encoder()], ["ephemeralStakeSeed", getU64Encoder()], ["destinationTransientStakeSeed", getU64Encoder()], ]), (value) => ({ ...value, discriminator: REDELEGATE_DISCRIMINATOR }), ); } export function getRedelegateInstructionDataDecoder(): FixedSizeDecoder { return getStructDecoder([ ["discriminator", getU8Decoder()], ["lamports", getU64Decoder()], ["sourceTransientStakeSeed", getU64Decoder()], ["ephemeralStakeSeed", getU64Decoder()], ["destinationTransientStakeSeed", getU64Decoder()], ]); } export function getRedelegateInstructionDataCodec(): FixedSizeCodec< RedelegateInstructionDataArgs, RedelegateInstructionData > { return combineCodec( getRedelegateInstructionDataEncoder(), getRedelegateInstructionDataDecoder(), ); } export type RedelegateAsyncInput< TAccountStakePool extends string = string, TAccountStaker extends string = string, TAccountWithdrawAuthority extends string = string, TAccountValidatorList extends string = string, TAccountReserveStake extends string = string, TAccountSourceCanonicalStake extends string = string, TAccountSourceTransientStake extends string = string, TAccountEphemeralStake extends string = string, TAccountDestinationTransientStake extends string = string, TAccountDestinationStake extends string = string, TAccountDestinationVote extends string = string, TAccountClockSysvar extends string = string, TAccountStakeHistorySysvar extends string = string, TAccountStakeConfigSysvar extends string = string, TAccountSystemProgram extends string = string, TAccountStakeProgram extends string = string, > = { stakePool: Address; staker: TransactionSigner; withdrawAuthority?: Address; validatorList: Address; reserveStake: Address; sourceCanonicalStake: Address; sourceTransientStake: Address; ephemeralStake: Address; destinationTransientStake: Address; destinationStake: Address; destinationVote: Address; clockSysvar?: Address; stakeHistorySysvar?: Address; stakeConfigSysvar?: Address; systemProgram?: Address; stakeProgram?: Address; lamports: RedelegateInstructionDataArgs["lamports"]; sourceTransientStakeSeed: RedelegateInstructionDataArgs["sourceTransientStakeSeed"]; ephemeralStakeSeed: RedelegateInstructionDataArgs["ephemeralStakeSeed"]; destinationTransientStakeSeed: RedelegateInstructionDataArgs["destinationTransientStakeSeed"]; }; /** * (Staker only) Redelegate active stake on a validator, eventually moving * it to another * Internally, this instruction splits a validator stake account into its * corresponding transient stake account, redelegates it to an ephemeral * stake account, then merges that stake into the destination transient * stake account. * In order to rebalance the pool without taking custody, the staker needs * a way of reducing the stake on a stake account. This instruction splits * some amount of stake, up to the total activated stake, from the * canonical validator stake account, into its "transient" stake * account. * The instruction only succeeds if the source transient stake account and * ephemeral stake account do not exist. * The amount of lamports to move must be at least rent-exemption plus the * minimum delegation amount. Rent-exemption plus minimum delegation * is required for the destination ephemeral stake account. * The rent-exemption for the source transient account comes from the stake * pool reserve, if needed. * The amount that arrives at the destination validator in the end is * `redelegate_lamports - rent_exemption` if the destination transient * account does *not* exist, and `redelegate_lamports` if the destination * transient account already exists. The `rent_exemption` is not activated * when creating the destination transient stake account, but if it already * exists, then the full amount is delegated. * 0. `[]` Stake pool * 1. `[s]` Stake pool staker * 2. `[]` Stake pool withdraw authority * 3. `[w]` Validator list * 4. `[w]` Reserve stake account, to withdraw rent exempt reserve * 5. `[w]` Source canonical stake account to split from * 6. `[w]` Source transient stake account to receive split and be * redelegated * 7. `[w]` Uninitialized ephemeral stake account to receive redelegation * 8. `[w]` Destination transient stake account to receive ephemeral stake * by merge * 9. `[]` Destination stake account to receive transient stake after * activation * 10. `[]` Destination validator vote account * 11. `[]` Clock sysvar * 12. `[]` Stake History sysvar * 13. `[]` Stake Config sysvar * 14. `[]` System program * 15. `[]` Stake program */ export async function getRedelegateInstructionAsync< TAccountStakePool extends string, TAccountStaker extends string, TAccountWithdrawAuthority extends string, TAccountValidatorList extends string, TAccountReserveStake extends string, TAccountSourceCanonicalStake extends string, TAccountSourceTransientStake extends string, TAccountEphemeralStake extends string, TAccountDestinationTransientStake extends string, TAccountDestinationStake extends string, TAccountDestinationVote extends string, TAccountClockSysvar extends string, TAccountStakeHistorySysvar extends string, TAccountStakeConfigSysvar extends string, TAccountSystemProgram extends string, TAccountStakeProgram extends string, TProgramAddress extends Address = typeof SPL_STAKE_POOL_PROGRAM_ADDRESS, >( input: RedelegateAsyncInput< TAccountStakePool, TAccountStaker, TAccountWithdrawAuthority, TAccountValidatorList, TAccountReserveStake, TAccountSourceCanonicalStake, TAccountSourceTransientStake, TAccountEphemeralStake, TAccountDestinationTransientStake, TAccountDestinationStake, TAccountDestinationVote, TAccountClockSysvar, TAccountStakeHistorySysvar, TAccountStakeConfigSysvar, TAccountSystemProgram, TAccountStakeProgram >, config?: { programAddress?: TProgramAddress }, ): Promise< RedelegateInstruction< TProgramAddress, TAccountStakePool, TAccountStaker, TAccountWithdrawAuthority, TAccountValidatorList, TAccountReserveStake, TAccountSourceCanonicalStake, TAccountSourceTransientStake, TAccountEphemeralStake, TAccountDestinationTransientStake, TAccountDestinationStake, TAccountDestinationVote, TAccountClockSysvar, TAccountStakeHistorySysvar, TAccountStakeConfigSysvar, TAccountSystemProgram, TAccountStakeProgram > > { // Program address. const programAddress = config?.programAddress ?? SPL_STAKE_POOL_PROGRAM_ADDRESS; // Original accounts. const originalAccounts = { stakePool: { value: input.stakePool ?? null, isWritable: false }, staker: { value: input.staker ?? null, isWritable: false }, withdrawAuthority: { value: input.withdrawAuthority ?? null, isWritable: false, }, validatorList: { value: input.validatorList ?? null, isWritable: true }, reserveStake: { value: input.reserveStake ?? null, isWritable: true }, sourceCanonicalStake: { value: input.sourceCanonicalStake ?? null, isWritable: true, }, sourceTransientStake: { value: input.sourceTransientStake ?? null, isWritable: true, }, ephemeralStake: { value: input.ephemeralStake ?? null, isWritable: true }, destinationTransientStake: { value: input.destinationTransientStake ?? null, isWritable: true, }, destinationStake: { value: input.destinationStake ?? null, isWritable: false, }, destinationVote: { value: input.destinationVote ?? null, isWritable: false, }, clockSysvar: { value: input.clockSysvar ?? null, isWritable: false }, stakeHistorySysvar: { value: input.stakeHistorySysvar ?? null, isWritable: false, }, stakeConfigSysvar: { value: input.stakeConfigSysvar ?? null, isWritable: false, }, systemProgram: { value: input.systemProgram ?? null, isWritable: false }, stakeProgram: { value: input.stakeProgram ?? null, isWritable: false }, }; const accounts = originalAccounts as Record< keyof typeof originalAccounts, ResolvedInstructionAccount >; // Original args. const args = { ...input }; // Resolve default values. if (!accounts.withdrawAuthority.value) { accounts.withdrawAuthority.value = await findWithdrawAuthorityPda( { stakePoolAddress: getAddressFromResolvedInstructionAccount( "stakePool", accounts.stakePool.value, ), }, { programAddress }, ); } if (!accounts.clockSysvar.value) { accounts.clockSysvar.value = "SysvarC1ock11111111111111111111111111111111" as Address<"SysvarC1ock11111111111111111111111111111111">; } if (!accounts.stakeHistorySysvar.value) { accounts.stakeHistorySysvar.value = "SysvarStakeHistory1111111111111111111111111" as Address<"SysvarStakeHistory1111111111111111111111111">; } if (!accounts.stakeConfigSysvar.value) { accounts.stakeConfigSysvar.value = "StakeConfig11111111111111111111111111111111" as Address<"StakeConfig11111111111111111111111111111111">; } if (!accounts.systemProgram.value) { accounts.systemProgram.value = "11111111111111111111111111111111" as Address<"11111111111111111111111111111111">; } if (!accounts.stakeProgram.value) { accounts.stakeProgram.value = "Stake11111111111111111111111111111111111111" as Address<"Stake11111111111111111111111111111111111111">; } const getAccountMeta = getAccountMetaFactory(programAddress, "programId"); return Object.freeze({ accounts: [ getAccountMeta("stakePool", accounts.stakePool), getAccountMeta("staker", accounts.staker), getAccountMeta("withdrawAuthority", accounts.withdrawAuthority), getAccountMeta("validatorList", accounts.validatorList), getAccountMeta("reserveStake", accounts.reserveStake), getAccountMeta("sourceCanonicalStake", accounts.sourceCanonicalStake), getAccountMeta("sourceTransientStake", accounts.sourceTransientStake), getAccountMeta("ephemeralStake", accounts.ephemeralStake), getAccountMeta( "destinationTransientStake", accounts.destinationTransientStake, ), getAccountMeta("destinationStake", accounts.destinationStake), getAccountMeta("destinationVote", accounts.destinationVote), getAccountMeta("clockSysvar", accounts.clockSysvar), getAccountMeta("stakeHistorySysvar", accounts.stakeHistorySysvar), getAccountMeta("stakeConfigSysvar", accounts.stakeConfigSysvar), getAccountMeta("systemProgram", accounts.systemProgram), getAccountMeta("stakeProgram", accounts.stakeProgram), ], data: getRedelegateInstructionDataEncoder().encode( args as RedelegateInstructionDataArgs, ), programAddress, } as RedelegateInstruction< TProgramAddress, TAccountStakePool, TAccountStaker, TAccountWithdrawAuthority, TAccountValidatorList, TAccountReserveStake, TAccountSourceCanonicalStake, TAccountSourceTransientStake, TAccountEphemeralStake, TAccountDestinationTransientStake, TAccountDestinationStake, TAccountDestinationVote, TAccountClockSysvar, TAccountStakeHistorySysvar, TAccountStakeConfigSysvar, TAccountSystemProgram, TAccountStakeProgram >); } export type RedelegateInput< TAccountStakePool extends string = string, TAccountStaker extends string = string, TAccountWithdrawAuthority extends string = string, TAccountValidatorList extends string = string, TAccountReserveStake extends string = string, TAccountSourceCanonicalStake extends string = string, TAccountSourceTransientStake extends string = string, TAccountEphemeralStake extends string = string, TAccountDestinationTransientStake extends string = string, TAccountDestinationStake extends string = string, TAccountDestinationVote extends string = string, TAccountClockSysvar extends string = string, TAccountStakeHistorySysvar extends string = string, TAccountStakeConfigSysvar extends string = string, TAccountSystemProgram extends string = string, TAccountStakeProgram extends string = string, > = { stakePool: Address; staker: TransactionSigner; withdrawAuthority: Address; validatorList: Address; reserveStake: Address; sourceCanonicalStake: Address; sourceTransientStake: Address; ephemeralStake: Address; destinationTransientStake: Address; destinationStake: Address; destinationVote: Address; clockSysvar?: Address; stakeHistorySysvar?: Address; stakeConfigSysvar?: Address; systemProgram?: Address; stakeProgram?: Address; lamports: RedelegateInstructionDataArgs["lamports"]; sourceTransientStakeSeed: RedelegateInstructionDataArgs["sourceTransientStakeSeed"]; ephemeralStakeSeed: RedelegateInstructionDataArgs["ephemeralStakeSeed"]; destinationTransientStakeSeed: RedelegateInstructionDataArgs["destinationTransientStakeSeed"]; }; /** * (Staker only) Redelegate active stake on a validator, eventually moving * it to another * Internally, this instruction splits a validator stake account into its * corresponding transient stake account, redelegates it to an ephemeral * stake account, then merges that stake into the destination transient * stake account. * In order to rebalance the pool without taking custody, the staker needs * a way of reducing the stake on a stake account. This instruction splits * some amount of stake, up to the total activated stake, from the * canonical validator stake account, into its "transient" stake * account. * The instruction only succeeds if the source transient stake account and * ephemeral stake account do not exist. * The amount of lamports to move must be at least rent-exemption plus the * minimum delegation amount. Rent-exemption plus minimum delegation * is required for the destination ephemeral stake account. * The rent-exemption for the source transient account comes from the stake * pool reserve, if needed. * The amount that arrives at the destination validator in the end is * `redelegate_lamports - rent_exemption` if the destination transient * account does *not* exist, and `redelegate_lamports` if the destination * transient account already exists. The `rent_exemption` is not activated * when creating the destination transient stake account, but if it already * exists, then the full amount is delegated. * 0. `[]` Stake pool * 1. `[s]` Stake pool staker * 2. `[]` Stake pool withdraw authority * 3. `[w]` Validator list * 4. `[w]` Reserve stake account, to withdraw rent exempt reserve * 5. `[w]` Source canonical stake account to split from * 6. `[w]` Source transient stake account to receive split and be * redelegated * 7. `[w]` Uninitialized ephemeral stake account to receive redelegation * 8. `[w]` Destination transient stake account to receive ephemeral stake * by merge * 9. `[]` Destination stake account to receive transient stake after * activation * 10. `[]` Destination validator vote account * 11. `[]` Clock sysvar * 12. `[]` Stake History sysvar * 13. `[]` Stake Config sysvar * 14. `[]` System program * 15. `[]` Stake program */ export function getRedelegateInstruction< TAccountStakePool extends string, TAccountStaker extends string, TAccountWithdrawAuthority extends string, TAccountValidatorList extends string, TAccountReserveStake extends string, TAccountSourceCanonicalStake extends string, TAccountSourceTransientStake extends string, TAccountEphemeralStake extends string, TAccountDestinationTransientStake extends string, TAccountDestinationStake extends string, TAccountDestinationVote extends string, TAccountClockSysvar extends string, TAccountStakeHistorySysvar extends string, TAccountStakeConfigSysvar extends string, TAccountSystemProgram extends string, TAccountStakeProgram extends string, TProgramAddress extends Address = typeof SPL_STAKE_POOL_PROGRAM_ADDRESS, >( input: RedelegateInput< TAccountStakePool, TAccountStaker, TAccountWithdrawAuthority, TAccountValidatorList, TAccountReserveStake, TAccountSourceCanonicalStake, TAccountSourceTransientStake, TAccountEphemeralStake, TAccountDestinationTransientStake, TAccountDestinationStake, TAccountDestinationVote, TAccountClockSysvar, TAccountStakeHistorySysvar, TAccountStakeConfigSysvar, TAccountSystemProgram, TAccountStakeProgram >, config?: { programAddress?: TProgramAddress }, ): RedelegateInstruction< TProgramAddress, TAccountStakePool, TAccountStaker, TAccountWithdrawAuthority, TAccountValidatorList, TAccountReserveStake, TAccountSourceCanonicalStake, TAccountSourceTransientStake, TAccountEphemeralStake, TAccountDestinationTransientStake, TAccountDestinationStake, TAccountDestinationVote, TAccountClockSysvar, TAccountStakeHistorySysvar, TAccountStakeConfigSysvar, TAccountSystemProgram, TAccountStakeProgram > { // Program address. const programAddress = config?.programAddress ?? SPL_STAKE_POOL_PROGRAM_ADDRESS; // Original accounts. const originalAccounts = { stakePool: { value: input.stakePool ?? null, isWritable: false }, staker: { value: input.staker ?? null, isWritable: false }, withdrawAuthority: { value: input.withdrawAuthority ?? null, isWritable: false, }, validatorList: { value: input.validatorList ?? null, isWritable: true }, reserveStake: { value: input.reserveStake ?? null, isWritable: true }, sourceCanonicalStake: { value: input.sourceCanonicalStake ?? null, isWritable: true, }, sourceTransientStake: { value: input.sourceTransientStake ?? null, isWritable: true, }, ephemeralStake: { value: input.ephemeralStake ?? null, isWritable: true }, destinationTransientStake: { value: input.destinationTransientStake ?? null, isWritable: true, }, destinationStake: { value: input.destinationStake ?? null, isWritable: false, }, destinationVote: { value: input.destinationVote ?? null, isWritable: false, }, clockSysvar: { value: input.clockSysvar ?? null, isWritable: false }, stakeHistorySysvar: { value: input.stakeHistorySysvar ?? null, isWritable: false, }, stakeConfigSysvar: { value: input.stakeConfigSysvar ?? null, isWritable: false, }, systemProgram: { value: input.systemProgram ?? null, isWritable: false }, stakeProgram: { value: input.stakeProgram ?? null, isWritable: false }, }; const accounts = originalAccounts as Record< keyof typeof originalAccounts, ResolvedInstructionAccount >; // Original args. const args = { ...input }; // Resolve default values. if (!accounts.clockSysvar.value) { accounts.clockSysvar.value = "SysvarC1ock11111111111111111111111111111111" as Address<"SysvarC1ock11111111111111111111111111111111">; } if (!accounts.stakeHistorySysvar.value) { accounts.stakeHistorySysvar.value = "SysvarStakeHistory1111111111111111111111111" as Address<"SysvarStakeHistory1111111111111111111111111">; } if (!accounts.stakeConfigSysvar.value) { accounts.stakeConfigSysvar.value = "StakeConfig11111111111111111111111111111111" as Address<"StakeConfig11111111111111111111111111111111">; } if (!accounts.systemProgram.value) { accounts.systemProgram.value = "11111111111111111111111111111111" as Address<"11111111111111111111111111111111">; } if (!accounts.stakeProgram.value) { accounts.stakeProgram.value = "Stake11111111111111111111111111111111111111" as Address<"Stake11111111111111111111111111111111111111">; } const getAccountMeta = getAccountMetaFactory(programAddress, "programId"); return Object.freeze({ accounts: [ getAccountMeta("stakePool", accounts.stakePool), getAccountMeta("staker", accounts.staker), getAccountMeta("withdrawAuthority", accounts.withdrawAuthority), getAccountMeta("validatorList", accounts.validatorList), getAccountMeta("reserveStake", accounts.reserveStake), getAccountMeta("sourceCanonicalStake", accounts.sourceCanonicalStake), getAccountMeta("sourceTransientStake", accounts.sourceTransientStake), getAccountMeta("ephemeralStake", accounts.ephemeralStake), getAccountMeta( "destinationTransientStake", accounts.destinationTransientStake, ), getAccountMeta("destinationStake", accounts.destinationStake), getAccountMeta("destinationVote", accounts.destinationVote), getAccountMeta("clockSysvar", accounts.clockSysvar), getAccountMeta("stakeHistorySysvar", accounts.stakeHistorySysvar), getAccountMeta("stakeConfigSysvar", accounts.stakeConfigSysvar), getAccountMeta("systemProgram", accounts.systemProgram), getAccountMeta("stakeProgram", accounts.stakeProgram), ], data: getRedelegateInstructionDataEncoder().encode( args as RedelegateInstructionDataArgs, ), programAddress, } as RedelegateInstruction< TProgramAddress, TAccountStakePool, TAccountStaker, TAccountWithdrawAuthority, TAccountValidatorList, TAccountReserveStake, TAccountSourceCanonicalStake, TAccountSourceTransientStake, TAccountEphemeralStake, TAccountDestinationTransientStake, TAccountDestinationStake, TAccountDestinationVote, TAccountClockSysvar, TAccountStakeHistorySysvar, TAccountStakeConfigSysvar, TAccountSystemProgram, TAccountStakeProgram >); } export type ParsedRedelegateInstruction< TProgram extends string = typeof SPL_STAKE_POOL_PROGRAM_ADDRESS, TAccountMetas extends readonly AccountMeta[] = readonly AccountMeta[], > = { programAddress: Address; accounts: { stakePool: TAccountMetas[0]; staker: TAccountMetas[1]; withdrawAuthority: TAccountMetas[2]; validatorList: TAccountMetas[3]; reserveStake: TAccountMetas[4]; sourceCanonicalStake: TAccountMetas[5]; sourceTransientStake: TAccountMetas[6]; ephemeralStake: TAccountMetas[7]; destinationTransientStake: TAccountMetas[8]; destinationStake: TAccountMetas[9]; destinationVote: TAccountMetas[10]; clockSysvar: TAccountMetas[11]; stakeHistorySysvar: TAccountMetas[12]; stakeConfigSysvar: TAccountMetas[13]; systemProgram: TAccountMetas[14]; stakeProgram: TAccountMetas[15]; }; data: RedelegateInstructionData; }; export function parseRedelegateInstruction< TProgram extends string, TAccountMetas extends readonly AccountMeta[], >( instruction: Instruction & InstructionWithAccounts & InstructionWithData, ): ParsedRedelegateInstruction { if (instruction.accounts.length < 16) { throw new SolanaError( SOLANA_ERROR__PROGRAM_CLIENTS__INSUFFICIENT_ACCOUNT_METAS, { actualAccountMetas: instruction.accounts.length, expectedAccountMetas: 16, }, ); } let accountIndex = 0; const getNextAccount = () => { const accountMeta = (instruction.accounts as TAccountMetas)[accountIndex]!; accountIndex += 1; return accountMeta; }; return { programAddress: instruction.programAddress, accounts: { stakePool: getNextAccount(), staker: getNextAccount(), withdrawAuthority: getNextAccount(), validatorList: getNextAccount(), reserveStake: getNextAccount(), sourceCanonicalStake: getNextAccount(), sourceTransientStake: getNextAccount(), ephemeralStake: getNextAccount(), destinationTransientStake: getNextAccount(), destinationStake: getNextAccount(), destinationVote: getNextAccount(), clockSysvar: getNextAccount(), stakeHistorySysvar: getNextAccount(), stakeConfigSysvar: getNextAccount(), systemProgram: getNextAccount(), stakeProgram: getNextAccount(), }, data: getRedelegateInstructionDataDecoder().decode(instruction.data), }; }