Documentation v1.0 has been released! Staking Guide, Protocols, Glossary, FAQ, and Support sections have been added.

Ethereum

Getting Started

You can use Javascript library to implement Ethereum staking for Everstake validator.

JavaScript Library

You can install and import Wallet SDK for Javascript. The link to the JS library on npm: https://www.npmjs.com/package/@everstake/wallet-sdk

Step. 1: Installing the Library

Install the npm library or yarn by copying the code below.

$ npm install @everstake/wallet-sdk-ethereum

Step. 2: Import Wallet SDK

After installing the app, you can import module of Ethereum blockchain and use the SDK:

Import ES6

// import module
import { Ethereum } from '@everstake/wallet-sdk-ethereum';

Import ES5

// import module
const { Ethereum } = require("@everstake/wallet-sdk-ethereum");

Methods

Actions

  • stake(address, amount, source): Stakes funds into pool. The minimum amount required for staking is 0.1 ETH.

  • activateStake(): Activates the pending stake by interchanging it with a withdrawal requests.

  • autocompound(address): Claims all autocompound user rewards and restakes them into new pool automatically.

  • unstake(address, amount, allowedInterchangeNum, source): You can unstake value from autocompound balance. Your ETH can be unstaked immediately if value <= pool pending balance. Also, if 'allowedInterchangeNum > 0', an instant ustake is possible. Else, you need to create a withdraw request. Please note that the execution of a withdraw request may take some time.

  • simulateUnstake(address, amount, allowedInterchangeNum, source): Simulates transactions without committing them. It is required, especially for predicting transaction outcomes and gas fees in Ethereum blockchain.

  • unstakePending(address, amount): Unstakes pending amount. Your ETH will be unstaked immediately. Smart contract checks remainder of pending balance after unstake. It should be greater or equal min stake amount (0.1 ETH for now).

  • claimWithdrawRequest(address): Claims funds requested by withdraw

Getting Info

  • balance(): Returns total deposited and activated pools balance. The total amount of ETH that has been staked.

  • pendingBalance(): Returns the pending balance of staked ETH in the pool, which is always less than 32 ETH.

  • pendingBalanceOf(address): Returns the pending balance of the user, which represents the amount of ETH staked but not yet active due to the pool not being fully filled. There is one type of pending balance: "Autocompound," which represents rewards earned by the user that are automatically staked but not yet active.

  • pendingDepositedBalance(): Returns pool pending deposited balance. Balance was deposited into Beacon deposit contract but validators are still not active.

  • pendingRestakedRewards(): Returns pool restaked rewards which in pending status.

  • pendingDepositedBalanceOf(address): Returns user pending deposited balance. Balance which deposited into validator but not active yet. Pending deposited balance can't be unstake till validator activation.

  • pendingRestakedRewardOf(address): Returns user restaked rewards in pending state.

  • RestakedRewardOf(address): Returns total user restaked rewards. Includes rewards in pending state.

  • depositedBalanceOf(address): Returns user active origin deposited balance.

  • getPoolFee(): Returns Pool fee in bips (1/10000). To obtain the pool fee percentage, simply multiply it by 100.

  • autocompoundBalanceOf(address): Returns total user autocompound balance. The "Autocompound balance" refers to the user's actively staked ETH balance that continuously increases as rewards are restaked. Part of this balance could be in pending state after rewards autocompound.

  • withdrawRequestQueueParams(): Provides a overview of the withdrawal request queue. It retrieves information about the total amount of funds requested for withdrawal over the entire operational period, giving an insight into the overall demand for withdrawals. Additionally, the function details the current amount that is permissible for interchange with deposits, which is crucial for maintaining a balanced liquidity between incoming and outgoing funds.

  • withdrawRequest(address): Returns user withdraw request info. Actual requested amount and amount ready for claim.

  • minStakeAmount(): Returns the minimum amount required for a single user stake.

  • poolBalances(): Returns batch of pool balances using multicall contract. One call instead of several.

  • userBalances(): Returns batch of user balances using multicall contract. One call instead of several.

