The official SDK designed for effortless data retrieval from the StakeWise platform. This SDK provides a streamlined interface over GraphQL requests and contract interactions.
For successful utilization of this library, ensure you have ethers version 6.7.1 or higher installed. The ethers package isn't bundled within the SDK. Instead, we leverage peerDependencies to maintain a lean package size.
Note: If your project uses version 5 of ethers, consider installing version 6 alongside it. Adjust import paths via a bundler. Additionally, you might consider loading our SDK asynchronously using dynamic imports to optimize your application's initial load performance. Here's a sample configuration with webpack:
npm i ethers-6@npm:ethers@6.7.1
webpackConfig.plugins.push(
new webpack.NormalModuleReplacementPlugin(
/ethers$/m, (resource) => {
const isStakeWise = /@stakewise\/v3-sdk/.test(resource.context)
if (isStakeWise) {
resource.request = resource.request.replace(/ethers/, 'ethers-6')
}
}
)
)You can do something similar for other builders as well
npm i @stakewise/v3-sdkIf your builder doesn't support .graphql files, then you need to add a plugin. For example, for webpack this would be graphql-tag.
If you are using another builder, you can easily find GQL support plugins
webpackConfig.module.rules.push(
{
test: /\.(graphql|gql)$/,
loader: 'graphql-tag/loader',
exclude: /node_modules/,
}
)Create SDK instance
import { StakeWiseSDK, Network } from '@stakewise/v3-sdk'
const sdk = new StakeWiseSDK({ network: Network.Mainnet })| Name | Type | Type | Description |
|---|---|---|---|
| network | Network |
Require | Chain id |
| provider | BrowserProvider or JsonRpcProvider |
Optional | You can provide your implementation of the provender for ethers |
| endpoints.web3 | string OR string[] |
Optional | Your urls for connect to blockchain |
| endpoints.subgraph | string |
Optional | stakewise sbugraph url |
| endpoints.api | string |
Optional | stakewise backend url |
| Vault | osToken |
|---|---|
| sdk.vault.deposit | sdk.osToken.mint |
| sdk.vault.withdraw | sdk.osToken.burn |
| sdk.vault.claimExitQueue |
Get a list of interactions with the vault.
| Name | Type | Type | Description |
|---|---|---|---|
| vaultAddress | string |
Require | - |
| userAddress | string |
Optional | If a user address is specified, the query will look for events for that address and the vault address only |
| types | AllocatorActionType |
Require | Event types can be found in enum AllocatorActionType which you can import from the library |
| limit | number |
Require | To implement pagination |
| skip | number |
Require | To implement pagination |
type Output = Array<{
actionType: AllocatorActionType
createdAt: number
assets: string
shares: string
link: string
id: string
}>In events related to osToken you can use shares, in all other assets
| Name | Description |
|---|---|
id |
Event identifier |
assets |
Transaction amount |
shares |
Transaction amount |
createdAt |
Transaction date |
actionType |
Type of action |
link |
Transaction link (etherscan/blockscout) |
import { AllocatorActionType } from '@stakewise/v3-sdk'
await sdk.vault.getStakerActions({
skip: 0,
limit: 20,
userAddress: '0x...',
vaultAddress: '0x...',
types: [
AllocatorActionType.Redeemed,
AllocatorActionType.Deposited,
AllocatorActionType.VaultCreated,
AllocatorActionType.ExitedAssetsClaimed,
],
})TVL and APY snapshots for the vault. With the help of this data it is possible to build a chart.
| Name | Type | Type | Description |
|---|---|---|---|
| vaultAddress | string |
Require | - |
| dateFrom | number |
Require | Time to start |
type Snapshot = {
APY: number
TVL: string
}
type Output = {
days: Record<number, Snapshot>
first: Snapshot
}| Name | Description |
|---|---|
days |
The result of the query on your parameters, is returned as an object where the keys are timestamps |
first |
We always send the very first saved snapshot regardless of the request parameters, this helps for rendering the chart |
await sdk.vault.getSnapshots({
vaultAddress: '0x...',
dateFrom: 1695730032793,
})Fetch components for performance score calculation.
| Name | Type | Type | Description |
|---|---|---|---|
| vaultAddress | string |
Require | - |
type Output = {
consensusRewardsEarned: bigint
consensusRewardsMissed: bigint
executionMevEarned: bigint
executionMevMissed: bigint
}| Name | Description |
|---|---|
consensusRewardsEarned |
The total amount of consensus rewards earned by the Vault |
consensusRewardsMissed |
The total amount of consensus rewards missed by the Vault |
executionMevEarned |
The total amount of execution rewards earned by the Vault |
executionMevMissed |
The total amount of execution rewards missed by the Vault. It will include the ones missed due to the invalid fee recipient address set for the validator |
await sdk.vault.getScoring({
vaultAddress: '0x...',
})Daily rewards for the user who has made a deposit in the vault. With the help of this data it is possible to build a chart.
| Name | Type | Type | Description |
|---|---|---|---|
| vaultAddress | string |
Require | - |
| userAddress | string |
Require | - |
| dateFrom | number |
Require | Time to start |
| dateTo | number |
Optional | Time to end |
| fillGaps | boolean |
Optional | Fill in the empty days with zeros |
type UserReward = {
date: number
sumRewards: string
dailyRewards: string
dailyRewardsEur: string
dailyRewardsGbp: string
dailyRewardsUsd: string
}
type Output = {
days: Record<number, UserReward>
}| Name | Description |
|---|---|
days |
The result of the query on your parameters, is returned as an object where the keys are timestamps |
await sdk.vault.getUserRewards({
userAddress: '0x...',
vaultAddress: '0x...',
dateFrom: 1695730032793,
})Returns the withdrawal queue for a specific user.
| Name | Type | Type |
|---|---|---|
| userAddress | string |
Require |
| vaultAddress | string |
Require |
type Position = {
exitQueueIndex: bigint
positionTicket: string
timestamp: string
}
type Output = {
total: bigint
withdrawable: bigint
positions: Position[]
}| Name | Description |
|---|---|
positions |
Queue positions |
total |
Total withdrawal amount (in ETH) |
withdrawable |
Amount available for withdrawal (in ETH) |
await sdk.vault.getExitQueuePositions({
vaultAddress: '0x...',
userAddress: '0x...',
})Returns the running vault validators.
| Name | Type | Type |
|---|---|---|
| vaultAddress | string |
Require |
| limit | number |
Require |
| skip | number |
Require |
type Output = {
createdAt: number
publicKey: string
earned: string
link: string
apy: string
}| Name | Description |
|---|---|
createdAt |
Date of Creation |
publicKey |
Validator public key |
earned |
Validator balance (in ETH) |
link |
Link to beaconchain |
apy |
Current validator apy |
await sdk.vault.getValidators({
skip: 0,
limit: 5,
vaultAddress: '0x...'
})Returns the master data of the vault
| Name | Type | Type |
|---|---|---|
| vaultAddress | string |
Require |
type Output = {
apy: number
isErc20: boolean
capacity: string
createdAt: number
feePercent: number
isPrivate: boolean
vaultAdmin: string
totalAssets: string
feeRecipient: string
whitelister: string
vaultAddress: string
mevRecipient: string
imageUrl: string | null
blocklistManager: string
vaultKeysManager: string
isSmoothingPool: boolean
tokenName: string | null
tokenSymbol: string | null
displayName: string | null
description: string | null
whitelist: Array<{
createdAt: number
address: string
}> | null
blocklist: Array<{
createdAt: number
address: string
}> | null
performance: number
}| Name | Description |
|---|---|
apy |
Current vault apy |
isErc20 |
Does the vault have its own ERC20 token |
capacity |
Maximum TVL of Vault |
createdAt |
Date of Creation |
feePercent |
Commission rate |
isPrivate |
Whether the storage is private |
isBlocklist |
Whether the storage has blocklist |
vaultAdmin |
Vault administrator address |
totalAssets |
TVL of Vault |
feeRecipient |
Vault fee address |
whitelister |
Whitelist manager |
vaultAddress |
Address of vault |
mevRecipient |
Validator fee recipient |
imageUrl |
Link for vault logo |
blocklistManager |
Blocklist manager |
vaultKeysManager |
Keys manager address |
isSmoothingPool |
Smoothing poll or Vault escrow |
tokenName |
ERC20 token name |
tokenSymbol |
ERC20 token symbol |
displayName |
Name of vault |
description |
Description of vault |
whitelist |
List of authorized users for deposits |
blocklist |
List of blocked users for deposits |
performance |
Vault performance indicator (percent) |
await sdk.vault.getVault({ vaultAddress: '0x...' })How much a user can withdraw
| Name | Type | Type | Info |
|---|---|---|---|
| ltvPercent | bigint |
Require | sdk.osToken.getBaseData |
| mintedAssets | bigint |
Require | sdk.osToken.getPosition |
| stakedAssets | bigint |
Require | sdk.vault.getStakeBalance |
type Output = bigintawait sdk.vault.getMaxWithdraw({
ltvPercent: 0n,
mintedAssets: 0n,
stakedAssets: 0n,
})Necessary to update the vault state
type Output = {
reward: string
proof: Array<string>
rewardsRoot: string
unlockedMevReward: string
}await sdk.vault.getHarvestParams({ vaultAddress: '0x...' })Getting user's balance in the vault
| Name | Type | Type |
|---|---|---|
| userAddress | string |
Require |
| vaultAddress | string |
Require |
type Output = {
shares: bigint
assets: bigint
}| Name | Description |
|---|---|
shares |
Balance in vault tokens |
assets |
Balance in ETH |
await sdk.vault.getStakeBalance({
userAddress: '0x...',
vaultAddress: '0x...',
})How many osToken burn do you need to make to withdraw all deposit.
| Name | Type | Type | Description |
|---|---|---|---|
| ltvPercent | bigint |
Require | sdk.osToken.getBaseData |
| mintedAssets | bigint |
Require | sdk.osToken.getPosition |
| stakedAssets | bigint |
Require | sdk.vault.getStakeBalance |
| newStakedAssets | bigint |
Require | The future amount of stake after the deposit |
type Output = bigintsdk.osToken.getBurnAmount({
ltvPercent: 0n,
mintedAssets: 0n,
stakedAssets: 0n,
newStakedAssets: 0n,
})Get the health of the position
| Name | Type | Type | Description |
|---|---|---|---|
| thresholdPercent | bigint |
Require | sdk.osToken.getBaseData |
| mintedAssets | bigint |
Require | sdk.osToken.getPosition |
| stakedAssets | bigint |
Require | sdk.vault.getStakeBalance |
type Output = {
value: number
health: OsTokenPositionHealth
}| Name | Description |
|---|---|
value |
Numerical value |
health |
Position Health (enum) |
sdk.osToken.getHealthFactor({
thresholdPercent: 0n,
mintedAssets: 0n,
stakedAssets: 0n,
})Current os token APY
type Output = stringconst apy = await sdk.osToken.getAPY()Os token average rewards per second
type Output = bigintconst averageRewardsPerSecond = await sdk.osToken.getAvgRewardsPerSecond()User position data
| Name | Type | Type | Description |
|---|---|---|---|
| thresholdPercent | bigint |
Require | sdk.osToken.getBaseData |
| stakedAssets | bigint |
Require | sdk.vault.getStakeBalance |
| userAddress | string |
Require | - |
| vaultAddress | string |
Require | - |
type Output = {
minted: {
fee: bigint
assets: bigint
shares: bigint
}
healthFactor: {
value: number
health: OsTokenPositionHealth
}
protocolFeePercent: bigint
}| Name | Description |
|---|---|
minted.fee |
Usage fee amount |
minted.shares |
Balance |
minted.assets |
Balance in ETH |
healthFactor |
sdk.osToken.getHealthFactor |
protocolFeePercent |
Usage fee percent |
await sdk.osToken.getPosition({
stakedAssets: 0n,
userAddress: '0x...',
vaultAddress: '0x...',
thresholdPercent: 0n,
})Maximum number of shares for minting
| Name | Type | Type | Description |
|---|---|---|---|
| ltvPercent | bigint |
Require | sdk.osToken.getBaseData |
| stakedAssets | bigint |
Require | sdk.vault.getStakeBalance |
| mintedAssets | bigint |
Require | sdk.osToken.getPosition |
type Output = bigintawait sdk.osToken.getMaxMint({
ltvPercent: 0n,
mintedAssets: 0n,
stakedAssets: 0n,
})Basic information on the token
type Output = {
rate: string
ltvPercent: bigint
thresholdPercent: bigint
}| Name | Description |
|---|---|
rate |
ETH - osToken rate |
ltvPercent |
The percent used to calculate how much user can mint OsToken shares |
thresholdPercent |
The liquidation threshold percent used to calculate health factor for OsToken position |
await sdk.osToken.getBaseData()Convert osToken to ETH
| Name | Type | Type |
|---|---|---|
| amount | bigint |
Require |
type Output = bigintawait sdk.utils.getAssetsFromShares({ amount: 0n })Convert ETH to osToken
| Name | Type | Type |
|---|---|---|
| amount | bigint |
Require |
type Output = bigintawait sdk.utils.getSharesFromAssets({ amount: 0n })Current price of SWISE token to USD.
type Output = stringawait sdk.utils.getSwiseUsdPrice()Retrieving a transaction to verify that the data went into the subgraph after the transaction
| Name | Type | Type | Description |
|---|---|---|---|
| hash | string |
Require | Transaction hash |
type Output = Array<{
id: string
}>await sdk.utils.getTransactions({ hash: '0x...' })Transactions work through the provider you sent when creating an instance of our SDK class. Or, if you are a custodian, you can get the transaction data and sign it yourself. Each transaction also gives you the opportunity to get an approximate gas for sending it. For custodians, it is more reliable to calculate the gas yourself. Each transaction has encode and estimateGas methods for your convenience
Deposit (stake) in a vault
| Name | Type | Type | Description |
|---|---|---|---|
| assets | bigint |
Require | Deposit amount |
| userAddress | string |
Require | - |
| vaultAddress | string |
Require | - |
const params = {
assets: 0n,
userAddress: '0x...',
vaultAddress: '0x...',
}
// Send transaction
const hash = await sdk.vault.deposit(params)
// When you sign transactions on the backend (for custodians)
const { data, to, value } = await sdk.vault.deposit.encode(params)
// Get an approximate gas per transaction
const gas = await sdk.vault.deposit.estimateGas(params)Withdrawal of funds from a vault
| Name | Type | Type | Description |
|---|---|---|---|
| assets | bigint |
Require | Withdraw amount |
| userAddress | string |
Require | - |
| vaultAddress | string |
Require | - |
const amountAssets = 200n // from input mb
const [
{ ltvPercent, thresholdPercent },
stake,
] = await Promise.all([
sdk.osToken.getBaseData(),
sdk.vault.getStakeBalance({
vaultAddress: '0x...',
userAddress: '0x...',
}),
])
const osToken = await sdk.osToken.getPosition({
stakedAssets: stake.assets,
vaultAddress: '0x...',
userAddress: '0x...',
thresholdPercent,
})
const maxWithdrawAssets = await sdk.vault.getMaxWithdraw({
mintedAssets: osToken.minted.assets,
stakedAssets: stake.assets,
ltvPercent,
})
if (amountAssets > maxWithdrawAssets) {
// There is a withdrawal restriction if you have an osToken.
return
}
const params = {
vaultAddress: '0x...',
userAddress: '0x...',
assets: amountAssets,
}
// Send transaction
const hash = await sdk.vault.withdraw(params)
// When you sign transactions on the backend (for custodians)
const { data, to } = await sdk.vault.withdraw.encode(params)
// Get an approximate gas per transaction
const gas = await sdk.vault.withdraw.estimateGas(params)Take the freed tokens from the queue
| Name | Type | Type | Description |
|---|---|---|---|
| positions | string |
Require | postions from sdk.vault.getExitQueuePositions |
| userAddress | string |
Require | - |
| vaultAddress | string |
Require | - |
const exitQueue = await sdk.vault.getExitQueuePositions({
vaultAddress: '0x...',
userAddress: '0x...',
})
if (!exitQueue.withdrawable) {
// The exit queue has not yet accumulated funds for withdrawal
return
}
if (!exitQueue.data.length) {
// No withdrawal positions
return
}
const params = {
positions: exitQueue.data,
vaultAddress: '0x...',
userAddress: '0x...',
}
// Send transaction
const hash = await sdk.vault.claimExitQueue(params)
// When you sign transactions on the backend (for custodians)
const { data, to } = await sdk.vault.claimExitQueue.encode(params)
// Get an approximate gas per transaction
const gas = await sdk.vault.claimExitQueue.estimateGas(params)Getting osToken. The amount of token you can get depends on the user's current deposit in the storage. Use data from methods sdk.osToken.getMaxMint and sdk.osToken.getHealthFactor to block a call to mint() if the number of shares is greater than what getMaxMint returns or if the number of osToken after the transaction would make the position unhealthy
| Name | Type | Type | Description |
|---|---|---|---|
| shares | bigint |
Require | mint amount |
| userAddress | string |
Require | - |
| vaultAddress | string |
Require | - |
import { OsTokenPositionHealth } from '@stakewise/v3-sdk'
const amountShares = 200n // from input mb
const [
{ ltvPercent, thresholdPercent },
stake,
] = await Promise.all([
sdk.osToken.getBaseData(),
sdk.vault.getStakeBalance({
vaultAddress: '0x...',
userAddress: '0x...',
}),
])
const osToken = await sdk.osToken.getPosition({
stakedAssets: stake.assets,
vaultAddress: '0x...',
userAddress: '0x...',
thresholdPercent,
})
const maxMint = await sdk.osToken.getMaxMint({
mintedAssets: osToken.minted.assets,
stakedAssets: stake.assets,
ltvPercent,
})
if (amountShares > maxMint) {
// The value of amountShares is more than we can mint
return
}
const newMintShares = osToken.minted.shares + amountShares
const newMintAssets = await sdk.osToken.getAssetsFromShares({
amount: newMintShares
})
const { health } = sdk.osToken.getHealthFactor({
thresholdPercent,
stakedAssets: stake.assets,
mintedAssets: newMintAssets,
})
if (health !== OsTokenPositionHealth.Healthy) {
// If you do a minting with so many amountShares, your position is no longer healthy
return
}
const params = {
vaultAddress: '0x...',
userAddress: '0x...',
shares: amountShares,
}
// Send transaction
const hash = await sdk.osToken.mint(params)
// When you sign transactions on the backend (for custodians)
const { data, to } = await sdk.osToken.mint.encode(params)
// Get an approximate gas per transaction
const gas = await sdk.osToken.mint.estimateGas(params)Burns your osToken
| Name | Type | Type | Description |
|---|---|---|---|
| shares | bigint |
Require | Burn amount |
| userAddress | string |
Require | - |
| vaultAddress | string |
Require | - |
const params = {
shares: 0n,
userAddress: '0x...',
vaultAddress: '0x...',
}
// Send transaction
const hash = await sdk.osToken.burn(params)
// When you sign transactions on the backend (for custodians)
const { data, to, value } = await sdk.osToken.burn.encode(params)
// Get an approximate gas per transaction
const gas = await sdk.osToken.burn.estimateGas(params)To retrieve the storage data, you just need the method above. Other parts of the api are needed for specific tasks.
| Name | Description |
|---|---|
| contracts | Instances of our contracts |
| vaultMulticall | A method to implement a transaction with vault update |
| config | Object with contract addresses and other data |
| provider | Current provider for blockchain communication |
| network | Selected network |
| Name | Description |
|---|---|
| BigDecimal | Wrapper over bignumber.js |
| configs | Data for each network |
| createContract | A wrapper over the Contract class from the ethers package |
