2

Is there an elegant way to get the total amount staked & rewarded for each era/block?

Right now I get a list of staking.Bonded data from Subscan:

{
  "code": 0,
  "message": "Success",
  "generated_at": 1678864944,
  "data": {
    "count": 422214,
    "events": [
      {
        "id": 1464944600037,
        "block_timestamp": 1678847754,
        "event_index": "14649446-37",
        "extrinsic_index": "14649446-2",
        "phase": 0,
        "module_id": "staking",
        "event_id": "Bonded",
        "extrinsic_hash": "0x8c9b68aa856100f9fcc2668bd4dcbdb86c3be13a955ea70c96b076fb0836fd5c",
        "finalized": true
      },
      {
        "id": 1464943300048,
        "block_timestamp": 1678847676,
        "event_index": "14649433-48",
        "extrinsic_index": "14649433-3",
        "phase": 0,
        "module_id": "staking",
        "event_id": "Bonded",
        "extrinsic_hash": "0xb6444aa174dd7cb14a7bb39f8ed18112e7912a7974274cd578f4feef1c62fae8",
        "finalized": true
      },
...

Then I parse the extrinsics with node decode-extrinsic.js events.json where decode-extrinsic.js is:

#!/usr/bin/env node

// Using the Polkadot Mainnet Endpoint
const { ApiPromise, WsProvider } = require("@polkadot/api");

async function main() {
  // Construct a provider with the endpoint URL
  const provider = new WsProvider("wss://rpc.polkadot.io/");
  // Create an API instance for Polkadot
  const api = await ApiPromise.create({ provider });
  // ...
  const fs = require("fs");

  // Read events data:
  // $ node decode-extrinsic.js "$SCRIPTPATH/../data/pages/$network-staking-$page.json"
  const fileNames = process.argv.splice(2);
  const fileName = fileNames[0];
  var data = JSON.parse(fs.readFileSync(fileName, "utf-8"));

  const promises = data.data.events.map(async (ev, index) => {
    const exampleBlockNumber = parseInt(ev.extrinsic_index.split("-")[0]);
    const extrinsicHash = ev.extrinsic_hash;

    const blockHash = await api.rpc.chain.getBlockHash(exampleBlockNumber);

    const signedBlock = await api.rpc.chain.getBlock(blockHash);
    signedBlock.block.extrinsics.forEach(async (ex, index) => {
      if (extrinsicHash === ex.hash.toHex()) {
        // console.log(index, ex.toHuman());
        const {
          isSigned,
          era,
          method: { args, method, section },
        } = ex;
        console.log(
          `${era.toHuman().MortalEra.period},${exampleBlockNumber},${args
            .map((a) => a.toString())
            .join(", ")}`
        );
      }
    });
    //  console.log(ev, exampleBlockNumber, extrinsicHash);
  })
  await Promise.all(promises);
};

main()
  .catch(console.error)
  .finally(() => process.exit());

However, this produces a jumble of mixed data:

64,14649433,Rewards
64,14649433,12Vj1D1QYSgHwmdqvy9fCsLgtBM1d8uxSAu9UqCEopYs5drH, 1032800000000, Stash
64,14649446,13urTj2o1zArvYKNMzZaow5rGrjRxkFNSSwpr4Y3J1WqFbqH, 1176551239546, Stash
64,14648832,500000000000
64,14648796,31600000000
64,14648792,67600000000
64,14648812,145300000000
64,14648750,Rewards
64,14649408,330000000000
64,14648237,10000000000
64,14648533,850000000000
64,14649360,320000000000
64,14648787,97500000000
64,14648176,{"freeBalance":3200000000}
64,14648803,45200000000
...

Appreciate any hints or tips.

1 Answer 1

3

Total amount staked per era can be read from the storage item ErasTotalStake.

To get total payout that will eventually be rewarded for an era (unless never claimed), you can read the storage item ErasValidatorReward.

I want to clarify that staking reward payouts in Polkadot and Kusama are lazy. What this means is rewards need to be claimed for each validator separately and are claimable up to 84 eras. If after 84 eras, the rewards are not claimed, they are purged.

1
  • It appears that doesn't give the history: const e = era.toHuman().MortalEra.period; const historyStaked = await api.query.staking.erasTotalStake(e); returns <BN: 0> Commented Mar 15, 2023 at 11:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.