Getting Validator Info

  • closeValidatorsStat(): Returns the number of validators expected to stop.

  • getPendingValidatorCount(): Returns number of validators prepared for deposit.

  • getPendingValidator(index): By using an index, retrieve the pending validator public key. Please note that the list of pending validators is dynamic, and the ordering may be unstable.

  • getValidatorCount(): Returns the total number of known validators. Validators can be in one of the following statuses: pending, deposited, or exited. Exited validators will be replaced by new pending validators to optimize memory usage.

  • getValidator(index): Returns validator pubkey and status.

Stake

The stake namespace contains method used for sending transactions on delegation. The unique method to the stake namespace is:

  • stake(address, amount, source): Stakes funds into pool. The minimum amount required for staking is 0.1 ETH. The source is a unique identifier provided by the Everstake that allows the Everstake to recognize and verify the origin of the staking transactions.

  • activateStake(): Activates the pending stake by interchanging it with a withdrawal requests.

Stake Code Example

// Import SDK
import { Ethereum } from '@everstake/wallet-ethereum';

const sdk = new Ethereum();

// User Public Address
const address = '0x7CB380672D37E6Cc2e1dE28616076Cf3Cexample';

// The unique identifier provided by the Everstake
const source = '0'; 

// The amount that the user stake
const amount = 1; // must be >= 0.1

// Stake - return Raw Transaction
const txnRequest = await sdk.stake(address, amount, source);
console.log(txnRequest); // Raw Transaction

Unstake

The unstake namespace contains method used for sending transactions on unstake. The unique method to the unstake namespace is:

  • unstake(address, amount, allowedInterchangeNum, source): You can unstake value from autocompound balance. Your ETH can be unstaked immediately if value <= pool pending balance. Also, if 'allowedInterchangeNum > 0', an instant ustake is possible. Else, you need to create a withdraw request. Please note that the execution of a withdraw request may take some time. The source is a unique identifier provided by the Everstake that allows the Everstake to recognize and verify the origin of the staking transactions.

  • unstakePending(address, amount): Unstakes pending amount. Your ETH will be unstaked immediately. Smart contract checks the remainder of pending balance after unstake. It should be greater or equal min stake amount (0.1 ETH for now).

Unstake Code Example

// Import SDK
import { Ethereum } from '@everstake/wallet-sdk-ethereum';

// User Public Address
const address = '0x7CB380672D37E6Cc2e1dE28616076Cf3Cexample';

const allowedInterchangeNum = 0; //from 0 to max

// The amount that the user unstakes
const amount = 1;

// The unique identifier provided by the Everstake
const source = '0'; 

const sdk = new Ethereum();

// Unstake - return Raw Transaction
const txnRequest = await sdk.unstake(address, amount, allowedInterchangeNum, source);
console.log(txnRequest); // Raw Transaction

Unstake Pending Code Example

// Import SDK
import { Ethereum } from '@everstake/wallet-sdk-ethereum';

// User Public Address
const address = '0x7CB380672D37E6Cc2e1dE28616076Cf3Cexample';

// The amount that the user unstake
const amount = 1;

const sdk = new Ethereum();

// Unstake - return Raw Transaction
const txnRequest = await sdk.unstakePending(address, amount);
console.log(txnRequest); // Raw Transaction

Claim Ethereum

The claim namespace contains method used for sending transactions on claim. The unique method to the claim namespace is:

  • claimWithdrawRequest(address): Claims funds requested by withdraw.

Claim Withdraw Request Code Example

// Import SDK
import { Ethereum } from '@everstake/wallet-sdk-ethereum';

// User Public Address
const address = '0x7CB380672D37E6Cc2e1dE28616076Cf3Cexample';

const sdk = new Ethereum();

// Claim Withdraw Request - return Raw Transaction
const txnRequest = await sdk.claimWithdrawRequest(address);
console.log(txnRequest); // Raw Transaction

Autocompound

The autocompound namespace contains method used for sending transactions on autocompound. The unique method to the autocompound namespace is:

  • autocompound(address): Claims all autocompound user rewards and restakes them into pool.

Autocompound Code Example

// Import SDK
import { Ethereum } from '@everstake/wallet-sdk-ethereum';

