Overview
NEAR protocol uses Proof of Stake (PoS) consensus to secure and validate transactions on the blockchain. Validators receive NEAR token rewards for producing new blocks. NEAR token holders can also receive rewards by delegating their tokens to validators.
When you participate in NEAR staking as a delegator, you deposit and stake tokens with a specific NEAR staking pool that is deployed by a validator. A smart contract orchestrates the delegation of funds and allows the validator to customize their methods for collecting and managing rewards.
When you stake NEAR using the Fireblocks SDK, your funds are delegated to a validator that is operated by a third-party staking provider. You must transfer your delegated NEAR tokens from your Fireblocks Vault to the validator's address.
The staking process consists of three phases: staking, unstaking, and withdrawing. While you are staking your tokens, you can’t spend or move them in any way. In order to withdraw staked funds and rewards, you must unstake them and wait for a cooldown period of approximately 2-3 days.
Like with other PoS staking protocols, NEAR tokens staked with a validator can be slashed if that validator misbehaves.
Rewards and fees
- Rewards are automatically restaked and compounded.
- Staked funds and associated rewards do not appear in your Fireblocks Vault until you withdraw them.
- There is currently no option to identify how many rewards you have accumulated using the NEAR SDK or the Fireblocks Console. We suggest that you use a blockchain explorer for this.
- You may have to pay transaction fees for some of the SDK calls (e.g. staking, unstaking, withdrawing, etc).
Staking NEAR on Fireblocks
Before you use Fireblocks to stake NEAR, complete all prerequisites for staking. Then, follow the steps below to stake NEAR from your Fireblocks vault account.
Prerequisites
To stake NEAR, you must:
- Fund your vault account with NEAR's base asset, NEAR token, to pay transaction and storage fees.
- Create a Transaction Authorization Policy (TAP) rule to allow Raw Signing for NEAR.
Fireblocks provides a reference SDK (typescript) for staking NEAR. The SDK interacts with the Fireblocks API and the NEAR blockchain and can be embedded in your existing workflows. The SDK supports both mainnet and testnet. It uses the Raw Signing API for signing NEAR staking transactions.
Note
Even though the relevant transactions submitted to the NEAR protocol are contract calls, they are signed with the Raw Signing API rather than the contract call API. The contract call API for the NEAR protocol is not currently supported on Fireblocks.
You can perform multiple stake calls from the same vault account. Each stake call will add the specified amount to the staked funds. Similarly, you can unstake or withdraw partial amounts rather than all at once.
Setup
- Download the Fireblocks NEAR staking SDK from github.
- Create a new, dedicated vault account for staking with a NEAR asset wallet. You should name the account "NEAR Staking."
- Retrieve the following details:
- apiKey: See retrieving your Fireblocks API key for more information.
- apiSecret: This is your private RSA key. Learn more about retrieving your RSA key by creating a CSR file.
- Create a typescript file based on the example below.
Functions
The following functions are applicable for staking with the NEAR SDK:
Stake
stake(amount: number)
This function allows you to delegate a specific amount to a NEAR validator. A stake call performs a single operation for staking (deposit_and_stake) which transfers funds from your account to the validator's address. Both the deposit and the delegation of the funds are initiated together following this call.
You can call the stake function multiple times from the same vault account. Each call adds the additional specified amount to the staked funds.
Parameters
- Amount: Amount of NEAR to stake (in NEAR units).
Returns
This function doesn't return any data.
Unstake
unstake(amount: number)
This function stops the staking entirely and is required before you can withdraw staked funds. Once this function is called, it will take about 2-3 days before you can withdraw the amount you unstaked.
You can call the unstake function multiple times.
Parameters
- Amount: Amount of NEAR to unstake (in NEAR units). If the value is set to -1, then all staked funds will be unstaked.
Returns
This function doesn't return any data.
Withdraw
withdraw(amount: number)
This function transfers the specified amount of unstaked funds back into your vault account. It should be called only after the unstaking process is complete, which is typically about 2-3 days after the unstake function was initiated.
You can call the withdraw function multiple times.
Parameters
- Amount: Amount of NEAR to withdraw (in NEAR units). If the value is set to -1, then all unstaked funds will be withdrawn.
Returns
This function doesn't return any data.
Get Balances
getBalances(smallestDenom: boolean = true)
This function returns the value of the total staked amount in the account.
Parameters
- smallestDenom: If set to true, the returned value is in YoctoNEAR units. If set to false, the returned value is in NEAR units. By default, this parameter is set to true (the returned value is in YoctoNEAR units).
Returns
- Promise<number[]>: Returns an array of a single value. The returned value is the total accumulated staked amounts of the account.
Examples
The following code snippets show examples of how to set up staking calls.
const fs = require('fs');
const path = require('path');
const FireblocksSDK = require('fireblocks-sdk').FireblocksSDK;
const NEARStaker = require('fireblocks-staking-sdk').NEARStaker;
const apiSecret = "...";
const apiKey = "...";
const fbks = new FireblocksSDK(apiSecret, apiKey);
async function defaultContractUsageExample() {
let staker = new NEARStaker(fbks, 0);
await staker.setup();
const amountToStake = 3;
const amountToUnstake = 2;
const amountToWithdraw = 2;
// Stake some NEAR.
await staker.stake(amountToStake);
// Get the current balance for the account.
let balances = await staker.getBalances();
const staked = balances[0];
// Unstake some NEAR.
await staker.unstake(amountToUnstake);
// Withdraw some NEAR.
await staker.withdraw(amountToWithdraw);
}
async function customValidatorUsage(){
let staker = new NEARStaker(fbks, 0, 'validator.near' /* Custom validator address */);
await staker.setup();
// Rest of the functionality is exactly the same.
}
async function testnetUsage(){
let staker = new NEARStaker(fbks, 0, 'validator.near', true);
await staker.setup();
// Rest 0f the functionality is exactly the same.
// You can also define a custom config with testnet as defined in the relevant section.
}
Initialization
NEARStaker(fbks, vaultAccountId, contractName, isTestnet, config, web3) - The NEAR staker instance should be initialized as in the examples above.
- fbks: FireblocksSDK - The FireblocksSDK instance. This parameter value should be hardcoded with the value shown in the example.
- vaultAccountId: any - Mandatory. The dedicated Fireblocks vault account ID that contains the NEAR wallet to delegate from. It can be obtained via the Fireblocks API or the Fireblocks Console.
- ContractName - String, optional. The name of the validator to use. If none is specified, then figment.poolv1.near (the contract name for Figment) is used.
- isTestnet - Boolean, optional. Whether or not the staking is performed on NEAR testnet. Set to false by default.
- Config - A connectConfig object; optional. Allows advanced configuration of URLs. By default, this parameter is set with a predefined config for NEAR according to the isTestnet flag.
- Web3 - Optional. Irrelevant for NEAR staking.