@@ -24,6 +24,7 @@ import {
24
24
prepareWithdrawAccounts ,
25
25
lamportsToSol ,
26
26
solToLamports ,
27
+ findEphemeralStakeProgramAddress ,
27
28
} from './utils' ;
28
29
import { StakePoolInstruction } from './instructions' ;
29
30
import {
@@ -36,6 +37,7 @@ import {
36
37
} from './layouts' ;
37
38
import { MAX_VALIDATORS_TO_UPDATE , MINIMUM_ACTIVE_STAKE , STAKE_POOL_PROGRAM_ID } from './constants' ;
38
39
import { create } from 'superstruct' ;
40
+ import BN from 'bn.js' ;
39
41
40
42
export type { StakePool , AccountType , ValidatorList , ValidatorStakeInfo } from './layouts' ;
41
43
export { STAKE_POOL_PROGRAM_ID } from './constants' ;
@@ -66,6 +68,17 @@ export interface StakePoolAccounts {
66
68
validatorList : ValidatorListAccount | undefined ;
67
69
}
68
70
71
+ interface RedelegateProps {
72
+ connection : Connection ;
73
+ stakePoolAddress : PublicKey ;
74
+ sourceVoteAccount : PublicKey ;
75
+ destinationVoteAccount : PublicKey ;
76
+ sourceTransientStakeSeed : number | BN ;
77
+ destinationTransientStakeSeed : number | BN ;
78
+ ephemeralStakeSeed : number | BN ;
79
+ lamports : number | BN ;
80
+ }
81
+
69
82
/**
70
83
* Retrieves and deserializes a StakePool account using a web3js connection and the stake pool address.
71
84
* @param connection: An active web3js connection.
@@ -401,7 +414,7 @@ export async function withdrawStake(
401
414
val . voteAccountAddress . equals ( voteAccount ) ,
402
415
) ;
403
416
if ( voteAccountAddress && voteAccountAddress !== voteAccount ) {
404
- throw new Error ( `Provided withdrawal vote account ${ voteAccountAddress } does not match delegation on stake receiver account ${ voteAccount } ,
417
+ throw new Error ( `Provided withdrawal vote account ${ voteAccountAddress } does not match delegation on stake receiver account ${ voteAccount } ,
405
418
remove this flag or provide a different stake account delegated to ${ voteAccountAddress } ` ) ;
406
419
}
407
420
if ( isValidVoter ) {
@@ -668,6 +681,7 @@ export async function increaseValidatorStake(
668
681
stakePoolAddress : PublicKey ,
669
682
validatorVote : PublicKey ,
670
683
lamports : number ,
684
+ ephemeralStakeSeed ?: number ,
671
685
) {
672
686
const stakePool = await getStakePoolAccount ( connection , stakePoolAddress ) ;
673
687
@@ -705,8 +719,14 @@ export async function increaseValidatorStake(
705
719
) ;
706
720
707
721
const instructions : TransactionInstruction [ ] = [ ] ;
708
- instructions . push (
709
- StakePoolInstruction . increaseValidatorStake ( {
722
+
723
+ if ( ephemeralStakeSeed != undefined ) {
724
+ const ephemeralStake = await findEphemeralStakeProgramAddress (
725
+ STAKE_POOL_PROGRAM_ID ,
726
+ stakePoolAddress ,
727
+ new BN ( ephemeralStakeSeed ) ,
728
+ ) ;
729
+ StakePoolInstruction . increaseAdditionalValidatorStake ( {
710
730
stakePool : stakePoolAddress ,
711
731
staker : stakePool . account . data . staker ,
712
732
validatorList : stakePool . account . data . validatorList ,
@@ -717,8 +737,25 @@ export async function increaseValidatorStake(
717
737
validatorStake,
718
738
validatorVote,
719
739
lamports,
720
- } ) ,
721
- ) ;
740
+ ephemeralStake,
741
+ ephemeralStakeSeed,
742
+ } ) ;
743
+ } else {
744
+ instructions . push (
745
+ StakePoolInstruction . increaseValidatorStake ( {
746
+ stakePool : stakePoolAddress ,
747
+ staker : stakePool . account . data . staker ,
748
+ validatorList : stakePool . account . data . validatorList ,
749
+ reserveStake : stakePool . account . data . reserveStake ,
750
+ transientStakeSeed : transientStakeSeed . toNumber ( ) ,
751
+ withdrawAuthority,
752
+ transientStake,
753
+ validatorStake,
754
+ validatorVote,
755
+ lamports,
756
+ } ) ,
757
+ ) ;
758
+ }
722
759
723
760
return {
724
761
instructions,
@@ -733,6 +770,7 @@ export async function decreaseValidatorStake(
733
770
stakePoolAddress : PublicKey ,
734
771
validatorVote : PublicKey ,
735
772
lamports : number ,
773
+ ephemeralStakeSeed ?: number ,
736
774
) {
737
775
const stakePool = await getStakePoolAccount ( connection , stakePoolAddress ) ;
738
776
const validatorList = await getValidatorListAccount (
@@ -769,18 +807,41 @@ export async function decreaseValidatorStake(
769
807
) ;
770
808
771
809
const instructions : TransactionInstruction [ ] = [ ] ;
772
- instructions . push (
773
- StakePoolInstruction . decreaseValidatorStake ( {
774
- stakePool : stakePoolAddress ,
775
- staker : stakePool . account . data . staker ,
776
- validatorList : stakePool . account . data . validatorList ,
777
- transientStakeSeed : transientStakeSeed . toNumber ( ) ,
778
- withdrawAuthority,
779
- validatorStake,
780
- transientStake,
781
- lamports,
782
- } ) ,
783
- ) ;
810
+
811
+ if ( ephemeralStakeSeed != undefined ) {
812
+ const ephemeralStake = await findEphemeralStakeProgramAddress (
813
+ STAKE_POOL_PROGRAM_ID ,
814
+ stakePoolAddress ,
815
+ new BN ( ephemeralStakeSeed ) ,
816
+ ) ;
817
+ instructions . push (
818
+ StakePoolInstruction . decreaseAdditionalValidatorStake ( {
819
+ stakePool : stakePoolAddress ,
820
+ staker : stakePool . account . data . staker ,
821
+ validatorList : stakePool . account . data . validatorList ,
822
+ transientStakeSeed : transientStakeSeed . toNumber ( ) ,
823
+ withdrawAuthority,
824
+ validatorStake,
825
+ transientStake,
826
+ lamports,
827
+ ephemeralStake,
828
+ ephemeralStakeSeed,
829
+ } ) ,
830
+ ) ;
831
+ } else {
832
+ instructions . push (
833
+ StakePoolInstruction . decreaseValidatorStake ( {
834
+ stakePool : stakePoolAddress ,
835
+ staker : stakePool . account . data . staker ,
836
+ validatorList : stakePool . account . data . validatorList ,
837
+ transientStakeSeed : transientStakeSeed . toNumber ( ) ,
838
+ withdrawAuthority,
839
+ validatorStake,
840
+ transientStake,
841
+ lamports,
842
+ } ) ,
843
+ ) ;
844
+ }
784
845
785
846
return {
786
847
instructions,
@@ -993,3 +1054,82 @@ export async function stakePoolInfo(connection: Connection, stakePoolAddress: Pu
993
1054
} , // CliStakePoolDetails
994
1055
} ;
995
1056
}
1057
+
1058
+ /**
1059
+ * Creates instructions required to redelegate stake.
1060
+ */
1061
+ export async function redelegate ( props : RedelegateProps ) {
1062
+ const {
1063
+ connection,
1064
+ stakePoolAddress,
1065
+ sourceVoteAccount,
1066
+ sourceTransientStakeSeed,
1067
+ destinationVoteAccount,
1068
+ destinationTransientStakeSeed,
1069
+ ephemeralStakeSeed,
1070
+ lamports,
1071
+ } = props ;
1072
+ const stakePool = await getStakePoolAccount ( connection , stakePoolAddress ) ;
1073
+
1074
+ const stakePoolWithdrawAuthority = await findWithdrawAuthorityProgramAddress (
1075
+ STAKE_POOL_PROGRAM_ID ,
1076
+ stakePoolAddress ,
1077
+ ) ;
1078
+
1079
+ const sourceValidatorStake = await findStakeProgramAddress (
1080
+ STAKE_POOL_PROGRAM_ID ,
1081
+ sourceVoteAccount ,
1082
+ stakePoolAddress ,
1083
+ ) ;
1084
+
1085
+ const sourceTransientStake = await findTransientStakeProgramAddress (
1086
+ STAKE_POOL_PROGRAM_ID ,
1087
+ sourceVoteAccount ,
1088
+ stakePoolAddress ,
1089
+ new BN ( sourceTransientStakeSeed ) ,
1090
+ ) ;
1091
+
1092
+ const destinationValidatorStake = await findStakeProgramAddress (
1093
+ STAKE_POOL_PROGRAM_ID ,
1094
+ destinationVoteAccount ,
1095
+ stakePoolAddress ,
1096
+ ) ;
1097
+
1098
+ const destinationTransientStake = await findTransientStakeProgramAddress (
1099
+ STAKE_POOL_PROGRAM_ID ,
1100
+ destinationVoteAccount ,
1101
+ stakePoolAddress ,
1102
+ new BN ( destinationTransientStakeSeed ) ,
1103
+ ) ;
1104
+
1105
+ const ephemeralStake = await findEphemeralStakeProgramAddress (
1106
+ STAKE_POOL_PROGRAM_ID ,
1107
+ stakePoolAddress ,
1108
+ new BN ( ephemeralStakeSeed ) ,
1109
+ ) ;
1110
+
1111
+ const instructions : TransactionInstruction [ ] = [ ] ;
1112
+
1113
+ instructions . push (
1114
+ StakePoolInstruction . redelegate ( {
1115
+ stakePool : stakePool . pubkey ,
1116
+ staker : stakePool . account . data . staker ,
1117
+ validatorList : stakePool . account . data . validatorList ,
1118
+ stakePoolWithdrawAuthority,
1119
+ ephemeralStake,
1120
+ ephemeralStakeSeed,
1121
+ sourceValidatorStake,
1122
+ sourceTransientStake,
1123
+ sourceTransientStakeSeed,
1124
+ destinationValidatorStake,
1125
+ destinationTransientStake,
1126
+ destinationTransientStakeSeed,
1127
+ validator : destinationVoteAccount ,
1128
+ lamports,
1129
+ } ) ,
1130
+ ) ;
1131
+
1132
+ return {
1133
+ instructions,
1134
+ } ;
1135
+ }
0 commit comments