@streamflow/staking 8.2.2 → 8.3.1

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
@@ -77,7 +77,6 @@ await client.searchStakeEntries({ payer, stakePool }) // returns all stake entri
77
77
  await client.searchRewardPools({ stakePool, mint })
78
78
 
79
79
  await client.searchRewardEntries({ stakeEntry, rewardPool })
80
-
81
80
  ```
82
81
 
83
82
  #### Create a staking pool
@@ -87,6 +86,11 @@ const client = new SolanaStakingClient({
87
86
  clusterUrl: "https://api.mainnet-beta.solana.com",
88
87
  cluster: ICluster.Mainnet
89
88
  });
89
+ /*
90
+ invoker should be of type SignerWalletAdapter | Keypair
91
+ computePrice and computeLimit are optional
92
+ */
93
+ const extParams = { invoker, computePrice: 10_000, computeLimit: 'autoSimulate' };
90
94
  /*
91
95
  Rewards Multiplier powered by 10^9.
92
96
  Example: if multiplier is 2_000_000_000 than stakes for maxDuration will have 2x more rewards than stakes for minDuration
@@ -116,8 +120,8 @@ const { metadataId: stakePoolPda } = await client.createStakePool({
116
120
  minDuration,
117
121
  mint: MINT_ADDRESS,
118
122
  permissionless,
119
- nonce:
120
- })
123
+ nonce,
124
+ }, extParams)
121
125
 
122
126
  ```
123
127
 
@@ -158,18 +162,17 @@ const permissionless = true;
158
162
  const freezeStakeMint = true;
159
163
 
160
164
  client.createRewardPool({
161
- nonce,
162
- rewardAmount,
163
- rewardPeriod,
164
- rewardMint,
165
- permissionless,
166
- freezeStakeMint,
167
- stakePool: stakePoolPda,
168
- stakePoolMint: MINT_ADDRESS,
169
- })
165
+ nonce,
166
+ rewardAmount,
167
+ rewardPeriod,
168
+ rewardMint,
169
+ permissionless,
170
+ freezeStakeMint,
171
+ stakePool: stakePoolPda,
172
+ stakePoolMint: MINT_ADDRESS,
173
+ }, extParams)
170
174
  ```
171
175
 
172
-
173
176
  #### Reward Amount configuration (in-depth)
174
177
 
175
178
  `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.
@@ -215,9 +218,31 @@ We recommend to use the `calculateRewardAmountFromRate` function exposed by the
215
218
  const nonce = 0;
216
219
  const amount = new BN(1000); // tokens to stake
217
220
  const duration = new BN(86400 * 2) // 2 days, must be in the range of stakePool's min and max durations
218
- await client.stake({ nonce, amount, duration, stakePool, stakePoolMint });
221
+ await client.stake({ nonce, amount, duration, stakePool, stakePoolMint }, extParams);
222
+
223
+ // Create Reward Entry to track rewards, call instruction for every reward pool on `stake`
224
+ await client.createRewardEntry({ stakePool, rewardPoolNonce, depositNonce: nonce, rewardMint }, extParams);
225
+ ```
226
+
227
+ > [!WARNING]
228
+ > For every Reward Pool a Reward entry should be created prior to claim and ideally at the same time when user stakes. Without a Reward Entry pool won't be able to properly track reward distribution.
229
+
230
+ You can also bundle multiple instructions with `prepare` calls to stake and create entries in one transaction:
231
+
232
+ ```typescript
233
+ const nonce = 1;
234
+ const stakeIxs = await client.prepareStakeInstructions({ nonce, amount, duration, stakePool, stakePoolMint }, extParams);
235
+ const rewardPoolNonce1 = 0;
236
+ const rewardPoolNonce2 = 1;
237
+ const reward1Ixs = await this.prepareCreateRewardEntryInstructions({ stakePool, rewardPoolNonce: rewardPoolNonce1, depositNonce: nonce, rewardMint }, extParams);
238
+ const reward2Ixs = await this.prepareCreateRewardEntryInstructions({ stakePool, rewardPoolNonce: rewardPoolNonce2, depositNonce: nonce, rewardMint }, extParams);
239
+
240
+ await client.execute([...stakeIxs, ...reward1Ixs, ...reward2Ixs, ], extParams);
219
241
  ```
220
242
 
243
+ > [!NOTE]
244
+ > `execute` method will bundle instructions in a transaction, estimate compute price and execute the transaction.
245
+
221
246
  #### Unstake/Withdraw to a stake pool
222
247
  ```typescript
