increaseValidatorStake static method

Future<List<TransactionInstruction>> increaseValidatorStake({
  1. required SolanaProvider connection,
  2. required SolAddress stakePoolAddress,
  3. required SolAddress validatorVote,
  4. required BigInt lamports,
  5. BigInt? ephemeralStakeSeed,
})

Creates instructions required to increase validator stake.

Implementation

static Future<List<TransactionInstruction>> increaseValidatorStake({
  required SolanaProvider connection,
  required SolAddress stakePoolAddress,
  required SolAddress validatorVote,
  required BigInt lamports,
  BigInt? ephemeralStakeSeed,
}) async {
  final stakePool = await connection.request(
    SolanaRPCGetStakePoolAccount(address: stakePoolAddress),
  );
  if (stakePool == null) {
    throw const SolanaPluginException('Stake pool account does not found.');
  }
  final validatorList = await connection.request(
    SolanaRPCGetStakePoolValidatorListAccount(
      address: stakePool.validatorList.address,
    ),
  );
  if (validatorList == null) {
    throw const SolanaPluginException(
      'Validator list account does not found.',
    );
  }

  final validatorInfo = validatorList.validators.firstWhere(
    (v) => v.voteAccountAddress.address == validatorVote.address,
    orElse:
        () =>
            throw const SolanaPluginException(
              'Vote account not found in validator list',
            ),
  );

  final withdrawAuthority =
      StakePoolProgramUtils.findWithdrawAuthorityProgramAddress(
        stakePoolAddress: stakePoolAddress,
      );
  // bump up by one to avoid reuse
  final transientStakeSeed =
      validatorInfo.transientSeedSuffixStart + BigInt.one;

  final transientStake =
      StakePoolProgramUtils.findTransientStakeProgramAddress(
        voteAccountAddress: validatorInfo.voteAccountAddress,
        stakePoolAddress: stakePoolAddress,
        seed: transientStakeSeed,
      );

  final validatorStake = StakePoolProgramUtils.findStakeProgramAddress(
    voteAccountAddress: validatorInfo.voteAccountAddress,
    stakePoolAddress: stakePoolAddress,
  );

  final instructions = <TransactionInstruction>[];

  if (ephemeralStakeSeed != null) {
    final ephemeralStake =
        StakePoolProgramUtils.findEphemeralStakeProgramAddress(
          stakePoolAddress: stakePoolAddress,
          seed: ephemeralStakeSeed,
        );
    instructions.add(
      StakePoolProgram.increaseAdditionalValidatorStake(
        stakePool: stakePoolAddress,
        staker: stakePool.staker,
        validatorList: stakePool.validatorList,
        reserveStake: stakePool.reserveStake,
        withdrawAuthority: withdrawAuthority.address,
        transientStake: transientStake.address,
        validatorStake: validatorStake.address,
        validatorVote: validatorVote,
        ephemeralStake: ephemeralStake.address,
        layout: StakePoolIncreaseAdditionalValidatorStakeLayout(
          lamports: lamports,
          ephemeralStakeSeed: ephemeralStakeSeed,
          transientStakeSeed: transientStakeSeed,
        ),
      ),
    );
  } else {
    instructions.add(
      StakePoolProgram.increaseValidatorStake(
        stakePool: stakePoolAddress,
        staker: stakePool.staker,
        validatorList: stakePool.validatorList,
        reserveStake: stakePool.reserveStake,
        withdrawAuthority: withdrawAuthority.address,
        transientStake: transientStake.address,
        validatorStake: validatorStake.address,
        validatorVote: validatorVote,
        layout: StakePoolIncreaseValidatorStakeLayout(
          lamports: lamports,
          transientStakeSeed: transientStakeSeed,
        ),
      ),
    );
  }

  return instructions;
}