decreaseValidatorStake static method

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

Creates instructions required to decrease validator stake.

Implementation

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

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

  final withdrawAuthority =
      StakePoolProgramUtils.findWithdrawAuthorityProgramAddress(
          stakePoolAddress: stakePoolAddress);

  final validatorStake = StakePoolProgramUtils.findStakeProgramAddress(
    voteAccountAddress: validatorInfo.voteAccountAddress,
    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 instructions = <TransactionInstruction>[];

  if (ephemeralStakeSeed != null) {
    final ephemeralStake =
        StakePoolProgramUtils.findEphemeralStakeProgramAddress(
      stakePoolAddress: stakePoolAddress,
      seed: ephemeralStakeSeed,
    );
    instructions.add(
      StakePoolProgram.decreaseAdditionalValidatorStake(
          stakePool: stakePoolAddress,
          staker: stakePool.staker,
          validatorList: stakePool.validatorList,
          reserveStake: stakePool.reserveStake,
          withdrawAuthority: withdrawAuthority.address,
          validatorStake: validatorStake.address,
          transientStake: transientStake.address,
          ephemeralStake: ephemeralStake.address,
          layout: StakePoolDecreaseAdditionalValidatorStakeLayout(
              lamports: lamports,
              ephemeralStakeSeed: ephemeralStakeSeed,
              transientStakeSeed: transientStakeSeed)),
    );
  } else {
    instructions.add(
      StakePoolProgram.decreaseValidatorStakeWithReserve(
          stakePool: stakePoolAddress,
          staker: stakePool.staker,
          validatorList: stakePool.validatorList,
          reserveStake: stakePool.reserveStake,
          withdrawAuthority: withdrawAuthority.address,
          validatorStake: validatorStake.address,
          transientStake: transientStake.address,
          layout: StakePoolDecreaseValidatorStakeWithReserveLayout(
              lamports: lamports, transientStakeSeed: transientStakeSeed)),
    );
  }

  return instructions;
}