[DROPS] Nodes && Testnet
January 20, 2022

SubQuery инструкция к модулю 4

ЗАДАНИЕ 1

1. Обновляем и устанавливаем софт:

sudo apt update
curl -s https://raw.githubusercontent.com/razumv/helpers/main/tools/install_node14.sh | bash
curl -s https://raw.githubusercontent.com/razumv/helpers/main/tools/install_docker.sh | bash

2. Устанавливаем subql / cli

npm install -g @subql/cli

3. Создаём проект

sudo subql init staking-rewards
cd staking-rewards

4. Редактируем файлы:

nano schema.graphql

type StakingReward @entity{
id: ID! #blockHeight-eventIdx
account: String!
balance: BigInt!
date: Date!
blockHeight: Int!
}

nano project.yaml

specVersion: 0.2.0
name: staking-rewards
version: 1.0.0
description: doubletop
repository: https://github.com/subquery/subql-starter
schema:
  file: ./schema.graphql
network:
  endpoint: wss://polkadot.api.onfinality.io/public-ws
  genesisHash: '0x91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3'
dataSources:
  - kind: substrate/Runtime
    startBlock: 7000000
    mapping:
      file: ./dist/index.js
      handlers:
        - handler: handleStakingRewarded
          kind: substrate/EventHandler
          filter:
            module: staking
            method: Rewarded
            

nano src/mappings/mappingHandlers.ts

import {SubstrateEvent} from "@subql/types";
import {StakingReward} from "../types";
import {Balance} from "@polkadot/types/interfaces";

export async function handleStakingRewarded(event: SubstrateEvent):
Promise<void> {
    const {event: {data: [account, newReward]}} = event;
    const entity = new StakingReward(`${event.block.block.header.number}-${event.idx.toString()}`);
    entity.account = account.toString();
    entity.balance = (newReward as Balance).toBigInt();
    entity.date = event.block.timestamp;
    entity.blockHeight = event.block.block.header.number.toNumber();
    await entity.save();
}

nano docker-compose.yml

version: '3'

services:
  postgres:
    image: postgres:12-alpine
    ports:
      - 5432:5432
    volumes:
      - .data/postgres:/var/lib/postgresql/data
    environment:
      POSTGRES_PASSWORD: postgres

  subquery-node:
    image: onfinality/subql-node:v0.25.3
    depends_on:
      - "postgres"
    restart: always
    environment:
      DB_USER: postgres
      DB_PASS: postgres
      DB_DATABASE: postgres
      DB_HOST: postgres
      DB_PORT: 5432
    volumes:
      - ./:/app
    command:
      - -f=/app
      - --db-schema=app

  graphql-engine:
    image: onfinality/subql-query:v0.8.0
    ports:
      - 3000:3000
    depends_on:
      - "postgres"
      - "subquery-node"
    restart: always
    environment:
      DB_USER: postgres
      DB_PASS: postgres
      DB_DATABASE: postgres
      DB_HOST: postgres
      DB_PORT: 5432
    command:
      - --name=app
      - --playground
      - --indexer=http://subquery-node:3000

5. Устанавливаем зависимости

yarn install
yarn codegen
yarn build

5. И выполняем:

docker-compose up -d
docker-compose logs -f --tail=100

6. Переходим в браузер, пишем ваш (ip_adress):3000

  • в загрузившейся странице вбиваем
query{
stakingRewards(first: 3 orderBy:BLOCK_HEIGHT_ASC){
nodes{
blockHeight
account
date
balance
}
}
}

И нажимаем на кнопку в виде Play.

Возвращаемся в терминал и останавливаем докер-компоус

docker-compose stop

ЗАДАНИЕ 2

nano schema.graphql

type StakingReward @entity{
id: ID! #blockHeight-eventIdx
account: String!
balance: BigInt!
date: Date!
blockHeight: Int!
}

type SumReward @entity{
id: ID! # AccountId
totalReward: BigInt!
blockheight: Int!
}

nano project.yaml

  GNU nano 4.8                                                          project.yaml                                                          Modified  
specVersion: 0.2.0
name: staking-rewards
version: 1.0.0
description: doubletop
repository: https://github.com/subquery/subql-starter
schema:
  file: ./schema.graphql
network:
  endpoint: wss://polkadot.api.onfinality.io/public-ws
  genesisHash: '0x91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3'
dataSources:
  - kind: substrate/Runtime
    startBlock: 7000000
    mapping:
      file: ./dist/index.js
      handlers:
       - handler: handleSumRewarded
         kind: substrate/EventHandler
         filter:
           module: staking
           method: Rewarded        
       - handler: handleStakingRewarded
         kind: substrate/EventHandler
         filter:
            module: staking
            method: Rewarded

nano src/mappings/mappingHandlers.ts

import {SubstrateEvent} from "@subql/types";
import {StakingReward, SumReward} from "../types";
import {Balance} from "@polkadot/types/interfaces";

export async function handleStakingRewarded(event: SubstrateEvent):
Promise<void> {
    const {event: {data: [account, newReward]}} = event;
    const entity = new
StakingReward(`${event.block.block.header.number}-${event.idx.toString()
}`);
    entity.account = account.toString();
    entity.balance = (newReward as Balance).toBigInt();
    entity.date = event.block.timestamp;
    entity.blockHeight = event.block.block.header.number.toNumber();
    await entity.save();
}

function createSumReward(accountId: string): SumReward {
    const entity = new SumReward(accountId);
    entity.totalReward = BigInt(0);
    return entity;
}
export async function handleSumRewarded(event: SubstrateEvent):
Promise<void> {
    const {event: {data: [account, newReward]}} = event;
    let entity = await SumReward.get(account.toString());
    if (entity === undefined){
    entity = createSumReward(account.toString());
}
    entity.totalReward = entity.totalReward + (newReward as Balance).toBigInt();
    entity.blockheight = event.block.block.header.number.toNumber();
    await entity.save();
}