// User Public Address
const address = '0x7CB380672D37E6Cc2e1dE28616076Cf3Cexample';

const sdk = new Ethereum();

// Autocompound - return Raw Transaction
const txnRequest = await sdk.autocompound(address);
console.log(txnRequest); // Raw Transaction

Getting Info

The get namespace contains method used for getting info. The unique method to the get namespace is:

  • balance(): Returns total deposited and activated pools balance. The total amount of ETH that has been staked.

  • pendingBalance(): Returns the pending balance of staked ETH in the pool, which is always less than 32 ETH.

  • pendingBalanceOf(address): Returns the pending balance of the user, which represents the amount of ETH staked but not yet active due to the pool not being fully filled. There is one type of pending balance: "Autocompound," which represents rewards earned by the user that are automatically staked but not yet active.

  • pendingDepositedBalance(): Returns pool pending deposited balance. Balance was deposited into Beacon deposit contract but validators are still not active.

  • pendingRestakedRewards(): Returns pool restaked rewards which in pending status.

  • pendingDepositedBalanceOf(address): Returns user pending deposited balance. Balance which deposited into validator but not active yet. Pending deposited balance can't be unstake till validator activation.

  • pendingRestakedRewardOf(address): Returns user restaked rewards in pending state.

  • RestakedRewardOf(address): Returns total user restaked rewards. Includes rewards in pending state.

  • depositedBalanceOf(address): Returns user active origin deposited balance.

  • getPoolFee(): Returns Pool fee in bips (1/10000). To obtain the pool fee percentage, simply multiply it by 100.

  • autocompoundBalanceOf(address): Returns total user autocompound balance. The "Autocompound balance" refers to the user's actively staked ETH balance that continuously increases as rewards are restaked. Part of this balance could be in pending state after rewards autocompound.

  • withdrawRequestQueueParams(): Provides a overview of the withdrawal request queue. It retrieves information about the total amount of funds requested for withdrawal over the entire operational period, giving an insight into the overall demand for withdrawals. Additionally, the function details the current amount that is permissible for interchange with deposits, which is crucial for maintaining a balanced liquidity between incoming and outgoing funds.

  • withdrawRequest(address): Returns user withdraw request info. Actual requested amount and amount ready for claim.

  • minStakeAmount(): Returns the minimum amount required for a single user stake.

  • poolBalances(): Returns batch of pool balances using multicall contract. One call instead of several.

  • userBalances(): Returns batch of user balances using multicall contract. One call instead of several.

Get Balance

// Import SDK
import { Ethereum } from '@everstake/wallet-sdk-ethereum';

const sdk = new Ethereum();

// Return total deposited and activated pool balance in ETH.
const result = await sdk.balance();
console.log(result); // 64 (Amount in ETH)

Get Pending Pool Balance

// Import SDK
import { Ethereum } from '@everstake/wallet-sdk-ethereum';

const sdk = new Ethereum();

// Return pool pending balance. Always < 32 ETH
const result = await sdk.pendingBalance();
console.log(result); // 12 (Amount in ETH)

Get Pending User Balance

// Import SDK
import { Ethereum } from '@everstake/wallet-sdk-ethereum';

const sdk = new Ethereum();

// user public address
const address = '0x7CB380672D37E6Cc2e1dE28616076Cf3Cexample';

// Return user pending balance.
const result = await sdk.pendingBalanceOf(address);
console.log(result); // see the response below

result = { 
    autocompound: 3,
} // (Amount in ETH)

Get Pending User Deposited Balance

// Import SDK
import { Ethereum } from '@everstake/wallet-sdk-ethereum';

const sdk = new Ethereum();

// user public address
const address = '0x7CB380672D37E6Cc2e1dE28616076Cf3Cexample';

// Return user stake in pending deposited state.
const result = await sdk.pendingDepositedBalanceOf(address);
console.log(result); 

Get Pending User Restake Rewards

// Import SDK
import { Ethereum } from '@everstake/wallet-sdk-ethereum';

const sdk = new Ethereum();

// user public address
const address = '0x7CB380672D37E6Cc2e1dE28616076Cf3Cexample';

