-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
30 changed files
with
5,216 additions
and
34 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,4 +2,4 @@ | |
|
||
. "$(dirname -- "$0")/_/husky.sh" | ||
|
||
npm run lint | ||
pnpm lint --parallel |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"printWidth": 110, | ||
"useTabs": false | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
{ | ||
"extends": [ | ||
"@streamflow/eslint-config" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
* | ||
!dist/**/* | ||
!package.json | ||
!README.md |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
build | ||
coverage |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,216 @@ | ||
# Streamflow Staking | ||
|
||
## JS SDK to interact with Streamflow Staking. | ||
|
||
This package allows you to | ||
- `create staking pools and rewards pools`; | ||
- `claim rewards`; | ||
- `stake`; | ||
- `unstake`; | ||
- `fund rewards pools`; | ||
|
||
with the Streamflow Staking protocol. | ||
|
||
This protocol is the complex of several programs which ensures flexibility and accountability for stakers and respective incentives for them. | ||
|
||
aforementioned programs are: | ||
- Stake Pools Program | ||
- Reward Pools Program | ||
- Fee Management Program (for streamflow usage, non-required and ommited from further docs) | ||
|
||
|
||
## API Reference | ||
API Documentation available here: [docs site →](https://streamflow-finance.github.io/js-sdk/) | ||
|
||
The Stake Pool Program entities: | ||
1. Stake Pool | ||
2. Stake Entry (PDA which stores info about current stakes, durations and rewards structure) | ||
|
||
The Reward Pool Program entities: | ||
1. Reward Pool (must has a back-reference to a stake pool) | ||
2. Reward Entry (PDA stores claims information and time-bound params) | ||
|
||
1 Stake Pool can have N Reward Pools. | ||
|
||
> [!NOTE] | ||
> There is a limitation of 255 Reward Pools per a single token mint for a stake pool. | ||
|
||
## Installation | ||
|
||
Install the sdk with npm | ||
|
||
```npm | ||
npm install @streamflow/staking | ||
``` | ||
```yarn | ||
yarn install @streamflow/staking | ||
``` | ||
```pnpm | ||
pnpm add @streamflow/staking | ||
``` | ||
|
||
## Usage/Examples | ||
|
||
#### Create a client | ||
```typescript | ||
const client = new SolanaStakingClient({ | ||
clusterUrl: "https://api.mainnet-beta.solana.com", | ||
cluster: ICluster.Mainnet | ||
}); | ||
``` | ||
|
||
> [!WARNING] | ||
> All operations expect ATAs to be created at the moment of execution and don't add these instructions. | ||
> - Stake - staker's ATAs for stake mint and stake mint (see deriveStakeMintPDA fn) | ||
> - Withdraw/Unstake - staker's ATAs for stake mint and stake mint (see deriveStakeMintPDA fn) | ||
> - Claim rewards - staker's ATAs for reward mint | ||
> - Fund Reward Pool - signer creates Streamflow Treasury's ATA for holding fee if defined | ||
#### Read operations | ||
```typescript | ||
|
||
await client.searchStakePools({ mint, creator }) // returns results of lookup, `mint` and `creator` both optional. Omit the argument to get all pools | ||
|
||
await client.searchStakeEntries({ payer, stakePool }) // returns all stake entries. Omit the argument to get all. | ||
|
||
await client.searchRewardPools({ stakePool, mint }) | ||
|
||
await client.searchRewardEntries({ stakeEntry, rewardPool }) | ||
|
||
``` | ||
|
||
#### Create a staking pool | ||
|
||
```typescript | ||
const client = new SolanaStakingClient({ | ||
clusterUrl: "https://api.mainnet-beta.solana.com", | ||
cluster: ICluster.Mainnet | ||
}); | ||
/* | ||
Rewards Multiplier powered by 10^9. | ||
Example: if multiplier is 2_000_000_000 than stakes for maxDuration will have 2x more rewards than stakes for minDuration | ||
*/ | ||
const multiplier = new BN(1_000_000_000); | ||
/* | ||
30 days - Unix time in seconds | ||
*/ | ||
const maxDuration = new BN(2592000); | ||
/* | ||
1 day - Unix time in seconds | ||
*/ | ||
const maxDuration = new BN(86400); | ||
/* | ||
Limits signers that can create/assign reward pools to this stake pool. True - anyone can | ||
*/ | ||
const permissionless = false; | ||
/* | ||
[0;256) derive stake pool PDA account address. | ||
If stake pool with the same mint already exists, it is required to pick a vacant nonce | ||
*/ | ||
const nonce = 0; | ||
|
||
const { metadataId: stakePoolPda } = await client.createStakePool({ | ||
maxWeight: multiplier, | ||
maxDuration, | ||
minDuration, | ||
mint: MINT_ADDRESS, | ||
permissionless, | ||
nonce: | ||
}) | ||
|
||
``` | ||
|
||
#### Create a rewardPool pool | ||
```typescript | ||
/* | ||
[0;256) derive reward pool PDA account address. | ||
If reward pool with the same mint already exists, it is required to pick a vacant nonce | ||
*/ | ||
const nonce = 0; | ||
/* | ||
Amount of rewarding tokens stakers get in return for staking exactly 1 token to the staking pool | ||
*/ | ||
const rewardAmount = new BN(100); | ||
/* | ||
1 day - Unix time in seconds. Period for rewarding stakers. Period starts counting from the moment of staking | ||
*/ | ||
const rewardPeriod = new BN(86400); | ||
const rewardMint = REWARD_MINT_ADDRESS; // rewarding token | ||
/* | ||
Whether to allow anyone to fund this reward pool. If true anyone can fund, otherwise only the creator can | ||
*/ | ||
const permissionless = true; | ||
|
||
client.createRewardPool({ | ||
nonce, | ||
rewardAmount, | ||
rewardPeriod, | ||
rewardMint, | ||
permissionless = false, | ||
stakePool: stakePoolPda, | ||
stakePoolMint: MINT_ADDRESS, | ||
}) | ||
``` | ||
|
||
|
||
#### Deposit/Stake to a stake pool | ||
```typescript | ||
/* | ||
[0;256) derive stake entry PDA account address. | ||
If stake entry with the same nonce already exists, it is required to pick a vacant one | ||
*/ | ||
const nonce = 0; | ||
const amount = new BN(1000); // tokens to stake | ||
const duration = new BN(86400 * 2) // 2 days, must be in the range of stakePool's min and max durations | ||
await client.stake({ nonce, amount, duration, stakePool, stakePoolMint }); | ||
``` | ||
|
||
#### Unstake/Withdraw to a stake pool | ||
```typescript | ||
/* | ||
Usually to achieve this the app already loaded available stakeEntries. | ||
Stake Entry holds used `nonce`, so `nonce` below could be taken from the stake entry | ||
*/ | ||
|
||
/* | ||
[0;256) derived stake entry PDA account address. | ||
If stake entry with the same nonce already exists, it is required to pick a vacant one | ||
*/ | ||
const nonce = 0; // | ||
await client.unstake({ stakePool, stakePoolMint, nonce }); | ||
``` | ||
|
||
#### Claim a reward | ||
Since each stake entry can produce multiple rewards (single claim per each reward pool linked to the staking pool) this operation | ||
can be triggered for every reward pool separately. | ||
|
||
```typescript | ||
await client.claimRewards({ | ||
rewardPoolNonce, | ||
depositNonce, | ||
stakePool, | ||
rewardMint, | ||
}); | ||
``` | ||
|
||
> [!Note] | ||
> All operations have accompanying APIs for manual transaction building. Consult with API docs to find respective calls. | ||
> For instance, prepareClaimRewardsInstructions. | ||
> These APIs allow to aggregate multiple operations in a single transaction according to the app needs. | ||
## Appendix | ||
|
||
Streamflow Staking protocol program IDs | ||
|
||
| Solana | | | ||
| ------- | -------------------------------------------- | | ||
| Staking Pools Mainnet | STAKEvGqQTtzJZH6BWDcbpzXXn2BBerPAgQ3EGLN2GH | | ||
| Reward Pools Mainnet | RWRDdfRbi3339VgKxTAXg4cjyniF7cbhNbMxZWiSKmj | | ||
| ---- | --- | | ||
| Staking Pools Devnet | STAKEvGqQTtzJZH6BWDcbpzXXn2BBerPAgQ3EGLN2GH | | ||
| Reward Pools Devnet | RWRDdfRbi3339VgKxTAXg4cjyniF7cbhNbMxZWiSKmj | | ||
|
||
### IDLs | ||
For further details you can consult with IDLs of protocols available at: | ||
`@streamflow/staking/dist/esm/solana/descriptor` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
export { default as SolanaStakingClient } from "./solana/client.js"; | ||
export * from "./solana/utils.js"; | ||
export * from "./solana/types.js"; | ||
export * from "./solana/lib/derive-accounts.js"; | ||
export * from "./solana/lib/rewards.js"; | ||
export * as constants from "./solana/constants.js"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
{ | ||
"name": "@streamflow/staking", | ||
"version": "7.0.0-alpha.1", | ||
"description": "JavaScript SDK to interact with Streamflow Staking protocol.", | ||
"homepage": "https://github.com/streamflow-finance/js-sdk/", | ||
"main": "dist/esm/index.js", | ||
"types": "dist/esm/index.d.ts", | ||
"type": "module", | ||
"exports": { | ||
".": { | ||
"import": "./dist/esm/index.js", | ||
"require": "./dist/cjs/index.js", | ||
"types": "./dist/esm/index.d.ts" | ||
}, | ||
"./solana": { | ||
"import": "./dist/esm/solana/index.js", | ||
"require": "./dist/cjs/solana/index.js", | ||
"types": "./dist/esm/solana/index.d.ts" | ||
} | ||
}, | ||
"scripts": { | ||
"build:cjs": "rm -rf dist/cjs; tsc -p tsconfig.cjs.json", | ||
"build:esm": "rm -rf dist/esm; tsc -p tsconfig.esm.json", | ||
"build": "rm -rf dist; pnpm run build:cjs && pnpm run build:esm", | ||
"pack": "pnpm build && pnpm pack", | ||
"lint": "eslint --fix .", | ||
"prepublishOnly": "npm run lint && npm run build" | ||
}, | ||
"gitHead": "a37306eba0e762af096db642fa22f07194014cfd", | ||
"devDependencies": { | ||
"@streamflow/eslint-config": "workspace:*", | ||
"@types/bn.js": "5.1.1", | ||
"date-fns": "2.28.0", | ||
"typescript": "^4.9.5" | ||
}, | ||
"dependencies": { | ||
"@coral-xyz/borsh": "^0.29.0", | ||
"@coral-xyz/anchor": "^0.30.0", | ||
"@solana/buffer-layout": "4.0.1 ", | ||
"@solana/spl-token": "0.3.6", | ||
"@solana/wallet-adapter-base": "0.9.19", | ||
"@solana/web3.js": "1.70.1", | ||
"@streamflow/common": "workspace:*", | ||
"bn.js": "5.2.1", | ||
"borsh": "^2.0.0", | ||
"bs58": "5.0.0", | ||
"p-queue": "^8.0.1" | ||
} | ||
} |
Oops, something went wrong.