5. Устанавливаем зависимости

yarn codegen
yarn build

5. И выполняем:

docker-compose up -d
docker-compose logs -f --tail=100

6. Переходим в браузер, пишем ваш (ip_adress):3000

  • в загрузившейся странице вбиваем
query{
sumRewards(first:3 orderBy:BLOCKHEIGHT_ASC){
nodes{
blockheight
id
totalReward
}
}
}

И нажимаем на кнопку в виде Play.

Возвращаемся в терминал и останавливаем докер-компоус

docker-compose stop

ЗАДАНИЕ 3

nano schema.graphql

type StakingReward @entity{
id: ID! #blockHeight-eventIdx
account: SumReward!
balance: BigInt!
date: Date!
blockheight: Int
}

type SumReward @entity{
id: ID! # AccountId
totalReward: BigInt!
blockheight: Int!
}

nano src/mappings/mappingHandlers.ts

import {SubstrateEvent} from "@subql/types";
import {StakingReward, SumReward} from "../types";
import {Balance} from "@polkadot/types/interfaces";

export async function handleStakingRewarded(event: SubstrateEvent):
Promise<void> {
    const {event: {data: [account, newReward]}} = event;
    const entity = new
StakingReward(`${event.block.block.header.number}-${event.idx.toString()
}`);
    entity.accountId = account.toString();
    entity.balance = (newReward as Balance).toBigInt();
    entity.date = event.block.timestamp;
    await entity.save();
}

function createSumReward(accountId: string): SumReward {
    const entity = new SumReward(accountId);
    entity.totalReward = BigInt(0);
    return entity;
}
export async function handleSumRewarded(event: SubstrateEvent):
Promise<void> {
    const {event: {data: [account, newReward]}} = event;
    let entity = await SumReward.get(account.toString());
    if (entity === undefined){
    entity = createSumReward(account.toString());
}
    entity.totalReward = entity.totalReward + (newReward as Balance).toBigInt();
    entity.blockheight = event.block.block.header.number.toNumber();
    await entity.save();
}

5. Устанавливаем зависимости

yarn codegen
yarn build
rm -rf staking-rewards/.data

5. И выполняем:

docker-compose up -d
docker-compose logs -f --tail=100

6. Переходим в браузер, пишем ваш (ip_adress):3000

  • в загрузившейся странице вбиваем
query{
sumRewards(filter:
{id:{equalTo:"16jWQMBXZNxfgXJmVL61gMX4uqtc9WTXV3c8DGx6DUKejm7"}}){
nodes{
blockheight
id
totalReward
stakingRewardsByAccountId{
nodes{
balance
}
}
}
}
}

И нажимаем на кнопку в виде Play.

Возвращаемся в терминал и останавливаем докер-компоус

docker-compose stop

ЗАДАНИЕ 4

nano schema.graphql

type StakingReward @entity{
id: ID! #blockHeight-eventIdx
account: SumReward!
balance: BigInt!
date: Date!
blockheight: Int
}

type SumReward @entity{
id: ID! # AccountId
totalReward: BigInt!
blockheight: Int
}

nano project.yaml

  GNU nano 4.8                                                          project.yaml                                                          Modified  
specVersion: 0.2.0
name: staking-rewards
version: 1.0.0
description: doubletop
repository: https://github.com/subquery/subql-starter
schema:
  file: ./schema.graphql
network:
  endpoint: wss://polkadot.api.onfinality.io/public-ws
  genesisHash: '0x91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3'
dataSources:
  - kind: substrate/Runtime
    startBlock: 6000000
    mapping:
      file: ./dist/index.js
      handlers:
       - handler: handleSumRewarded
         kind: substrate/EventHandler
         filter:
           module: staking
           method: Rewarded        
       - handler: handleStakingRewarded
         kind: substrate/EventHandler
         filter:
            module: staking
            method: Rewarded

nano src/mappings/mappingHandlers.ts

import {SubstrateEvent} from "@subql/types";
import {StakingReward, SumReward} from "../types";
import {Balance} from "@polkadot/types/interfaces";

export async function handleStakingReward(event: SubstrateEvent):
Promise<void> {
    const {event: {data: [account, newReward]}} = event;
    const entity = new
StakingReward(`${event.block.block.header.number}-${event.idx.toString()
}`);
    entity.accountId = account.toString();
    entity.balance = (newReward as Balance).toBigInt();
    entity.date = event.block.timestamp;
    await entity.save();
}

function createSumReward(accountId: string): SumReward {
    const entity = new SumReward(accountId);
    entity.totalReward = BigInt(0);
    return entity;
}
export async function handleSumReward(event: SubstrateEvent):
Promise<void> {
    const {event: {data: [account, newReward]}} = event;
    let entity = await SumReward.get(account.toString());
    if (entity === undefined){
    entity = createSumReward(account.toString());
}
    entity.totalReward = entity.totalReward + (newReward as Balance).toBigInt();
    entity.blockheight = event.block.block.header.number.toNumber();
    await entity.save();
}

5. Устанавливаем зависимости

yarn codegen
yarn build

5. И выполняем:

docker-compose up -d
docker-compose logs -f --tail=100

6. Переходим в браузер, пишем ваш (ip_adress):3000

  • в загрузившейся странице вбиваем
query{
sumRewards(first:3 orderBy:BLOCKHEIGHT_ASC){
nodes{
blockheight
id
totalReward
}
}
}

И нажимаем на кнопку в виде Play.

Возвращаемся в терминал и останавливаем докер-компоус

docker-compose stop