// Return user restaked rewards in pending state.
const result = await sdk.pendingRestakedRewardOf(address);
console.log(result); 

Get User Active Origin Deposited Balance

// Import SDK
import { Ethereum } from '@everstake/wallet-sdk-ethereum';

const sdk = new Ethereum();

// user public address
const address = '0x7CB380672D37E6Cc2e1dE28616076Cf3Cexample';

// Return user active origin deposited balance.
const result = await sdk.depositedBalanceOf(address);
console.log(result); 

Get Pool Fee

// Import SDK
import { Ethereum } from '@everstake/wallet-sdk-ethereum';

const sdk = new Ethereum();

// Return Pool fee
const result = await sdk.getPoolFee();
console.log(result); // 0.05

Get Autocompound Balance

// Import SDK
import { Ethereum } from '@everstake/wallet-sdk-ethereum';

const sdk = new Ethereum();

// user public address
const address = '0x7CB380672D37E6Cc2e1dE28616076Cf3Cexample';

// Return total user autocompound balance. 
// Part of this balance could be in pending 
// state after rewards autocompound
const result = await sdk.autocompoundBalanceOf(address);
console.log(result); // 0.5 (Amount in ETH)

Get Withdraw Request Queue Params

// Import SDK
import { Ethereum } from '@everstake/wallet-sdk-ethereum';

const sdk = new Ethereum();

// Return info about withdraw requests queue. 
// Totally alltime requested withdraw amount. 
// Actual allowed for intercharge with deposits amount. 
// Alltime withdraw treasury filled amount. 
// Alltime claimed by users amount
const result = await sdk.withdrawRequestQueueParams();
console.log(result); // see the response below

result = {
    // Totally alltime requested withdraw amount.
    withdrawRequested: 1,
    // Actual allowed for interchange with deposits amount.
    interchangeAllowed: 2,
    // Alltime withdraw treasury filled amount.
    filled: 3,
    // Alltime claimed by users amount
    claimed: 4,
}

Get Withdraw Request

// Import SDK
import { Ethereum } from '@everstake/wallet-sdk-ethereum';

const sdk = new Ethereum();

// user public address
const address = '0x7CB380672D37E6Cc2e1dE28616076Cf3Cexample';

// Return user withdraw request info. Actual requested amount and amount ready for claim
const result = await sdk.withdrawRequest(address);
console.log(result); // see the response below

result = {
    requested: 1.2,
    readyForClaim: 1.2,
}

Get Unstake Balance

// Import SDK
import { Ethereum } from '@everstake/wallet-sdk-ethereum';

const sdk = new Ethereum();

// user public address
const address = '0x7CB380672D37E6Cc2e1dE28616076Cf3Cexample';

// Return total active balance. Common + autocompound
const result = await sdk.unstakeBalanceOf(address);
console.log(result); // 4.5 (Amount in ETH)

Get Pool Balances

// Import SDK
import { Ethereum } from '@everstake/wallet-sdk-ethereum';

const sdk = new Ethereum();

// Returns pool balances using multicall contract
const result = await sdk.poolBalances();
console.log(result);

// results object with pool balances
result = {
    balance: '154167.566649533603258904',
    pendingBalance: '25.429162610682642258',
    pendingDepositedBalance: '416',
    pendingRestakedRewards: '0.',
    readyforAutocompoundRewardsAmount: '0.'
}

Get User Balances

// Import SDK
import { Ethereum } from '@everstake/wallet-sdk-ethereum';

const sdk = new Ethereum();

// user public address
const address = '0x7CB380672D37E6Cc2e1dE28616076Cf3Cexample';

// Return user balances using multicall contract
const result = await sdk.userBalances(address);
console.log(result); // see the response below

// results object with user balances
result = {
    pendingBalanceOf: '6.961237984991404976',
    pendingDepositedBalanceOf: '2.888762015008595024',
    pendingRestakedRewardOf: '0.',
    autocompoundBalanceOf: '10.1561269071460993',
    depositedBalanceOf: '10'
}

Getting Validator Info

