@kamino-finance/klend-sdk 5.10.28-beta.0 → 5.11.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. package/dist/classes/action.d.ts +22 -14
  2. package/dist/classes/action.d.ts.map +1 -1
  3. package/dist/classes/action.js +585 -132
  4. package/dist/classes/action.js.map +1 -1
  5. package/dist/classes/index.d.ts +0 -3
  6. package/dist/classes/index.d.ts.map +1 -1
  7. package/dist/classes/index.js +0 -3
  8. package/dist/classes/index.js.map +1 -1
  9. package/dist/classes/manager.js +1 -1
  10. package/dist/classes/manager.js.map +1 -1
  11. package/dist/classes/obligation.d.ts +1 -6
  12. package/dist/classes/obligation.d.ts.map +1 -1
  13. package/dist/classes/obligation.js +2 -4
  14. package/dist/classes/obligation.js.map +1 -1
  15. package/dist/classes/types.d.ts +1 -13
  16. package/dist/classes/types.d.ts.map +1 -1
  17. package/dist/idl.json +71 -5
  18. package/dist/idl_codegen/accounts/Obligation.d.ts +6 -0
  19. package/dist/idl_codegen/accounts/Obligation.d.ts.map +1 -1
  20. package/dist/idl_codegen/accounts/Obligation.js +8 -1
  21. package/dist/idl_codegen/accounts/Obligation.js.map +1 -1
  22. package/dist/idl_codegen/errors/custom.d.ts +35 -3
  23. package/dist/idl_codegen/errors/custom.d.ts.map +1 -1
  24. package/dist/idl_codegen/errors/custom.js +61 -5
  25. package/dist/idl_codegen/errors/custom.js.map +1 -1
  26. package/dist/idl_codegen/instructions/repayAndWithdrawAndRedeem.d.ts +9 -0
  27. package/dist/idl_codegen/instructions/repayAndWithdrawAndRedeem.d.ts.map +1 -1
  28. package/dist/idl_codegen/instructions/repayAndWithdrawAndRedeem.js +22 -1
  29. package/dist/idl_codegen/instructions/repayAndWithdrawAndRedeem.js.map +1 -1
  30. package/dist/idl_codegen/instructions/withdrawObligationCollateralAndRedeemReserveCollateral.js +1 -1
  31. package/dist/idl_codegen/instructions/withdrawObligationCollateralAndRedeemReserveCollateral.js.map +1 -1
  32. package/dist/idl_codegen/instructions/withdrawObligationCollateralAndRedeemReserveCollateralV2.js +1 -1
  33. package/dist/idl_codegen/instructions/withdrawObligationCollateralAndRedeemReserveCollateralV2.js.map +1 -1
  34. package/dist/idl_codegen/zero_padding/ObligationZP.d.ts +2 -0
  35. package/dist/idl_codegen/zero_padding/ObligationZP.d.ts.map +1 -1
  36. package/dist/idl_codegen/zero_padding/ObligationZP.js +6 -1
  37. package/dist/idl_codegen/zero_padding/ObligationZP.js.map +1 -1
  38. package/dist/lending_operations/repay_with_collateral_operations.d.ts +3 -2
  39. package/dist/lending_operations/repay_with_collateral_operations.d.ts.map +1 -1
  40. package/dist/lending_operations/repay_with_collateral_operations.js +7 -6
  41. package/dist/lending_operations/repay_with_collateral_operations.js.map +1 -1
  42. package/dist/lending_operations/swap_collateral_operations.d.ts +5 -0
  43. package/dist/lending_operations/swap_collateral_operations.d.ts.map +1 -1
  44. package/dist/lending_operations/swap_collateral_operations.js +4 -2
  45. package/dist/lending_operations/swap_collateral_operations.js.map +1 -1
  46. package/dist/leverage/calcs.d.ts +1 -1
  47. package/dist/leverage/calcs.d.ts.map +1 -1
  48. package/dist/leverage/calcs.js +10 -12
  49. package/dist/leverage/calcs.js.map +1 -1
  50. package/dist/leverage/operations.d.ts +8 -8
  51. package/dist/leverage/operations.d.ts.map +1 -1
  52. package/dist/leverage/operations.js +27 -24
  53. package/dist/leverage/operations.js.map +1 -1
  54. package/dist/leverage/types.d.ts +4 -1
  55. package/dist/leverage/types.d.ts.map +1 -1
  56. package/dist/utils/seeds.d.ts +5 -0
  57. package/dist/utils/seeds.d.ts.map +1 -1
  58. package/dist/utils/seeds.js +10 -1
  59. package/dist/utils/seeds.js.map +1 -1
  60. package/dist/utils/userMetadata.d.ts.map +1 -1
  61. package/dist/utils/userMetadata.js +6 -9
  62. package/dist/utils/userMetadata.js.map +1 -1
  63. package/package.json +4 -4
  64. package/src/classes/action.ts +749 -146
  65. package/src/classes/index.ts +0 -3
  66. package/src/classes/manager.ts +1 -1
  67. package/src/classes/obligation.ts +4 -8
  68. package/src/classes/types.ts +1 -17
  69. package/src/client.ts +7 -3
  70. package/src/idl.json +71 -5
  71. package/src/idl_codegen/accounts/Obligation.ts +12 -1
  72. package/src/idl_codegen/errors/custom.ts +66 -4
  73. package/src/idl_codegen/instructions/repayAndWithdrawAndRedeem.ts +31 -1
  74. package/src/idl_codegen/instructions/withdrawObligationCollateralAndRedeemReserveCollateral.ts +1 -1
  75. package/src/idl_codegen/instructions/withdrawObligationCollateralAndRedeemReserveCollateralV2.ts +1 -1
  76. package/src/idl_codegen/zero_padding/ObligationZP.ts +6 -1
  77. package/src/lending_operations/repay_with_collateral_operations.ts +11 -3
  78. package/src/lending_operations/swap_collateral_operations.ts +11 -0
  79. package/src/leverage/calcs.ts +13 -16
  80. package/src/leverage/operations.ts +38 -11
  81. package/src/leverage/types.ts +4 -1
  82. package/src/utils/seeds.ts +13 -0
  83. package/src/utils/userMetadata.ts +19 -24
  84. package/dist/classes/stakePool.d.ts +0 -8
  85. package/dist/classes/stakePool.d.ts.map +0 -1
  86. package/dist/classes/stakePool.js +0 -18
  87. package/dist/classes/stakePool.js.map +0 -1
  88. package/dist/classes/standardStakePool.d.ts +0 -255
  89. package/dist/classes/standardStakePool.d.ts.map +0 -1
  90. package/dist/classes/standardStakePool.js +0 -275
  91. package/dist/classes/standardStakePool.js.map +0 -1
  92. package/dist/classes/unstakingPool.d.ts +0 -111
  93. package/dist/classes/unstakingPool.d.ts.map +0 -1
  94. package/dist/classes/unstakingPool.js +0 -437
  95. package/dist/classes/unstakingPool.js.map +0 -1
  96. package/dist/idl_codegen_unstaking_pool/accounts/PoolState.d.ts +0 -50
  97. package/dist/idl_codegen_unstaking_pool/accounts/PoolState.d.ts.map +0 -1
  98. package/dist/idl_codegen_unstaking_pool/accounts/PoolState.js +0 -156
  99. package/dist/idl_codegen_unstaking_pool/accounts/PoolState.js.map +0 -1
  100. package/dist/idl_codegen_unstaking_pool/accounts/index.d.ts +0 -3
  101. package/dist/idl_codegen_unstaking_pool/accounts/index.d.ts.map +0 -1
  102. package/dist/idl_codegen_unstaking_pool/accounts/index.js +0 -6
  103. package/dist/idl_codegen_unstaking_pool/accounts/index.js.map +0 -1
  104. package/dist/idl_codegen_unstaking_pool/errors/anchor.d.ts +0 -435
  105. package/dist/idl_codegen_unstaking_pool/errors/anchor.d.ts.map +0 -1
  106. package/dist/idl_codegen_unstaking_pool/errors/anchor.js +0 -767
  107. package/dist/idl_codegen_unstaking_pool/errors/anchor.js.map +0 -1
  108. package/dist/idl_codegen_unstaking_pool/errors/custom.d.ts +0 -163
  109. package/dist/idl_codegen_unstaking_pool/errors/custom.d.ts.map +0 -1
  110. package/dist/idl_codegen_unstaking_pool/errors/custom.js +0 -290
  111. package/dist/idl_codegen_unstaking_pool/errors/custom.js.map +0 -1
  112. package/dist/idl_codegen_unstaking_pool/errors/index.d.ts +0 -6
  113. package/dist/idl_codegen_unstaking_pool/errors/index.d.ts.map +0 -1
  114. package/dist/idl_codegen_unstaking_pool/errors/index.js +0 -75
  115. package/dist/idl_codegen_unstaking_pool/errors/index.js.map +0 -1
  116. package/dist/idl_codegen_unstaking_pool/instructions/burn.d.ts +0 -21
  117. package/dist/idl_codegen_unstaking_pool/instructions/burn.d.ts.map +0 -1
  118. package/dist/idl_codegen_unstaking_pool/instructions/burn.js +0 -73
  119. package/dist/idl_codegen_unstaking_pool/instructions/burn.js.map +0 -1
  120. package/dist/idl_codegen_unstaking_pool/instructions/collect.d.ts +0 -16
  121. package/dist/idl_codegen_unstaking_pool/instructions/collect.d.ts.map +0 -1
  122. package/dist/idl_codegen_unstaking_pool/instructions/collect.js +0 -29
  123. package/dist/idl_codegen_unstaking_pool/instructions/collect.js.map +0 -1
  124. package/dist/idl_codegen_unstaking_pool/instructions/index.d.ts +0 -11
  125. package/dist/idl_codegen_unstaking_pool/instructions/index.d.ts.map +0 -1
  126. package/dist/idl_codegen_unstaking_pool/instructions/index.js +0 -14
  127. package/dist/idl_codegen_unstaking_pool/instructions/index.js.map +0 -1
  128. package/dist/idl_codegen_unstaking_pool/instructions/initializePool.d.ts +0 -15
  129. package/dist/idl_codegen_unstaking_pool/instructions/initializePool.d.ts.map +0 -1
  130. package/dist/idl_codegen_unstaking_pool/instructions/initializePool.js +0 -28
  131. package/dist/idl_codegen_unstaking_pool/instructions/initializePool.js.map +0 -1
  132. package/dist/idl_codegen_unstaking_pool/instructions/mint.d.ts +0 -21
  133. package/dist/idl_codegen_unstaking_pool/instructions/mint.d.ts.map +0 -1
  134. package/dist/idl_codegen_unstaking_pool/instructions/mint.js +0 -77
  135. package/dist/idl_codegen_unstaking_pool/instructions/mint.js.map +0 -1
  136. package/dist/idl_codegen_unstaking_pool/instructions/updatePoolConfig.d.ts +0 -13
  137. package/dist/idl_codegen_unstaking_pool/instructions/updatePoolConfig.d.ts.map +0 -1
  138. package/dist/idl_codegen_unstaking_pool/instructions/updatePoolConfig.js +0 -58
  139. package/dist/idl_codegen_unstaking_pool/instructions/updatePoolConfig.js.map +0 -1
  140. package/dist/idl_codegen_unstaking_pool/programId.d.ts +0 -4
  141. package/dist/idl_codegen_unstaking_pool/programId.d.ts.map +0 -1
  142. package/dist/idl_codegen_unstaking_pool/programId.js +0 -9
  143. package/dist/idl_codegen_unstaking_pool/programId.js.map +0 -1
  144. package/dist/idl_codegen_unstaking_pool/types/PoolConfigField.d.ts +0 -32
  145. package/dist/idl_codegen_unstaking_pool/types/PoolConfigField.d.ts.map +0 -1
  146. package/dist/idl_codegen_unstaking_pool/types/PoolConfigField.js +0 -105
  147. package/dist/idl_codegen_unstaking_pool/types/PoolConfigField.js.map +0 -1
  148. package/dist/idl_codegen_unstaking_pool/types/index.d.ts +0 -5
  149. package/dist/idl_codegen_unstaking_pool/types/index.d.ts.map +0 -1
  150. package/dist/idl_codegen_unstaking_pool/types/index.js +0 -39
  151. package/dist/idl_codegen_unstaking_pool/types/index.js.map +0 -1
  152. package/src/classes/stakePool.ts +0 -21
  153. package/src/classes/standardStakePool.ts +0 -361
  154. package/src/classes/unstakingPool.ts +0 -565
  155. package/src/idl_codegen_unstaking_pool/accounts/PoolState.ts +0 -163
  156. package/src/idl_codegen_unstaking_pool/accounts/index.ts +0 -2
  157. package/src/idl_codegen_unstaking_pool/errors/anchor.ts +0 -764
  158. package/src/idl_codegen_unstaking_pool/errors/custom.ts +0 -288
  159. package/src/idl_codegen_unstaking_pool/errors/index.ts +0 -49
  160. package/src/idl_codegen_unstaking_pool/instructions/burn.ts +0 -60
  161. package/src/idl_codegen_unstaking_pool/instructions/collect.ts +0 -43
  162. package/src/idl_codegen_unstaking_pool/instructions/index.ts +0 -10
  163. package/src/idl_codegen_unstaking_pool/instructions/initializePool.ts +0 -41
  164. package/src/idl_codegen_unstaking_pool/instructions/mint.ts +0 -64
  165. package/src/idl_codegen_unstaking_pool/instructions/updatePoolConfig.ts +0 -40
  166. package/src/idl_codegen_unstaking_pool/programId.ts +0 -7
  167. package/src/idl_codegen_unstaking_pool/types/PoolConfigField.ts +0 -85
  168. package/src/idl_codegen_unstaking_pool/types/index.ts +0 -6
  169. package/src/idl_unstaking_pool.json +0 -456
