Staking
Pre-requisites
Please make sure that you've followed our getting started guide and set up your development environment.
You'll also need the following:
In order to stake, your users will need to have created a profile for your project. They'll also need eligible characters that can stake (more on this below).
Overview
Staking is very similar to missions in the way that it allows users to earn rewards.
The difference is that when characters are staked in a staking pool, they're locked until a user unstakes them. During that time, these characters earn rewards based on the staking pool's reward distribution mechanism.
Create staking pool
- JavaScript
- GraphQL
import { LockTypeEnum } from "@honeycomb-protocol/edge-client";
const {
createCreateStakingPoolTransaction: {
transactions, // The transaction response, you'll need to sign and send this transaction
stakingPoolAddress, // The address of the staking pool when it's created
multipliersAddress, // The address of the multipliers when they're created (if you've added any)
},
} = await client.createCreateStakingPoolTransaction({
project: projectAddress.toString(),
resource: resourceAddress.toString(), // Resource's pubkey address in string format, your users will earn rewards in the form of this resource
authority: adminPublicKey.toString(),
delegateAuthority: delegateAuthority.toString(),
payer: payerPublicKey.toString(),
multiplier: { // Optional, if you want to add multipliers, these multipliers increase the rewards for your users based on the conditions you set
decimals: 2,
multipliers: [
// Provide one of these per multiplier: collection, creator, minNftCount, minStakeDuration
{
value: "10",
type: {
collection: collection.toString(),
}
},
{
value: "5",
type: {
creator: creatorPublicKey.toString(),
}
},
{
value: "2",
type: {
minNftCount: "1",
}
},
{
value: "3",
type: {
minStakeDuration: "1",
}
}
]
},
metadata: { // Staking pool metadata
name: "Staking", // Staking pool name
rewardsPerDuration: "1", // Rewards per duration
rewardsDuration: "3600", // Rewards duration in seconds, 3600 means rewards can be collected every hour
maxRewardsDuration: "7200", // Maximum rewards duration in seconds
minStakeDuration: "7200", // Minimum stake duration in seconds before rewards can be claimed
cooldownDuration: "0", // Rewards cooldown
resetStakeDuration: "0", // Reset stake duration
startTime: Date.now().toString(), // Staking pool start time, UNIX second format send as a string
endTime: null, // Staking pool endtime, UNIX second format send as a string, send null if you don't want to set an end time
lockType: LockTypeEnum.Freeze, // Character lock type for the staking pool, send either Freeze or Custody
}
});
query CreateCreateStakingPoolTransaction($project: String!, $resource: String!, $metadata: CreateStakingPoolMetadataInput!, $authority: String!, $delegateAuthority: String, $multiplier: InitStakingMultiplierMetadataInput) {
createCreateStakingPoolTransaction(project: $project, resource: $resource, metadata: $metadata, authority: $authority, delegateAuthority: $delegateAuthority, multiplier: $multiplier) {
transactions {
transactions
blockhash
lastValidBlockHeight
}
stakingPoolAddress
multipliersAddress
}
}
Provide the accompanying data like so:
{
"project": "pubkey", // Project's pubkey address in string format
"resource": "pubkey", // Resource's pubkey address in string format
"authority": "pubkey", // Authority's pubkey address in string format
"payer": "pubkey", // Optional, fee payer's pubkey address in string format,
"delegateAuthority": "pubkey", // Optional, delegate authority's pubkey address in string format
"metadata": {
"cooldownDuration": "bigint", // Duration in seconds, UNIX format, send as a string (example: 1 week = 604800 seconds)
"endTime": "bigint", // Staking pool endtime, UNIX second format send as a string
"lockType": "Freeze/Custody", // Character lock type for the staking pool, send either Freeze or Custody
"maxRewardsDuration": "bigint", // Maximum rewards duration in seconds, send as a string
"minStakeDuration": "bigint", // Minimum stake duration in seconds, send as a string
"name": "string", // Staking pool name
"resetStakeDuration": "bigint", // Reset stake duration in seconds, send as a string
"rewardsDuration": "bigint", // Rewards duration in seconds, send as a string
"rewardsPerDuration": int, // Rewards per duration, send as a string
"startTime": "bigint" // Staking pool start time, UNIX second format send as a string
},
"multiplier": { // Optional, if you want to add multipliers, these multipliers increase the rewards for your users based on the conditions you set
"decimals": 2,
"multipliers": [
{
"value": "10",
"type": {
// Use any combination of these: collection, creator, minNftCount, minStakeDuration
"collection": "pubkey",
"creator": "pubkey",
"minNftCount": "1",
"minStakeDuration": "1",
}
}
]
}
}
Update staking pool
The create staking pool function will create a new pool, but your users won't be able to stake in it until you update it with a character model. Here's how you can do so.
- JavaScript
- GraphQL
import { LockTypeEnum } from "@honeycomb-protocol/edge-client";
const {
createUpdateStakingPoolTransaction: txResponse // This is the transaction response, you'll need to sign and send this transaction
} = await client.createUpdateStakingPoolTransaction({
project: projectAddress.toString(),
authority: adminPublicKey.toString(),
resource: resourceAddress.toString(), // Optional, only use if you want to change the resource
delegateAuthority: delegateAuthority.toString(), // Optional, only use if you want to change the delegate authority
stakingPool: stakingPoolAddress.toString(),
characterModel: characterModelAddress.toString(), // Optional, but you'll need to initially provide this if you want to allow characters to stake in this pool
payer: payerPublicKey.toString(), // Optional, tx payer pubkey
metadata: { // Optional, all of the properties in this object are also optional
cooldownDuration: "0", // Duration in seconds, UNIX format, send as a string (example: 1 week = 604800 seconds)
endTime: null, // Staking pool endtime, UNIX second format send as a string, send null if you don't want to set an end time
lockType: LockTypeEnum.Freeze, // Character lock type for the staking pool, send either Freeze or Custody
maxRewardsDuration: "9600", // Maximum rewards duration in seconds, send as a string
minStakeDuration: "3600", // Minimum stake duration in seconds, send as a string
name: "New name", // Staking pool name
resetStakeDuration: "86400", // Reset stake duration in seconds, send as a string
rewardsDuration: "3600", // Rewards duration in seconds, send as a string
rewardsPerDuration: "100", // Rewards per duration, send as a string
startTime: Date.now().toString(), // Staking pool start time, UNIX second format send as a string
}
});
query CreateUpdateStakingPoolTransaction($project: String!, $stakingPool: String!, $authority: String!, $metadata: UpdateStakingPoolMetadataInput, $characterModel: String, $resource: String, $delegateAuthority: String, $payer: String) {
createUpdateStakingPoolTransaction(project: $project, stakingPool: $stakingPool, authority: $authority, metadata: $metadata, characterModel: $characterModel, resource: $resource, delegateAuthority: $delegateAuthority, payer: $payer) {
transaction
blockhash
lastValidBlockHeight
}
}
Provide the accompanying data like so:
{
"project": "pubkey", // Project's pubkey address in string format
"stakingPool": "pubkey", // Staking pool's pubkey address in string format
"authority": "pubkey", // Authority's pubkey address in string format
"resource": "pubkey", // Optional, resource's pubkey address in string format
"delegateAuthority": "pubkey", // Optional, delegate authority's pubkey address in string format
"characterModel": "pubkey", // Optional, character model's pubkey address in string format
"payer": "pubkey", // Optional, tx payer's pubkey address in string format
"metadata": {
"cooldownDuration": "int", // Duration in seconds, UNIX format, send as a string (example: 1 week = 604800 seconds)
"endTime": "int", // Staking pool endtime, UNIX second format send as a string
"lockType": "Freeze", // Character lock type for the staking pool, send either Freeze or Custody
"maxRewardsDuration": "int", // Maximum rewards duration in seconds, send as a string
"minStakeDuration": "int", // Minimum stake duration in seconds, send as a string
"name": "string", // Staking pool name
"resetStakeDuration": "int", // Reset stake duration in seconds, send as a string
"rewardsDuration": "int", // Rewards duration in seconds, send as a string
"rewardsPerDuration": int, // Rewards per duration, send as a string
"startTime": "int" // Staking pool start time, UNIX second format send as a string
}
}
Create multipliers
- JavaScript
- GraphQL
const {
createInitMultipliersTransaction: {
tx, // The transaction response, you'll need to sign and send this transaction
multipliersAddress, // The address of the multipliers when they're created
},
} = await client.createInitMultipliersTransaction({
project: projectAddress.toString(),
authority: adminPublicKey.toString(),
stakingPool: stakingPoolAddress.toString(),
multipliers: [
{
value: "10",
type: {
collection: collection.toString(),
},
},
{
value: "5",
type: {
creator: creatorPublicKey.toString(),
},
},
{
value: "2",
type: {
minNftCount: "1",
},
},
{
value: "3",
type: {
minStakeDuration: "1", // Minimum stake duration in seconds
},
}
],
decimals: 3,
});
query CreateBurnResourceTransaction($resource: String!, $params: BurnResourceInput!, $authority: String!, $payer: String, $project: String!, $stakingPool: String!, $decimals: Int!, $multipliers: [AddMultiplierMetadataInput]!, $createInitMultipliersTransactionAuthority2: String!, $delegateAuthority: String, $createInitMultipliersTransactionPayer2: String) {
createBurnResourceTransaction(resource: $resource, params: $params, authority: $authority, payer: $payer) {
transaction
blockhash
lastValidBlockHeight
}
createInitMultipliersTransaction(project: $project, stakingPool: $stakingPool, decimals: $decimals, multipliers: $multipliers, authority: $createInitMultipliersTransactionAuthority2, delegateAuthority: $delegateAuthority, payer: $createInitMultipliersTransactionPayer2) {
tx {
transaction
blockhash
lastValidBlockHeight
}
multipliersAddress
}
}
Add the accompanying data:
{
"project": "pubkey", // Project's pubkey address in string format
"authority": "pubkey", // Authority's pubkey address in string format
"payer": "pubkey", // Optional, tx payer's pubkey address in string format
"delegateAuthority": "pubkey", // Optional, delegate authority's pubkey address in string format
"stakingPool": "pubkey", // Staking pool's pubkey address in string format
"decimals": int, // Number of decimals
"multipliers": [
{
"value": "int", // Multiplier value, send as a string
"type": {
// Send only one of these per multiplier object
"minStakeDuration": "int", // Minimum stake duration in seconds, send as a string
"minNftCount": "int", // Minimum NFT count, send as a string
"creator": "pubkey", // Creator's pubkey address in string format
"collection": "pubkey" // Collection's pubkey address in string format
}
}
],
}
Add multipliers
- JavaScript
- GraphQL
const {
createAddMultiplierTransaction: txResponse // This is the transaction response, you'll need to sign and send this transaction
} = await client.createAddMultiplierTransaction({
project: projectAddress,
authority: adminPublicKey.toString(),
multiplier: multipliersAddress.toString(), // Existing multipliers address
payer: payerPublicKey.toString(), // Optional, tx payer pubkey
delegateAuthority: delegateAuthority.toString(), // Optional, delegate authority pubkey
metadata: [
// Specify any multipliers you want to add here
{
value: "10",
type: {
collection: collection.toString(),
},
},
{
value: "5",
type: {
creator: creatorPublicKey.toString(),
},
},
{
value: "2",
type: {
minNftCount: "1",
},
},
{
value: "3",
type: {
minStakeDuration: "1",
},
}
],
});
query CreateAddMultiplierTransaction($project: String!, $multiplier: String!, $metadata: AddMultiplierMetadataInput!, $authority: String!, $delegateAuthority: String, $payer: String) {
createAddMultiplierTransaction(project: $project, multiplier: $multiplier, metadata: $metadata, authority: $authority, delegateAuthority: $delegateAuthority, payer: $payer) {
transaction
blockhash
lastValidBlockHeight
}
}
Provide the accompanying data like so:
{
"project": "pubkey", // Project's pubkey address in string format
"multiplier": "pubkey", // Multiplier's pubkey address in string format
"authority": "pubkey", // Authority's pubkey address in string format
"delegateAuthority": "pubkey", // Optional, delegate authority's pubkey address in string format
"payer": "pubkey", // Optional, tx payer's pubkey address in string format
"metadata": [
// Specify any multipliers you want to add here
{
"value": "10",
"type": {
"collection": "pubkey",
},
},
{
"value": "5",
"type": {
"creator": "pubkey",
},
},
{
"value": "2",
"type": {
"minNftCount": "1",
},
},
{
"value": "3",
"type": {
"minStakeDuration": "1",
},
}
]
}
Stake characters
- JavaScript
- GraphQL
const {
createStakeCharactersTransactions: txResponse // This is the transaction response, you'll need to sign and send this transaction
} = await client.createStakeCharactersTransactions({
project: projectAddress.toString(),
stakingPool: stakingPoolAddress.toString(),
characterModel: characterModelAddress.toString(),
characterAddresses: [
characterAddress.toString(),
],
feePayer: payerPublicKey.toString(),
});
query CreateStakeCharactersTransactions($characterAddresses: [String!]!, $project: String!, $characterModel: String!, $stakingPool: String!, $feePayer: String) {
createStakeCharactersTransactions(characterAddresses: $characterAddresses, project: $project, characterModel: $characterModel, stakingPool: $stakingPool, feePayer: $feePayer) {
transactions
blockhash
lastValidBlockHeight
}
}
Provide the accompanying data:
{
"characterAddresses": ["pubkey"], // Array of character addresses
"project": "pubkey", // Project's pubkey address in string format
"characterModel": "pubkey", // Character model's pubkey address in string format
"stakingPool": "pubkey", // Staking pool's pubkey address in string format
"feePayer": "pubkey"
}
Claim staking rewards
- JavaScript
- GraphQL
const {
createClaimStakingRewardsTransactions: txResponse // This is the transaction response, you'll need to sign and send this transaction
} = await client.createClaimStakingRewardsTransactions({
characterAddresses: [
characterAddress.toString(),
],
characterModel: characterModelAddress.toString(),
feePayer: payerPublicKey.toString(),
});
query CreateClaimStakingRewardsTransactions($characterAddresses: [String!]!, $characterModel: String!, $feePayer: String) {
createClaimStakingRewardsTransactions(characterAddresses: $characterAddresses, characterModel: $characterModel, feePayer: $feePayer) {
transactions
blockhash
lastValidBlockHeight
}
}
Provide the accompanying data like so:
{
"characterAddresses": ["pubkey"], // Array of character addresses
"characterModel": "pubkey", // Character model's pubkey address in string format
"feePayer": "pubkey"
}
Unstake characters
- JavaScript
- GraphQL
const {
createUnstakeCharactersTransactions: txResponse // This is the transaction response, you'll need to sign and send this transaction
} = await client.createUnstakeCharactersTransactions({
characterAddresses: [
characterAddress.toString(),
],
characterModel: characterModelAddress.toString(),
feePayer: payerPublicKey.toString(),
});
query CreateUnstakeCharactersTransactions($characterAddresses: [String!]!, $characterModel: String!, $feePayer: String) {
createUnstakeCharactersTransactions(characterAddresses: $characterAddresses, characterModel: $characterModel, feePayer: $feePayer) {
transactions
blockhash
lastValidBlockHeight
}
}
Provide the accompanying data like so:
{
"characterAddresses": ["pubkey"], // Array of character addresses
"characterModel": "pubkey", // Character model's pubkey address in string format
"feePayer": "pubkey"
}