@streamflow/staking 7.0.0-alpha.9 → 7.0.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 +48 -2
- package/dist/cjs/__tests__/solana/rewards.spec.js +61 -0
- package/dist/cjs/index.js +3 -5
- package/dist/cjs/solana/client.js +76 -57
- package/dist/cjs/solana/constants.js +12 -3
- package/dist/cjs/solana/descriptor/idl/reward_pool.json +3 -5
- package/dist/cjs/solana/descriptor/idl/stake_pool.json +60 -262
- package/dist/cjs/solana/{utils.js → lib/fee-amounts.js} +5 -22
- package/dist/cjs/solana/lib/rewards.js +41 -21
- package/dist/cjs/solana/lib/stake-weight.js +19 -0
- package/dist/esm/__tests__/solana/rewards.spec.d.ts +1 -0
- package/dist/esm/__tests__/solana/rewards.spec.js +56 -0
- package/dist/esm/index.d.ts +3 -2
- package/dist/esm/index.js +3 -2
- package/dist/esm/solana/client.d.ts +14 -3
- package/dist/esm/solana/client.js +50 -32
- package/dist/esm/solana/constants.d.ts +5 -3
- package/dist/esm/solana/constants.js +13 -4
- package/dist/esm/solana/descriptor/idl/reward_pool.json +3 -5
- package/dist/esm/solana/descriptor/idl/stake_pool.json +60 -262
- package/dist/esm/solana/{utils.d.ts → lib/fee-amounts.d.ts} +0 -2
- package/dist/esm/solana/{utils.js → lib/fee-amounts.js} +2 -14
- package/dist/esm/solana/lib/rewards.d.ts +6 -4
- package/dist/esm/solana/lib/rewards.js +38 -22
- package/dist/esm/solana/lib/stake-weight.d.ts +2 -0
- package/dist/esm/solana/lib/stake-weight.js +12 -0
- package/dist/esm/solana/types.d.ts +6 -3
- package/package.json +8 -7
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { PublicKey } from "@solana/web3.js";
|
|
2
2
|
// eslint-disable-next-line no-restricted-imports
|
|
3
3
|
import BN from "bn.js";
|
|
4
|
-
import {
|
|
5
|
-
|
|
4
|
+
import { getBN, getNumberFromBN } from "@streamflow/common";
|
|
5
|
+
import { REWARD_AMOUNT_DECIMALS, REWARD_AMOUNT_PRECISION_FACTOR_BN, SCALE_PRECISION_FACTOR_BN } from "../constants.js";
|
|
6
6
|
export class RewardEntryAccumulator {
|
|
7
|
-
delegate;
|
|
8
7
|
lastAccountedTs;
|
|
9
8
|
claimedAmount;
|
|
10
9
|
accountedAmount;
|
|
@@ -14,17 +13,19 @@ export class RewardEntryAccumulator {
|
|
|
14
13
|
lastRewardAmount;
|
|
15
14
|
lastRewardPeriod;
|
|
16
15
|
buffer;
|
|
17
|
-
constructor(
|
|
18
|
-
this.
|
|
19
|
-
this.
|
|
20
|
-
this.
|
|
21
|
-
this.
|
|
22
|
-
this.
|
|
23
|
-
this.
|
|
24
|
-
this.
|
|
25
|
-
this.
|
|
26
|
-
this.
|
|
27
|
-
|
|
16
|
+
constructor(lastAccountedTs, claimedAmount, accountedAmount, rewardPool, stakeEntry, createdTs, lastRewardAmount, lastRewardPeriod, buffer) {
|
|
17
|
+
this.lastAccountedTs = lastAccountedTs;
|
|
18
|
+
this.claimedAmount = claimedAmount;
|
|
19
|
+
this.accountedAmount = accountedAmount;
|
|
20
|
+
this.rewardPool = rewardPool;
|
|
21
|
+
this.stakeEntry = stakeEntry;
|
|
22
|
+
this.createdTs = createdTs;
|
|
23
|
+
this.buffer = buffer;
|
|
24
|
+
this.lastRewardAmount = lastRewardAmount;
|
|
25
|
+
this.lastRewardPeriod = lastRewardPeriod;
|
|
26
|
+
}
|
|
27
|
+
static fromEntry(entry) {
|
|
28
|
+
return new this(entry.lastAccountedTs, entry.claimedAmount, entry.accountedAmount, entry.rewardPool, entry.stakeEntry, entry.createdTs, entry.lastRewardAmount, entry.lastRewardPeriod, entry.buffer);
|
|
28
29
|
}
|
|
29
30
|
// Calculate accountable amount by calculating how many seconds have passed since last claim/stake time
|
|
30
31
|
getAccountableAmount(stakedTs, accountableTs, effectiveStakedAmount, rewardAmount, rewardPeriod) {
|
|
@@ -35,15 +36,13 @@ export class RewardEntryAccumulator {
|
|
|
35
36
|
}
|
|
36
37
|
const periodsPassed = secondsPassed.div(rewardPeriod);
|
|
37
38
|
const claimablePerEffectiveStake = periodsPassed.mul(rewardAmount);
|
|
38
|
-
|
|
39
|
-
return accountableAmount;
|
|
39
|
+
return claimablePerEffectiveStake.mul(effectiveStakedAmount).div(SCALE_PRECISION_FACTOR_BN);
|
|
40
40
|
}
|
|
41
41
|
// Calculates claimable amount from accountable amount.
|
|
42
42
|
getClaimableAmount() {
|
|
43
|
-
const claimedAmount = this.claimedAmount.mul(
|
|
43
|
+
const claimedAmount = this.claimedAmount.mul(REWARD_AMOUNT_PRECISION_FACTOR_BN);
|
|
44
44
|
const nonClaimedAmount = this.accountedAmount.sub(claimedAmount);
|
|
45
|
-
|
|
46
|
-
return claimableAmount;
|
|
45
|
+
return nonClaimedAmount.div(REWARD_AMOUNT_PRECISION_FACTOR_BN);
|
|
47
46
|
}
|
|
48
47
|
// Get the time of the last unlock
|
|
49
48
|
getLastAccountedTs(stakedTs, claimableTs, rewardPeriod) {
|
|
@@ -51,8 +50,7 @@ export class RewardEntryAccumulator {
|
|
|
51
50
|
const totalSecondsPassed = claimableTs.sub(lastAccountedTs);
|
|
52
51
|
const periodsPassed = totalSecondsPassed.div(rewardPeriod);
|
|
53
52
|
const periodsToSeconds = periodsPassed.mul(rewardPeriod);
|
|
54
|
-
|
|
55
|
-
return currClaimTs;
|
|
53
|
+
return lastAccountedTs.add(periodsToSeconds);
|
|
56
54
|
}
|
|
57
55
|
// Adds accounted amount
|
|
58
56
|
addAccountedAmount(accountedAmount) {
|
|
@@ -80,7 +78,7 @@ export const calcRewards = (rewardEntryAccount, stakeEntryAccount, rewardPoolAcc
|
|
|
80
78
|
const rewardEntry = rewardEntryAccount?.account ?? createDefaultRewardEntry(stakeEntryAccount, rewardPoolAccount);
|
|
81
79
|
const stakeEntry = stakeEntryAccount.account;
|
|
82
80
|
const rewardPool = rewardPoolAccount.account;
|
|
83
|
-
const rewardEntryAccumulator =
|
|
81
|
+
const rewardEntryAccumulator = RewardEntryAccumulator.fromEntry(rewardEntry);
|
|
84
82
|
if (rewardEntryAccumulator.createdTs.lt(stakeEntry.createdTs)) {
|
|
85
83
|
throw new Error("InvalidRewardEntry");
|
|
86
84
|
}
|
|
@@ -134,3 +132,21 @@ export const calcRewards = (rewardEntryAccount, stakeEntryAccount, rewardPoolAcc
|
|
|
134
132
|
rewardEntryAccumulator.addAccountedAmount(accountableAmount);
|
|
135
133
|
return rewardEntryAccumulator.getClaimableAmount();
|
|
136
134
|
};
|
|
135
|
+
export const calculateRewardRateFromAmount = (rewardAmount, stakeTokenDecimals, rewardTokenDecimals) => {
|
|
136
|
+
const decimals = rewardTokenDecimals + (REWARD_AMOUNT_DECIMALS - stakeTokenDecimals);
|
|
137
|
+
return getNumberFromBN(rewardAmount, decimals);
|
|
138
|
+
};
|
|
139
|
+
export const calculateRewardAmountFromValue = (rewardTokenValue, stakeTokenDecimals) => {
|
|
140
|
+
const decimalsDiff = REWARD_AMOUNT_DECIMALS - stakeTokenDecimals;
|
|
141
|
+
if (decimalsDiff === 0) {
|
|
142
|
+
return rewardTokenValue;
|
|
143
|
+
}
|
|
144
|
+
const diffFactor = new BN(10).pow(new BN(Math.abs(decimalsDiff)));
|
|
145
|
+
if (decimalsDiff > 0) {
|
|
146
|
+
return rewardTokenValue.mul(diffFactor);
|
|
147
|
+
}
|
|
148
|
+
return rewardTokenValue.div(diffFactor);
|
|
149
|
+
};
|
|
150
|
+
export const calculateRewardAmountFromRate = (rewardRate, stakeTokenDecimals, rewardTokenDecimals) => {
|
|
151
|
+
return calculateRewardAmountFromValue(getBN(rewardRate, rewardTokenDecimals), stakeTokenDecimals);
|
|
152
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import BN from "bn.js";
|
|
2
|
+
import { SCALE_PRECISION_FACTOR_BN } from "../constants.js";
|
|
3
|
+
export const calculateStakeWeight = (minDuration, maxDuration, maxWeight, duration) => {
|
|
4
|
+
const durationSpan = maxDuration.sub(minDuration);
|
|
5
|
+
if (durationSpan.eq(new BN(0))) {
|
|
6
|
+
return SCALE_PRECISION_FACTOR_BN;
|
|
7
|
+
}
|
|
8
|
+
const durationExceedingMin = duration.sub(minDuration);
|
|
9
|
+
const normalizedWeight = durationExceedingMin.mul(SCALE_PRECISION_FACTOR_BN).div(durationSpan);
|
|
10
|
+
const weightDiff = maxWeight.sub(SCALE_PRECISION_FACTOR_BN);
|
|
11
|
+
return BN.max(SCALE_PRECISION_FACTOR_BN.add(normalizedWeight.mul(weightDiff).div(SCALE_PRECISION_FACTOR_BN)), SCALE_PRECISION_FACTOR_BN);
|
|
12
|
+
};
|
|
@@ -11,12 +11,10 @@ export type StakeEntry = IdlTypes<StakePoolIDL>["stakeEntry"];
|
|
|
11
11
|
export type RewardEntry = IdlTypes<RewardPoolIDL>["rewardEntry"];
|
|
12
12
|
export type RewardPool = IdlTypes<RewardPoolIDL>["rewardPool"];
|
|
13
13
|
export type FeeValue = IdlTypes<FeeManagerIDL>["feeValue"];
|
|
14
|
+
export type DefaultFeeValueConfig = IdlTypes<FeeManagerIDL>["config"];
|
|
14
15
|
export interface IInteractSolanaExt extends ITransactionSolanaExt {
|
|
15
16
|
invoker: SignerWalletAdapter | Keypair;
|
|
16
17
|
}
|
|
17
|
-
export interface ICreateSolanaExt extends IInteractSolanaExt {
|
|
18
|
-
isNative?: boolean;
|
|
19
|
-
}
|
|
20
18
|
export interface BaseStakePoolArgs {
|
|
21
19
|
stakePool: Address;
|
|
22
20
|
stakePoolMint: Address;
|
|
@@ -52,6 +50,11 @@ export interface CreateRewardPoolArgs extends BaseStakePoolArgs, TokenProgram {
|
|
|
52
50
|
rewardPeriod: BN;
|
|
53
51
|
permissionless: boolean;
|
|
54
52
|
}
|
|
53
|
+
export interface UpdateRewardPoolArgs {
|
|
54
|
+
rewardAmount: BN | null;
|
|
55
|
+
rewardPeriod: BN | null;
|
|
56
|
+
rewardPool: Address;
|
|
57
|
+
}
|
|
55
58
|
export interface ClaimRewardPoolArgs extends BaseStakePoolArgs, TokenProgram {
|
|
56
59
|
depositNonce: number;
|
|
57
60
|
rewardMint: Address;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@streamflow/staking",
|
|
3
|
-
"version": "7.0.
|
|
3
|
+
"version": "7.0.1",
|
|
4
4
|
"description": "JavaScript SDK to interact with Streamflow Staking protocol.",
|
|
5
5
|
"homepage": "https://github.com/streamflow-finance/js-sdk/",
|
|
6
6
|
"main": "dist/esm/index.js",
|
|
@@ -24,22 +24,23 @@
|
|
|
24
24
|
"build": "rm -rf dist; pnpm run build:cjs && pnpm run build:esm",
|
|
25
25
|
"pack": "pnpm build && pnpm pack",
|
|
26
26
|
"lint": "eslint --fix .",
|
|
27
|
+
"test": "vitest",
|
|
27
28
|
"prepublishOnly": "npm run lint && npm run build"
|
|
28
29
|
},
|
|
29
|
-
"gitHead": "
|
|
30
|
+
"gitHead": "1d52555f15b31f9267ab841e3238a596ca6b7e6f",
|
|
30
31
|
"devDependencies": {
|
|
31
|
-
"@streamflow/eslint-config": "7.0.
|
|
32
|
+
"@streamflow/eslint-config": "7.0.1",
|
|
32
33
|
"@types/bn.js": "5.1.1",
|
|
33
|
-
"typescript": "^
|
|
34
|
+
"typescript": "^5.6.3"
|
|
34
35
|
},
|
|
35
36
|
"dependencies": {
|
|
36
37
|
"@coral-xyz/anchor": "^0.30.0",
|
|
37
38
|
"@coral-xyz/borsh": "^0.29.0",
|
|
38
39
|
"@solana/buffer-layout": "4.0.1",
|
|
39
|
-
"@solana/spl-token": "0.
|
|
40
|
+
"@solana/spl-token": "0.4.9",
|
|
40
41
|
"@solana/wallet-adapter-base": "0.9.19",
|
|
41
|
-
"@solana/web3.js": "1.
|
|
42
|
-
"@streamflow/common": "7.0.
|
|
42
|
+
"@solana/web3.js": "1.95.4",
|
|
43
|
+
"@streamflow/common": "7.0.1",
|
|
43
44
|
"bn.js": "5.2.1",
|
|
44
45
|
"borsh": "^2.0.0",
|
|
45
46
|
"bs58": "5.0.0",
|