@@ -1,39 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.PoolConfigField = void 0;
37
- const PoolConfigField = __importStar(require("./PoolConfigField"));
38
- exports.PoolConfigField = PoolConfigField;
39
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/idl_codegen_unstaking_pool/types/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,mEAAqD;AAE5C,0CAAe"}
@@ -1,21 +0,0 @@
1
- import { Connection, PublicKey } from '@solana/web3.js/lib';
2
- import { maybeGetStakedPoolByMint } from './standardStakePool';
3
- import { StakePool as StandardStakePool } from '@solana/spl-stake-pool/dist/layouts';
4
-
5
- // Expand this type to represent all supported stake pool implementations
6
- export type GenericStakePool = StandardStakePool;
7
- export enum StakePoolType {
8
- Standard,
9
- }
10
-
11
- export async function mapStakedSolMintToPool(
12
- connection: Connection,
13
- mint: PublicKey
14
- ): Promise<[GenericStakePool, PublicKey, StakePoolType]> {
15
- // We cannot know which pool the mint corresponds to, so we fetch them program by program
16
- const maybeStandardPoolAndKey = await maybeGetStakedPoolByMint(connection, mint);
17
- if (maybeStandardPoolAndKey) {
18
- return [...maybeStandardPoolAndKey, StakePoolType.Standard];
19
- }
20
- throw new Error(`Cannot map mint ${mint} to staked sol pool`);
21
- }
@@ -1,361 +0,0 @@
1
- import { STAKE_POOL_PROGRAM_ID, ValidatorList, ValidatorListLayout } from '@solana/spl-stake-pool';
2
- import { StakePool, StakePoolLayout } from '@solana/spl-stake-pool';
3
- import { AccountMeta, Connection, Keypair, PublicKey } from '@solana/web3.js';
4
- import { CLOCK_PROGRAM_ID, STAKE_PROGRAM_ID } from './unstakingPool';
5
- import BN from 'bn.js';
6
- import assert from 'assert';
7
- import { enums, Infer, nullable, number, type } from 'superstruct';
8
-
9
- export const TRANSIENT_STAKE_SEED_PREFIX = Buffer.from('transient');
10
- export const STAKE_ACCOUNT_RENT_EXEMPTION = 2_282_880;
11
- const MINIMUM_ACTIVE_STAKE = 1_000_000;
12
- // This represents the minimum each validator stake account must have and cannot be withdrawn
13
- const TRANSIENT_STAKE_ACCOUNT_RENT_EXEMPTION = STAKE_ACCOUNT_RENT_EXEMPTION + MINIMUM_ACTIVE_STAKE;
14
-
15
- export async function getStandardPoolState(address: PublicKey, connection: Connection): Promise<StakePool> {
16
- const accountInfo = await connection.getAccountInfo(address);
17
- if (!accountInfo) {
18
- throw new Error(`Cannot fetch standard stake pool account ${address.toString()}`);
19
- }
20
- return StakePoolLayout.decode(accountInfo.data);
21
- }
22
-
23
- export async function getValidatorList(address: PublicKey, connection: Connection): Promise<ValidatorList> {
24
- const accountInfo = await connection.getAccountInfo(address);
25
- if (!accountInfo) {
26
- throw new Error(`Cannot fetch standard stake pool account ${address.toString()}`);
27
- }
28
- return ValidatorListLayout.decode(accountInfo.data);
29
- }
30
-
31
- export async function maybeGetStakedPoolByMint(
32
- connection: Connection,
33
- mint: PublicKey
34
- ): Promise<[StakePool, PublicKey] | undefined> {
35
- const results = await connection.getProgramAccounts(STAKE_POOL_PROGRAM_ID, {
36
- filters: [{ memcmp: { offset: 162, bytes: mint.toBase58() } }],
37
- });
38
- // There should be only 1 stake pool for mint
39
- if (results.length === 0) {
40
- return undefined;
41
- }
42
- if (results.length === 1) {
43
- return [StakePoolLayout.decode(results[0].account.data), results[0].pubkey];
44
- }
45
- throw new Error(`Got ${results.length} stake pools for mint ${mint.toString()} and not sure which one is correct.`);
46
- }
47
-
48
- export async function getStandardPoolMintRemainingAccounts(
49
- connection: Connection,
50
- stakedSolPool: StakePool,
51
- stakedSolPoolPk: PublicKey,
52
- stakedSolToDeposit: BN
53
- ): Promise<[Array<AccountMeta>, Array<Keypair>]> {
54
- let withdrawAuthority = await findWithdrawAuthorityProgramAddress(STAKE_POOL_PROGRAM_ID, stakedSolPoolPk);
55
- const remainingAccounts = [
56
- { pubkey: stakedSolPoolPk, isSigner: false, isWritable: true },
57
- { pubkey: stakedSolPool.validatorList, isSigner: false, isWritable: true },
58
- { pubkey: withdrawAuthority, isSigner: false, isWritable: true },
59
- { pubkey: stakedSolPool.managerFeeAccount, isSigner: false, isWritable: true },
60
- { pubkey: CLOCK_PROGRAM_ID, isSigner: false, isWritable: false },
61
- { pubkey: STAKE_PROGRAM_ID, isSigner: false, isWritable: false },
62
- { pubkey: STAKE_POOL_PROGRAM_ID, isSigner: false, isWritable: false },
63
- ];
64
- const withdrawCandidates = await getWithdrawCandidates(
65
- connection,
66
- stakedSolPool,
67
- stakedSolPoolPk,
68
- stakedSolToDeposit
69
- );
70
- // Each withdraw candidate should also create a new keypair for the stake account
71
- const withdrawCandidatesTo: Keypair[] = [];
72
- for (const withdrawCandidateFrom of withdrawCandidates) {
73
- remainingAccounts.push({ pubkey: withdrawCandidateFrom, isSigner: false, isWritable: true });
74
- const withdrawCandidateTo = Keypair.generate();
75
- remainingAccounts.push({ pubkey: withdrawCandidateTo.publicKey, isSigner: true, isWritable: true });
76
- withdrawCandidatesTo.push(withdrawCandidateTo);
77
- }
78
- return [remainingAccounts, withdrawCandidatesTo];
79
- }
80
-
81
- async function getAllWithdrawCandidatesSorted(
82
- connection: Connection,
83
- stakedSolPool: StakePool,
84
- stakedSolPoolPk: PublicKey
85
- ): Promise<Array<{ isPreferred: boolean; balance: number; pk: PublicKey }>> {
86
- const activeValidators: { isPreferred: boolean; balance: number; pk: PublicKey }[] = [];
87
- const transientValidators: { isPreferred: boolean; balance: number; pk: PublicKey }[] = [];
88
- const validatorList = await getValidatorList(stakedSolPool.validatorList, connection);
89
- const accountsToFetch: PublicKey[] = [];
90
- // Add all accounts to be fetched to an array so that we can use getMultipleAccounts
91
- for (const validator of validatorList.validators) {
92
- const stakeAccount = await findStakeProgramAddress(
93
- STAKE_POOL_PROGRAM_ID,
94
- validator.voteAccountAddress,
95
- stakedSolPoolPk,
96
- validator.transientSeedSuffixStart.toNumber()
97
- );
98
- const transientAccount = await findTransientStakeProgramAddress(
99
- STAKE_POOL_PROGRAM_ID,
100
- validator.voteAccountAddress,
101
- stakedSolPoolPk,
102
- validator.transientSeedSuffixEnd
103
- );
104
- accountsToFetch.push(stakeAccount);
105
- accountsToFetch.push(transientAccount);
106
- }
107
- let accountsBalances: Array<number> = [];
108
- // TODO: if this is still too slow we can also start all getMultipleAccounts in parallel and do Promise.all
109
- for (let i = 0; i < accountsToFetch.length; i += 100) {
110
- const accountInfos = await connection.getMultipleAccountsInfo(accountsToFetch.slice(i, i + 100));
111
- accountsBalances = accountsBalances.concat(
112
- accountInfos.map((accountInfo) => (accountInfo ? accountInfo.lamports : 0))
113
- );
114
- }
115
- assert(accountsBalances.length === accountsToFetch.length);
116
- let i = 0;
117
- for (const validator of validatorList.validators) {
118
- const isPreferred = stakedSolPool.preferredWithdrawValidatorVoteAddress
119
- ? validator.voteAccountAddress.equals(stakedSolPool.preferredWithdrawValidatorVoteAddress)
120
- : false;
121
- const stakeAccount = accountsToFetch[i];
122
- const stakeAccountBalance = accountsBalances[i] - TRANSIENT_STAKE_ACCOUNT_RENT_EXEMPTION;
123
- if (stakeAccountBalance > 0) {
124
- activeValidators.push({ isPreferred, balance: stakeAccountBalance, pk: stakeAccount });
125
- }
126
- const transientAccount = accountsToFetch[i + 1];
127
- const transientAccountBalance = accountsBalances[i + 1] - TRANSIENT_STAKE_ACCOUNT_RENT_EXEMPTION;
128
- if (transientAccountBalance > 0) {
129
- transientValidators.push({ isPreferred, balance: transientAccountBalance, pk: transientAccount });
130
- }
131
- i += 2;
132
- }
133
- // Sorting descending based on balance, but preferred validators should always be used first
134
- activeValidators.sort((a, b) => {
135
- if (a.isPreferred) {
136
- return -1;
137
- }
138
- if (b.isPreferred) {
139
- return 1;
140
- }
141
- return b.balance - a.balance;
142
- });
143
- transientValidators.sort((a, b) => {
144
- if (a.isPreferred) {
145
- return -1;
146
- }
147
- if (b.isPreferred) {
148
- return 1;
149
- }
150
- return b.balance - a.balance;
151
- });
152
- const allCandidates = activeValidators.concat(transientValidators);
153
-
154
- // Add reserve stake account at the end as that should be used only if no validators have enough stake
155
- const reserveStakeBalance = (await connection.getBalance(stakedSolPool.reserveStake)) - STAKE_ACCOUNT_RENT_EXEMPTION;
156
- if (reserveStakeBalance > 0) {
157
- allCandidates.push({
158
- isPreferred: false,
159
- balance: reserveStakeBalance,
160
- pk: stakedSolPool.reserveStake,
161
- });
162
- }
163
- return allCandidates;
164
- }
165
-
166
- export async function getWithdrawCandidates(
167
- connection: Connection,
168
- stakedSolPool: StakePool,
169
- stakedSolPoolPk: PublicKey,
170
- stakedSolToDeposit: BN
171
- ): Promise<Array<PublicKey>> {
172
- const allCandidates = await getAllWithdrawCandidatesSorted(connection, stakedSolPool, stakedSolPoolPk);
173
-
174
- let stakedSolRemaining = stakedSolToDeposit;
175
- let solToWithdraw = new BN(0);
176
- const withdrawCandidates: Array<PublicKey> = [];
177
-
178
- // Try to withdraw all of the SOL from validators' active/transient accounts
179
- for (const candidate of allCandidates) {
180
- if (stakedSolRemaining.isZero()) {
181
- break;
182
- }
183
-
184
- // See how much the validator balance is worth in staked sol
185
- // but limit to amount of needed stake sol
186
- let stakedSolAmountToWithdraw = BN.min(
187
- stakedSolRemaining,
188
- solToStakePoolTokensWithInverseFee(stakedSolPool, new BN(candidate.balance))
189
- );
190
- // Convert it back to staked sol so we get the real amount
191
- let actualSolAmount = calcLamportsWithdrawAmount(stakedSolPool, stakedSolAmountToWithdraw);
192
-
193
- const remainingSolAmount = calcLamportsWithdrawAmount(
194
- stakedSolPool,
195
- stakedSolRemaining.sub(stakedSolAmountToWithdraw)
196
- );
197
-
198
- // If the current validator uses up all of the remaining staked sol except some minimum that we need
199
- // in order to split_stake, then leave at least the minimum required to be consumed by another validator
200
- if (!remainingSolAmount.isZero() && remainingSolAmount < new BN(MINIMUM_ACTIVE_STAKE)) {
201
- stakedSolAmountToWithdraw = stakedSolAmountToWithdraw.sub(
202
- solToStakePoolTokensWithInverseFee(stakedSolPool, new BN(MINIMUM_ACTIVE_STAKE))
203
- );
204
- actualSolAmount = calcLamportsWithdrawAmount(stakedSolPool, stakedSolAmountToWithdraw);
205
- }
206
-
207
- if (actualSolAmount < new BN(MINIMUM_ACTIVE_STAKE) && !candidate.pk.equals(stakedSolPool.reserveStake)) {
208
- // Skip if the amount to withdraw is less than the minimum required for a valid stake
209
- continue;
210
- }
211
-
212
- // Update stake_pool so simulation stays true to what happens on chain
213
- stakedSolRemaining = stakedSolRemaining.sub(stakedSolAmountToWithdraw);
214
- solToWithdraw = solToWithdraw.add(actualSolAmount);
215
- stakedSolPool.totalLamports = stakedSolPool.totalLamports.sub(actualSolAmount);
216
- stakedSolPool.poolTokenSupply = stakedSolPool.poolTokenSupply.sub(
217
- stakePoolTokensMinusFee(stakedSolPool, stakedSolAmountToWithdraw)
218
- );
219
- withdrawCandidates.push(candidate.pk);
220
- }
221
-
222
- return withdrawCandidates;
223
- }
224
-
225
- function calcPoolTokensStakeWithdrawalFee(stakedSolPool: StakePool, stakedSolAmountToWithdraw: BN): BN {
226
- const denominator = stakedSolPool.stakeWithdrawalFee.denominator;
227
- if (denominator.isZero()) {
228
- return new BN(0);
229
- }
230
- const numerator = stakedSolAmountToWithdraw.mul(stakedSolPool.stakeWithdrawalFee.numerator);
231
- const poolTokens = numerator.add(denominator).sub(new BN(1)).div(denominator);
232
- return poolTokens;
233
- }
234
-
235
- function stakePoolTokensMinusFee(stakedSolPool: StakePool, stakedSolAmountToWithdraw: BN): BN {
236
- const stakedSolFee = calcPoolTokensStakeWithdrawalFee(stakedSolPool, stakedSolAmountToWithdraw);
237
- return stakedSolAmountToWithdraw.sub(stakedSolFee);
238
- }
239
-
240
- function solToStakePoolTokensWithInverseFee(stakedSolPool: StakePool, sol: BN): BN {
241
- let poolTokens = calcPoolTokensForDeposit(stakedSolPool, sol);
242
- if (!stakedSolPool.stakeWithdrawalFee.numerator.isZero()) {
243
- const numerator = poolTokens.mul(stakedSolPool.stakeWithdrawalFee.denominator);
244
- const denominator = stakedSolPool.stakeWithdrawalFee.denominator.sub(stakedSolPool.stakeWithdrawalFee.numerator);
245
- if (denominator.isZero()) {
246
- // If the pool has 100% fee for some reason just fail it, we cannot compute the inverse
247
- throw new Error('Pool fee cannot be 100%');
248
- }
249
- poolTokens = numerator.div(denominator);
250
- }
251
- return poolTokens;
252
- }
253
-
254
- // Below functions/types are not exported from spl-stake-pool
255
-
256
- /**
257
- * Generates the withdraw authority program address for the stake pool
258
- */
259
- export async function findWithdrawAuthorityProgramAddress(
260
- programId: PublicKey,
261
- stakePoolAddress: PublicKey,
262
- ) {
263
- const [publicKey] = await PublicKey.findProgramAddress(
264
- [stakePoolAddress.toBuffer(), Buffer.from('withdraw')],
265
- programId,
266
- );
267
- return publicKey;
268
- }
269
-
270
- export async function findStakeProgramAddress(
271
- programId: PublicKey,
272
- voteAccountAddress: PublicKey,
273
- stakedSolPoolPk: PublicKey,
274
- seed: number
275
- ): Promise<PublicKey> {
276
- const [publicKey] = await PublicKey.findProgramAddress(
277
- [
278
- voteAccountAddress.toBuffer(),
279
- stakedSolPoolPk.toBuffer(),
280
- seed ? new BN(seed).toArrayLike(Buffer, 'le', 4) : Buffer.alloc(0),
281
- ],
282
- programId
283
- );
284
- return publicKey;
285
- }
286
-
287
- export async function findTransientStakeProgramAddress(
288
- programId: PublicKey,
289
- voteAccountAddress: PublicKey,
290
- stakePoolAddress: PublicKey,
291
- seed: BN
292
- ) {
293
- const [publicKey] = await PublicKey.findProgramAddress(
294
- [
295
- TRANSIENT_STAKE_SEED_PREFIX,
296
- voteAccountAddress.toBuffer(),
297
- stakePoolAddress.toBuffer(),
298
- seed.toArrayLike(Buffer, 'le', 8),
299
- ],
300
- programId
301
- );
302
- return publicKey;
303
- }
304
-
305
- function calcPoolTokensForDeposit(stakePool: StakePool, stakeLamports: BN): BN {
306
- if (stakePool.poolTokenSupply.isZero() || stakePool.totalLamports.isZero()) {
307
- return stakeLamports;
308
- }
309
- const numerator = stakeLamports.mul(stakePool.poolTokenSupply);
310
- return numerator.div(stakePool.totalLamports);
311
- }
312
-
313
- export function calcLamportsWithdrawAmount(stakePool: StakePool, poolTokens: BN): BN {
314
- const numerator = poolTokens.mul(stakePool.totalLamports);
315
- const denominator = stakePool.poolTokenSupply;
316
- if (numerator.lt(denominator)) {
317
- return new BN(0);
318
- }
319
- return numerator.div(denominator);
320
- }
321
-
322
- export declare const BigNumFromString: import('superstruct').Struct<BN, null>;
323
- export declare const PublicKeyFromString: import('superstruct').Struct<PublicKey, null>;
324
- export const StakeAccountType = enums(['uninitialized', 'initialized', 'delegated', 'rewardsPool']);
325
-
326
- export type StakeMeta = Infer<typeof StakeMeta>;
327
- export const StakeMeta = type({
328
- rentExemptReserve: BigNumFromString,
329
- authorized: type({
330
- staker: PublicKeyFromString,
331
- withdrawer: PublicKeyFromString,
332
- }),
333
- lockup: type({
334
- unixTimestamp: number(),
335
- epoch: number(),
336
- custodian: PublicKeyFromString,
337
- }),
338
- });
339
-
340
- export type StakeAccountInfo = Infer<typeof StakeAccountInfo>;
341
- export const StakeAccountInfo = type({
342
- meta: StakeMeta,
343
- stake: nullable(
344
- type({
345
- delegation: type({
346
- voter: PublicKeyFromString,
347
- stake: BigNumFromString,
348
- activationEpoch: BigNumFromString,
349
- deactivationEpoch: BigNumFromString,
350
- warmupCooldownRate: number(),
351
- }),
352
- creditsObserved: number(),
353
- })
354
- ),
355
- });
356
-
357
- export type StakeAccount = Infer<typeof StakeAccount>;
358
- export const StakeAccount = type({
359
- type: StakeAccountType,
360
- info: StakeAccountInfo,
361
- });