@streamflow/staking 7.0.0-alpha.9 → 7.0.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.
package/README.md CHANGED
@@ -106,7 +106,7 @@ const maxDuration = new BN(86400);
106
106
  const permissionless = false;
107
107
  /*
108
108
  [0;256) derive stake pool PDA account address.
109
- If stake pool with the same mint already exists, it is required to pick a vacant nonce
109
+ If stake pool with the same mint and creator/authority already exists, it is required to pick a vacant nonce
110
110
  */
111
111
  const nonce = 0;
112
112
 
@@ -123,6 +123,8 @@ const { metadataId: stakePoolPda } = await client.createStakePool({
123
123
 
124
124
  #### Create a rewardPool pool
125
125
  ```typescript
126
+ import { calculateRewardAmountFromRate } from "@streamflow/staking";
127
+
126
128
  /*
127
129
  [0;256) derive reward pool PDA account address.
128
130
  If reward pool with the same mint already exists, it is required to pick a vacant nonce
@@ -132,6 +134,14 @@ const nonce = 0;
132
134
  Amount of rewarding tokens stakers get in return for staking exactly 1 token to the staking pool
133
135
  */
134
136
  const rewardAmount = new BN(100);
137
+ /*
138
+ Alternatively you may want to calculate the correct reward amount from desired reward rate taking into account stake pool and reward pools tokes decimals
139
+ */
140
+ const rewardRate = 0.0025;
141
+ const stakeTokenDecimals = 9;
142
+ const rewardTokenDecimals = 6;
143
+ // For every effectively Staked 1 WHOLE token 0.0025 of Reward Token will be distributed
144
+ const rewardAmount = calculateRewardAmountFromRate(rewardRate, stakeTokenDecimals, rewardTokenDecimals);
135
145
  /*
136
146
  1 day - Unix time in seconds. Period for rewarding stakers. Period starts counting from the moment of staking
137
147
  */
@@ -154,6 +164,42 @@ client.createRewardPool({
154
164
  ```
155
165
 
156
166
 
167
+ #### Reward Amount configuration (in-depth)
168
+
169
+ `rewardAmount` represents a 10^9 fraction of a raw token distributed for every **effective staked raw token** - it's important to account for both reward and stake token decimals when creating staking pool because of that.
170
+
171
+ Example with only raw tokens: if `rewardAmount` is configured to be `1_000` and user staked `1_000_000_000` Raw Tokens with a weight of `2` (in the actual protocol this number will be represented as `2_000_000_000`), it means that the effective number of raw tokens staked is `2_000_000_000` and on every reward distribution user will get `2_000_000_000 * 1_000 / 10^9 = 200` Raw Tokens;
172
+
173
+ Examples with decimals:
174
+
175
+ RT - Reward Token
176
+ ST - Stake Pool Token
177
+ P - fixed `rewardAmount` precision of 9
178
+
179
+ User wants to set reward amount of `0.003` for every effective staked whole token, depending on number of decimals RT and ST have configuration may look different:
180
+
181
+ 1. RT with 6 decimals, ST with 6 decimals.
182
+ - `0.003` of RT is `3_000` raw tokens;
183
+ - ST has 6 decimals while P is 9, therefore `9 - 6 = 3`;
184
+ - We need to add 3 decimals to the `rewardAmount` for proper distribution making it `3_000_000`;
185
+ 2. RT with 12 decimals, ST with 12 decimals.
186
+ - `0.003` of RT is `3_000_000_000` raw tokens;
187
+ - ST has 12 decimals while P is 9, therefore `9 - 12 = -3`;
188
+ - We need to remove decimals from the raw token to be distributed making `rewardAmount` = `3_000_000`;
189
+ 3. RT with 5 decimals, ST with 7 decimals.
190
+ - `0.003` of RT is `300` raw tokens;
191
+ - ST has 7 decimals while P is 9, therefore `9 - 7 = 2`;
192
+ - We need to add 2 decimals making `rewardAmount` = `30_000`;
193
+ 4. RT with 9 decimals, ST with 3 decimals.
194
+ - `0.003` of RT is `3_000_000` raw tokens;
195
+ - the difference between RT and ST decimals is `9 - 3 = 6`;
196
+ - ST has 3 decimals while P is 9, therefore `9 - 3 = 6`;
197
+ - We need to add 6 decimals making `rewardAmount` = `3_000_000_000_000`;
198
+
199
+ We recommend to use the `calculateRewardAmountFromRate` function exposed by the sdk for the correct reward amount configuration.
200
+
201
+ **Also, some configurations where there is big difference between Stake Pool and Reward Pool token decimals may be unsupported, in this case the function will return 0, so be aware.**
202
+
157
203
  #### Deposit/Stake to a stake pool
158
204
  ```typescript
159
205
  /*
@@ -213,4 +259,4 @@ Streamflow Staking protocol program IDs
213
259
 
214
260
  ### IDLs
215
261
  For further details you can consult with IDLs of protocols available at:
216
- `@streamflow/staking/dist/esm/solana/descriptor`
262
+ `@streamflow/staking/dist/esm/solana/descriptor`
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const common_1 = require("@streamflow/common");
7
+ const web3_js_1 = require("@solana/web3.js");
8
+ // eslint-disable-next-line no-restricted-imports
9
+ const bn_js_1 = __importDefault(require("bn.js"));
10
+ const vitest_1 = require("vitest");
11
+ const rewards_js_1 = require("../../solana/lib/rewards.js");
12
+ const constants_js_1 = require("../../solana/constants.js");
13
+ const populateRewardEntry = (effectiveStakedAmount, rewardAmount, rewardPeriod, periods) => {
14
+ const rewardEntry = new rewards_js_1.RewardEntryAccumulator(new bn_js_1.default(0), new bn_js_1.default(0), new bn_js_1.default(0), web3_js_1.PublicKey.default, web3_js_1.PublicKey.default, new bn_js_1.default(0), new bn_js_1.default(0), new bn_js_1.default(0), []);
15
+ if (effectiveStakedAmount && rewardAmount && rewardPeriod) {
16
+ rewardEntry.accountedAmount = rewardEntry.getAccountableAmount(new bn_js_1.default(0), rewardPeriod.muln(periods || 1), effectiveStakedAmount, rewardAmount, rewardPeriod);
17
+ }
18
+ return rewardEntry;
19
+ };
20
+ (0, vitest_1.describe)("RewardEntryAccumulator", () => {
21
+ (0, vitest_1.describe)("getClaimableAmount", () => {
22
+ const testCases = [
23
+ [9, 9, 1, 0.0025, new bn_js_1.default(2500000)],
24
+ [6, 9, 1, 0.0025, new bn_js_1.default(2500000000)],
25
+ [9, 6, 1, 0.0025, new bn_js_1.default(2500)],
26
+ [1, 8, 1, 0.0025, new bn_js_1.default(25000000000000)],
27
+ ];
28
+ testCases.forEach(([stakeTokenDecimals, rewardTokenDecimals, periods, rewardRate, expectedRewardAmount]) => {
29
+ (0, vitest_1.test)(`test decimals - ${stakeTokenDecimals}/${rewardTokenDecimals}/${periods}/${rewardRate}`, () => {
30
+ const stakedAmount = (0, common_1.getBN)(1, stakeTokenDecimals);
31
+ const effectiveStakedAmount = stakedAmount.mul(constants_js_1.SCALE_PRECISION_FACTOR_BN);
32
+ const rewardPeriod = new bn_js_1.default(1);
33
+ const rewardAmount = (0, rewards_js_1.calculateRewardAmountFromRate)(rewardRate, stakeTokenDecimals, rewardTokenDecimals);
34
+ const rewardEntry = populateRewardEntry(effectiveStakedAmount, rewardAmount, rewardPeriod, periods);
35
+ const claimableAmount = rewardEntry.getClaimableAmount();
36
+ (0, vitest_1.expect)(rewardAmount.toString()).toEqual(expectedRewardAmount.toString());
37
+ (0, vitest_1.expect)(claimableAmount.toString()).toEqual((0, common_1.getBN)(rewardRate, rewardTokenDecimals).muln(periods).toString());
38
+ (0, vitest_1.expect)((0, rewards_js_1.calculateRewardRateFromAmount)(rewardAmount, stakeTokenDecimals, rewardTokenDecimals)).toEqual(rewardRate);
39
+ });
40
+ });
41
+ (0, vitest_1.test)(`test decimals - negative difference`, () => {
42
+ let rewardAmount = (0, rewards_js_1.calculateRewardAmountFromRate)(0.0025, 18, 1);
43
+ (0, vitest_1.expect)(rewardAmount.toString()).toEqual(new bn_js_1.default(0).toString());
44
+ rewardAmount = (0, rewards_js_1.calculateRewardAmountFromRate)(0.0025, 12, 4);
45
+ (0, vitest_1.expect)(rewardAmount.toString()).toEqual(new bn_js_1.default(0).toString());
46
+ });
47
+ (0, vitest_1.test)(`test decimals - precision loss`, () => {
48
+ const stakeTokenDecimals = 12;
49
+ const rewardTokenDecimals = 6;
50
+ const stakedAmount = (0, common_1.getBN)(1, stakeTokenDecimals);
51
+ const effectiveStakedAmount = stakedAmount.mul(constants_js_1.SCALE_PRECISION_FACTOR_BN);
52
+ const rewardPeriod = new bn_js_1.default(1);
53
+ const rewardAmount = (0, rewards_js_1.calculateRewardAmountFromRate)(0.0025, stakeTokenDecimals, rewardTokenDecimals);
54
+ const rewardEntry = populateRewardEntry(effectiveStakedAmount, rewardAmount, rewardPeriod);
55
+ const claimableAmount = rewardEntry.getClaimableAmount();
56
+ (0, vitest_1.expect)(rewardAmount.toString()).toEqual(new bn_js_1.default(2).toString());
57
+ (0, vitest_1.expect)(claimableAmount.toString()).toEqual((0, common_1.getBN)(0.002, rewardTokenDecimals).toString());
58
+ (0, vitest_1.expect)((0, rewards_js_1.calculateRewardRateFromAmount)(rewardAmount, stakeTokenDecimals, rewardTokenDecimals)).toEqual(0.002);
59
+ });
60
+ });
61
+ });
package/dist/cjs/index.js CHANGED
@@ -25,15 +25,13 @@ var __importStar = (this && this.__importStar) || function (mod) {
25
25
  __setModuleDefault(result, mod);
26
26
  return result;
27
27
  };
28
- var __importDefault = (this && this.__importDefault) || function (mod) {
29
- return (mod && mod.__esModule) ? mod : { "default": mod };
30
- };
31
28
  Object.defineProperty(exports, "__esModule", { value: true });
32
29
  exports.constants = exports.SolanaStakingClient = void 0;
33
30
  var client_js_1 = require("./solana/client.js");
34
- Object.defineProperty(exports, "SolanaStakingClient", { enumerable: true, get: function () { return __importDefault(client_js_1).default; } });
35
- __exportStar(require("./solana/utils.js"), exports);
31
+ Object.defineProperty(exports, "SolanaStakingClient", { enumerable: true, get: function () { return client_js_1.SolanaStakingClient; } });
36
32
  __exportStar(require("./solana/types.js"), exports);
37
33
  __exportStar(require("./solana/lib/derive-accounts.js"), exports);
38
34
  __exportStar(require("./solana/lib/rewards.js"), exports);
35
+ __exportStar(require("./solana/lib/fee-amounts.js"), exports);
36
+ __exportStar(require("./solana/lib/stake-weight.js"), exports);
39
37
  exports.constants = __importStar(require("./solana/constants.js"));
@@ -3,6 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.SolanaStakingClient = void 0;
6
7
  const anchor_1 = require("@coral-xyz/anchor");
7
8
  const spl_token_1 = require("@solana/spl-token");
8
9
  const web3_js_1 = require("@solana/web3.js");
@@ -44,7 +45,7 @@ class SolanaStakingClient {
44
45
  }
45
46
  getCurrentProgramId(programKey) {
46
47
  const program = this.programs[programKey];
47
- invariant(program, `Program ${programKey} is not found`);
48
+ (0, common_1.invariant)(program, `Program ${programKey} is not found`);
48
49
  return program.programId;
49
50
  }
50
51
  getCommitment() {
@@ -56,7 +57,7 @@ class SolanaStakingClient {
56
57
  }
57
58
  async searchStakePools(criteria = {}) {
58
59
  const { stakePoolProgram } = this.programs;
59
- return stakePoolProgram.account.stakePool.all(getFilters(criteria, constants_js_1.STAKE_POOL_BYTE_OFFSETS));
60
+ return stakePoolProgram.account.stakePool.all((0, solana_1.getFilters)(criteria, constants_js_1.STAKE_POOL_BYTE_OFFSETS));
60
61
  }
61
62
  async getStakeEntry(id) {
62
63
  const { stakePoolProgram } = this.programs;
@@ -64,15 +65,27 @@ class SolanaStakingClient {
64
65
  }
65
66
  async searchStakeEntries(criteria = {}) {
66
67
  const { stakePoolProgram } = this.programs;
67
- return stakePoolProgram.account.stakeEntry.all(getFilters(criteria, constants_js_1.STAKE_ENTRY_BYTE_OFFSETS));
68
+ return stakePoolProgram.account.stakeEntry.all((0, solana_1.getFilters)(criteria, constants_js_1.STAKE_ENTRY_BYTE_OFFSETS));
68
69
  }
69
70
  async searchRewardPools(criteria = {}) {
70
71
  const { rewardPoolProgram } = this.programs;
71
- return rewardPoolProgram.account.rewardPool.all(getFilters(criteria, constants_js_1.REWARD_POOL_BYTE_OFFSETS));
72
+ return rewardPoolProgram.account.rewardPool.all((0, solana_1.getFilters)(criteria, constants_js_1.REWARD_POOL_BYTE_OFFSETS));
72
73
  }
73
74
  async searchRewardEntries(criteria) {
74
75
  const { rewardPoolProgram } = this.programs;
75
- return rewardPoolProgram.account.rewardEntry.all(getFilters(criteria, constants_js_1.REWARD_ENTRY_BYTE_OFFSETS));
76
+ return rewardPoolProgram.account.rewardEntry.all((0, solana_1.getFilters)(criteria, constants_js_1.REWARD_ENTRY_BYTE_OFFSETS));
77
+ }
78
+ async getFee(target) {
79
+ const perTargetFee = await this.getFeeValueIfExists(target);
80
+ if (perTargetFee) {
81
+ return perTargetFee;
82
+ }
83
+ return this.getDefaultFeeValue();
84
+ }
85
+ getDefaultFeeValue() {
86
+ const { feeManagerProgram } = this.programs;
87
+ const feeValueKey = (0, derive_accounts_js_1.deriveConfigPDA)(feeManagerProgram.programId);
88
+ return feeManagerProgram.account.config.fetch(feeValueKey);
76
89
  }
77
90
  getFeeValueIfExists(target) {
78
91
  const { feeManagerProgram } = this.programs;
@@ -91,7 +104,7 @@ class SolanaStakingClient {
91
104
  async prepareCreateStakePoolInstructions({ maxWeight, maxDuration, minDuration, mint, permissionless = false, nonce, tokenProgramId = spl_token_1.TOKEN_PROGRAM_ID, }, extParams) {
92
105
  const { stakePoolProgram } = this.programs;
93
106
  const creator = extParams.invoker.publicKey;
94
- invariant(creator, "Undefined invoker publicKey");
107
+ (0, common_1.invariant)(creator, "Undefined invoker publicKey");
95
108
  const createInstruction = await stakePoolProgram.methods
96
109
  .createPool(nonce, maxWeight, minDuration, maxDuration, permissionless)
97
110
  .accounts({
@@ -100,7 +113,7 @@ class SolanaStakingClient {
100
113
  tokenProgram: tokenProgramId,
101
114
  })
102
115
  .instruction();
103
- const stakePoolPDA = (0, derive_accounts_js_1.deriveStakePoolPDA)(stakePoolProgram.programId, pk(mint), creator, nonce);
116
+ const stakePoolPDA = (0, derive_accounts_js_1.deriveStakePoolPDA)(stakePoolProgram.programId, (0, solana_1.pk)(mint), creator, nonce);
104
117
  return { ixs: [createInstruction], publicKey: stakePoolPDA };
105
118
  }
106
119
  async stake(data, extParams) {
@@ -114,10 +127,10 @@ class SolanaStakingClient {
114
127
  async prepareStakeInstructions({ nonce, amount, duration, stakePool, stakePoolMint, tokenProgramId = spl_token_1.TOKEN_PROGRAM_ID }, extParams) {
115
128
  const { stakePoolProgram } = this.programs;
116
129
  const staker = extParams.invoker.publicKey;
117
- invariant(staker, "Undefined invoker publicKey");
118
- const mint = (0, derive_accounts_js_1.deriveStakeMintPDA)(stakePoolProgram.programId, pk(stakePool));
119
- const stakeMintAccountKey = (0, spl_token_1.getAssociatedTokenAddressSync)(mint, staker, false, pk(tokenProgramId));
120
- const poolMintAccountKey = (0, spl_token_1.getAssociatedTokenAddressSync)(pk(stakePoolMint), staker, false, pk(tokenProgramId));
130
+ (0, common_1.invariant)(staker, "Undefined invoker publicKey");
131
+ const mint = (0, derive_accounts_js_1.deriveStakeMintPDA)(stakePoolProgram.programId, (0, solana_1.pk)(stakePool));
132
+ const stakeMintAccountKey = (0, spl_token_1.getAssociatedTokenAddressSync)(mint, staker, false, (0, solana_1.pk)(tokenProgramId));
133
+ const poolMintAccountKey = (0, spl_token_1.getAssociatedTokenAddressSync)((0, solana_1.pk)(stakePoolMint), staker, false, (0, solana_1.pk)(tokenProgramId));
121
134
  const instruction = await stakePoolProgram.methods
122
135
  .stake(nonce, amount, duration)
123
136
  .accounts({
@@ -142,11 +155,11 @@ class SolanaStakingClient {
142
155
  async prepareUnstakeInstructions({ stakePool, stakePoolMint, nonce, tokenProgramId = spl_token_1.TOKEN_PROGRAM_ID }, extParams) {
143
156
  const { stakePoolProgram } = this.programs;
144
157
  const staker = extParams.invoker.publicKey;
145
- invariant(staker, "Undefined invoker publicKey");
146
- const stakeMintKey = (0, derive_accounts_js_1.deriveStakeMintPDA)(stakePoolProgram.programId, pk(stakePool));
147
- const stakeEntryKey = (0, derive_accounts_js_1.deriveStakeEntryPDA)(stakePoolProgram.programId, pk(stakePool), staker, nonce);
148
- const poolMintAccountKey = (0, spl_token_1.getAssociatedTokenAddressSync)(pk(stakePoolMint), staker, false, pk(tokenProgramId));
149
- const stakeMintAccountKey = (0, spl_token_1.getAssociatedTokenAddressSync)(stakeMintKey, staker, false, pk(tokenProgramId));
158
+ (0, common_1.invariant)(staker, "Undefined invoker publicKey");
159
+ const stakeMintKey = (0, derive_accounts_js_1.deriveStakeMintPDA)(stakePoolProgram.programId, (0, solana_1.pk)(stakePool));
160
+ const stakeEntryKey = (0, derive_accounts_js_1.deriveStakeEntryPDA)(stakePoolProgram.programId, (0, solana_1.pk)(stakePool), staker, nonce);
161
+ const poolMintAccountKey = (0, spl_token_1.getAssociatedTokenAddressSync)((0, solana_1.pk)(stakePoolMint), staker, false, (0, solana_1.pk)(tokenProgramId));
162
+ const stakeMintAccountKey = (0, spl_token_1.getAssociatedTokenAddressSync)(stakeMintKey, staker, false, (0, solana_1.pk)(tokenProgramId));
150
163
  const instruction = await stakePoolProgram.methods
151
164
  .unstake()
152
165
  .accounts({
@@ -171,7 +184,7 @@ class SolanaStakingClient {
171
184
  async prepareCreateRewardPoolInstructions({ nonce, rewardAmount, rewardPeriod, rewardMint, permissionless = false, stakePool, tokenProgramId = spl_token_1.TOKEN_PROGRAM_ID, }, extParams) {
172
185
  const { rewardPoolProgram } = this.programs;
173
186
  const creator = extParams.invoker.publicKey;
174
- invariant(creator, "Undefined invoker publicKey");
187
+ (0, common_1.invariant)(creator, "Undefined invoker publicKey");
175
188
  const instruction = await rewardPoolProgram.methods
176
189
  .createPool(nonce, rewardAmount, rewardPeriod, permissionless)
177
190
  .accounts({
@@ -181,7 +194,7 @@ class SolanaStakingClient {
181
194
  tokenProgram: tokenProgramId,
182
195
  })
183
196
  .instruction();
184
- const rewardPoolKey = (0, derive_accounts_js_1.deriveRewardPoolPDA)(rewardPoolProgram.programId, pk(stakePool), pk(rewardMint), nonce);
197
+ const rewardPoolKey = (0, derive_accounts_js_1.deriveRewardPoolPDA)(rewardPoolProgram.programId, (0, solana_1.pk)(stakePool), (0, solana_1.pk)(rewardMint), nonce);
185
198
  return { publicKey: rewardPoolKey, ixs: [instruction] };
186
199
  }
187
200
  async claimRewards(data, extParams) {
@@ -195,15 +208,15 @@ class SolanaStakingClient {
195
208
  async prepareClaimRewardsInstructions({ rewardPoolNonce, depositNonce, stakePool, tokenProgramId = spl_token_1.TOKEN_PROGRAM_ID, rewardMint }, extParams) {
196
209
  const { stakePoolProgram, rewardPoolProgram } = this.programs;
197
210
  const staker = extParams.invoker.publicKey;
198
- invariant(staker, "Undefined invoker publicKey");
211
+ (0, common_1.invariant)(staker, "Undefined invoker publicKey");
199
212
  const instruction = await rewardPoolProgram.methods
200
213
  .claimRewards()
201
214
  .accounts({
202
- stakeEntry: (0, derive_accounts_js_1.deriveStakeEntryPDA)(stakePoolProgram.programId, pk(stakePool), staker, depositNonce),
203
- rewardPool: (0, derive_accounts_js_1.deriveRewardPoolPDA)(rewardPoolProgram.programId, pk(stakePool), pk(rewardMint), rewardPoolNonce),
215
+ stakeEntry: (0, derive_accounts_js_1.deriveStakeEntryPDA)(stakePoolProgram.programId, (0, solana_1.pk)(stakePool), staker, depositNonce),
216
+ rewardPool: (0, derive_accounts_js_1.deriveRewardPoolPDA)(rewardPoolProgram.programId, (0, solana_1.pk)(stakePool), (0, solana_1.pk)(rewardMint), rewardPoolNonce),
204
217
  claimant: staker,
205
218
  tokenProgram: tokenProgramId,
206
- to: (0, spl_token_1.getAssociatedTokenAddressSync)(pk(rewardMint), staker, false, pk(tokenProgramId)),
219
+ to: (0, spl_token_1.getAssociatedTokenAddressSync)((0, solana_1.pk)(rewardMint), staker, false, (0, solana_1.pk)(tokenProgramId)),
207
220
  })
208
221
  .instruction();
209
222
  return { ixs: [instruction] };
@@ -219,14 +232,14 @@ class SolanaStakingClient {
219
232
  async prepareFundPoolInstructions({ amount, tokenProgramId = spl_token_1.TOKEN_PROGRAM_ID, rewardMint, stakePool, feeValue, nonce }, extParams) {
220
233
  const { rewardPoolProgram } = this.programs;
221
234
  const staker = extParams.invoker.publicKey;
222
- invariant(staker, "Undefined invoker publicKey");
235
+ (0, common_1.invariant)(staker, "Undefined invoker publicKey");
223
236
  const existingFee = await this.getFeeValueIfExists(staker);
224
- const rewardMintPk = pk(rewardMint);
225
- const tokenProgramPk = pk(tokenProgramId);
237
+ const rewardMintPk = (0, solana_1.pk)(rewardMint);
238
+ const tokenProgramPk = (0, solana_1.pk)(tokenProgramId);
226
239
  const treasuryATA = !existingFee || existingFee.streamflowFee.gtn(0)
227
240
  ? await (0, solana_1.checkOrCreateAtaBatch)(this.connection, [constants_js_1.STREAMFLOW_TREASURY_PUBLIC_KEY], rewardMintPk, extParams.invoker, tokenProgramPk)
228
241
  : null;
229
- const rewardPoolPda = (0, derive_accounts_js_1.deriveRewardPoolPDA)(rewardPoolProgram.programId, pk(stakePool), rewardMintPk, nonce);
242
+ const rewardPoolPda = (0, derive_accounts_js_1.deriveRewardPoolPDA)(rewardPoolProgram.programId, (0, solana_1.pk)(stakePool), rewardMintPk, nonce);
230
243
  const instruction = await rewardPoolProgram.methods
231
244
  .fundPool(amount)
232
245
  .accountsPartial({
@@ -252,18 +265,51 @@ class SolanaStakingClient {
252
265
  async prepareCreateRewardEntryInstructions({ stakePoolMint, stakePool, rewardPoolNonce, depositNonce }, extParams) {
253
266
  const { stakePoolProgram, rewardPoolProgram } = this.programs;
254
267
  const staker = extParams.invoker.publicKey;
255
- invariant(staker, "Undefined invoker publicKey");
268
+ (0, common_1.invariant)(staker, "Undefined invoker publicKey");
256
269
  const instruction = await rewardPoolProgram.methods
257
270
  .createEntry()
258
271
  .accounts({
259
272
  payer: staker,
260
273
  authority: staker,
261
- stakeEntry: (0, derive_accounts_js_1.deriveStakeEntryPDA)(stakePoolProgram.programId, pk(stakePool), staker, depositNonce),
262
- rewardPool: (0, derive_accounts_js_1.deriveRewardPoolPDA)(rewardPoolProgram.programId, pk(stakePool), pk(stakePoolMint), rewardPoolNonce),
274
+ stakeEntry: (0, derive_accounts_js_1.deriveStakeEntryPDA)(stakePoolProgram.programId, (0, solana_1.pk)(stakePool), staker, depositNonce),
275
+ rewardPool: (0, derive_accounts_js_1.deriveRewardPoolPDA)(rewardPoolProgram.programId, (0, solana_1.pk)(stakePool), (0, solana_1.pk)(stakePoolMint), rewardPoolNonce),
276
+ })
277
+ .instruction();
278
+ return { ixs: [instruction] };
279
+ }
280
+ async updateRewardPool(data, extParams) {
281
+ const { ixs } = await this.prepareUpdateRewardPoolInstructions(data, extParams);
282
+ const { signature } = await this.execute(ixs, extParams);
283
+ return {
284
+ ixs,
285
+ txId: signature,
286
+ };
287
+ }
288
+ async prepareUpdateRewardPoolInstructions({ rewardPool, rewardAmount, rewardPeriod }, extParams) {
289
+ const { rewardPoolProgram } = this.programs;
290
+ const invoker = extParams.invoker.publicKey;
291
+ (0, common_1.invariant)(invoker, "Undefined invoker publicKey");
292
+ const instruction = await rewardPoolProgram.methods
293
+ .updatePool(rewardAmount, rewardPeriod)
294
+ .accountsPartial({
295
+ authority: invoker,
296
+ rewardPool,
263
297
  })
264
298
  .instruction();
265
299
  return { ixs: [instruction] };
266
300
  }
301
+ decode(programKey, accountName, accInfo) {
302
+ const decodingProgram = this.programs[programKey];
303
+ (0, common_1.invariant)(decodingProgram, `Decoding program with key ${programKey} is not available`);
304
+ return decodingProgram.coder.accounts.decode(accountName.toString(), accInfo);
305
+ }
306
+ getDiscriminator(programKey, accountName) {
307
+ const decodingProgram = this.programs[programKey];
308
+ (0, common_1.invariant)(decodingProgram, `Decoding program with key ${programKey} is not available`);
309
+ const accountEntity = decodingProgram.idl.accounts.find((acc) => acc.name === accountName);
310
+ (0, common_1.invariant)(accountEntity, `Decoding program with key ${programKey} doesn't specify account with name ${accountName.toString()}`);
311
+ return accountEntity.discriminator;
312
+ }
267
313
  async execute(ixs, extParams) {
268
314
  const { tx, hash, context } = await (0, solana_1.prepareTransaction)(this.connection, ixs, extParams.invoker.publicKey);
269
315
  try {
@@ -285,31 +331,4 @@ class SolanaStakingClient {
285
331
  }
286
332
  }
287
333
  }
288
- exports.default = SolanaStakingClient;
289
- function pk(address) {
290
- return typeof address === "string" ? new web3_js_1.PublicKey(address) : address;
291
- }
292
- const prefix = "Assertion failed";
293
- function invariant(condition, message) {
294
- if (condition) {
295
- return;
296
- }
297
- const provided = typeof message === "function" ? message() : message;
298
- const value = provided ? `${prefix}: ${provided}` : prefix;
299
- throw new Error(value);
300
- }
301
- function getFilters(criteria, byteOffsets) {
302
- return Object.entries(criteria).reduce((acc, [key, value]) => {
303
- const criteriaKey = key;
304
- const effectiveByteOffset = byteOffsets[criteriaKey];
305
- if (criteria[criteriaKey] && effectiveByteOffset) {
306
- acc.push({
307
- memcmp: {
308
- offset: effectiveByteOffset,
309
- bytes: value.toString(),
310
- },
311
- });
312
- }
313
- return acc;
314
- }, []);
315
- }
334
+ exports.SolanaStakingClient = SolanaStakingClient;
@@ -1,15 +1,18 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.REWARD_POOL_PROGRAM_ID = exports.STAKE_POOL_PROGRAM_ID = exports.REWARD_ENTRY_BYTE_OFFSETS = exports.REWARD_ENTRY_STAKE_ENTRY_OFFSET = exports.REWARD_ENTRY_REWARD_POOL_OFFSET = exports.REWARD_POOL_BYTE_OFFSETS = exports.REWARD_POOL_MINT_OFFSET = exports.REWARD_POOL_STAKE_POOL_OFFSET = exports.STAKE_POOL_BYTE_OFFSETS = exports.STAKE_POOL_CREATOR_OFFSET = exports.STAKE_POOL_MINT_OFFSET = exports.STAKE_ENTRY_BYTE_OFFSETS = exports.STAKE_ENTRY_OWNER_OFFSET = exports.STAKE_ENTRY_STAKE_POOL_OFFSET = exports.ANCHOR_DISCRIMINATOR_OFFSET = exports.STREAMFLOW_TREASURY_PUBLIC_KEY = exports.FEE_VALUE_PREFIX = exports.CONFIG_PREFIX = exports.REWARD_ENTRY_PREFIX = exports.REWARD_VAULT_PREFIX = exports.REWARD_POOL_PREFIX = exports.STAKE_VAULT_PREFIX = exports.STAKE_MINT_PREFIX = exports.STAKE_POOL_PREFIX = exports.STAKE_ENTRY_PREFIX = exports.STAKE_ENTRY_DISCRIMINATOR = exports.U64_MAX = exports.SCALE_PRECISION_FACTOR_BN = exports.SCALE_PRECISION_FACTOR = exports.DEFAULT_FEE_BN = exports.DEFAULT_FEE = exports.FEE_PRECISION_FACTOR_BN = exports.FEE_PRECISION_FACTOR = void 0;
3
+ exports.FEE_PROGRAM_ID = exports.REWARD_POOL_PROGRAM_ID = exports.STAKE_POOL_PROGRAM_ID = exports.REWARD_ENTRY_BYTE_OFFSETS = exports.REWARD_ENTRY_STAKE_ENTRY_OFFSET = exports.REWARD_ENTRY_REWARD_POOL_OFFSET = exports.REWARD_POOL_BYTE_OFFSETS = exports.REWARD_POOL_MINT_OFFSET = exports.REWARD_POOL_STAKE_POOL_OFFSET = exports.STAKE_POOL_BYTE_OFFSETS = exports.STAKE_POOL_CREATOR_OFFSET = exports.STAKE_POOL_MINT_OFFSET = exports.STAKE_ENTRY_BYTE_OFFSETS = exports.STAKE_ENTRY_OWNER_OFFSET = exports.STAKE_ENTRY_STAKE_POOL_OFFSET = exports.ANCHOR_DISCRIMINATOR_OFFSET = exports.STREAMFLOW_TREASURY_PUBLIC_KEY = exports.FEE_VALUE_PREFIX = exports.CONFIG_PREFIX = exports.REWARD_ENTRY_PREFIX = exports.REWARD_VAULT_PREFIX = exports.REWARD_POOL_PREFIX = exports.STAKE_VAULT_PREFIX = exports.STAKE_MINT_PREFIX = exports.STAKE_POOL_PREFIX = exports.STAKE_ENTRY_PREFIX = exports.STAKE_ENTRY_DISCRIMINATOR = exports.U64_MAX = exports.REWARD_AMOUNT_PRECISION_FACTOR_BN = exports.REWARD_AMOUNT_PRECISION_FACTOR = exports.REWARD_AMOUNT_DECIMALS = exports.SCALE_PRECISION_FACTOR_BN = exports.SCALE_PRECISION_FACTOR = exports.DEFAULT_FEE_BN = exports.DEFAULT_FEE = exports.FEE_PRECISION_FACTOR_BN = exports.FEE_PRECISION_FACTOR = void 0;
4
4
  const anchor_1 = require("@coral-xyz/anchor");
5
5
  const common_1 = require("@streamflow/common");
6
6
  const web3_js_1 = require("@solana/web3.js");
7
7
  exports.FEE_PRECISION_FACTOR = 10000;
8
8
  exports.FEE_PRECISION_FACTOR_BN = new anchor_1.BN(exports.FEE_PRECISION_FACTOR);
9
- exports.DEFAULT_FEE = 99;
9
+ exports.DEFAULT_FEE = 19;
10
10
  exports.DEFAULT_FEE_BN = new anchor_1.BN(exports.DEFAULT_FEE);
11
11
  exports.SCALE_PRECISION_FACTOR = 1000000000;
12
12
  exports.SCALE_PRECISION_FACTOR_BN = new anchor_1.BN(exports.SCALE_PRECISION_FACTOR);
13
+ exports.REWARD_AMOUNT_DECIMALS = 9;
14
+ exports.REWARD_AMOUNT_PRECISION_FACTOR = 1000000000;
15
+ exports.REWARD_AMOUNT_PRECISION_FACTOR_BN = new anchor_1.BN(exports.REWARD_AMOUNT_PRECISION_FACTOR);
13
16
  exports.U64_MAX = 18446744073709551615n;
14
17
  exports.STAKE_ENTRY_DISCRIMINATOR = [187, 127, 9, 35, 155, 68, 86, 40];
15
18
  exports.STAKE_ENTRY_PREFIX = Buffer.from("stake-entry", "utf-8");
@@ -29,7 +32,7 @@ exports.STAKE_ENTRY_BYTE_OFFSETS = {
29
32
  payer: exports.STAKE_ENTRY_OWNER_OFFSET,
30
33
  stakePool: exports.STAKE_ENTRY_STAKE_POOL_OFFSET,
31
34
  };
32
- exports.STAKE_POOL_MINT_OFFSET = exports.ANCHOR_DISCRIMINATOR_OFFSET + 8;
35
+ exports.STAKE_POOL_MINT_OFFSET = exports.ANCHOR_DISCRIMINATOR_OFFSET + 2;
33
36
  exports.STAKE_POOL_CREATOR_OFFSET = exports.STAKE_POOL_MINT_OFFSET + 32;
34
37
  exports.STAKE_POOL_BYTE_OFFSETS = {
35
38
  mint: exports.STAKE_POOL_MINT_OFFSET,
@@ -59,3 +62,9 @@ exports.REWARD_POOL_PROGRAM_ID = {
59
62
  [common_1.ICluster.Testnet]: "RWRDdfRbi3339VgKxTAXg4cjyniF7cbhNbMxZWiSKmj",
60
63
  [common_1.ICluster.Local]: "RWRDdfRbi3339VgKxTAXg4cjyniF7cbhNbMxZWiSKmj",
61
64
  };
65
+ exports.FEE_PROGRAM_ID = {
66
+ [common_1.ICluster.Mainnet]: "FEELzfBhsWXTNJX53zZcDVfRNoFYZQ6cZA3jLiGVL16V",
67
+ [common_1.ICluster.Devnet]: "FEELzfBhsWXTNJX53zZcDVfRNoFYZQ6cZA3jLiGVL16V",
68
+ [common_1.ICluster.Testnet]: "FEELzfBhsWXTNJX53zZcDVfRNoFYZQ6cZA3jLiGVL16V",
69
+ [common_1.ICluster.Local]: "FEELzfBhsWXTNJX53zZcDVfRNoFYZQ6cZA3jLiGVL16V",
70
+ };
@@ -338,8 +338,8 @@
338
338
  "program": {
339
339
  "kind": "const",
340
340
  "value": [
341
- 140, 151, 37, 143, 78, 36, 137, 241, 187, 61, 16, 41, 20, 142, 13, 131, 11, 90, 19, 153, 218,
342
- 255, 16, 132, 4, 142, 123, 216, 219, 233, 248, 89
341
+ 140, 151, 37, 143, 78, 36, 137, 241, 187, 61, 16, 41, 20, 142, 13, 131, 11, 90, 19, 153, 218, 255, 16,
342
+ 132, 4, 142, 123, 216, 219, 233, 248, 89
343
343
  ]
344
344
  }
345
345
  }
@@ -778,9 +778,7 @@
778
778
  },
779
779
  {
780
780
  "name": "effective_amount",
781
- "docs": [
782
- "Effective Amount staked, does not equal to deposited amount, accounts for Stake Weight"
783
- ],
781
+ "docs": ["Effective Amount staked, does not equal to deposited amount, accounts for Stake Weight"],
784
782
  "type": "u128"
785
783
  },
786
784
  {