The getValidator namespace contains method used for getting validator info. The unique method to the getValidator namespace is:

  • closeValidatorsStat(): Returns the number of validators expected to stop.

  • getPendingValidatorCount(): Returns number of validators prepared for deposit.

  • getPendingValidator(index): By using an index, retrieve the pending validator public key. Please note that the list of pending validators is dynamic, and the ordering may be unstable.

  • getValidatorCount(): Returns the total number of known validators. Validators can be in one of the following statuses: pending, deposited, or exited. Exited validators will be replaced by new pending validators to optimize memory usage.

  • getValidator(index): Returns validator pubkey and status.

Get Close Validators Stat

// Import SDK
import { Ethereum } from '@everstake/wallet-sdk-ethereum';

const sdk = new Ethereum();

// Return number of expected to stop validators
const result = await sdk.closeValidatorsStat();
console.log(result); // 5

Get Pending Validator Count

// Import SDK
import { Ethereum } from '@everstake/wallet-sdk-ethereum';

const sdk = new Ethereum();

// Returns num of validators prepared for deposit
const result = await sdk.getPendingValidatorCount();
console.log(result); // 5

Get Pending Validator

// Import SDK
import { Ethereum } from '@everstake/wallet-sdk-ethereum';

const sdk = new Ethereum();

const index = 0;

// By index return pending validator pubkey. List of pending validators is dinamic so ordering unstable
const result = await sdk.getPendingValidator(index);
console.log(result); 
// 0x905d5e630840ea9112c2b8f562018e4ad799cf3e40ca03d20fec04e9393aee592655650d83abb01c11df5ce1849d36a7

Get Validator Count

// Import SDK
import { Ethereum } from '@everstake/wallet-sdk-ethereum';

const sdk = new Ethereum();

// Return total num of known validators. 
// Validator can be in one of statuses: pending, deposited, exited. 
// Exited validators will be rewrited by new pending validators to optimize memory usage
const result = await sdk.getValidatorCount();
console.log(result); // 10

Get Validator

// Import SDK
import { Ethereum } from '@everstake/wallet-sdk-ethereum';

const sdk = new Ethereum();

// Return validator pubkey and status
const result = await sdk.getValidatorCount();
console.log(result); // see the response below

relult = {
    pubkey: '0x905d5e630840ea9112c2b8f562018e4ad799cf3e40ca03d20fec04e9393aee592655650d83abb01c11df5ce1849d36a7',
    status: 'unknown' || 'pending' || 'deposited',
}

Sign Transaction

Securely sign Ethereum transactions using your own infrastructure with the assistance of our SDK. By signing transactions on your side, you maintain control over your private keys and sensitive data, enhancing the security of your operations. Our SDK simplifies the process, providing the necessary tools and functions to prepare, sign, and send transactions to the Ethereum network while ensuring that your private keys never leave your secure environment.

Signing on your side, Code Example

try {
    // import web3 lib
    import Web3 from "web3";
    const web3 = new Web3(RPC_URL);

    let result = null;
    await web3.eth.accounts.signTransaction(tx, privateKey).then(async (signedTx) => {
        result = await web3.eth.sendSignedTransaction(signedTx.rawTransaction);
    });
    return result; // Transaction result
} catch (error) {
    throw new Error(error);
}

Simulate Unstake

The simulate namespace contains method used for simalating transactions on unstake. The unique method to the simulate namespace is:

  • simulateUnstake(address, amount, allowedInterchangeNum, source): Simulates transactions without committing them. It is required, especially for predicting transaction outcomes and gas fees in Ethereum blockchain. The source is a unique identifier provided by the Everstake that allows the Everstake to recognize and verify the origin of the staking transactions.

Simulate Unstake Code Example

// Import SDK
import { Ethereum } from '@everstake/wallet-sdk-ethereum';

// User Public Address
const address = '0x7CB380672D37E6Cc2e1dE28616076Cf3Cexample';

// The number of interchanges when unstaking
const allowedInterchangeNum = 1;

// The unique identifier provided by the Everstake
const source = '0';

const sdk = new Ethereum();

// Simulate Unstake
const txnRequest = await sdk.simulateUnstake(address, amount, allowedInterchangeNum, source);
console.log(txnRequest);