223
248
  /*
@@ -231,6 +256,9 @@ await client.stake({ nonce, amount, duration, stakePool, stakePoolMint });
231
256
  */
232
257
  const nonce = 0; //
233
258
  await client.unstake({ stakePool, stakePoolMint, nonce });
259
+
260
+ // Done separately, returns rent fee back to the user
261
+ await client.closeStakeEntry({ stakePool, nonce })
234
262
  ```
235
263
 
236
264
  #### Claim a reward
@@ -251,6 +279,65 @@ await client.claimRewards({
251
279
  > For instance, prepareClaimRewardsInstructions.
252
280
  > These APIs allow to aggregate multiple operations in a single transaction according to the app needs.
253
281
 
282
+ ### Grouped actions
283
+
284
+ Client also exposes methods to group staking/unstaking with reward pool actions.
285
+
286
+ ```typescript
287
+ /// Will stake into a Stake Pool and create Reward Entries for every passed pool - reward entries are used to track rewards, ideally should be created right after staking.
288
+ {
289
+ const { txId } = await client.stakeAndCreateEntries({
290
+ stakePool,
291
+ stakePoolMint: mint,
292
+ amount: new BN(1),
293
+ duration: new BN(0),
294
+ nonce: stakeNonce,
295
+ rewardPools: [{
296
+ nonce: 0,
297
+ mint,
298
+ rewardPoolType: "fixed",
299
+ }]
300
+ }, extParams);
301
+ console.log("Stake signature: ", txId);
302
+ }
303
+
304
+ // Performs multiple actions needed to fully unstake:
305
+ // 1. Claims all unclaimed rewards from all passed pools
306
+ // 2. Unstakes from a Stake Pool and closes the stake entry
307
+ // 3. Closes Reward Entries, returning the rent fee back
308
+ {
309
+ const { txId } = await client.unstakeAndClaim({
310
+ stakePool,
311
+ stakePoolMint: mint,
312
+ nonce: stakeNonce,
313
+ rewardPools: [{
314
+ nonce: 0,
315
+ mint,
316
+ rewardPoolType: "fixed"
317
+ }]
318
+ }, extParams);
319
+ console.log("Unstake signature: ", txId);
320
+ }
321
+
322
+ // Useful when user can't claim rewards, but wants to unstake and close all created entries.
323
+ {
324
+ const { txId } = await client.unstakeAndClose({
325
+ stakePool,
326
+ stakePoolMint: mint,
327
+ nonce: stakeNonce,
328
+ rewardPools: [{
329
+ nonce: 0,
330
+ mint,
331
+ rewardPoolType: "fixed"
332
+ }]
333
+ }, extParams);
334
+ console.log("Unstake signature: ", txId);
335
+ }
336
+ ```
337
+
338
+ > [!Note]
339
+ > Transactions can become quite large if you have many rewards pools, that can make it impossible to do all actions in 1 transaction - in this case please stick with `prepare` methods to build custom instructions and execute them with `execute`.
340
+
254
341
  ### Set Token Metadata
255
342
 
256
343
  SolanaStakingClient also exposes original IDL of all programs, so you can use some additional instructions, that are not wrapped by the client. Currently there is no method to update Token Metadata of the Staking Mint that stakers get in return for their stake, but you can call the instructions from the original IDL like so:
@@ -274,9 +361,8 @@ ix = await program.methods.setTokenMetadataT22("sToken", "sTST", "https://arweav
274
361
  authority: keypair.publicKey
275
362
  }).instruction();
276
363
 
277
- const { tx, hash, context } = await prepareTransaction(client.connection, [ix], keypair.publicKey);
278
- const sig = await signAndExecuteTransaction(client.connection, keypair, tx, { hash, context }, {});
279
- console.log(sig);
364
+ const { signature } = await client.execute([ix], {invoker: keypair});
365
+ console.log(signature);
280
366
  ```
281
367
 
282
368
  ## Appendix