From c3a689bb7e8c1efbe6bc60ecbdbc1fe7b902bc43 Mon Sep 17 00:00:00 2001 From: youssea <81751092+youssefea@users.noreply.github.com> Date: Thu, 22 Jun 2023 21:35:20 +0100 Subject: [PATCH 01/14] Create README.md --- .../moonbeam-substrate-evm-starter/README.md | 105 ++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 Moonbeam/moonbeam-substrate-evm-starter/README.md diff --git a/Moonbeam/moonbeam-substrate-evm-starter/README.md b/Moonbeam/moonbeam-substrate-evm-starter/README.md new file mode 100644 index 00000000..d5334f6b --- /dev/null +++ b/Moonbeam/moonbeam-substrate-evm-starter/README.md @@ -0,0 +1,105 @@ +# SubQuery - Starter Package + +A basic Frontier EVM example project with an event and call handler. Read more about this at https://university.subquery.network/build/substrate-evm.html. This project can be use as a starting point for developing your SubQuery project + +The Starter Package is an example that you can use as a starting point for developing your SubQuery project. +A SubQuery package defines which data The SubQuery will index from the Substrate blockchain, and how it will store it. + +## Preparation + +#### Environment + +- [Typescript](https://www.typescriptlang.org/) are required to compile project and define types. + +- Both SubQuery CLI and generated Project have dependencies and require [Node](https://nodejs.org/en/). + +#### Install the SubQuery CLI + +Install SubQuery CLI globally on your terminal by using NPM: + +``` +npm install -g @subql/cli +``` + +Run help to see available commands and usage provide by CLI + +``` +subql help +``` + +## Initialize the starter package + +Inside the directory in which you want to create the SubQuery project, simply replace `project-name` with your project name and run the command: + +``` +subql init project-name +``` + +Then you should see a folder with your project name has been created inside the directory, you can use this as the start point of your project. And the files should be identical as in the [Directory Structure](https://doc.subquery.network/directory_structure.html). + +Last, under the project directory, run following command to install all the dependency. + +``` +yarn install +``` + +## Configure your project + +In the starter package, we have provided a simple example of project configuration. You will be mainly working on the following files: + +- The Manifest in `project.yaml` +- The GraphQL Schema in `schema.graphql` +- The Mapping functions in `src/mappings/` directory + +For more information on how to write the SubQuery, +check out our doc section on [Define the SubQuery](https://doc.subquery.network/define_a_subquery.html) + +#### Code generation + +In order to index your SubQuery project, it is mandatory to build your project first. +Run this command under the project directory. + +``` +yarn codegen +``` + +## Build the project + +In order to deploy your SubQuery project to our hosted service, it is mandatory to pack your configuration before upload. +Run pack command from root directory of your project will automatically generate a `your-project-name.tgz` file. + +``` +yarn build +``` + +## Indexing and Query + +#### Run required systems in docker + +Under the project directory run following command: + +``` +docker-compose pull && docker-compose up +``` + +#### Query the project + +Open your browser and head to `http://localhost:3000`. + +Finally, you should see a GraphQL playground is showing in the explorer and the schemas that ready to query. + +For the `subql-starter` project, you can try to query with the following code to get a taste of how it works. + +```graphql +{ + query { + starterEntities(first: 10) { + nodes { + field1 + field2 + field3 + } + } + } +} +``` From d12aae582a898e2b7f2f0381877c6020dd26cab4 Mon Sep 17 00:00:00 2001 From: youssefea Date: Thu, 22 Jun 2023 21:57:44 +0100 Subject: [PATCH 02/14] first commit to Moonbeam substrate evm starter --- .../moonbeam-substrate-evm-starter/.gitignore | 55 +++++ .../moonbeam-substrate-evm-starter/LICENSE | 21 ++ .../moonbeam-substrate-evm-starter/README.md | 37 ++- .../docker-compose.yml | 47 ++++ .../erc20.abi.json | 222 ++++++++++++++++++ .../package.json | 30 +++ .../project.yaml | 49 ++++ .../schema.graphql | 16 ++ .../src/index.ts | 2 + .../src/mappings/mappingHandlers.ts | 37 +++ .../tsconfig.json | 18 ++ .../moonbeam-substrate-evm-starter/types.yaml | 180 ++++++++++++++ 12 files changed, 694 insertions(+), 20 deletions(-) create mode 100644 Moonbeam/moonbeam-substrate-evm-starter/.gitignore create mode 100644 Moonbeam/moonbeam-substrate-evm-starter/LICENSE create mode 100644 Moonbeam/moonbeam-substrate-evm-starter/docker-compose.yml create mode 100644 Moonbeam/moonbeam-substrate-evm-starter/erc20.abi.json create mode 100644 Moonbeam/moonbeam-substrate-evm-starter/package.json create mode 100644 Moonbeam/moonbeam-substrate-evm-starter/project.yaml create mode 100644 Moonbeam/moonbeam-substrate-evm-starter/schema.graphql create mode 100644 Moonbeam/moonbeam-substrate-evm-starter/src/index.ts create mode 100644 Moonbeam/moonbeam-substrate-evm-starter/src/mappings/mappingHandlers.ts create mode 100644 Moonbeam/moonbeam-substrate-evm-starter/tsconfig.json create mode 100644 Moonbeam/moonbeam-substrate-evm-starter/types.yaml diff --git a/Moonbeam/moonbeam-substrate-evm-starter/.gitignore b/Moonbeam/moonbeam-substrate-evm-starter/.gitignore new file mode 100644 index 00000000..f032df43 --- /dev/null +++ b/Moonbeam/moonbeam-substrate-evm-starter/.gitignore @@ -0,0 +1,55 @@ +# These are some examples of commonly ignored file patterns. +# You should customize this list as applicable to your project. +# Learn more about .gitignore: +# https://www.atlassian.com/git/tutorials/saving-changes/gitignore + +# Node artifact files +node_modules/ +dist/ + +# lock files +yarn.lock +package-lock.json + +# Compiled Java class files +*.class + +# Compiled Python bytecode +*.py[cod] + +# Log files +*.log + +# Package files +*.jar + +# Maven +target/ +dist/ +src/types + +# JetBrains IDE +.idea/ + +# Unit test reports +TEST*.xml + +# Generated by MacOS +.DS_Store + +# Generated by Windows +Thumbs.db + +# Applications +*.app +*.exe +*.war + +# Large media files +*.mp4 +*.tiff +*.avi +*.flv +*.mov +*.wmv + diff --git a/Moonbeam/moonbeam-substrate-evm-starter/LICENSE b/Moonbeam/moonbeam-substrate-evm-starter/LICENSE new file mode 100644 index 00000000..3c806ae5 --- /dev/null +++ b/Moonbeam/moonbeam-substrate-evm-starter/LICENSE @@ -0,0 +1,21 @@ +MIT LICENSE + +Copyright 2020-2021 OnFinality Limited authors & contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Moonbeam/moonbeam-substrate-evm-starter/README.md b/Moonbeam/moonbeam-substrate-evm-starter/README.md index d5334f6b..e21cd2ba 100644 --- a/Moonbeam/moonbeam-substrate-evm-starter/README.md +++ b/Moonbeam/moonbeam-substrate-evm-starter/README.md @@ -1,17 +1,17 @@ # SubQuery - Starter Package -A basic Frontier EVM example project with an event and call handler. Read more about this at https://university.subquery.network/build/substrate-evm.html. This project can be use as a starting point for developing your SubQuery project The Starter Package is an example that you can use as a starting point for developing your SubQuery project. -A SubQuery package defines which data The SubQuery will index from the Substrate blockchain, and how it will store it. +A SubQuery package defines which data The SubQuery will index from the Substrate blockchain, and how it will store it. ## Preparation #### Environment -- [Typescript](https://www.typescriptlang.org/) are required to compile project and define types. +- [Typescript](https://www.typescriptlang.org/) are required to compile project and define types. - Both SubQuery CLI and generated Project have dependencies and require [Node](https://nodejs.org/en/). + #### Install the SubQuery CLI @@ -22,7 +22,6 @@ npm install -g @subql/cli ``` Run help to see available commands and usage provide by CLI - ``` subql help ``` @@ -30,19 +29,17 @@ subql help ## Initialize the starter package Inside the directory in which you want to create the SubQuery project, simply replace `project-name` with your project name and run the command: - ``` -subql init project-name +subql init --starter project-name ``` - Then you should see a folder with your project name has been created inside the directory, you can use this as the start point of your project. And the files should be identical as in the [Directory Structure](https://doc.subquery.network/directory_structure.html). Last, under the project directory, run following command to install all the dependency. - ``` yarn install ``` + ## Configure your project In the starter package, we have provided a simple example of project configuration. You will be mainly working on the following files: @@ -51,17 +48,17 @@ In the starter package, we have provided a simple example of project configurati - The GraphQL Schema in `schema.graphql` - The Mapping functions in `src/mappings/` directory -For more information on how to write the SubQuery, -check out our doc section on [Define the SubQuery](https://doc.subquery.network/define_a_subquery.html) +For more information on how to write the SubQuery, +check out our doc section on [Define the SubQuery](https://doc.subquery.network/define_a_subquery.html) #### Code generation In order to index your SubQuery project, it is mandatory to build your project first. Run this command under the project directory. -``` +```` yarn codegen -``` +```` ## Build the project @@ -76,12 +73,12 @@ yarn build #### Run required systems in docker + Under the project directory run following command: ``` docker-compose pull && docker-compose up ``` - #### Query the project Open your browser and head to `http://localhost:3000`. @@ -90,16 +87,16 @@ Finally, you should see a GraphQL playground is showing in the explorer and the For the `subql-starter` project, you can try to query with the following code to get a taste of how it works. -```graphql +````graphql { - query { - starterEntities(first: 10) { - nodes { - field1 - field2 + query{ + starterEntities(first:10){ + nodes{ + field1, + field2, field3 } } } } -``` +```` diff --git a/Moonbeam/moonbeam-substrate-evm-starter/docker-compose.yml b/Moonbeam/moonbeam-substrate-evm-starter/docker-compose.yml new file mode 100644 index 00000000..9354dc03 --- /dev/null +++ b/Moonbeam/moonbeam-substrate-evm-starter/docker-compose.yml @@ -0,0 +1,47 @@ +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:latest + 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 + - --local + + graphql-engine: + image: onfinality/subql-query:latest + 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 diff --git a/Moonbeam/moonbeam-substrate-evm-starter/erc20.abi.json b/Moonbeam/moonbeam-substrate-evm-starter/erc20.abi.json new file mode 100644 index 00000000..06b572dd --- /dev/null +++ b/Moonbeam/moonbeam-substrate-evm-starter/erc20.abi.json @@ -0,0 +1,222 @@ +[ + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_spender", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_from", + "type": "address" + }, + { + "name": "_to", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "name": "balance", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_to", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_owner", + "type": "address" + }, + { + "name": "_spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "payable": true, + "stateMutability": "payable", + "type": "fallback" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "from", + "type": "address" + }, + { + "indexed": true, + "name": "to", + "type": "address" + }, + { + "indexed": false, + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + } +] diff --git a/Moonbeam/moonbeam-substrate-evm-starter/package.json b/Moonbeam/moonbeam-substrate-evm-starter/package.json new file mode 100644 index 00000000..65cea296 --- /dev/null +++ b/Moonbeam/moonbeam-substrate-evm-starter/package.json @@ -0,0 +1,30 @@ +{ + "name": "moonbuilders-demo", + "version": "1.0.0", + "description": "", + "main": "dist/index.js", + "scripts": { + "build": "tsc -b", + "prepack": "rm -rf dist && npm build", + "test": "jest", + "codegen": "./node_modules/.bin/subql codegen" + }, + "homepage": "https://github.com/subquery/subql-starter", + "repository": "github:subquery/subql-starter", + "files": [ + "dist", + "schema.graphql", + "project.yaml" + ], + "author": "Scott Twiname", + "license": "MIT", + "devDependencies": { + "@polkadot/api": "^6", + "@subql/cli": "latest", + "@subql/types": "latest", + "typescript": "^4.1.3" + }, + "dependencies": { + "@subql/contract-processors": "^0.3.2" + } +} diff --git a/Moonbeam/moonbeam-substrate-evm-starter/project.yaml b/Moonbeam/moonbeam-substrate-evm-starter/project.yaml new file mode 100644 index 00000000..1a41fe86 --- /dev/null +++ b/Moonbeam/moonbeam-substrate-evm-starter/project.yaml @@ -0,0 +1,49 @@ +specVersion: 0.2.0 +name: moonbuilders-demo +version: 1.0.0 +description: '' +repository: 'git@github.com:stwiname/moonbuilders-demo.git' +schema: + file: ./schema.graphql +network: + genesisHash: '0x401a1f9dca3da46f5c4091016c8a2f26dcea05865116b286f60f668207d1474b' + endpoint: 'wss://moonriver.api.onfinality.io/public-ws' + dictionary: 'https://api.subquery.network/sq/subquery/moonriver-dictionary' + chaintypes: + file: "./types.yaml" +dataSources: + - kind: substrate/Runtime + startBlock: 69218 + mapping: + file: './dist/index.js' + handlers: + - handler: collatorJoined + kind: substrate/EventHandler + filter: + module: parachainStaking + method: JoinedCollatorCandidates + - handler: collatorLeft + kind: substrate/CallHandler + filter: + module: parachainStaking + method: leaveCandidates + - kind: substrate/Moonbeam + startBlock: 562683 + processor: + file: './node_modules/@subql/contract-processors/dist/moonbeam.js' + options: + # Must be a key of assets + abi: erc20 + address: '0x6bd193ee6d2104f14f94e2ca6efefae561a4334b' + assets: + erc20: + file: './erc20.abi.json' + mapping: + file: ./dist/index.js + handlers: + - handler: erc20Transfer + kind: substrate/MoonbeamEvent + filter: + topics: + - Transfer(address indexed from,address indexed to,uint256 value) + diff --git a/Moonbeam/moonbeam-substrate-evm-starter/schema.graphql b/Moonbeam/moonbeam-substrate-evm-starter/schema.graphql new file mode 100644 index 00000000..b7d0f813 --- /dev/null +++ b/Moonbeam/moonbeam-substrate-evm-starter/schema.graphql @@ -0,0 +1,16 @@ +type Erc20Transfer @entity { + + id: ID! #id is a required field + + from: String! + to: String! + + contractAddress: String! + amount: BigInt! +} + +type Collator @entity { + id: ID! #collator address + + joinedDate: Date! +} diff --git a/Moonbeam/moonbeam-substrate-evm-starter/src/index.ts b/Moonbeam/moonbeam-substrate-evm-starter/src/index.ts new file mode 100644 index 00000000..55d8e9cd --- /dev/null +++ b/Moonbeam/moonbeam-substrate-evm-starter/src/index.ts @@ -0,0 +1,2 @@ +//Exports all handler functions +export * from './mappings/mappingHandlers' diff --git a/Moonbeam/moonbeam-substrate-evm-starter/src/mappings/mappingHandlers.ts b/Moonbeam/moonbeam-substrate-evm-starter/src/mappings/mappingHandlers.ts new file mode 100644 index 00000000..46e8136d --- /dev/null +++ b/Moonbeam/moonbeam-substrate-evm-starter/src/mappings/mappingHandlers.ts @@ -0,0 +1,37 @@ +import {SubstrateEvent, SubstrateExtrinsic} from "@subql/types"; +import {Erc20Transfer, Collator} from "../types"; +import { MoonbeamEvent } from '@subql/contract-processors/dist/moonbeam'; +import { BigNumber } from '@ethersproject/bignumber'; + +export async function collatorJoined(event: SubstrateEvent): Promise { + + const address = event.extrinsic.extrinsic.signer.toString(); + + const collator = Collator.create({ + id: address, + joinedDate: event.block.timestamp + }); + + await collator.save(); + +} + +export async function collatorLeft(call: SubstrateExtrinsic): Promise { + + const address = call.extrinsic.signer.toString(); + await Collator.remove(address); +} + +export async function erc20Transfer(event: MoonbeamEvent<[string, string, BigNumber] & { from: string, to: string, value: BigNumber, }>): Promise { + const transfer = Erc20Transfer.create({ + id: event.transactionHash, + from: event.args.from, + to: event.args.to, + amount: event.args.value.toBigInt(), + contractAddress: event.address, + }); + + await transfer.save(); +} + + diff --git a/Moonbeam/moonbeam-substrate-evm-starter/tsconfig.json b/Moonbeam/moonbeam-substrate-evm-starter/tsconfig.json new file mode 100644 index 00000000..9b95212d --- /dev/null +++ b/Moonbeam/moonbeam-substrate-evm-starter/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "esModuleInterop": true, + "declaration": true, + "importHelpers": true, + "resolveJsonModule": true, + "module": "commonjs", + "outDir": "dist", + "rootDir": "src", + "target": "es2017" + }, + "include": [ + "src/**/*", + "node_modules/@subql/types/dist/global.d.ts" + ] +} diff --git a/Moonbeam/moonbeam-substrate-evm-starter/types.yaml b/Moonbeam/moonbeam-substrate-evm-starter/types.yaml new file mode 100644 index 00000000..0e0587a6 --- /dev/null +++ b/Moonbeam/moonbeam-substrate-evm-starter/types.yaml @@ -0,0 +1,180 @@ +types: + AccountId: EthereumAccountId + Address: AccountId + Balance: u128 + LookupSource: AccountId + Account: + nonce: U256 + balance: u128 + ExtrinsicSignature: EthereumSignature + RoundIndex: u32 + Candidate: + id: AccountId + fee: Perbill + bond: Balance + nominators: Vec + total: Balance + state: CollatorStatus + Nominator: + nominations: Vec + total: Balance + Bond: + owner: AccountId + amount: Balance + TxPoolResultContent: + pending: HashMap> + queued: HashMap> + TxPoolResultInspect: + pending: HashMap> + queued: HashMap> + TxPoolResultStatus: + pending: U256 + queued: U256 + Summary: Bytes + PoolTransaction: + hash: H256 + nonce: U256 + blockHash: Option + blockNumber: Option + from: H160 + to: Option + value: U256 + gasPrice: U256 + gas: U256 + input: Bytes + AccountInfo: AccountInfoWithTripleRefCount + CollatorStatus: + _enum: + Active: 'Null' + Idle: 'Null' + Leaving: RoundIndex + Range: RangeBalance + RangeBalance: + min: Balance + ideal: Balance + max: Balance + RangePerbill: + min: Perbill + ideal: Perbill + max: Perbill + InflationInfo: + expect: RangeBalance + annual: RangePerbill + round: RangePerbill + OrderedSet: Vec + Collator: + id: AccountId + bond: Balance + nominators: Vec + total: Balance + state: CollatorStatus + CollatorSnapshot: + bond: Balance + nominators: Vec + total: Balance + SystemInherentData: + validationData: PersistedValidationData + relayChain_state: StorageProof + downwardMessages: Vec + horizontalMessages: BTreeMap> + RoundInfo: + current: RoundIndex + first: BlockNumber + length: u32 + AuthorId: AccountId32 + AccountId32: H256 + RelayChainAccountId: AccountId32 + RewardInfo: + totalReward: Balance + claimedReward: Balance + contributedRelayAddresses: Vec + Collator2: + id: AccountId + bond: Balance + nominators: Vec + topNominators: Vec + bottomNominators: Vec + totalCounted: Balance + totalBacking: Balance + state: CollatorStatus + NominatorAdded: + _enum: + AddedToTop: Balance + AddedToBottom: 'Null' + RegistrationInfo: + account: AccountId + deposit: Balance + ParachainBondConfig: + account: AccountId + percent: Percent + EthereumSignature: + r: H256 + s: H256 + v: U8 + NominatorStatus: + _enum: + Active: 'Null' + Leaving: RoundIndex + Nominator2: + nominations: Vec + revocations: Vec + total: Balance + scheduledRevocationsCount: u32 + scheduledRevocationsTotal: Balance + status: NominatorStatus + ExitQ: + candidates: Vec + nominatorsLeaving: Vec + candidateSchedule: Vec<(AccountId, RoundIndex)> + nominatorSchedule: Vec<(AccountId, Option, RoundIndex)> + AssetType: + _enum: + Xcm: MultiLocation + AssetId: u128 + TAssetBalance: u128 + ENUM_AccountId32: + network: NetworkId + id: "[u8; 32]" + ENUM_AccountKey20: + network: NetworkId + key: "[u8; 20]" + ENUM_AccountIndex64: + network: NetworkId + index: Compact + ENUM_Plurality: + id: BodyId + part: BodyPart + JunctionV0: + _enum: + Parent: 'Null' + Parachain: Compact + AccountId32: ENUM_AccountId32 + AccountIndex64: ENUM_AccountIndex64 + AccountKey20: ENUM_AccountKey20 + PalletInstance: u8 + GeneralIndex: Compact + GeneralKey: Vec + OnlyChild: 'Null' + Plurality: ENUM_Plurality + CurrencyId: + _enum: + SelfReserve: 'Null' + OtherReserve: u128 + AssetRegistrarMetadata: + name: Vec + symbol: Vec + decimals: u8 + isFrozen: bool + VestingBlockNumber: u32 + MultiLocation: MultiLocationV1 + JunctionV1: + _enum: + Parachain: Compact + AccountId32: ENUM_AccountId32 + AccountIndex64: ENUM_AccountIndex64 + AccountKey20: ENUM_AccountKey20 + PalletInstance: u8 + GeneralIndex: Compact + GeneralKey: Vec + OnlyChild: 'Null' + Plurality: ENUM_Plurality From 36202998b7b5070bc0001bf0791f1bdeebe8bd65 Mon Sep 17 00:00:00 2001 From: youssefea Date: Thu, 22 Jun 2023 22:58:20 +0100 Subject: [PATCH 03/14] "add moonbeam substrate evm starter" --- Moonbeam/moonbeam-substrate-evm-starter/project.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Moonbeam/moonbeam-substrate-evm-starter/project.yaml b/Moonbeam/moonbeam-substrate-evm-starter/project.yaml index 1a41fe86..397b6a0b 100644 --- a/Moonbeam/moonbeam-substrate-evm-starter/project.yaml +++ b/Moonbeam/moonbeam-substrate-evm-starter/project.yaml @@ -20,12 +20,12 @@ dataSources: - handler: collatorJoined kind: substrate/EventHandler filter: - module: parachainStaking + module: staking method: JoinedCollatorCandidates - handler: collatorLeft kind: substrate/CallHandler filter: - module: parachainStaking + module: staking method: leaveCandidates - kind: substrate/Moonbeam startBlock: 562683 From 3dbe886d1f14ddce2d7fb1d248d4845f026d8ec5 Mon Sep 17 00:00:00 2001 From: youssefea Date: Thu, 22 Jun 2023 22:59:42 +0100 Subject: [PATCH 04/14] add new moonbeam starter files --- .../.github/scripts/publish-deploy.sh | 15 + .../.github/workflows/cli-deploy.yml | 34 ++ .../.github/workflows/pr.yml | 24 + .../moonbeam-substrate-evm-starter/.gitignore | 1 + .../moonbeam-substrate-evm-starter/README.md | 44 +- .../abis/erc20Metadata.json | 457 ++++++++++++++++++ .../docker-compose.yml | 30 +- .../docker/load-extensions.sh | 5 + .../docker/pg-Dockerfile | 9 + .../package.json | 34 +- .../schema.graphql | 37 +- .../src/chaintypes.ts | 39 ++ .../src/index.ts | 3 +- .../src/mappings/mappingHandlers.ts | 143 +++++- .../src/test/mappingHandlers.test.ts | 12 + .../tsconfig.json | 5 +- 16 files changed, 818 insertions(+), 74 deletions(-) create mode 100644 Moonbeam/moonbeam-substrate-evm-starter/.github/scripts/publish-deploy.sh create mode 100644 Moonbeam/moonbeam-substrate-evm-starter/.github/workflows/cli-deploy.yml create mode 100644 Moonbeam/moonbeam-substrate-evm-starter/.github/workflows/pr.yml create mode 100644 Moonbeam/moonbeam-substrate-evm-starter/abis/erc20Metadata.json create mode 100644 Moonbeam/moonbeam-substrate-evm-starter/docker/load-extensions.sh create mode 100644 Moonbeam/moonbeam-substrate-evm-starter/docker/pg-Dockerfile create mode 100644 Moonbeam/moonbeam-substrate-evm-starter/src/chaintypes.ts create mode 100644 Moonbeam/moonbeam-substrate-evm-starter/src/test/mappingHandlers.test.ts diff --git a/Moonbeam/moonbeam-substrate-evm-starter/.github/scripts/publish-deploy.sh b/Moonbeam/moonbeam-substrate-evm-starter/.github/scripts/publish-deploy.sh new file mode 100644 index 00000000..3c9dc04b --- /dev/null +++ b/Moonbeam/moonbeam-substrate-evm-starter/.github/scripts/publish-deploy.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +while getopts p:o:e: flag +do + case "${flag}" in + e) ENDPOINT=${OPTARG};; + p) PROJECTNAME=${OPTARG};; + o) ORG=${OPTARG};; + *) echo "Usage: $0 [-p projectname] [-o org] [-e endpoint]" && exit 1;; + esac +done + +IPFSCID=$(npx subql publish -o -f .) + +npx subql deployment:deploy -d --ipfsCID="$IPFSCID" --projectName="${PROJECTNAME}" --org="${ORG%/*}" --endpoint="${ENDPOINT}" diff --git a/Moonbeam/moonbeam-substrate-evm-starter/.github/workflows/cli-deploy.yml b/Moonbeam/moonbeam-substrate-evm-starter/.github/workflows/cli-deploy.yml new file mode 100644 index 00000000..658d2c6c --- /dev/null +++ b/Moonbeam/moonbeam-substrate-evm-starter/.github/workflows/cli-deploy.yml @@ -0,0 +1,34 @@ +name: "CLI deploy" + +on: + workflow_dispatch: + inputs: + projectName: + description: "Project name" + required: true + type: string +jobs: + deploy: + name: CLI Deploy + runs-on: ubuntu-latest + environment: + name: DEPLOYMENT + env: + SUBQL_ACCESS_TOKEN: ${{ secrets.SUBQL_ACCESS_TOKEN }} + ENDPOINT: ${{ secrets.ENDPOINT }} + steps: + - uses: actions/checkout@v2 + - name: Setup Node.js environment + uses: actions/setup-node@v2 + with: + node-version: 16 + - run: yarn + - name: Codegen + run: yarn codegen + - name: Version + run: npx subql --version + - name: repo + run: echo ${{github.repository}} + - name: Publish and Deploy + run: | + sh .github/workflows/scripts/publish-deploy.sh -o ${{github.repository}} -p ${{github.event.inputs.projectName}} -e ${{secrets.ENDPOINT}} diff --git a/Moonbeam/moonbeam-substrate-evm-starter/.github/workflows/pr.yml b/Moonbeam/moonbeam-substrate-evm-starter/.github/workflows/pr.yml new file mode 100644 index 00000000..b428f2d8 --- /dev/null +++ b/Moonbeam/moonbeam-substrate-evm-starter/.github/workflows/pr.yml @@ -0,0 +1,24 @@ +name: PR +on: + pull_request: + paths-ignore: + - ".github/workflows/**" +jobs: + pr: + name: pr + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Setup Node.js environment + uses: actions/setup-node@v2 + with: + node-version: 16 + - run: yarn + - name: Codegen + run: yarn codegen + - name: Build + run: yarn build + - name: Install subql-node + run: yarn global add @subql/node + - name: Run tests with Subquery Node + run: subql-node test -f ${{ github.workspace }} diff --git a/Moonbeam/moonbeam-substrate-evm-starter/.gitignore b/Moonbeam/moonbeam-substrate-evm-starter/.gitignore index f032df43..4a94e1b9 100644 --- a/Moonbeam/moonbeam-substrate-evm-starter/.gitignore +++ b/Moonbeam/moonbeam-substrate-evm-starter/.gitignore @@ -53,3 +53,4 @@ Thumbs.db *.mov *.wmv +.data \ No newline at end of file diff --git a/Moonbeam/moonbeam-substrate-evm-starter/README.md b/Moonbeam/moonbeam-substrate-evm-starter/README.md index e21cd2ba..374b807d 100644 --- a/Moonbeam/moonbeam-substrate-evm-starter/README.md +++ b/Moonbeam/moonbeam-substrate-evm-starter/README.md @@ -1,17 +1,15 @@ # SubQuery - Starter Package - The Starter Package is an example that you can use as a starting point for developing your SubQuery project. -A SubQuery package defines which data The SubQuery will index from the Substrate blockchain, and how it will store it. +A SubQuery package defines which data The SubQuery will index from the Substrate blockchain, and how it will store it. ## Preparation #### Environment -- [Typescript](https://www.typescriptlang.org/) are required to compile project and define types. +- [Typescript](https://www.typescriptlang.org/) are required to compile project and define types. - Both SubQuery CLI and generated Project have dependencies and require [Node](https://nodejs.org/en/). - #### Install the SubQuery CLI @@ -22,6 +20,7 @@ npm install -g @subql/cli ``` Run help to see available commands and usage provide by CLI + ``` subql help ``` @@ -29,17 +28,19 @@ subql help ## Initialize the starter package Inside the directory in which you want to create the SubQuery project, simply replace `project-name` with your project name and run the command: + ``` subql init --starter project-name ``` + Then you should see a folder with your project name has been created inside the directory, you can use this as the start point of your project. And the files should be identical as in the [Directory Structure](https://doc.subquery.network/directory_structure.html). Last, under the project directory, run following command to install all the dependency. + ``` yarn install ``` - ## Configure your project In the starter package, we have provided a simple example of project configuration. You will be mainly working on the following files: @@ -48,17 +49,17 @@ In the starter package, we have provided a simple example of project configurati - The GraphQL Schema in `schema.graphql` - The Mapping functions in `src/mappings/` directory -For more information on how to write the SubQuery, -check out our doc section on [Define the SubQuery](https://doc.subquery.network/define_a_subquery.html) +For more information on how to write the SubQuery, +check out our doc section on [Define the SubQuery](https://doc.subquery.network/define_a_subquery.html) #### Code generation In order to index your SubQuery project, it is mandatory to build your project first. Run this command under the project directory. -```` +``` yarn codegen -```` +``` ## Build the project @@ -73,12 +74,12 @@ yarn build #### Run required systems in docker - Under the project directory run following command: ``` docker-compose pull && docker-compose up ``` + #### Query the project Open your browser and head to `http://localhost:3000`. @@ -87,16 +88,19 @@ Finally, you should see a GraphQL playground is showing in the explorer and the For the `subql-starter` project, you can try to query with the following code to get a taste of how it works. -````graphql -{ - query{ - starterEntities(first:10){ - nodes{ - field1, - field2, - field3 - } +```graphql +query { + transactions(first:3 orderBy:BLOCK_HEIGHT_ASC){ + totalCount + nodes{ + blockHeight + timestamp + transactionHash + blockHash + contractAddress + from + value } } } -```` +``` diff --git a/Moonbeam/moonbeam-substrate-evm-starter/abis/erc20Metadata.json b/Moonbeam/moonbeam-substrate-evm-starter/abis/erc20Metadata.json new file mode 100644 index 00000000..c6361bef --- /dev/null +++ b/Moonbeam/moonbeam-substrate-evm-starter/abis/erc20Metadata.json @@ -0,0 +1,457 @@ +{ + "source": { + "hash": "0x85297d9db0204852b790e8f89a3350a687ba1c7bf9ee93bd2d9953005a4c34be", + "language": "ink! 3.4.0", + "compiler": "rustc 1.67.0-nightly" + }, + "contract": { + "name": "lottery", + "version": "0.1.0", + "authors": ["Nikhil Ranjan"] + }, + "V3": { + "spec": { + "constructors": [ + { + "args": [], + "docs": [], + "label": "new", + "payable": false, + "selector": "0x9bae9d5e" + } + ], + "docs": [], + "events": [ + { + "args": [ + { + "docs": [" The player who entered."], + "indexed": false, + "label": "player", + "type": { + "displayName": ["AccountId"], + "type": 0 + } + }, + { + "docs": [" The value sent."], + "indexed": false, + "label": "value", + "type": { + "displayName": ["Balance"], + "type": 6 + } + } + ], + "docs": [], + "label": "Entered" + }, + { + "args": [ + { + "docs": [" The winner."], + "indexed": false, + "label": "winner", + "type": { + "displayName": ["AccountId"], + "type": 0 + } + }, + { + "docs": [" The winning amount."], + "indexed": false, + "label": "amount", + "type": { + "displayName": ["Balance"], + "type": 6 + } + } + ], + "docs": [], + "label": "Won" + } + ], + "messages": [ + { + "args": [], + "docs": [" Returns the current owner of the lottery"], + "label": "owner", + "mutates": false, + "payable": false, + "returnType": { + "displayName": ["AccountId"], + "type": 0 + }, + "selector": "0xfeaea4fa" + }, + { + "args": [], + "docs": [], + "label": "pot", + "mutates": false, + "payable": false, + "returnType": { + "displayName": ["Balance"], + "type": 6 + }, + "selector": "0xd096c0d0" + }, + { + "args": [], + "docs": [" Returns the current state of the lottery"], + "label": "is_running", + "mutates": false, + "payable": false, + "returnType": { + "displayName": ["bool"], + "type": 3 + }, + "selector": "0x1b0e6452" + }, + { + "args": [], + "docs": [" Returns the list of players"], + "label": "get_players", + "mutates": false, + "payable": false, + "returnType": { + "displayName": ["Vec"], + "type": 4 + }, + "selector": "0xa3355842" + }, + { + "args": [ + { + "label": "caller", + "type": { + "displayName": ["AccountId"], + "type": 0 + } + } + ], + "docs": [" Retrieve the balance of the account."], + "label": "get_balance", + "mutates": false, + "payable": false, + "returnType": { + "displayName": ["Option"], + "type": 8 + }, + "selector": "0xea817e65" + }, + { + "args": [], + "docs": [" Allows a player to enter the lottery by sending a value"], + "label": "enter", + "mutates": true, + "payable": true, + "returnType": { + "displayName": ["Result"], + "type": 9 + }, + "selector": "0x8883954a" + }, + { + "args": [], + "docs": [], + "label": "pick_winner", + "mutates": true, + "payable": false, + "returnType": { + "displayName": ["Result"], + "type": 9 + }, + "selector": "0x1d49cc13" + }, + { + "args": [], + "docs": [], + "label": "start_lottery", + "mutates": true, + "payable": false, + "returnType": { + "displayName": ["Result"], + "type": 9 + }, + "selector": "0x996e2d9b" + }, + { + "args": [], + "docs": [], + "label": "stop_lottery", + "mutates": true, + "payable": false, + "returnType": { + "displayName": ["Result"], + "type": 9 + }, + "selector": "0xcb2815e1" + } + ] + }, + "storage": { + "struct": { + "fields": [ + { + "layout": { + "cell": { + "key": "0x0000000000000000000000000000000000000000000000000000000000000000", + "ty": 0 + } + }, + "name": "owner" + }, + { + "layout": { + "cell": { + "key": "0x0100000000000000000000000000000000000000000000000000000000000000", + "ty": 3 + } + }, + "name": "running" + }, + { + "layout": { + "cell": { + "key": "0x0200000000000000000000000000000000000000000000000000000000000000", + "ty": 4 + } + }, + "name": "players" + }, + { + "layout": { + "cell": { + "key": "0x0300000000000000000000000000000000000000000000000000000000000000", + "ty": 5 + } + }, + "name": "entries" + } + ] + } + }, + "types": [ + { + "id": 0, + "type": { + "def": { + "composite": { + "fields": [ + { + "type": 1, + "typeName": "[u8; 32]" + } + ] + } + }, + "path": ["ink_env", "types", "AccountId"] + } + }, + { + "id": 1, + "type": { + "def": { + "array": { + "len": 32, + "type": 2 + } + } + } + }, + { + "id": 2, + "type": { + "def": { + "primitive": "u8" + } + } + }, + { + "id": 3, + "type": { + "def": { + "primitive": "bool" + } + } + }, + { + "id": 4, + "type": { + "def": { + "sequence": { + "type": 0 + } + } + } + }, + { + "id": 5, + "type": { + "def": { + "composite": { + "fields": [ + { + "name": "offset_key", + "type": 7, + "typeName": "Key" + } + ] + } + }, + "params": [ + { + "name": "K", + "type": 0 + }, + { + "name": "V", + "type": 6 + } + ], + "path": ["ink_storage", "lazy", "mapping", "Mapping"] + } + }, + { + "id": 6, + "type": { + "def": { + "primitive": "u128" + } + } + }, + { + "id": 7, + "type": { + "def": { + "composite": { + "fields": [ + { + "type": 1, + "typeName": "[u8; 32]" + } + ] + } + }, + "path": ["ink_primitives", "Key"] + } + }, + { + "id": 8, + "type": { + "def": { + "variant": { + "variants": [ + { + "index": 0, + "name": "None" + }, + { + "fields": [ + { + "type": 6 + } + ], + "index": 1, + "name": "Some" + } + ] + } + }, + "params": [ + { + "name": "T", + "type": 6 + } + ], + "path": ["Option"] + } + }, + { + "id": 9, + "type": { + "def": { + "variant": { + "variants": [ + { + "fields": [ + { + "type": 10 + } + ], + "index": 0, + "name": "Ok" + }, + { + "fields": [ + { + "type": 11 + } + ], + "index": 1, + "name": "Err" + } + ] + } + }, + "params": [ + { + "name": "T", + "type": 10 + }, + { + "name": "E", + "type": 11 + } + ], + "path": ["Result"] + } + }, + { + "id": 10, + "type": { + "def": { + "tuple": [] + } + } + }, + { + "id": 11, + "type": { + "def": { + "variant": { + "variants": [ + { + "index": 0, + "name": "LotteryNotRunning" + }, + { + "index": 1, + "name": "CallerNotOwner" + }, + { + "index": 2, + "name": "NoValueSent" + }, + { + "index": 3, + "name": "ErrTransfer" + }, + { + "index": 4, + "name": "PlayerAlreadyInLottery" + }, + { + "index": 5, + "name": "NoEntries" + } + ] + } + }, + "path": ["lottery", "lottery", "Error"] + } + } + ] + } +} diff --git a/Moonbeam/moonbeam-substrate-evm-starter/docker-compose.yml b/Moonbeam/moonbeam-substrate-evm-starter/docker-compose.yml index 9354dc03..ff58acb6 100644 --- a/Moonbeam/moonbeam-substrate-evm-starter/docker-compose.yml +++ b/Moonbeam/moonbeam-substrate-evm-starter/docker-compose.yml @@ -1,19 +1,27 @@ -version: '3' +version: "3" services: postgres: - image: postgres:12-alpine + build: + context: . + dockerfile: ./docker/pg-Dockerfile ports: - 5432:5432 volumes: - .data/postgres:/var/lib/postgresql/data environment: POSTGRES_PASSWORD: postgres + healthcheck: + test: ["CMD-SHELL", "pg_isready -U postgres"] + interval: 5s + timeout: 5s + retries: 5 subquery-node: image: onfinality/subql-node:latest depends_on: - - "postgres" + "postgres": + condition: service_healthy restart: always environment: DB_USER: postgres @@ -23,17 +31,25 @@ services: DB_PORT: 5432 volumes: - ./:/app - command: + command: + - ${SUB_COMMAND} # set SUB_COMMAND env variable to "test" to run tests - -f=/app - - --local + - --db-schema=app + healthcheck: + test: ["CMD", "curl", "-f", "http://subquery-node:3000/ready"] + interval: 3s + timeout: 5s + retries: 10 graphql-engine: image: onfinality/subql-query:latest ports: - 3000:3000 depends_on: - - "postgres" - - "subquery-node" + "postgres": + condition: service_healthy + "subquery-node": + condition: service_healthy restart: always environment: DB_USER: postgres diff --git a/Moonbeam/moonbeam-substrate-evm-starter/docker/load-extensions.sh b/Moonbeam/moonbeam-substrate-evm-starter/docker/load-extensions.sh new file mode 100644 index 00000000..6d33f863 --- /dev/null +++ b/Moonbeam/moonbeam-substrate-evm-starter/docker/load-extensions.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <", + formerStakedEra: "EraIndex", + claimedRewards: "Balance", + }, + EraRewardAndStake: { + rewards: "Balance", + staked: "Balance", + }, + EraIndex: "u32", + }, + }, + ], +}; + +export default { typesBundle: definitions }; diff --git a/Moonbeam/moonbeam-substrate-evm-starter/src/index.ts b/Moonbeam/moonbeam-substrate-evm-starter/src/index.ts index 55d8e9cd..89dc0c5f 100644 --- a/Moonbeam/moonbeam-substrate-evm-starter/src/index.ts +++ b/Moonbeam/moonbeam-substrate-evm-starter/src/index.ts @@ -1,2 +1,3 @@ //Exports all handler functions -export * from './mappings/mappingHandlers' +import "@polkadot/api-augment"; +export * from "./mappings/mappingHandlers"; diff --git a/Moonbeam/moonbeam-substrate-evm-starter/src/mappings/mappingHandlers.ts b/Moonbeam/moonbeam-substrate-evm-starter/src/mappings/mappingHandlers.ts index 46e8136d..1350ae50 100644 --- a/Moonbeam/moonbeam-substrate-evm-starter/src/mappings/mappingHandlers.ts +++ b/Moonbeam/moonbeam-substrate-evm-starter/src/mappings/mappingHandlers.ts @@ -1,37 +1,134 @@ -import {SubstrateEvent, SubstrateExtrinsic} from "@subql/types"; -import {Erc20Transfer, Collator} from "../types"; -import { MoonbeamEvent } from '@subql/contract-processors/dist/moonbeam'; -import { BigNumber } from '@ethersproject/bignumber'; +import { Approval, DApp, DAppReward, Transaction } from "../types"; +import { WasmCall, WasmEvent } from "@subql/substrate-wasm-processor"; +import { Balance, AccountId } from "@polkadot/types/interfaces/runtime"; +import { Option } from "@polkadot/types-codec"; +import { SubstrateEvent } from "@subql/types"; -export async function collatorJoined(event: SubstrateEvent): Promise { +// Setup types from ABI +type ApproveCallArgs = [AccountId, Balance]; +type TransferEventArgs = [Option, Option, Balance]; - const address = event.extrinsic.extrinsic.signer.toString(); - - const collator = Collator.create({ - id: address, - joinedDate: event.block.timestamp - }); +export async function handleWasmCall( + call: WasmCall +): Promise { + logger.info(`Processing WASM Call at ${call.blockNumber}`); + const approval = new Approval(`${call.blockNumber}-${call.idx}`); + approval.hash = call.hash; + approval.owner = call.from.toString(); + approval.contractAddress = call.dest.toString(); + if (typeof call.data !== "string") { + const [spender, value] = call.data.args; + approval.spender = spender.toString(); + approval.value = value.toBigInt(); + } else { + logger.info(`Decode call failed ${call.hash}`); + } + await approval.save(); +} - await collator.save(); +export async function handleWasmEvent( + event: WasmEvent +): Promise { + logger.info(`Processing WASM Even at ${event.blockNumber}`); + const [from, to, value] = event.args; + const transaction = Transaction.create({ + id: `${event.blockNumber}-${event.eventIndex}`, + transactionHash: event.transactionHash, + value: value.toBigInt(), + from: from.toString(), + to: to.toString(), + contractAddress: event.contract.toString(), + }); + await transaction.save(); } -export async function collatorLeft(call: SubstrateExtrinsic): Promise { +export async function handleNewContract(event: SubstrateEvent): Promise { + logger.info( + `Processing new Dapp Staking Contract event at ${event.block.block.header.number}` + ); + const { + event: { + data: [accountId, smartContract], + }, + } = event; + // Retrieve the record by its ID + let dapp: DApp = await DApp.get(smartContract.toString()); + if (!dapp) { + dapp = DApp.create({ + id: smartContract.toString(), + accountID: accountId.toString(), + totalStake: BigInt(0), + }); - const address = call.extrinsic.signer.toString(); - await Collator.remove(address); + await dapp.save(); + } } -export async function erc20Transfer(event: MoonbeamEvent<[string, string, BigNumber] & { from: string, to: string, value: BigNumber, }>): Promise { - const transfer = Erc20Transfer.create({ - id: event.transactionHash, - from: event.args.from, - to: event.args.to, - amount: event.args.value.toBigInt(), - contractAddress: event.address, +export async function handleBondAndStake(event: SubstrateEvent): Promise { + logger.info( + `Processing new Dapp Staking Bond and Stake event at ${event.block.block.header.number}` + ); + const { + event: { + data: [accountId, smartContract, balanceOf], + }, + } = event; + // Retrieve the dapp by its ID + let dapp: DApp = await DApp.get(smartContract.toString()); + if (!dapp) { + dapp = DApp.create({ + id: smartContract.toString(), + accountID: accountId.toString(), + totalStake: BigInt(0), }); + } - await transfer.save(); + dapp.totalStake += (balanceOf as Balance).toBigInt(); + await dapp.save(); } +export async function handleUnbondAndUnstake( + event: SubstrateEvent +): Promise { + logger.info( + `Processing new Dapp Staking Bond and Unstake event at ${event.block.block.header.number}` + ); + const { + event: { + data: [accountId, smartContract, balanceOf], + }, + } = event; + // Retrieve the dapp by its ID + let dapp: DApp = await DApp.get(smartContract.toString()); + if (!dapp) { + dapp = DApp.create({ + id: smartContract.toString(), + accountID: accountId.toString(), + totalStake: BigInt(0), + }); + } + + dapp.totalStake -= (balanceOf as Balance).toBigInt(); + await dapp.save(); +} +export async function handleReward(event: SubstrateEvent): Promise { + logger.info( + `Processing new Dapp Staking Reward event at ${event.block.block.header.number}` + ); + const { + event: { + data: [accountID, smartContract, eraIndex, balanceOf], + }, + } = event; + // Retrieve the record by its ID + const dAppReward: DAppReward = DAppReward.create({ + id: `${event.block.block.header.number.toNumber()}-${event.idx}`, + dAppId: smartContract.toString(), + accountID: accountID.toString(), + eraIndex: parseInt(eraIndex.toString()), + balanceOf: (balanceOf as Balance).toBigInt(), + }); + await dAppReward.save(); +} diff --git a/Moonbeam/moonbeam-substrate-evm-starter/src/test/mappingHandlers.test.ts b/Moonbeam/moonbeam-substrate-evm-starter/src/test/mappingHandlers.test.ts new file mode 100644 index 00000000..fc12d09a --- /dev/null +++ b/Moonbeam/moonbeam-substrate-evm-starter/src/test/mappingHandlers.test.ts @@ -0,0 +1,12 @@ +import {subqlTest} from "@subql/testing"; + +/* +// https://academy.subquery.network/build/testing.html +subqlTest( + "testName", // test name + 1000003, // block height to process + [], // dependent entities + [], // expected entities + "handleEvent" //handler name +); +*/ diff --git a/Moonbeam/moonbeam-substrate-evm-starter/tsconfig.json b/Moonbeam/moonbeam-substrate-evm-starter/tsconfig.json index 9b95212d..4be11b62 100644 --- a/Moonbeam/moonbeam-substrate-evm-starter/tsconfig.json +++ b/Moonbeam/moonbeam-substrate-evm-starter/tsconfig.json @@ -11,8 +11,5 @@ "rootDir": "src", "target": "es2017" }, - "include": [ - "src/**/*", - "node_modules/@subql/types/dist/global.d.ts" - ] + "include": ["src/**/*", "node_modules/@subql/types/dist/global.d.ts"] } From 32726b583c2a29676481d12bfa4ae5ed98eadbbb Mon Sep 17 00:00:00 2001 From: youssefea Date: Thu, 22 Jun 2023 23:28:27 +0100 Subject: [PATCH 05/14] Updating manifest file --- .../project.yaml | 51 +++++++++++++------ .../schema.graphql | 37 ++++---------- 2 files changed, 44 insertions(+), 44 deletions(-) diff --git a/Moonbeam/moonbeam-substrate-evm-starter/project.yaml b/Moonbeam/moonbeam-substrate-evm-starter/project.yaml index 397b6a0b..7e0a84b2 100644 --- a/Moonbeam/moonbeam-substrate-evm-starter/project.yaml +++ b/Moonbeam/moonbeam-substrate-evm-starter/project.yaml @@ -1,16 +1,35 @@ -specVersion: 0.2.0 +specVersion: 1.0.0 name: moonbuilders-demo -version: 1.0.0 -description: '' -repository: 'git@github.com:stwiname/moonbuilders-demo.git' +version: 0.0.1 +runner: + node: + name: "@subql/node" + version: "*" + query: + name: "@subql/query" + version: "*" +description: 'A basic Substrate EVM example project with an event and call handler. Read more + about this at https://academy.subquery.network/build/substrate-wasm.html. This + project can be use as a starting point for developing your SubQuery project' +repository: 'https://github.com/subquery/subql-starter.git' schema: file: ./schema.graphql network: - genesisHash: '0x401a1f9dca3da46f5c4091016c8a2f26dcea05865116b286f60f668207d1474b' - endpoint: 'wss://moonriver.api.onfinality.io/public-ws' - dictionary: 'https://api.subquery.network/sq/subquery/moonriver-dictionary' + # The genesis hash of the network (hash of block 0) + chainId: "0xfe58ea77779b7abda7da4ec526d14db9b1e9cd40a217c34892af80a9b332b76d" + # This endpoint must be a public non-pruned archive node + # Public nodes may be rate limited, which can affect indexing speed + # When developing your project we suggest getting a private API key + # You can get them from OnFinality for free https://app.onfinality.io + # https://documentation.onfinality.io/support/the-enhanced-api-service + endpoint: + [ + "wss://moonbeam.api.onfinality.io/public-ws", + "wss://wss.api.moonbeam.network", + ] + dictionary: "https://api.subquery.network/sq/subquery/moonbeam-dictionary" chaintypes: - file: "./types.yaml" + file: ./dist/chaintypes.js dataSources: - kind: substrate/Runtime startBlock: 69218 @@ -21,27 +40,27 @@ dataSources: kind: substrate/EventHandler filter: module: staking - method: JoinedCollatorCandidates + method: joinCandidates - handler: collatorLeft kind: substrate/CallHandler filter: module: staking - method: leaveCandidates + method: executeLeaveCandidates - kind: substrate/Moonbeam - startBlock: 562683 + # This is the datasource for Moonbeam's EVM processor + startBlock: 3281780 processor: - file: './node_modules/@subql/contract-processors/dist/moonbeam.js' + file: ./node_modules/@subql/frontier-evm-processor/dist/bundle.js options: - # Must be a key of assets abi: erc20 - address: '0x6bd193ee6d2104f14f94e2ca6efefae561a4334b' + contract: "0x322E86852e492a7Ee17f28a78c663da38FB33bfb" # Mainnet assets: erc20: - file: './erc20.abi.json' + file: ./erc20.abi.json mapping: file: ./dist/index.js handlers: - - handler: erc20Transfer + - handler: handleErc20Transfer kind: substrate/MoonbeamEvent filter: topics: diff --git a/Moonbeam/moonbeam-substrate-evm-starter/schema.graphql b/Moonbeam/moonbeam-substrate-evm-starter/schema.graphql index ff03b26d..6f8badbf 100644 --- a/Moonbeam/moonbeam-substrate-evm-starter/schema.graphql +++ b/Moonbeam/moonbeam-substrate-evm-starter/schema.graphql @@ -2,38 +2,19 @@ # Add the `@index` or `@index(unique: true)` annotation after any non-key field # https://academy.subquery.network/build/graphql.html#indexing-by-non-primary-key-field -type Transaction @entity { - id: ID! # Transaction hash - transactionHash: String - blockHeight: BigInt - blockHash: String - timestamp: Date - value: BigInt +type Erc20Transfer @entity { + + id: ID! #id is a required field from: String! to: String! contractAddress: String! -} + amount: BigInt! -type Approval @entity { - id: ID! # Transaction hash - blockHeight: BigInt - value: BigInt - hash: String - owner: String! - spender: String! - contractAddress: String! } -type DApp @entity { - id: ID! #EVM is a required field - accountID: String! - totalStake: BigInt! -} +type Collator @entity { -type DAppReward @entity { - id: ID! - dApp: DApp! - accountID: String! - eraIndex: Int! - balanceOf: BigInt! -} + id: ID! #collator address + joinedDate: Date! + +} \ No newline at end of file From 275b7bb3c610ec115a7da16dd9ec9f794440cd16 Mon Sep 17 00:00:00 2001 From: youssefea Date: Fri, 23 Jun 2023 11:48:57 +0100 Subject: [PATCH 06/14] Restarting project --- .../.github/scripts/publish-deploy.sh | 15 - .../.github/workflows/cli-deploy.yml | 34 -- .../.github/workflows/pr.yml | 24 - .../moonbeam-substrate-evm-starter/.gitignore | 56 --- .../moonbeam-substrate-evm-starter/LICENSE | 21 - .../moonbeam-substrate-evm-starter/README.md | 106 ---- .../abis/erc20Metadata.json | 457 ------------------ .../docker-compose.yml | 63 --- .../docker/load-extensions.sh | 5 - .../docker/pg-Dockerfile | 9 - .../erc20.abi.json | 222 --------- .../package.json | 40 -- .../project.yaml | 68 --- .../schema.graphql | 20 - .../src/chaintypes.ts | 39 -- .../src/index.ts | 3 - .../src/mappings/mappingHandlers.ts | 134 ----- .../src/test/mappingHandlers.test.ts | 12 - .../tsconfig.json | 15 - .../moonbeam-substrate-evm-starter/types.yaml | 180 ------- 20 files changed, 1523 deletions(-) delete mode 100644 Moonbeam/moonbeam-substrate-evm-starter/.github/scripts/publish-deploy.sh delete mode 100644 Moonbeam/moonbeam-substrate-evm-starter/.github/workflows/cli-deploy.yml delete mode 100644 Moonbeam/moonbeam-substrate-evm-starter/.github/workflows/pr.yml delete mode 100644 Moonbeam/moonbeam-substrate-evm-starter/.gitignore delete mode 100644 Moonbeam/moonbeam-substrate-evm-starter/LICENSE delete mode 100644 Moonbeam/moonbeam-substrate-evm-starter/README.md delete mode 100644 Moonbeam/moonbeam-substrate-evm-starter/abis/erc20Metadata.json delete mode 100644 Moonbeam/moonbeam-substrate-evm-starter/docker-compose.yml delete mode 100644 Moonbeam/moonbeam-substrate-evm-starter/docker/load-extensions.sh delete mode 100644 Moonbeam/moonbeam-substrate-evm-starter/docker/pg-Dockerfile delete mode 100644 Moonbeam/moonbeam-substrate-evm-starter/erc20.abi.json delete mode 100644 Moonbeam/moonbeam-substrate-evm-starter/package.json delete mode 100644 Moonbeam/moonbeam-substrate-evm-starter/project.yaml delete mode 100644 Moonbeam/moonbeam-substrate-evm-starter/schema.graphql delete mode 100644 Moonbeam/moonbeam-substrate-evm-starter/src/chaintypes.ts delete mode 100644 Moonbeam/moonbeam-substrate-evm-starter/src/index.ts delete mode 100644 Moonbeam/moonbeam-substrate-evm-starter/src/mappings/mappingHandlers.ts delete mode 100644 Moonbeam/moonbeam-substrate-evm-starter/src/test/mappingHandlers.test.ts delete mode 100644 Moonbeam/moonbeam-substrate-evm-starter/tsconfig.json delete mode 100644 Moonbeam/moonbeam-substrate-evm-starter/types.yaml diff --git a/Moonbeam/moonbeam-substrate-evm-starter/.github/scripts/publish-deploy.sh b/Moonbeam/moonbeam-substrate-evm-starter/.github/scripts/publish-deploy.sh deleted file mode 100644 index 3c9dc04b..00000000 --- a/Moonbeam/moonbeam-substrate-evm-starter/.github/scripts/publish-deploy.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/bash - -while getopts p:o:e: flag -do - case "${flag}" in - e) ENDPOINT=${OPTARG};; - p) PROJECTNAME=${OPTARG};; - o) ORG=${OPTARG};; - *) echo "Usage: $0 [-p projectname] [-o org] [-e endpoint]" && exit 1;; - esac -done - -IPFSCID=$(npx subql publish -o -f .) - -npx subql deployment:deploy -d --ipfsCID="$IPFSCID" --projectName="${PROJECTNAME}" --org="${ORG%/*}" --endpoint="${ENDPOINT}" diff --git a/Moonbeam/moonbeam-substrate-evm-starter/.github/workflows/cli-deploy.yml b/Moonbeam/moonbeam-substrate-evm-starter/.github/workflows/cli-deploy.yml deleted file mode 100644 index 658d2c6c..00000000 --- a/Moonbeam/moonbeam-substrate-evm-starter/.github/workflows/cli-deploy.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: "CLI deploy" - -on: - workflow_dispatch: - inputs: - projectName: - description: "Project name" - required: true - type: string -jobs: - deploy: - name: CLI Deploy - runs-on: ubuntu-latest - environment: - name: DEPLOYMENT - env: - SUBQL_ACCESS_TOKEN: ${{ secrets.SUBQL_ACCESS_TOKEN }} - ENDPOINT: ${{ secrets.ENDPOINT }} - steps: - - uses: actions/checkout@v2 - - name: Setup Node.js environment - uses: actions/setup-node@v2 - with: - node-version: 16 - - run: yarn - - name: Codegen - run: yarn codegen - - name: Version - run: npx subql --version - - name: repo - run: echo ${{github.repository}} - - name: Publish and Deploy - run: | - sh .github/workflows/scripts/publish-deploy.sh -o ${{github.repository}} -p ${{github.event.inputs.projectName}} -e ${{secrets.ENDPOINT}} diff --git a/Moonbeam/moonbeam-substrate-evm-starter/.github/workflows/pr.yml b/Moonbeam/moonbeam-substrate-evm-starter/.github/workflows/pr.yml deleted file mode 100644 index b428f2d8..00000000 --- a/Moonbeam/moonbeam-substrate-evm-starter/.github/workflows/pr.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: PR -on: - pull_request: - paths-ignore: - - ".github/workflows/**" -jobs: - pr: - name: pr - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Setup Node.js environment - uses: actions/setup-node@v2 - with: - node-version: 16 - - run: yarn - - name: Codegen - run: yarn codegen - - name: Build - run: yarn build - - name: Install subql-node - run: yarn global add @subql/node - - name: Run tests with Subquery Node - run: subql-node test -f ${{ github.workspace }} diff --git a/Moonbeam/moonbeam-substrate-evm-starter/.gitignore b/Moonbeam/moonbeam-substrate-evm-starter/.gitignore deleted file mode 100644 index 4a94e1b9..00000000 --- a/Moonbeam/moonbeam-substrate-evm-starter/.gitignore +++ /dev/null @@ -1,56 +0,0 @@ -# These are some examples of commonly ignored file patterns. -# You should customize this list as applicable to your project. -# Learn more about .gitignore: -# https://www.atlassian.com/git/tutorials/saving-changes/gitignore - -# Node artifact files -node_modules/ -dist/ - -# lock files -yarn.lock -package-lock.json - -# Compiled Java class files -*.class - -# Compiled Python bytecode -*.py[cod] - -# Log files -*.log - -# Package files -*.jar - -# Maven -target/ -dist/ -src/types - -# JetBrains IDE -.idea/ - -# Unit test reports -TEST*.xml - -# Generated by MacOS -.DS_Store - -# Generated by Windows -Thumbs.db - -# Applications -*.app -*.exe -*.war - -# Large media files -*.mp4 -*.tiff -*.avi -*.flv -*.mov -*.wmv - -.data \ No newline at end of file diff --git a/Moonbeam/moonbeam-substrate-evm-starter/LICENSE b/Moonbeam/moonbeam-substrate-evm-starter/LICENSE deleted file mode 100644 index 3c806ae5..00000000 --- a/Moonbeam/moonbeam-substrate-evm-starter/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT LICENSE - -Copyright 2020-2021 OnFinality Limited authors & contributors - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/Moonbeam/moonbeam-substrate-evm-starter/README.md b/Moonbeam/moonbeam-substrate-evm-starter/README.md deleted file mode 100644 index 374b807d..00000000 --- a/Moonbeam/moonbeam-substrate-evm-starter/README.md +++ /dev/null @@ -1,106 +0,0 @@ -# SubQuery - Starter Package - -The Starter Package is an example that you can use as a starting point for developing your SubQuery project. -A SubQuery package defines which data The SubQuery will index from the Substrate blockchain, and how it will store it. - -## Preparation - -#### Environment - -- [Typescript](https://www.typescriptlang.org/) are required to compile project and define types. - -- Both SubQuery CLI and generated Project have dependencies and require [Node](https://nodejs.org/en/). - -#### Install the SubQuery CLI - -Install SubQuery CLI globally on your terminal by using NPM: - -``` -npm install -g @subql/cli -``` - -Run help to see available commands and usage provide by CLI - -``` -subql help -``` - -## Initialize the starter package - -Inside the directory in which you want to create the SubQuery project, simply replace `project-name` with your project name and run the command: - -``` -subql init --starter project-name -``` - -Then you should see a folder with your project name has been created inside the directory, you can use this as the start point of your project. And the files should be identical as in the [Directory Structure](https://doc.subquery.network/directory_structure.html). - -Last, under the project directory, run following command to install all the dependency. - -``` -yarn install -``` - -## Configure your project - -In the starter package, we have provided a simple example of project configuration. You will be mainly working on the following files: - -- The Manifest in `project.yaml` -- The GraphQL Schema in `schema.graphql` -- The Mapping functions in `src/mappings/` directory - -For more information on how to write the SubQuery, -check out our doc section on [Define the SubQuery](https://doc.subquery.network/define_a_subquery.html) - -#### Code generation - -In order to index your SubQuery project, it is mandatory to build your project first. -Run this command under the project directory. - -``` -yarn codegen -``` - -## Build the project - -In order to deploy your SubQuery project to our hosted service, it is mandatory to pack your configuration before upload. -Run pack command from root directory of your project will automatically generate a `your-project-name.tgz` file. - -``` -yarn build -``` - -## Indexing and Query - -#### Run required systems in docker - -Under the project directory run following command: - -``` -docker-compose pull && docker-compose up -``` - -#### Query the project - -Open your browser and head to `http://localhost:3000`. - -Finally, you should see a GraphQL playground is showing in the explorer and the schemas that ready to query. - -For the `subql-starter` project, you can try to query with the following code to get a taste of how it works. - -```graphql -query { - transactions(first:3 orderBy:BLOCK_HEIGHT_ASC){ - totalCount - nodes{ - blockHeight - timestamp - transactionHash - blockHash - contractAddress - from - value - } - } -} -``` diff --git a/Moonbeam/moonbeam-substrate-evm-starter/abis/erc20Metadata.json b/Moonbeam/moonbeam-substrate-evm-starter/abis/erc20Metadata.json deleted file mode 100644 index c6361bef..00000000 --- a/Moonbeam/moonbeam-substrate-evm-starter/abis/erc20Metadata.json +++ /dev/null @@ -1,457 +0,0 @@ -{ - "source": { - "hash": "0x85297d9db0204852b790e8f89a3350a687ba1c7bf9ee93bd2d9953005a4c34be", - "language": "ink! 3.4.0", - "compiler": "rustc 1.67.0-nightly" - }, - "contract": { - "name": "lottery", - "version": "0.1.0", - "authors": ["Nikhil Ranjan"] - }, - "V3": { - "spec": { - "constructors": [ - { - "args": [], - "docs": [], - "label": "new", - "payable": false, - "selector": "0x9bae9d5e" - } - ], - "docs": [], - "events": [ - { - "args": [ - { - "docs": [" The player who entered."], - "indexed": false, - "label": "player", - "type": { - "displayName": ["AccountId"], - "type": 0 - } - }, - { - "docs": [" The value sent."], - "indexed": false, - "label": "value", - "type": { - "displayName": ["Balance"], - "type": 6 - } - } - ], - "docs": [], - "label": "Entered" - }, - { - "args": [ - { - "docs": [" The winner."], - "indexed": false, - "label": "winner", - "type": { - "displayName": ["AccountId"], - "type": 0 - } - }, - { - "docs": [" The winning amount."], - "indexed": false, - "label": "amount", - "type": { - "displayName": ["Balance"], - "type": 6 - } - } - ], - "docs": [], - "label": "Won" - } - ], - "messages": [ - { - "args": [], - "docs": [" Returns the current owner of the lottery"], - "label": "owner", - "mutates": false, - "payable": false, - "returnType": { - "displayName": ["AccountId"], - "type": 0 - }, - "selector": "0xfeaea4fa" - }, - { - "args": [], - "docs": [], - "label": "pot", - "mutates": false, - "payable": false, - "returnType": { - "displayName": ["Balance"], - "type": 6 - }, - "selector": "0xd096c0d0" - }, - { - "args": [], - "docs": [" Returns the current state of the lottery"], - "label": "is_running", - "mutates": false, - "payable": false, - "returnType": { - "displayName": ["bool"], - "type": 3 - }, - "selector": "0x1b0e6452" - }, - { - "args": [], - "docs": [" Returns the list of players"], - "label": "get_players", - "mutates": false, - "payable": false, - "returnType": { - "displayName": ["Vec"], - "type": 4 - }, - "selector": "0xa3355842" - }, - { - "args": [ - { - "label": "caller", - "type": { - "displayName": ["AccountId"], - "type": 0 - } - } - ], - "docs": [" Retrieve the balance of the account."], - "label": "get_balance", - "mutates": false, - "payable": false, - "returnType": { - "displayName": ["Option"], - "type": 8 - }, - "selector": "0xea817e65" - }, - { - "args": [], - "docs": [" Allows a player to enter the lottery by sending a value"], - "label": "enter", - "mutates": true, - "payable": true, - "returnType": { - "displayName": ["Result"], - "type": 9 - }, - "selector": "0x8883954a" - }, - { - "args": [], - "docs": [], - "label": "pick_winner", - "mutates": true, - "payable": false, - "returnType": { - "displayName": ["Result"], - "type": 9 - }, - "selector": "0x1d49cc13" - }, - { - "args": [], - "docs": [], - "label": "start_lottery", - "mutates": true, - "payable": false, - "returnType": { - "displayName": ["Result"], - "type": 9 - }, - "selector": "0x996e2d9b" - }, - { - "args": [], - "docs": [], - "label": "stop_lottery", - "mutates": true, - "payable": false, - "returnType": { - "displayName": ["Result"], - "type": 9 - }, - "selector": "0xcb2815e1" - } - ] - }, - "storage": { - "struct": { - "fields": [ - { - "layout": { - "cell": { - "key": "0x0000000000000000000000000000000000000000000000000000000000000000", - "ty": 0 - } - }, - "name": "owner" - }, - { - "layout": { - "cell": { - "key": "0x0100000000000000000000000000000000000000000000000000000000000000", - "ty": 3 - } - }, - "name": "running" - }, - { - "layout": { - "cell": { - "key": "0x0200000000000000000000000000000000000000000000000000000000000000", - "ty": 4 - } - }, - "name": "players" - }, - { - "layout": { - "cell": { - "key": "0x0300000000000000000000000000000000000000000000000000000000000000", - "ty": 5 - } - }, - "name": "entries" - } - ] - } - }, - "types": [ - { - "id": 0, - "type": { - "def": { - "composite": { - "fields": [ - { - "type": 1, - "typeName": "[u8; 32]" - } - ] - } - }, - "path": ["ink_env", "types", "AccountId"] - } - }, - { - "id": 1, - "type": { - "def": { - "array": { - "len": 32, - "type": 2 - } - } - } - }, - { - "id": 2, - "type": { - "def": { - "primitive": "u8" - } - } - }, - { - "id": 3, - "type": { - "def": { - "primitive": "bool" - } - } - }, - { - "id": 4, - "type": { - "def": { - "sequence": { - "type": 0 - } - } - } - }, - { - "id": 5, - "type": { - "def": { - "composite": { - "fields": [ - { - "name": "offset_key", - "type": 7, - "typeName": "Key" - } - ] - } - }, - "params": [ - { - "name": "K", - "type": 0 - }, - { - "name": "V", - "type": 6 - } - ], - "path": ["ink_storage", "lazy", "mapping", "Mapping"] - } - }, - { - "id": 6, - "type": { - "def": { - "primitive": "u128" - } - } - }, - { - "id": 7, - "type": { - "def": { - "composite": { - "fields": [ - { - "type": 1, - "typeName": "[u8; 32]" - } - ] - } - }, - "path": ["ink_primitives", "Key"] - } - }, - { - "id": 8, - "type": { - "def": { - "variant": { - "variants": [ - { - "index": 0, - "name": "None" - }, - { - "fields": [ - { - "type": 6 - } - ], - "index": 1, - "name": "Some" - } - ] - } - }, - "params": [ - { - "name": "T", - "type": 6 - } - ], - "path": ["Option"] - } - }, - { - "id": 9, - "type": { - "def": { - "variant": { - "variants": [ - { - "fields": [ - { - "type": 10 - } - ], - "index": 0, - "name": "Ok" - }, - { - "fields": [ - { - "type": 11 - } - ], - "index": 1, - "name": "Err" - } - ] - } - }, - "params": [ - { - "name": "T", - "type": 10 - }, - { - "name": "E", - "type": 11 - } - ], - "path": ["Result"] - } - }, - { - "id": 10, - "type": { - "def": { - "tuple": [] - } - } - }, - { - "id": 11, - "type": { - "def": { - "variant": { - "variants": [ - { - "index": 0, - "name": "LotteryNotRunning" - }, - { - "index": 1, - "name": "CallerNotOwner" - }, - { - "index": 2, - "name": "NoValueSent" - }, - { - "index": 3, - "name": "ErrTransfer" - }, - { - "index": 4, - "name": "PlayerAlreadyInLottery" - }, - { - "index": 5, - "name": "NoEntries" - } - ] - } - }, - "path": ["lottery", "lottery", "Error"] - } - } - ] - } -} diff --git a/Moonbeam/moonbeam-substrate-evm-starter/docker-compose.yml b/Moonbeam/moonbeam-substrate-evm-starter/docker-compose.yml deleted file mode 100644 index ff58acb6..00000000 --- a/Moonbeam/moonbeam-substrate-evm-starter/docker-compose.yml +++ /dev/null @@ -1,63 +0,0 @@ -version: "3" - -services: - postgres: - build: - context: . - dockerfile: ./docker/pg-Dockerfile - ports: - - 5432:5432 - volumes: - - .data/postgres:/var/lib/postgresql/data - environment: - POSTGRES_PASSWORD: postgres - healthcheck: - test: ["CMD-SHELL", "pg_isready -U postgres"] - interval: 5s - timeout: 5s - retries: 5 - - subquery-node: - image: onfinality/subql-node:latest - depends_on: - "postgres": - condition: service_healthy - restart: always - environment: - DB_USER: postgres - DB_PASS: postgres - DB_DATABASE: postgres - DB_HOST: postgres - DB_PORT: 5432 - volumes: - - ./:/app - command: - - ${SUB_COMMAND} # set SUB_COMMAND env variable to "test" to run tests - - -f=/app - - --db-schema=app - healthcheck: - test: ["CMD", "curl", "-f", "http://subquery-node:3000/ready"] - interval: 3s - timeout: 5s - retries: 10 - - graphql-engine: - image: onfinality/subql-query:latest - ports: - - 3000:3000 - depends_on: - "postgres": - condition: service_healthy - "subquery-node": - condition: service_healthy - 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 diff --git a/Moonbeam/moonbeam-substrate-evm-starter/docker/load-extensions.sh b/Moonbeam/moonbeam-substrate-evm-starter/docker/load-extensions.sh deleted file mode 100644 index 6d33f863..00000000 --- a/Moonbeam/moonbeam-substrate-evm-starter/docker/load-extensions.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh - -psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <", - formerStakedEra: "EraIndex", - claimedRewards: "Balance", - }, - EraRewardAndStake: { - rewards: "Balance", - staked: "Balance", - }, - EraIndex: "u32", - }, - }, - ], -}; - -export default { typesBundle: definitions }; diff --git a/Moonbeam/moonbeam-substrate-evm-starter/src/index.ts b/Moonbeam/moonbeam-substrate-evm-starter/src/index.ts deleted file mode 100644 index 89dc0c5f..00000000 --- a/Moonbeam/moonbeam-substrate-evm-starter/src/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -//Exports all handler functions -import "@polkadot/api-augment"; -export * from "./mappings/mappingHandlers"; diff --git a/Moonbeam/moonbeam-substrate-evm-starter/src/mappings/mappingHandlers.ts b/Moonbeam/moonbeam-substrate-evm-starter/src/mappings/mappingHandlers.ts deleted file mode 100644 index 1350ae50..00000000 --- a/Moonbeam/moonbeam-substrate-evm-starter/src/mappings/mappingHandlers.ts +++ /dev/null @@ -1,134 +0,0 @@ -import { Approval, DApp, DAppReward, Transaction } from "../types"; -import { WasmCall, WasmEvent } from "@subql/substrate-wasm-processor"; -import { Balance, AccountId } from "@polkadot/types/interfaces/runtime"; -import { Option } from "@polkadot/types-codec"; -import { SubstrateEvent } from "@subql/types"; - -// Setup types from ABI -type ApproveCallArgs = [AccountId, Balance]; -type TransferEventArgs = [Option, Option, Balance]; - -export async function handleWasmCall( - call: WasmCall -): Promise { - logger.info(`Processing WASM Call at ${call.blockNumber}`); - const approval = new Approval(`${call.blockNumber}-${call.idx}`); - approval.hash = call.hash; - approval.owner = call.from.toString(); - approval.contractAddress = call.dest.toString(); - if (typeof call.data !== "string") { - const [spender, value] = call.data.args; - approval.spender = spender.toString(); - approval.value = value.toBigInt(); - } else { - logger.info(`Decode call failed ${call.hash}`); - } - await approval.save(); -} - -export async function handleWasmEvent( - event: WasmEvent -): Promise { - logger.info(`Processing WASM Even at ${event.blockNumber}`); - const [from, to, value] = event.args; - const transaction = Transaction.create({ - id: `${event.blockNumber}-${event.eventIndex}`, - transactionHash: event.transactionHash, - value: value.toBigInt(), - from: from.toString(), - to: to.toString(), - contractAddress: event.contract.toString(), - }); - - await transaction.save(); -} - -export async function handleNewContract(event: SubstrateEvent): Promise { - logger.info( - `Processing new Dapp Staking Contract event at ${event.block.block.header.number}` - ); - const { - event: { - data: [accountId, smartContract], - }, - } = event; - // Retrieve the record by its ID - let dapp: DApp = await DApp.get(smartContract.toString()); - if (!dapp) { - dapp = DApp.create({ - id: smartContract.toString(), - accountID: accountId.toString(), - totalStake: BigInt(0), - }); - - await dapp.save(); - } -} - -export async function handleBondAndStake(event: SubstrateEvent): Promise { - logger.info( - `Processing new Dapp Staking Bond and Stake event at ${event.block.block.header.number}` - ); - const { - event: { - data: [accountId, smartContract, balanceOf], - }, - } = event; - // Retrieve the dapp by its ID - let dapp: DApp = await DApp.get(smartContract.toString()); - if (!dapp) { - dapp = DApp.create({ - id: smartContract.toString(), - accountID: accountId.toString(), - totalStake: BigInt(0), - }); - } - - dapp.totalStake += (balanceOf as Balance).toBigInt(); - await dapp.save(); -} - -export async function handleUnbondAndUnstake( - event: SubstrateEvent -): Promise { - logger.info( - `Processing new Dapp Staking Bond and Unstake event at ${event.block.block.header.number}` - ); - const { - event: { - data: [accountId, smartContract, balanceOf], - }, - } = event; - // Retrieve the dapp by its ID - let dapp: DApp = await DApp.get(smartContract.toString()); - if (!dapp) { - dapp = DApp.create({ - id: smartContract.toString(), - accountID: accountId.toString(), - totalStake: BigInt(0), - }); - } - - dapp.totalStake -= (balanceOf as Balance).toBigInt(); - await dapp.save(); -} - -export async function handleReward(event: SubstrateEvent): Promise { - logger.info( - `Processing new Dapp Staking Reward event at ${event.block.block.header.number}` - ); - const { - event: { - data: [accountID, smartContract, eraIndex, balanceOf], - }, - } = event; - // Retrieve the record by its ID - const dAppReward: DAppReward = DAppReward.create({ - id: `${event.block.block.header.number.toNumber()}-${event.idx}`, - dAppId: smartContract.toString(), - accountID: accountID.toString(), - eraIndex: parseInt(eraIndex.toString()), - balanceOf: (balanceOf as Balance).toBigInt(), - }); - await dAppReward.save(); -} diff --git a/Moonbeam/moonbeam-substrate-evm-starter/src/test/mappingHandlers.test.ts b/Moonbeam/moonbeam-substrate-evm-starter/src/test/mappingHandlers.test.ts deleted file mode 100644 index fc12d09a..00000000 --- a/Moonbeam/moonbeam-substrate-evm-starter/src/test/mappingHandlers.test.ts +++ /dev/null @@ -1,12 +0,0 @@ -import {subqlTest} from "@subql/testing"; - -/* -// https://academy.subquery.network/build/testing.html -subqlTest( - "testName", // test name - 1000003, // block height to process - [], // dependent entities - [], // expected entities - "handleEvent" //handler name -); -*/ diff --git a/Moonbeam/moonbeam-substrate-evm-starter/tsconfig.json b/Moonbeam/moonbeam-substrate-evm-starter/tsconfig.json deleted file mode 100644 index 4be11b62..00000000 --- a/Moonbeam/moonbeam-substrate-evm-starter/tsconfig.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "compilerOptions": { - "emitDecoratorMetadata": true, - "experimentalDecorators": true, - "esModuleInterop": true, - "declaration": true, - "importHelpers": true, - "resolveJsonModule": true, - "module": "commonjs", - "outDir": "dist", - "rootDir": "src", - "target": "es2017" - }, - "include": ["src/**/*", "node_modules/@subql/types/dist/global.d.ts"] -} diff --git a/Moonbeam/moonbeam-substrate-evm-starter/types.yaml b/Moonbeam/moonbeam-substrate-evm-starter/types.yaml deleted file mode 100644 index 0e0587a6..00000000 --- a/Moonbeam/moonbeam-substrate-evm-starter/types.yaml +++ /dev/null @@ -1,180 +0,0 @@ -types: - AccountId: EthereumAccountId - Address: AccountId - Balance: u128 - LookupSource: AccountId - Account: - nonce: U256 - balance: u128 - ExtrinsicSignature: EthereumSignature - RoundIndex: u32 - Candidate: - id: AccountId - fee: Perbill - bond: Balance - nominators: Vec - total: Balance - state: CollatorStatus - Nominator: - nominations: Vec - total: Balance - Bond: - owner: AccountId - amount: Balance - TxPoolResultContent: - pending: HashMap> - queued: HashMap> - TxPoolResultInspect: - pending: HashMap> - queued: HashMap> - TxPoolResultStatus: - pending: U256 - queued: U256 - Summary: Bytes - PoolTransaction: - hash: H256 - nonce: U256 - blockHash: Option - blockNumber: Option - from: H160 - to: Option - value: U256 - gasPrice: U256 - gas: U256 - input: Bytes - AccountInfo: AccountInfoWithTripleRefCount - CollatorStatus: - _enum: - Active: 'Null' - Idle: 'Null' - Leaving: RoundIndex - Range: RangeBalance - RangeBalance: - min: Balance - ideal: Balance - max: Balance - RangePerbill: - min: Perbill - ideal: Perbill - max: Perbill - InflationInfo: - expect: RangeBalance - annual: RangePerbill - round: RangePerbill - OrderedSet: Vec - Collator: - id: AccountId - bond: Balance - nominators: Vec - total: Balance - state: CollatorStatus - CollatorSnapshot: - bond: Balance - nominators: Vec - total: Balance - SystemInherentData: - validationData: PersistedValidationData - relayChain_state: StorageProof - downwardMessages: Vec - horizontalMessages: BTreeMap> - RoundInfo: - current: RoundIndex - first: BlockNumber - length: u32 - AuthorId: AccountId32 - AccountId32: H256 - RelayChainAccountId: AccountId32 - RewardInfo: - totalReward: Balance - claimedReward: Balance - contributedRelayAddresses: Vec - Collator2: - id: AccountId - bond: Balance - nominators: Vec - topNominators: Vec - bottomNominators: Vec - totalCounted: Balance - totalBacking: Balance - state: CollatorStatus - NominatorAdded: - _enum: - AddedToTop: Balance - AddedToBottom: 'Null' - RegistrationInfo: - account: AccountId - deposit: Balance - ParachainBondConfig: - account: AccountId - percent: Percent - EthereumSignature: - r: H256 - s: H256 - v: U8 - NominatorStatus: - _enum: - Active: 'Null' - Leaving: RoundIndex - Nominator2: - nominations: Vec - revocations: Vec - total: Balance - scheduledRevocationsCount: u32 - scheduledRevocationsTotal: Balance - status: NominatorStatus - ExitQ: - candidates: Vec - nominatorsLeaving: Vec - candidateSchedule: Vec<(AccountId, RoundIndex)> - nominatorSchedule: Vec<(AccountId, Option, RoundIndex)> - AssetType: - _enum: - Xcm: MultiLocation - AssetId: u128 - TAssetBalance: u128 - ENUM_AccountId32: - network: NetworkId - id: "[u8; 32]" - ENUM_AccountKey20: - network: NetworkId - key: "[u8; 20]" - ENUM_AccountIndex64: - network: NetworkId - index: Compact - ENUM_Plurality: - id: BodyId - part: BodyPart - JunctionV0: - _enum: - Parent: 'Null' - Parachain: Compact - AccountId32: ENUM_AccountId32 - AccountIndex64: ENUM_AccountIndex64 - AccountKey20: ENUM_AccountKey20 - PalletInstance: u8 - GeneralIndex: Compact - GeneralKey: Vec - OnlyChild: 'Null' - Plurality: ENUM_Plurality - CurrencyId: - _enum: - SelfReserve: 'Null' - OtherReserve: u128 - AssetRegistrarMetadata: - name: Vec - symbol: Vec - decimals: u8 - isFrozen: bool - VestingBlockNumber: u32 - MultiLocation: MultiLocationV1 - JunctionV1: - _enum: - Parachain: Compact - AccountId32: ENUM_AccountId32 - AccountIndex64: ENUM_AccountIndex64 - AccountKey20: ENUM_AccountKey20 - PalletInstance: u8 - GeneralIndex: Compact - GeneralKey: Vec - OnlyChild: 'Null' - Plurality: ENUM_Plurality From dd78023c1534c72010927847cbe48858e4517402 Mon Sep 17 00:00:00 2001 From: youssefea Date: Fri, 23 Jun 2023 11:52:55 +0100 Subject: [PATCH 07/14] Updating project with new template --- .../.github/scripts/publish-deploy.sh | 15 + .../.github/workflows/cli-deploy.yml | 34 ++ .../.github/workflows/pr.yml | 24 + .../moonbeam-substrate-evm-starter/.gitignore | 57 +++ .../.project-cid | 1 + .../moonbeam-substrate-evm-starter/README.md | 105 +++++ .../docker-compose.yml | 63 +++ .../docker/load-extensions.sh | 5 + .../docker/pg-Dockerfile | 9 + .../erc721.abi.json | 422 ++++++++++++++++++ .../package.json | 45 ++ .../project.yaml | 50 +++ .../schema.graphql | 37 ++ .../src/chaintypes.ts | 3 + .../src/index.ts | 3 + .../src/mappings/mappingHandlers.ts | 126 ++++++ .../src/test/mappingHandlers.test.ts | 35 ++ .../tsconfig.json | 15 + 18 files changed, 1049 insertions(+) create mode 100644 Moonbeam/moonbeam-substrate-evm-starter/.github/scripts/publish-deploy.sh create mode 100644 Moonbeam/moonbeam-substrate-evm-starter/.github/workflows/cli-deploy.yml create mode 100644 Moonbeam/moonbeam-substrate-evm-starter/.github/workflows/pr.yml create mode 100644 Moonbeam/moonbeam-substrate-evm-starter/.gitignore create mode 100644 Moonbeam/moonbeam-substrate-evm-starter/.project-cid create mode 100644 Moonbeam/moonbeam-substrate-evm-starter/README.md create mode 100644 Moonbeam/moonbeam-substrate-evm-starter/docker-compose.yml create mode 100644 Moonbeam/moonbeam-substrate-evm-starter/docker/load-extensions.sh create mode 100644 Moonbeam/moonbeam-substrate-evm-starter/docker/pg-Dockerfile create mode 100644 Moonbeam/moonbeam-substrate-evm-starter/erc721.abi.json create mode 100644 Moonbeam/moonbeam-substrate-evm-starter/package.json create mode 100644 Moonbeam/moonbeam-substrate-evm-starter/project.yaml create mode 100644 Moonbeam/moonbeam-substrate-evm-starter/schema.graphql create mode 100644 Moonbeam/moonbeam-substrate-evm-starter/src/chaintypes.ts create mode 100644 Moonbeam/moonbeam-substrate-evm-starter/src/index.ts create mode 100644 Moonbeam/moonbeam-substrate-evm-starter/src/mappings/mappingHandlers.ts create mode 100644 Moonbeam/moonbeam-substrate-evm-starter/src/test/mappingHandlers.test.ts create mode 100644 Moonbeam/moonbeam-substrate-evm-starter/tsconfig.json diff --git a/Moonbeam/moonbeam-substrate-evm-starter/.github/scripts/publish-deploy.sh b/Moonbeam/moonbeam-substrate-evm-starter/.github/scripts/publish-deploy.sh new file mode 100644 index 00000000..3c9dc04b --- /dev/null +++ b/Moonbeam/moonbeam-substrate-evm-starter/.github/scripts/publish-deploy.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +while getopts p:o:e: flag +do + case "${flag}" in + e) ENDPOINT=${OPTARG};; + p) PROJECTNAME=${OPTARG};; + o) ORG=${OPTARG};; + *) echo "Usage: $0 [-p projectname] [-o org] [-e endpoint]" && exit 1;; + esac +done + +IPFSCID=$(npx subql publish -o -f .) + +npx subql deployment:deploy -d --ipfsCID="$IPFSCID" --projectName="${PROJECTNAME}" --org="${ORG%/*}" --endpoint="${ENDPOINT}" diff --git a/Moonbeam/moonbeam-substrate-evm-starter/.github/workflows/cli-deploy.yml b/Moonbeam/moonbeam-substrate-evm-starter/.github/workflows/cli-deploy.yml new file mode 100644 index 00000000..658d2c6c --- /dev/null +++ b/Moonbeam/moonbeam-substrate-evm-starter/.github/workflows/cli-deploy.yml @@ -0,0 +1,34 @@ +name: "CLI deploy" + +on: + workflow_dispatch: + inputs: + projectName: + description: "Project name" + required: true + type: string +jobs: + deploy: + name: CLI Deploy + runs-on: ubuntu-latest + environment: + name: DEPLOYMENT + env: + SUBQL_ACCESS_TOKEN: ${{ secrets.SUBQL_ACCESS_TOKEN }} + ENDPOINT: ${{ secrets.ENDPOINT }} + steps: + - uses: actions/checkout@v2 + - name: Setup Node.js environment + uses: actions/setup-node@v2 + with: + node-version: 16 + - run: yarn + - name: Codegen + run: yarn codegen + - name: Version + run: npx subql --version + - name: repo + run: echo ${{github.repository}} + - name: Publish and Deploy + run: | + sh .github/workflows/scripts/publish-deploy.sh -o ${{github.repository}} -p ${{github.event.inputs.projectName}} -e ${{secrets.ENDPOINT}} diff --git a/Moonbeam/moonbeam-substrate-evm-starter/.github/workflows/pr.yml b/Moonbeam/moonbeam-substrate-evm-starter/.github/workflows/pr.yml new file mode 100644 index 00000000..b428f2d8 --- /dev/null +++ b/Moonbeam/moonbeam-substrate-evm-starter/.github/workflows/pr.yml @@ -0,0 +1,24 @@ +name: PR +on: + pull_request: + paths-ignore: + - ".github/workflows/**" +jobs: + pr: + name: pr + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Setup Node.js environment + uses: actions/setup-node@v2 + with: + node-version: 16 + - run: yarn + - name: Codegen + run: yarn codegen + - name: Build + run: yarn build + - name: Install subql-node + run: yarn global add @subql/node + - name: Run tests with Subquery Node + run: subql-node test -f ${{ github.workspace }} diff --git a/Moonbeam/moonbeam-substrate-evm-starter/.gitignore b/Moonbeam/moonbeam-substrate-evm-starter/.gitignore new file mode 100644 index 00000000..1b334008 --- /dev/null +++ b/Moonbeam/moonbeam-substrate-evm-starter/.gitignore @@ -0,0 +1,57 @@ +# These are some examples of commonly ignored file patterns. +# You should customize this list as applicable to your project. +# Learn more about .gitignore: +# https://www.atlassian.com/git/tutorials/saving-changes/gitignore + +# Node artifact files +node_modules/ +dist/ +.data/ + +# lock files +yarn.lock +package-lock.json + +# Compiled Java class files +*.class + +# Compiled Python bytecode +*.py[cod] + +# Log files +*.log + +# Package files +*.jar + +# Maven +target/ +dist/ +src/types + +# JetBrains IDE +.idea/ + +# Unit test reports +TEST*.xml + +# Generated by MacOS +.DS_Store + +# Generated by Windows +Thumbs.db + +# Applications +*.app +*.exe +*.war + +# Large media files +*.mp4 +*.tiff +*.avi +*.flv +*.mov +*.wmv + +.data/* \ No newline at end of file diff --git a/Moonbeam/moonbeam-substrate-evm-starter/.project-cid b/Moonbeam/moonbeam-substrate-evm-starter/.project-cid new file mode 100644 index 00000000..83c585e4 --- /dev/null +++ b/Moonbeam/moonbeam-substrate-evm-starter/.project-cid @@ -0,0 +1 @@ +QmcRJzjwZDxXvAA4t54ccrUkzo7emngk7Ayje3ai3iLrQ5 \ No newline at end of file diff --git a/Moonbeam/moonbeam-substrate-evm-starter/README.md b/Moonbeam/moonbeam-substrate-evm-starter/README.md new file mode 100644 index 00000000..d5334f6b --- /dev/null +++ b/Moonbeam/moonbeam-substrate-evm-starter/README.md @@ -0,0 +1,105 @@ +# SubQuery - Starter Package + +A basic Frontier EVM example project with an event and call handler. Read more about this at https://university.subquery.network/build/substrate-evm.html. This project can be use as a starting point for developing your SubQuery project + +The Starter Package is an example that you can use as a starting point for developing your SubQuery project. +A SubQuery package defines which data The SubQuery will index from the Substrate blockchain, and how it will store it. + +## Preparation + +#### Environment + +- [Typescript](https://www.typescriptlang.org/) are required to compile project and define types. + +- Both SubQuery CLI and generated Project have dependencies and require [Node](https://nodejs.org/en/). + +#### Install the SubQuery CLI + +Install SubQuery CLI globally on your terminal by using NPM: + +``` +npm install -g @subql/cli +``` + +Run help to see available commands and usage provide by CLI + +``` +subql help +``` + +## Initialize the starter package + +Inside the directory in which you want to create the SubQuery project, simply replace `project-name` with your project name and run the command: + +``` +subql init project-name +``` + +Then you should see a folder with your project name has been created inside the directory, you can use this as the start point of your project. And the files should be identical as in the [Directory Structure](https://doc.subquery.network/directory_structure.html). + +Last, under the project directory, run following command to install all the dependency. + +``` +yarn install +``` + +## Configure your project + +In the starter package, we have provided a simple example of project configuration. You will be mainly working on the following files: + +- The Manifest in `project.yaml` +- The GraphQL Schema in `schema.graphql` +- The Mapping functions in `src/mappings/` directory + +For more information on how to write the SubQuery, +check out our doc section on [Define the SubQuery](https://doc.subquery.network/define_a_subquery.html) + +#### Code generation + +In order to index your SubQuery project, it is mandatory to build your project first. +Run this command under the project directory. + +``` +yarn codegen +``` + +## Build the project + +In order to deploy your SubQuery project to our hosted service, it is mandatory to pack your configuration before upload. +Run pack command from root directory of your project will automatically generate a `your-project-name.tgz` file. + +``` +yarn build +``` + +## Indexing and Query + +#### Run required systems in docker + +Under the project directory run following command: + +``` +docker-compose pull && docker-compose up +``` + +#### Query the project + +Open your browser and head to `http://localhost:3000`. + +Finally, you should see a GraphQL playground is showing in the explorer and the schemas that ready to query. + +For the `subql-starter` project, you can try to query with the following code to get a taste of how it works. + +```graphql +{ + query { + starterEntities(first: 10) { + nodes { + field1 + field2 + field3 + } + } + } +} +``` diff --git a/Moonbeam/moonbeam-substrate-evm-starter/docker-compose.yml b/Moonbeam/moonbeam-substrate-evm-starter/docker-compose.yml new file mode 100644 index 00000000..2bbffdec --- /dev/null +++ b/Moonbeam/moonbeam-substrate-evm-starter/docker-compose.yml @@ -0,0 +1,63 @@ +version: "3" + +services: + postgres: + build: + context: . + dockerfile: ./docker/pg-Dockerfile + ports: + - 5432:5432 + volumes: + - .data/postgres:/var/lib/postgresql/data + environment: + POSTGRES_PASSWORD: postgres + healthcheck: + test: ["CMD-SHELL", "pg_isready -U postgres"] + interval: 5s + timeout: 5s + retries: 5 + + subquery-node: + image: onfinality/subql-node:latest + depends_on: + "postgres": + condition: service_healthy + restart: always + environment: + DB_USER: postgres + DB_PASS: postgres + DB_DATABASE: postgres + DB_HOST: postgres + DB_PORT: 5432 + volumes: + - ./:/app + command: + - test # set SUB_COMMAND env variable to "test" to run tests + - -f=/app + - --db-schema=app + healthcheck: + test: ["CMD", "curl", "-f", "http://subquery-node:3000/ready"] + interval: 3s + timeout: 5s + retries: 10 + + graphql-engine: + image: onfinality/subql-query:latest + ports: + - 3000:3000 + depends_on: + "postgres": + condition: service_healthy + "subquery-node": + condition: service_healthy + 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 diff --git a/Moonbeam/moonbeam-substrate-evm-starter/docker/load-extensions.sh b/Moonbeam/moonbeam-substrate-evm-starter/docker/load-extensions.sh new file mode 100644 index 00000000..6d33f863 --- /dev/null +++ b/Moonbeam/moonbeam-substrate-evm-starter/docker/load-extensions.sh @@ -0,0 +1,5 @@ +#!/bin/sh + +psql -v ON_ERROR_STOP=1 --username "$POSTGRES_USER" <- + A basic ERC721 indexer on moonbeam +repository: "https://github.com/subquery/tutorials-frontier-evm-starter" +schema: + file: ./schema.graphql +network: + # The genesis hash of the network (hash of block 0) + chainId: "0xfe58ea77779b7abda7da4ec526d14db9b1e9cd40a217c34892af80a9b332b76d" + # This endpoint must be a public non-pruned archive node + # Public nodes may be rate limited, which can affect indexing speed + # When developing your project we suggest getting a private API key + # You can get them from OnFinality for free https://app.onfinality.io + # https://documentation.onfinality.io/support/the-enhanced-api-service + endpoint: + - wss://moonbeam.api.onfinality.io/public-ws + - wss://wss.api.moonbeam.network + dictionary: "https://api.subquery.network/sq/subquery/moonbeam-dictionary" + chaintypes: + file: ./dist/chaintypes.js +dataSources: + - kind: substrate/FrontierEvm + startBlock: 209451 + processor: + file: "./node_modules/@subql/frontier-evm-processor/dist/bundle.js" + options: + # Must be a key of assets + abi: erc721 + # Contract address (or recipient if transfer) to filter, if `null` should be for contract creation + address: "0x8fBE243D898e7c88A6724bB9eB13d746614D23d6" + assets: + erc721: + file: ./erc721.abi.json + mapping: + file: ./dist/index.js + handlers: + - handler: handleTransfer + kind: substrate/FrontierEvmEvent + filter: + topics: + - "Transfer(address indexed from,address indexed to,uint256 indexed tokenId)" \ No newline at end of file diff --git a/Moonbeam/moonbeam-substrate-evm-starter/schema.graphql b/Moonbeam/moonbeam-substrate-evm-starter/schema.graphql new file mode 100644 index 00000000..1b5689d7 --- /dev/null +++ b/Moonbeam/moonbeam-substrate-evm-starter/schema.graphql @@ -0,0 +1,37 @@ +# To improve query performance, we strongly suggest adding indexes to any field that you plan to filter or sort by +# Add the `@index` or `@index(unique: true)` annotation after any non-key field +# https://academy.subquery.network/build/graphql.html#indexing-by-non-primary-key-field + +type Token @entity { + id: ID! + owner: Owner + uri: String + transfers: [Transfer!]! @derivedFrom(field: "token") + contract: Contract +} + +type Owner @entity { + id: ID! + ownedTokens: [Token!]! @derivedFrom(field: "owner") + balance: BigInt +} + +type Contract @entity { + id: ID! + name: String + symbol: String + totalSupply: BigInt + mintedTokens: [Token!]! @derivedFrom(field: "contract") +} + +type Transfer @entity { + id: ID! + token: Token! + # Empty from is minting + from: Owner + # Empty to is burning + to: Owner + timestamp: BigInt! + block: BigInt! + transactionHash: String! +} \ No newline at end of file diff --git a/Moonbeam/moonbeam-substrate-evm-starter/src/chaintypes.ts b/Moonbeam/moonbeam-substrate-evm-starter/src/chaintypes.ts new file mode 100644 index 00000000..d90fbf8e --- /dev/null +++ b/Moonbeam/moonbeam-substrate-evm-starter/src/chaintypes.ts @@ -0,0 +1,3 @@ +import { typesBundleDeprecated } from "moonbeam-types-bundle"; + +export default { typesBundle: typesBundleDeprecated }; diff --git a/Moonbeam/moonbeam-substrate-evm-starter/src/index.ts b/Moonbeam/moonbeam-substrate-evm-starter/src/index.ts new file mode 100644 index 00000000..89dc0c5f --- /dev/null +++ b/Moonbeam/moonbeam-substrate-evm-starter/src/index.ts @@ -0,0 +1,3 @@ +//Exports all handler functions +import "@polkadot/api-augment"; +export * from "./mappings/mappingHandlers"; diff --git a/Moonbeam/moonbeam-substrate-evm-starter/src/mappings/mappingHandlers.ts b/Moonbeam/moonbeam-substrate-evm-starter/src/mappings/mappingHandlers.ts new file mode 100644 index 00000000..42c0f6a7 --- /dev/null +++ b/Moonbeam/moonbeam-substrate-evm-starter/src/mappings/mappingHandlers.ts @@ -0,0 +1,126 @@ +import { + Token, Owner, Contract, Transfer, +} from "../types"; +import { + FrontierEvmEvent, + FrontierEvmCall, +} from "@subql/frontier-evm-processor"; +global.atob = require("atob"); +global.Blob = require('node-blob'); +import { ethers } from "ethers"; +import { BigNumber } from "ethers"; +import { Erc721Abi__factory } from "../types/contracts"; +import { FrontierEthProvider } from "@subql/frontier-evm-processor"; + +// Setup types from ABI +type TransferEventArgs = [string, string, BigNumber] & { + from: string; + to: string; + tokenId: string; +}; + +export async function handleTransfer( + event: FrontierEvmEvent +): Promise { + + logger.info('New log found at ' + event.blockNumber.toString()); + let previousOwner = await Owner.get(event.args.from); + let newOwner = await Owner.get(event.args.to); + let token = await Token.get(event.args.tokenId.toString()); + let transferId = event.transactionHash; + let transfer = await Transfer.get(transferId); + let contract = await Contract.get(event.address); + let provider = new ethers.providers.JsonRpcProvider("https://moonbeam.blastapi.io/bc88ffcb-8768-4dc8-aee4-5bbb4e285a73"); + const instance = Erc721Abi__factory.connect(event.address, provider ); + logger.info('Contract instance initiated'+instance.address.toString()); + + + if (previousOwner == null) { + previousOwner = new Owner(event.args.from); + + previousOwner.balance = BigInt(0); + } else { + let prevBalance = previousOwner.balance; + if (prevBalance > BigInt(0)) { + previousOwner.balance = prevBalance - BigInt(1); + } + } + + if (newOwner == null) { + newOwner = new Owner(event.args.to); + newOwner.balance = BigInt(1); + } else { + let prevBalance = newOwner.balance; + newOwner.balance = prevBalance + BigInt(1); + } + + if (token == null) { + token = new Token(event.args.tokenId.toString()); + token.contractId = event.address; + + try + { + let uri = await instance.tokenURI(event.args.tokenId.toString()); + logger.info('token uri'+uri); + if (!uri==null) { + token.uri = uri; + } + } + catch(e){} + } + + token.ownerId = event.args.to; + + if (transfer == null) { + transfer = new Transfer(transferId); + transfer.tokenId = event.args.tokenId.toString(); + transfer.fromId = event.args.from; + transfer.toId = event.args.to; + transfer.timestamp = BigInt(event.blockTimestamp.getTime()); + transfer.block = BigInt(event.blockNumber); + transfer.transactionHash = event.transactionHash; + } + + if (contract == null) { + contract = new Contract(event.address); + } + + try + { + let name = await instance.name(); + if (!name==null) { + contract.name = name; + } + } + catch(e){} + + try + { + let symbol = await instance.symbol(); + if (!symbol==null) { + contract.symbol = symbol; + } + } + catch(e){} + + try + { + let totalSupply = await instance.totalSupply(); + if (!totalSupply==null) { + contract.totalSupply = BigInt(totalSupply.toString()); + } + } + catch(e){} + + previousOwner.save(); + logger.info('prev owner stored'+previousOwner.id.toString()); + newOwner.save(); + logger.info('new owner stored' + newOwner.id.toString()); + token.save(); + logger.info('token stored'+token.id.toString()); + contract.save(); + logger.info('contract stored'+contract.id.toString()); + transfer.save(); + logger.info('transfer stored'+ transfer.id.toString()); + +} diff --git a/Moonbeam/moonbeam-substrate-evm-starter/src/test/mappingHandlers.test.ts b/Moonbeam/moonbeam-substrate-evm-starter/src/test/mappingHandlers.test.ts new file mode 100644 index 00000000..d02dad32 --- /dev/null +++ b/Moonbeam/moonbeam-substrate-evm-starter/src/test/mappingHandlers.test.ts @@ -0,0 +1,35 @@ +import { subqlTest } from "@subql/testing"; +import { Transfer,Token,Contract,Owner } from "../types"; + +let newToken= new Token("1"); + + + +subqlTest( + "handleBlock test", + 3497330, + [ + Contract.create({ + id: '0x1FF2ADAa387dD27c22b31086E658108588eDa03a', + name: 'CryptoPunks', + symbol: 'PUNK', + totalSupply: BigInt(10000), + }), + Transfer.create({ + id: '0x1FF2ADAa387dD27c22b31086E658108588eDa03aTRANSFERID', + tokenId:"1", + fromId: '0x00000000000FROM', + toId: '0x00000000000TO', + timestamp: BigInt(1627440000), + block: BigInt(3497330), + transactionHash: '0x1FF2ADAa387dD27c22b31086E658108588eDa03aTRANSACTIONHASH', + }), + ], + [ + Owner.create({ + id: '0x00000000000TO', + balance: BigInt(1), + }), + ], + 'handleTransfer', + ); \ No newline at end of file diff --git a/Moonbeam/moonbeam-substrate-evm-starter/tsconfig.json b/Moonbeam/moonbeam-substrate-evm-starter/tsconfig.json new file mode 100644 index 00000000..4be11b62 --- /dev/null +++ b/Moonbeam/moonbeam-substrate-evm-starter/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "esModuleInterop": true, + "declaration": true, + "importHelpers": true, + "resolveJsonModule": true, + "module": "commonjs", + "outDir": "dist", + "rootDir": "src", + "target": "es2017" + }, + "include": ["src/**/*", "node_modules/@subql/types/dist/global.d.ts"] +} From ee9b70362012dc0589f238819212bb34095393bb Mon Sep 17 00:00:00 2001 From: youssefea Date: Fri, 23 Jun 2023 12:49:26 +0100 Subject: [PATCH 08/14] updating manifest schema and mapping --- .../erc20.abi.json | 222 +++++++++ .../erc721.abi.json | 422 ------------------ .../project.yaml | 35 +- .../schema.graphql | 39 +- .../src/mappings/mappingHandlers.ts | 142 ++---- .../src/test/mappingHandlers.test.ts | 4 +- 6 files changed, 293 insertions(+), 571 deletions(-) create mode 100644 Moonbeam/moonbeam-substrate-evm-starter/erc20.abi.json delete mode 100644 Moonbeam/moonbeam-substrate-evm-starter/erc721.abi.json diff --git a/Moonbeam/moonbeam-substrate-evm-starter/erc20.abi.json b/Moonbeam/moonbeam-substrate-evm-starter/erc20.abi.json new file mode 100644 index 00000000..58f67d9a --- /dev/null +++ b/Moonbeam/moonbeam-substrate-evm-starter/erc20.abi.json @@ -0,0 +1,222 @@ +[ + { + "constant": true, + "inputs": [], + "name": "name", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_spender", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "approve", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "totalSupply", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_from", + "type": "address" + }, + { + "name": "_to", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "transferFrom", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "decimals", + "outputs": [ + { + "name": "", + "type": "uint8" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_owner", + "type": "address" + } + ], + "name": "balanceOf", + "outputs": [ + { + "name": "balance", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": true, + "inputs": [], + "name": "symbol", + "outputs": [ + { + "name": "", + "type": "string" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "constant": false, + "inputs": [ + { + "name": "_to", + "type": "address" + }, + { + "name": "_value", + "type": "uint256" + } + ], + "name": "transfer", + "outputs": [ + { + "name": "", + "type": "bool" + } + ], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, + { + "constant": true, + "inputs": [ + { + "name": "_owner", + "type": "address" + }, + { + "name": "_spender", + "type": "address" + } + ], + "name": "allowance", + "outputs": [ + { + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, + { + "payable": true, + "stateMutability": "payable", + "type": "fallback" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "owner", + "type": "address" + }, + { + "indexed": true, + "name": "spender", + "type": "address" + }, + { + "indexed": false, + "name": "value", + "type": "uint256" + } + ], + "name": "Approval", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "name": "from", + "type": "address" + }, + { + "indexed": true, + "name": "to", + "type": "address" + }, + { + "indexed": false, + "name": "value", + "type": "uint256" + } + ], + "name": "Transfer", + "type": "event" + } +] \ No newline at end of file diff --git a/Moonbeam/moonbeam-substrate-evm-starter/erc721.abi.json b/Moonbeam/moonbeam-substrate-evm-starter/erc721.abi.json deleted file mode 100644 index 8ac3a26c..00000000 --- a/Moonbeam/moonbeam-substrate-evm-starter/erc721.abi.json +++ /dev/null @@ -1,422 +0,0 @@ -[ - { - "inputs": [ - { - "internalType": "string", - "name": "name", - "type": "string" - }, - { - "internalType": "string", - "name": "symbol", - "type": "string" - }, - { - "internalType": "string", - "name": "baseURI", - "type": "string" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "approved", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "indexed": false, - "internalType": "bool", - "name": "approved", - "type": "bool" - } - ], - "name": "ApprovalForAll", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "indexed": true, - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "approve", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "baseURI", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "getApproved", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "address", - "name": "operator", - "type": "address" - } - ], - "name": "isApprovedForAll", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "name", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "ownerOf", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "safeTransferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - }, - { - "internalType": "bytes", - "name": "_data", - "type": "bytes" - } - ], - "name": "safeTransferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "operator", - "type": "address" - }, - { - "internalType": "bool", - "name": "approved", - "type": "bool" - } - ], - "name": "setApprovalForAll", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes4", - "name": "interfaceId", - "type": "bytes4" - } - ], - "name": "supportsInterface", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "symbol", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "index", - "type": "uint256" - } - ], - "name": "tokenByIndex", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "owner", - "type": "address" - }, - { - "internalType": "uint256", - "name": "index", - "type": "uint256" - } - ], - "name": "tokenOfOwnerByIndex", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "tokenURI", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "totalSupply", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "from", - "type": "address" - }, - { - "internalType": "address", - "name": "to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "tokenId", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - } -] \ No newline at end of file diff --git a/Moonbeam/moonbeam-substrate-evm-starter/project.yaml b/Moonbeam/moonbeam-substrate-evm-starter/project.yaml index e7c53140..6e42804d 100644 --- a/Moonbeam/moonbeam-substrate-evm-starter/project.yaml +++ b/Moonbeam/moonbeam-substrate-evm-starter/project.yaml @@ -1,5 +1,5 @@ specVersion: 1.0.0 -name: subql-nft +name: moonbeam-substrate-evm-starter version: 1.0.0 runner: node: @@ -9,8 +9,10 @@ runner: name: "@subql/query" version: "*" description: >- - A basic ERC721 indexer on moonbeam -repository: "https://github.com/subquery/tutorials-frontier-evm-starter" + A basic Substrate EVM example project with an event and call handler. Read more + about this at https://academy.subquery.network/build/substrate-evm.html. This + project can be use as a starting point for developing your SubQuery project +repository: "https://github.com/subquery/subql-starter.git" schema: file: ./schema.graphql network: @@ -28,22 +30,39 @@ network: chaintypes: file: ./dist/chaintypes.js dataSources: + - kind: substrate/Runtime + # This is the datasource for Moonbeam's Native Substrate processor + startBlock: 209451 + mapping: + file: ./dist/index.js + handlers: + - handler: handleCollatorJoined + kind: substrate/CallHandler + filter: + module: staking + method: joinCandidates + - handler: handleCollatorLeft + kind: substrate/CallHandler + filter: + module: staking + method: executeLeaveCandidates + - kind: substrate/FrontierEvm startBlock: 209451 processor: file: "./node_modules/@subql/frontier-evm-processor/dist/bundle.js" options: # Must be a key of assets - abi: erc721 + abi: erc20 # Contract address (or recipient if transfer) to filter, if `null` should be for contract creation - address: "0x8fBE243D898e7c88A6724bB9eB13d746614D23d6" + address: "0x322E86852e492a7Ee17f28a78c663da38FB33bfb" assets: - erc721: - file: ./erc721.abi.json + erc20: + file: ./erc20.abi.json mapping: file: ./dist/index.js handlers: - - handler: handleTransfer + - handler: handleErc20Transfer kind: substrate/FrontierEvmEvent filter: topics: diff --git a/Moonbeam/moonbeam-substrate-evm-starter/schema.graphql b/Moonbeam/moonbeam-substrate-evm-starter/schema.graphql index 1b5689d7..6f8badbf 100644 --- a/Moonbeam/moonbeam-substrate-evm-starter/schema.graphql +++ b/Moonbeam/moonbeam-substrate-evm-starter/schema.graphql @@ -2,36 +2,19 @@ # Add the `@index` or `@index(unique: true)` annotation after any non-key field # https://academy.subquery.network/build/graphql.html#indexing-by-non-primary-key-field -type Token @entity { - id: ID! - owner: Owner - uri: String - transfers: [Transfer!]! @derivedFrom(field: "token") - contract: Contract -} +type Erc20Transfer @entity { -type Owner @entity { - id: ID! - ownedTokens: [Token!]! @derivedFrom(field: "owner") - balance: BigInt -} + id: ID! #id is a required field + from: String! + to: String! + contractAddress: String! + amount: BigInt! -type Contract @entity { - id: ID! - name: String - symbol: String - totalSupply: BigInt - mintedTokens: [Token!]! @derivedFrom(field: "contract") } -type Transfer @entity { - id: ID! - token: Token! - # Empty from is minting - from: Owner - # Empty to is burning - to: Owner - timestamp: BigInt! - block: BigInt! - transactionHash: String! +type Collator @entity { + + id: ID! #collator address + joinedDate: Date! + } \ No newline at end of file diff --git a/Moonbeam/moonbeam-substrate-evm-starter/src/mappings/mappingHandlers.ts b/Moonbeam/moonbeam-substrate-evm-starter/src/mappings/mappingHandlers.ts index 42c0f6a7..747944a3 100644 --- a/Moonbeam/moonbeam-substrate-evm-starter/src/mappings/mappingHandlers.ts +++ b/Moonbeam/moonbeam-substrate-evm-starter/src/mappings/mappingHandlers.ts @@ -1,126 +1,46 @@ import { - Token, Owner, Contract, Transfer, + Erc20Transfer, Collator } from "../types"; import { - FrontierEvmEvent, - FrontierEvmCall, + FrontierEvmEvent } from "@subql/frontier-evm-processor"; + +import { + SubstrateExtrinsic, + SubstrateEvent, +} from "@subql/types"; + global.atob = require("atob"); global.Blob = require('node-blob'); -import { ethers } from "ethers"; import { BigNumber } from "ethers"; -import { Erc721Abi__factory } from "../types/contracts"; -import { FrontierEthProvider } from "@subql/frontier-evm-processor"; - -// Setup types from ABI -type TransferEventArgs = [string, string, BigNumber] & { - from: string; - to: string; - tokenId: string; -}; - -export async function handleTransfer( - event: FrontierEvmEvent -): Promise { - - logger.info('New log found at ' + event.blockNumber.toString()); - let previousOwner = await Owner.get(event.args.from); - let newOwner = await Owner.get(event.args.to); - let token = await Token.get(event.args.tokenId.toString()); - let transferId = event.transactionHash; - let transfer = await Transfer.get(transferId); - let contract = await Contract.get(event.address); - let provider = new ethers.providers.JsonRpcProvider("https://moonbeam.blastapi.io/bc88ffcb-8768-4dc8-aee4-5bbb4e285a73"); - const instance = Erc721Abi__factory.connect(event.address, provider ); - logger.info('Contract instance initiated'+instance.address.toString()); - - - if (previousOwner == null) { - previousOwner = new Owner(event.args.from); - previousOwner.balance = BigInt(0); - } else { - let prevBalance = previousOwner.balance; - if (prevBalance > BigInt(0)) { - previousOwner.balance = prevBalance - BigInt(1); - } - } +export async function collatorJoined(event: SubstrateEvent): Promise { - if (newOwner == null) { - newOwner = new Owner(event.args.to); - newOwner.balance = BigInt(1); - } else { - let prevBalance = newOwner.balance; - newOwner.balance = prevBalance + BigInt(1); - } + const address = event.extrinsic.extrinsic.signer.toString(); - if (token == null) { - token = new Token(event.args.tokenId.toString()); - token.contractId = event.address; + const collator = Collator.create({ + id: address, + joinedDate: event.block.timestamp + }); - try - { - let uri = await instance.tokenURI(event.args.tokenId.toString()); - logger.info('token uri'+uri); - if (!uri==null) { - token.uri = uri; - } - } - catch(e){} - } + await collator.save(); - token.ownerId = event.args.to; - - if (transfer == null) { - transfer = new Transfer(transferId); - transfer.tokenId = event.args.tokenId.toString(); - transfer.fromId = event.args.from; - transfer.toId = event.args.to; - transfer.timestamp = BigInt(event.blockTimestamp.getTime()); - transfer.block = BigInt(event.blockNumber); - transfer.transactionHash = event.transactionHash; - } - - if (contract == null) { - contract = new Contract(event.address); - } - - try - { - let name = await instance.name(); - if (!name==null) { - contract.name = name; - } - } - catch(e){} - - try - { - let symbol = await instance.symbol(); - if (!symbol==null) { - contract.symbol = symbol; - } - } - catch(e){} +} - try - { - let totalSupply = await instance.totalSupply(); - if (!totalSupply==null) { - contract.totalSupply = BigInt(totalSupply.toString()); - } - } - catch(e){} +export async function collatorLeft(call: SubstrateExtrinsic): Promise { - previousOwner.save(); - logger.info('prev owner stored'+previousOwner.id.toString()); - newOwner.save(); - logger.info('new owner stored' + newOwner.id.toString()); - token.save(); - logger.info('token stored'+token.id.toString()); - contract.save(); - logger.info('contract stored'+contract.id.toString()); - transfer.save(); - logger.info('transfer stored'+ transfer.id.toString()); - + const address = call.extrinsic.signer.toString(); + await Collator.remove(address); } + +export async function erc20Transfer(event: FrontierEvmEvent<[string, string, BigNumber] & { from: string, to: string, value: BigNumber, }>): Promise { + const transfer = Erc20Transfer.create({ + id: event.transactionHash, + from: event.args.from, + to: event.args.to, + amount: event.args.value.toBigInt(), + contractAddress: event.address, + }); + + await transfer.save(); +} \ No newline at end of file diff --git a/Moonbeam/moonbeam-substrate-evm-starter/src/test/mappingHandlers.test.ts b/Moonbeam/moonbeam-substrate-evm-starter/src/test/mappingHandlers.test.ts index d02dad32..dc01bfcc 100644 --- a/Moonbeam/moonbeam-substrate-evm-starter/src/test/mappingHandlers.test.ts +++ b/Moonbeam/moonbeam-substrate-evm-starter/src/test/mappingHandlers.test.ts @@ -1,4 +1,4 @@ -import { subqlTest } from "@subql/testing"; +/*import { subqlTest } from "@subql/testing"; import { Transfer,Token,Contract,Owner } from "../types"; let newToken= new Token("1"); @@ -32,4 +32,4 @@ subqlTest( }), ], 'handleTransfer', - ); \ No newline at end of file + );*/ \ No newline at end of file From 4ca1aca769788a0076d8bd132ce548f040e7a576 Mon Sep 17 00:00:00 2001 From: youssefea Date: Fri, 23 Jun 2023 13:14:39 +0100 Subject: [PATCH 09/14] fixing multiple manifest, schema & docker compose --- .../docker-compose.yml | 2 +- .../project.yaml | 4 +-- .../src/mappings/mappingHandlers.ts | 2 ++ .../src/test/mappingHandlers.test.ts | 35 ------------------- .../src/tests/mappingHandlers.test.ts | 13 +++++++ 5 files changed, 18 insertions(+), 38 deletions(-) delete mode 100644 Moonbeam/moonbeam-substrate-evm-starter/src/test/mappingHandlers.test.ts create mode 100644 Moonbeam/moonbeam-substrate-evm-starter/src/tests/mappingHandlers.test.ts diff --git a/Moonbeam/moonbeam-substrate-evm-starter/docker-compose.yml b/Moonbeam/moonbeam-substrate-evm-starter/docker-compose.yml index 2bbffdec..8b3df5ed 100644 --- a/Moonbeam/moonbeam-substrate-evm-starter/docker-compose.yml +++ b/Moonbeam/moonbeam-substrate-evm-starter/docker-compose.yml @@ -32,7 +32,7 @@ services: volumes: - ./:/app command: - - test # set SUB_COMMAND env variable to "test" to run tests + #- test # set SUB_COMMAND env variable to "test" to run tests - -f=/app - --db-schema=app healthcheck: diff --git a/Moonbeam/moonbeam-substrate-evm-starter/project.yaml b/Moonbeam/moonbeam-substrate-evm-starter/project.yaml index 6e42804d..13eb07da 100644 --- a/Moonbeam/moonbeam-substrate-evm-starter/project.yaml +++ b/Moonbeam/moonbeam-substrate-evm-starter/project.yaml @@ -32,7 +32,7 @@ network: dataSources: - kind: substrate/Runtime # This is the datasource for Moonbeam's Native Substrate processor - startBlock: 209451 + startBlock: 1 mapping: file: ./dist/index.js handlers: @@ -48,7 +48,7 @@ dataSources: method: executeLeaveCandidates - kind: substrate/FrontierEvm - startBlock: 209451 + startBlock: 189831 processor: file: "./node_modules/@subql/frontier-evm-processor/dist/bundle.js" options: diff --git a/Moonbeam/moonbeam-substrate-evm-starter/src/mappings/mappingHandlers.ts b/Moonbeam/moonbeam-substrate-evm-starter/src/mappings/mappingHandlers.ts index 747944a3..c57467c2 100644 --- a/Moonbeam/moonbeam-substrate-evm-starter/src/mappings/mappingHandlers.ts +++ b/Moonbeam/moonbeam-substrate-evm-starter/src/mappings/mappingHandlers.ts @@ -16,6 +16,8 @@ import { BigNumber } from "ethers"; export async function collatorJoined(event: SubstrateEvent): Promise { + logger.info(`Processing SubstrateEvent at ${event.block.block.header.number}`); + const address = event.extrinsic.extrinsic.signer.toString(); const collator = Collator.create({ diff --git a/Moonbeam/moonbeam-substrate-evm-starter/src/test/mappingHandlers.test.ts b/Moonbeam/moonbeam-substrate-evm-starter/src/test/mappingHandlers.test.ts deleted file mode 100644 index dc01bfcc..00000000 --- a/Moonbeam/moonbeam-substrate-evm-starter/src/test/mappingHandlers.test.ts +++ /dev/null @@ -1,35 +0,0 @@ -/*import { subqlTest } from "@subql/testing"; -import { Transfer,Token,Contract,Owner } from "../types"; - -let newToken= new Token("1"); - - - -subqlTest( - "handleBlock test", - 3497330, - [ - Contract.create({ - id: '0x1FF2ADAa387dD27c22b31086E658108588eDa03a', - name: 'CryptoPunks', - symbol: 'PUNK', - totalSupply: BigInt(10000), - }), - Transfer.create({ - id: '0x1FF2ADAa387dD27c22b31086E658108588eDa03aTRANSFERID', - tokenId:"1", - fromId: '0x00000000000FROM', - toId: '0x00000000000TO', - timestamp: BigInt(1627440000), - block: BigInt(3497330), - transactionHash: '0x1FF2ADAa387dD27c22b31086E658108588eDa03aTRANSACTIONHASH', - }), - ], - [ - Owner.create({ - id: '0x00000000000TO', - balance: BigInt(1), - }), - ], - 'handleTransfer', - );*/ \ No newline at end of file diff --git a/Moonbeam/moonbeam-substrate-evm-starter/src/tests/mappingHandlers.test.ts b/Moonbeam/moonbeam-substrate-evm-starter/src/tests/mappingHandlers.test.ts new file mode 100644 index 00000000..cb1d8936 --- /dev/null +++ b/Moonbeam/moonbeam-substrate-evm-starter/src/tests/mappingHandlers.test.ts @@ -0,0 +1,13 @@ +import {subqlTest} from "@subql/testing"; +import {Collator, Erc20Transfer} from "../types"; + +/* +// https://academy.subquery.network/build/testing.html +subqlTest( + "testName", // test name + 1000003, // block height to process + [], // dependent entities + [], // expected entities + "handleEvent" //handler name +); +*/ \ No newline at end of file From 93b0bd4776ba7146d2a9b58ebcb5d14a03b1dfdb Mon Sep 17 00:00:00 2001 From: youssefea Date: Fri, 23 Jun 2023 17:41:36 +0100 Subject: [PATCH 10/14] manifest update --- Moonbeam/moonbeam-substrate-evm-starter/project.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Moonbeam/moonbeam-substrate-evm-starter/project.yaml b/Moonbeam/moonbeam-substrate-evm-starter/project.yaml index 13eb07da..4c118de3 100644 --- a/Moonbeam/moonbeam-substrate-evm-starter/project.yaml +++ b/Moonbeam/moonbeam-substrate-evm-starter/project.yaml @@ -54,7 +54,7 @@ dataSources: options: # Must be a key of assets abi: erc20 - # Contract address (or recipient if transfer) to filter, if `null` should be for contract creation + # Contract address of $FRAX address: "0x322E86852e492a7Ee17f28a78c663da38FB33bfb" assets: erc20: From 65f2dde9e33defd8c59d03c84bf38cb90d39bf19 Mon Sep 17 00:00:00 2001 From: youssefea Date: Sun, 25 Jun 2023 20:52:02 +0100 Subject: [PATCH 11/14] updating mapping and manifest --- .../.project-cid | 2 +- .../project.yaml | 6 ++--- .../src/mappings/mappingHandlers.ts | 14 +++++----- .../src/tests/mappingHandlers.test.ts | 26 ++++++++++++------- 4 files changed, 29 insertions(+), 19 deletions(-) diff --git a/Moonbeam/moonbeam-substrate-evm-starter/.project-cid b/Moonbeam/moonbeam-substrate-evm-starter/.project-cid index 83c585e4..0fac55f4 100644 --- a/Moonbeam/moonbeam-substrate-evm-starter/.project-cid +++ b/Moonbeam/moonbeam-substrate-evm-starter/.project-cid @@ -1 +1 @@ -QmcRJzjwZDxXvAA4t54ccrUkzo7emngk7Ayje3ai3iLrQ5 \ No newline at end of file +QmcL3wVRtwgNYpgyfUfDJX3ZVUAe5j3qAmma9NN5DmCYtd \ No newline at end of file diff --git a/Moonbeam/moonbeam-substrate-evm-starter/project.yaml b/Moonbeam/moonbeam-substrate-evm-starter/project.yaml index 4c118de3..c6f531c6 100644 --- a/Moonbeam/moonbeam-substrate-evm-starter/project.yaml +++ b/Moonbeam/moonbeam-substrate-evm-starter/project.yaml @@ -24,15 +24,15 @@ network: # You can get them from OnFinality for free https://app.onfinality.io # https://documentation.onfinality.io/support/the-enhanced-api-service endpoint: - - wss://moonbeam.api.onfinality.io/public-ws - - wss://wss.api.moonbeam.network + - https://moonbeam.blastapi.io/bc88ffcb-8768-4dc8-aee4-5bbb4e285a73 + - wss://moonbeam.blastapi.io/bc88ffcb-8768-4dc8-aee4-5bbb4e285a73 dictionary: "https://api.subquery.network/sq/subquery/moonbeam-dictionary" chaintypes: file: ./dist/chaintypes.js dataSources: - kind: substrate/Runtime # This is the datasource for Moonbeam's Native Substrate processor - startBlock: 1 + startBlock: 189831 mapping: file: ./dist/index.js handlers: diff --git a/Moonbeam/moonbeam-substrate-evm-starter/src/mappings/mappingHandlers.ts b/Moonbeam/moonbeam-substrate-evm-starter/src/mappings/mappingHandlers.ts index c57467c2..7e71180a 100644 --- a/Moonbeam/moonbeam-substrate-evm-starter/src/mappings/mappingHandlers.ts +++ b/Moonbeam/moonbeam-substrate-evm-starter/src/mappings/mappingHandlers.ts @@ -14,28 +14,30 @@ global.atob = require("atob"); global.Blob = require('node-blob'); import { BigNumber } from "ethers"; -export async function collatorJoined(event: SubstrateEvent): Promise { +export async function handleCollatorJoined(call: SubstrateExtrinsic): Promise { - logger.info(`Processing SubstrateEvent at ${event.block.block.header.number}`); + logger.info(`Processing SubstrateEvent at ${call.block.block.header.number}`); - const address = event.extrinsic.extrinsic.signer.toString(); + const address = call.extrinsic.signer.toString(); const collator = Collator.create({ id: address, - joinedDate: event.block.timestamp + joinedDate: call.block.timestamp }); await collator.save(); } -export async function collatorLeft(call: SubstrateExtrinsic): Promise { +export async function handleCollatorLeft(call: SubstrateExtrinsic): Promise { + + logger.info(`Processing SubstrateCall at ${call.block.block.header.number}`); const address = call.extrinsic.signer.toString(); await Collator.remove(address); } -export async function erc20Transfer(event: FrontierEvmEvent<[string, string, BigNumber] & { from: string, to: string, value: BigNumber, }>): Promise { +export async function handleErc20Transfer(event: FrontierEvmEvent<[string, string, BigNumber] & { from: string, to: string, value: BigNumber, }>): Promise { const transfer = Erc20Transfer.create({ id: event.transactionHash, from: event.args.from, diff --git a/Moonbeam/moonbeam-substrate-evm-starter/src/tests/mappingHandlers.test.ts b/Moonbeam/moonbeam-substrate-evm-starter/src/tests/mappingHandlers.test.ts index cb1d8936..e6d350e8 100644 --- a/Moonbeam/moonbeam-substrate-evm-starter/src/tests/mappingHandlers.test.ts +++ b/Moonbeam/moonbeam-substrate-evm-starter/src/tests/mappingHandlers.test.ts @@ -1,13 +1,21 @@ import {subqlTest} from "@subql/testing"; import {Collator, Erc20Transfer} from "../types"; -/* -// https://academy.subquery.network/build/testing.html + subqlTest( - "testName", // test name - 1000003, // block height to process - [], // dependent entities - [], // expected entities - "handleEvent" //handler name -); -*/ \ No newline at end of file + "newCollator test", // test name + 1, // block height to process + [ + Collator.create({ + id: "1", + joinedDate: new Date(1000), + }), + ], // dependent entities + [ + Collator.create({ + id: "1", + joinedDate: new Date(1000), + }) + ], // expected entities + "handleCollatorJoined" //handler name +); \ No newline at end of file From 648135aacfc1d3986e2878e247b4791eb020d23f Mon Sep 17 00:00:00 2001 From: youssefea Date: Mon, 26 Jun 2023 17:40:12 +0100 Subject: [PATCH 12/14] updating manifest, readme and mappingHandlers --- Moonbeam/moonbeam-substrate-evm-starter/README.md | 2 +- Moonbeam/moonbeam-substrate-evm-starter/package.json | 2 +- Moonbeam/moonbeam-substrate-evm-starter/project.yaml | 4 ++-- .../src/mappings/mappingHandlers.ts | 6 ++++-- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/Moonbeam/moonbeam-substrate-evm-starter/README.md b/Moonbeam/moonbeam-substrate-evm-starter/README.md index d5334f6b..cd525191 100644 --- a/Moonbeam/moonbeam-substrate-evm-starter/README.md +++ b/Moonbeam/moonbeam-substrate-evm-starter/README.md @@ -1,6 +1,6 @@ # SubQuery - Starter Package -A basic Frontier EVM example project with an event and call handler. Read more about this at https://university.subquery.network/build/substrate-evm.html. This project can be use as a starting point for developing your SubQuery project +A basic Frontier EVM + Substrate example project with an event handler for the FrontierEVM and call handler for Substrate calls. Read more about this at https://academy.subquery.network/quickstart/quickstart_chains/polkadot-moonbeam.html. This project can be used as a starting point for developing your SubQuery project The Starter Package is an example that you can use as a starting point for developing your SubQuery project. A SubQuery package defines which data The SubQuery will index from the Substrate blockchain, and how it will store it. diff --git a/Moonbeam/moonbeam-substrate-evm-starter/package.json b/Moonbeam/moonbeam-substrate-evm-starter/package.json index 7a12d7a0..d03928ed 100644 --- a/Moonbeam/moonbeam-substrate-evm-starter/package.json +++ b/Moonbeam/moonbeam-substrate-evm-starter/package.json @@ -33,7 +33,7 @@ "@polkadot/api": "^10", "@subql/cli": "latest", "@subql/frontier-evm-processor": "latest", - "@subql/node": "latest", + "@subql/node": "^2.8.0", "@subql/testing": "latest", "@subql/types": "^1.1.0", "typescript": "^4.6.2" diff --git a/Moonbeam/moonbeam-substrate-evm-starter/project.yaml b/Moonbeam/moonbeam-substrate-evm-starter/project.yaml index c6f531c6..a2f81a26 100644 --- a/Moonbeam/moonbeam-substrate-evm-starter/project.yaml +++ b/Moonbeam/moonbeam-substrate-evm-starter/project.yaml @@ -24,8 +24,8 @@ network: # You can get them from OnFinality for free https://app.onfinality.io # https://documentation.onfinality.io/support/the-enhanced-api-service endpoint: - - https://moonbeam.blastapi.io/bc88ffcb-8768-4dc8-aee4-5bbb4e285a73 - - wss://moonbeam.blastapi.io/bc88ffcb-8768-4dc8-aee4-5bbb4e285a73 + - wss://moonbeam.api.onfinality.io/public-ws + - wss://wss.api.moonbeam.network dictionary: "https://api.subquery.network/sq/subquery/moonbeam-dictionary" chaintypes: file: ./dist/chaintypes.js diff --git a/Moonbeam/moonbeam-substrate-evm-starter/src/mappings/mappingHandlers.ts b/Moonbeam/moonbeam-substrate-evm-starter/src/mappings/mappingHandlers.ts index 7e71180a..1ca03d74 100644 --- a/Moonbeam/moonbeam-substrate-evm-starter/src/mappings/mappingHandlers.ts +++ b/Moonbeam/moonbeam-substrate-evm-starter/src/mappings/mappingHandlers.ts @@ -15,7 +15,7 @@ global.Blob = require('node-blob'); import { BigNumber } from "ethers"; export async function handleCollatorJoined(call: SubstrateExtrinsic): Promise { - + //We added a logger to the top of this function, in order to see the block number of the event we are processing. logger.info(`Processing SubstrateEvent at ${call.block.block.header.number}`); const address = call.extrinsic.signer.toString(); @@ -30,7 +30,7 @@ export async function handleCollatorJoined(call: SubstrateExtrinsic): Promise { - + //We added a logger to the top of this function, in order to see the block number of the event we are processing. logger.info(`Processing SubstrateCall at ${call.block.block.header.number}`); const address = call.extrinsic.signer.toString(); @@ -38,6 +38,8 @@ export async function handleCollatorLeft(call: SubstrateExtrinsic): Promise): Promise { + //We added a logger to the top of this function, in order to see the block number of the event we are processing. + logger.info(`Processing MoonbeamEvent at ${event.blockNumber.toString()}`); const transfer = Erc20Transfer.create({ id: event.transactionHash, from: event.args.from, From 7e7099e14626e66e732549d2005a093aacca1dd9 Mon Sep 17 00:00:00 2001 From: youssefea Date: Mon, 26 Jun 2023 18:14:53 +0100 Subject: [PATCH 13/14] updating manifest --- Moonbeam/moonbeam-substrate-evm-starter/project.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Moonbeam/moonbeam-substrate-evm-starter/project.yaml b/Moonbeam/moonbeam-substrate-evm-starter/project.yaml index a2f81a26..b942356c 100644 --- a/Moonbeam/moonbeam-substrate-evm-starter/project.yaml +++ b/Moonbeam/moonbeam-substrate-evm-starter/project.yaml @@ -1,6 +1,6 @@ specVersion: 1.0.0 name: moonbeam-substrate-evm-starter -version: 1.0.0 +version: 0.0.1 runner: node: name: "@subql/node" @@ -32,7 +32,7 @@ network: dataSources: - kind: substrate/Runtime # This is the datasource for Moonbeam's Native Substrate processor - startBlock: 189831 + startBlock: 1 mapping: file: ./dist/index.js handlers: From 7a621a179e3611265f24b6529fbf50271f53b06a Mon Sep 17 00:00:00 2001 From: youssea <81751092+youssefea@users.noreply.github.com> Date: Thu, 6 Jul 2023 23:38:24 +0100 Subject: [PATCH 14/14] Update README.md --- .../moonbeam-substrate-evm-starter/README.md | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/Moonbeam/moonbeam-substrate-evm-starter/README.md b/Moonbeam/moonbeam-substrate-evm-starter/README.md index cd525191..5edee07f 100644 --- a/Moonbeam/moonbeam-substrate-evm-starter/README.md +++ b/Moonbeam/moonbeam-substrate-evm-starter/README.md @@ -91,15 +91,14 @@ Finally, you should see a GraphQL playground is showing in the explorer and the For the `subql-starter` project, you can try to query with the following code to get a taste of how it works. ```graphql -{ - query { - starterEntities(first: 10) { - nodes { - field1 - field2 - field3 - } +query { + erc20transfers (first: 10, orderBy: AMOUNT_DESC) { + nodes { + id + value + from + to + } } - } } ```