From 3c8a0ac779665b9d4efadfaee855adf78b23cf4c Mon Sep 17 00:00:00 2001 From: godlin Date: Mon, 20 May 2024 14:47:17 +0200 Subject: [PATCH 1/4] frontier -> multi-chain --- Astar/astar-evm-starter/README.md | 32 +++-- .../{ => abis}/erc20.abi.json | 0 Astar/astar-evm-starter/docker-compose.yml | 56 ++++++-- Astar/astar-evm-starter/evm.yaml | 41 ++++++ Astar/astar-evm-starter/package.json | 19 +-- Astar/astar-evm-starter/project.ts | 88 ------------- Astar/astar-evm-starter/schema.graphql | 31 +++-- .../src/mappings/mappingHandlers.ts | 90 +++++++------ .../subquery-multichain.yaml | 7 + Astar/astar-evm-starter/substrate.yaml | 34 +++++ Humanode/Humanode-starter/README.md | 120 ++++++++++-------- .../Humanode-starter/abis}/erc20.abi.json | 0 Humanode/Humanode-starter/docker-compose.yml | 56 ++++++-- Humanode/Humanode-starter/evm.yaml | 41 ++++++ Humanode/Humanode-starter/package.json | 18 ++- Humanode/Humanode-starter/project.ts | 105 --------------- Humanode/Humanode-starter/schema.graphql | 14 +- Humanode/Humanode-starter/src/chaintypes.ts | 0 .../src/mappings/mappingHandlers.ts | 72 ++++------- .../Humanode-starter/subquery-multichain.yaml | 7 + Humanode/Humanode-starter/substrate.yaml | 36 ++++++ Moonbeam/moonbeam-evm-starter/README.md | 30 +++-- .../abis}/erc20.abi.json | 0 .../moonbeam-evm-starter/docker-compose.yml | 56 ++++++-- Moonbeam/moonbeam-evm-starter/evm.yaml | 42 ++++++ Moonbeam/moonbeam-evm-starter/package.json | 22 ++-- Moonbeam/moonbeam-evm-starter/project.ts | 89 ------------- Moonbeam/moonbeam-evm-starter/schema.graphql | 17 ++- .../src/mappings/mappingHandlers.ts | 91 +++++++------ .../subquery-multichain.yaml | 7 + Moonbeam/moonbeam-evm-starter/substrate.yaml | 34 +++++ .../.github/scripts/publish-deploy.sh | 15 --- .../.github/workflows/cli-deploy.yml | 34 ----- .../.github/workflows/pr.yml | 24 ---- .../moonbeam-substrate-evm-starter/.gitignore | 58 --------- .../.project-cid | 1 - .../moonbeam-substrate-evm-starter/README.md | 85 ------------- .../docker-compose.yml | 66 ---------- .../docker/load-extensions.sh | 5 - .../docker/pg-Dockerfile | 12 -- .../package.json | 44 ------- .../moonbeam-substrate-evm-starter/project.ts | 107 ---------------- .../schema.graphql | 16 --- .../src/chaintypes.ts | 3 - .../src/index.ts | 3 - .../src/mappings/mappingHandlers.ts | 56 -------- .../src/tests/mappingHandlers.test.ts | 11 -- .../tsconfig.json | 20 --- Moonriver/moonriver-evm-starter/README.md | 30 +++-- .../{ => abis}/erc20.abi.json | 0 .../moonriver-evm-starter/docker-compose.yml | 56 ++++++-- Moonriver/moonriver-evm-starter/evm.yaml | 42 ++++++ Moonriver/moonriver-evm-starter/package.json | 17 +-- Moonriver/moonriver-evm-starter/project.ts | 88 ------------- .../moonriver-evm-starter/schema.graphql | 17 ++- .../src/mappings/mappingHandlers.ts | 89 +++++++------ .../subquery-multichain.yaml | 7 + .../moonriver-evm-starter/substrate.yaml | 34 +++++ Peaq/peaq-starter/README.md | 32 +++-- Peaq/peaq-starter/{ => abis}/erc20.abi.json | 0 Peaq/peaq-starter/docker-compose.yml | 56 ++++++-- Peaq/peaq-starter/evm.yaml | 40 ++++++ Peaq/peaq-starter/package.json | 15 +-- Peaq/peaq-starter/project.ts | 82 ------------ Peaq/peaq-starter/schema.graphql | 31 +++-- .../src/mappings/mappingHandlers.ts | 90 +++++++------ Peaq/peaq-starter/subquery-multichain.yaml | 7 + Peaq/peaq-starter/substrate.yaml | 31 +++++ 68 files changed, 1109 insertions(+), 1470 deletions(-) rename Astar/astar-evm-starter/{ => abis}/erc20.abi.json (100%) create mode 100644 Astar/astar-evm-starter/evm.yaml delete mode 100644 Astar/astar-evm-starter/project.ts create mode 100644 Astar/astar-evm-starter/subquery-multichain.yaml create mode 100644 Astar/astar-evm-starter/substrate.yaml rename {Moonbeam/moonbeam-evm-starter => Humanode/Humanode-starter/abis}/erc20.abi.json (100%) create mode 100644 Humanode/Humanode-starter/evm.yaml delete mode 100644 Humanode/Humanode-starter/project.ts delete mode 100644 Humanode/Humanode-starter/src/chaintypes.ts create mode 100644 Humanode/Humanode-starter/subquery-multichain.yaml create mode 100644 Humanode/Humanode-starter/substrate.yaml rename Moonbeam/{moonbeam-substrate-evm-starter => moonbeam-evm-starter/abis}/erc20.abi.json (100%) create mode 100644 Moonbeam/moonbeam-evm-starter/evm.yaml delete mode 100644 Moonbeam/moonbeam-evm-starter/project.ts create mode 100644 Moonbeam/moonbeam-evm-starter/subquery-multichain.yaml create mode 100644 Moonbeam/moonbeam-evm-starter/substrate.yaml 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/.project-cid delete mode 100644 Moonbeam/moonbeam-substrate-evm-starter/README.md 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/package.json delete mode 100644 Moonbeam/moonbeam-substrate-evm-starter/project.ts 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/tests/mappingHandlers.test.ts delete mode 100644 Moonbeam/moonbeam-substrate-evm-starter/tsconfig.json rename Moonriver/moonriver-evm-starter/{ => abis}/erc20.abi.json (100%) create mode 100644 Moonriver/moonriver-evm-starter/evm.yaml delete mode 100644 Moonriver/moonriver-evm-starter/project.ts create mode 100644 Moonriver/moonriver-evm-starter/subquery-multichain.yaml create mode 100644 Moonriver/moonriver-evm-starter/substrate.yaml rename Peaq/peaq-starter/{ => abis}/erc20.abi.json (100%) create mode 100644 Peaq/peaq-starter/evm.yaml delete mode 100644 Peaq/peaq-starter/project.ts create mode 100644 Peaq/peaq-starter/subquery-multichain.yaml create mode 100644 Peaq/peaq-starter/substrate.yaml diff --git a/Astar/astar-evm-starter/README.md b/Astar/astar-evm-starter/README.md index db652696..699584ba 100644 --- a/Astar/astar-evm-starter/README.md +++ b/Astar/astar-evm-starter/README.md @@ -2,7 +2,7 @@ [SubQuery](https://subquery.network) is a fast, flexible, and reliable open-source data indexer that provides you with custom APIs for your web3 project across all of our supported networks. To learn about how to get started with SubQuery, [visit our docs](https://academy.subquery.network). -**This SubQuery project indexes all transfers and approval events for all ERC20 tokens on Astar's EVM** +**This SubQuery project indexes all transfers and approval events for all ERC20 tokens on Astar's EVM as well as transfers related to Substrate** ## Start @@ -41,26 +41,32 @@ For this project, you can try to query with the following GraphQL code to get a ```graphql { query { - transactions(first: 5, orderBy: VALUE_DESC) { - totalCount + eRC20TokenTransfers(first: 3) { nodes { id - transactionHash - blockHeight from to value contractAddress } } - } - approvals(first: 5) { - nodes { - id - owner - spender - value - contractAddress + eRC20Approvals(first: 3) { + nodes { + id + value + owner + spender + contractAddress + } + } + substrateTransfers(first: 3) { + nodes { + id + from + to + amount + date + } } } } diff --git a/Astar/astar-evm-starter/erc20.abi.json b/Astar/astar-evm-starter/abis/erc20.abi.json similarity index 100% rename from Astar/astar-evm-starter/erc20.abi.json rename to Astar/astar-evm-starter/abis/erc20.abi.json diff --git a/Astar/astar-evm-starter/docker-compose.yml b/Astar/astar-evm-starter/docker-compose.yml index 57a72876..b526d223 100644 --- a/Astar/astar-evm-starter/docker-compose.yml +++ b/Astar/astar-evm-starter/docker-compose.yml @@ -17,7 +17,38 @@ services: timeout: 5s retries: 5 - subquery-node: + subquery-node-evm: + image: subquerynetwork/subql-node-ethereum: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: + - --multi-chain + - --db-schema=multi-chain + - --disable-historical + - -f=app/evm.yaml + - --batch-size=30 + - --workers=4 + healthcheck: + test: + - CMD + - curl + - -f + - http://subquery-node-ethereum:3000/ready + interval: 3s + timeout: 5s + retries: 10 + + subquery-node-substrate: image: subquerynetwork/subql-node-substrate:latest depends_on: "postgres": @@ -32,14 +63,16 @@ services: volumes: - ./:/app command: - - ${SUB_COMMAND:-} # set SUB_COMMAND env variable to "test" to run tests - - -f=/app - - --db-schema=app - - --workers=4 - - --batch-size=30 - - --unfinalized-blocks=true + - -f=app/substrate.yaml + - --multi-chain + - --db-schema=multi-chain + - --disable-historical healthcheck: - test: ["CMD", "curl", "-f", "http://subquery-node:3000/ready"] + test: + - CMD + - curl + - -f + - http://subquery-node-project-kusama:3000/ready interval: 3s timeout: 5s retries: 10 @@ -51,9 +84,7 @@ services: depends_on: "postgres": condition: service_healthy - "subquery-node": - condition: service_healthy - restart: always + restart: unless-stopped environment: DB_USER: postgres DB_PASS: postgres @@ -61,6 +92,5 @@ services: DB_HOST: postgres DB_PORT: 5432 command: - - --name=app + - --name=multi-chain - --playground - - --indexer=http://subquery-node:3000 diff --git a/Astar/astar-evm-starter/evm.yaml b/Astar/astar-evm-starter/evm.yaml new file mode 100644 index 00000000..90275447 --- /dev/null +++ b/Astar/astar-evm-starter/evm.yaml @@ -0,0 +1,41 @@ +# // Auto-generated , DO NOT EDIT +specVersion: 1.0.0 +version: 0.0.1 +name: astar-evm-starter +description: >- + This project can be use as a starting point for developing your new Ethereum + SubQuery project +runner: + node: + name: "@subql/node-ethereum" + version: ">=3.0.0" + query: + name: "@subql/query" + version: "*" +schema: + file: ./schema.graphql +network: + chainId: "592" + endpoint: + - wss://astar.api.onfinality.io/public-ws + - wss://rpc.astar.network +dataSources: + - kind: ethereum/Runtime + startBlock: 970733 + options: + abi: erc20 + assets: + erc20: + file: ./abis/erc20.abi.json + mapping: + file: ./dist/index.js + handlers: + - handler: handleEVMLog + kind: ethereum/LogHandler + filter: + topics: + - Transfer(address indexed from,address indexed to,uint256 value) + - handler: handleEVMTransaction + kind: ethereum/TransactionHandler + filter: + function: approve(address to,uint256 value) diff --git a/Astar/astar-evm-starter/package.json b/Astar/astar-evm-starter/package.json index db9e9bba..65550da8 100644 --- a/Astar/astar-evm-starter/package.json +++ b/Astar/astar-evm-starter/package.json @@ -1,7 +1,7 @@ { "name": "astar-evm-starter", "version": "1.0.0", - "description": "A basic Frontier EVM example project with an event and call handler. Read more about this at https://university.subquery.network/create/frontier/. This project can be use as a starting point for developing your SubQuery project", + "description": "A basic 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", "main": "dist/index.js", "scripts": { "build": "subql build", @@ -24,19 +24,20 @@ "ipfs-unixfs": "6.0.6" }, "devDependencies": { - "@polkadot/api": "^10", "@subql/cli": "latest", - "@subql/frontier-evm-processor": "latest", - "@subql/node": "latest", - "@subql/testing": "latest", "@subql/types": "latest", - "@subql/types-ethereum": "latest", - "typescript": "^5.2.2" + "@subql/testing": "latest", + "@subql/node-ethereum": "latest", + "ethers": "^5.7.2", + "@polkadot/api": "^10", + "typescript": "^5.2.2", + "@subql/node": "latest" }, "exports": { "chaintypes": "src/chaintypes.ts" }, "dependencies": { - "assert": "^2.0.0" + "assert": "^2.0.0", + "@subql/types-ethereum": "latest" } -} +} \ No newline at end of file diff --git a/Astar/astar-evm-starter/project.ts b/Astar/astar-evm-starter/project.ts deleted file mode 100644 index f41f0cb4..00000000 --- a/Astar/astar-evm-starter/project.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { - SubstrateDatasourceKind, - SubstrateHandlerKind, - SubstrateProject, -} from "@subql/types"; - -import { FrontierEvmDatasource } from "@subql/frontier-evm-processor"; - -// Can expand the Datasource processor types via the genreic param -const project: SubstrateProject = { - specVersion: "1.0.0", - version: "0.0.1", - name: "astar-evm-starter", - description: `A basic Frontier EVM example project with an event and call handler. Read more - about this at https://university.subquery.network/create/frontier/. This - project can be use as a starting point for developing your SubQuery project`, - runner: { - node: { - name: "@subql/node", - version: ">=3.0.1", - }, - query: { - name: "@subql/query", - version: "*", - }, - }, - schema: { - file: "./schema.graphql", - }, - network: { - /* The genesis hash of the network (hash of block 0) */ - chainId: - "0x9eb76c5184c4ab8679d2d5d819fdf90b9c001403e9e17da2e14b6d8aec4029c6", - /** - * These endpoint(s) should be public non-pruned archive node - * We recommend providing more than one endpoint for improved reliability, performance, and uptime - * Public nodes may be rate limited, which can affect indexing speed - * When developing your project we suggest getting a private API key - * If you use a rate limited endpoint, adjust the --batch-size and --workers parameters - * These settings can be found in your docker-compose.yaml, they will slow indexing but prevent your project being rate limited - */ - endpoint: [ - "wss://astar.api.onfinality.io/public-ws", - "wss://rpc.astar.network", - ], - chaintypes: { - file: "./dist/chaintypes.js", - }, - }, - dataSources: [ - { - kind: "substrate/FrontierEvm", - startBlock: 970733, - processor: { - file: "./node_modules/@subql/frontier-evm-processor/dist/bundle.js", - options: { - abi: "erc20", - // address: '0x0000000000000000000000000000000000000000' // A specific contract to index - }, - }, - assets: new Map([["erc20", { file: "./erc20.abi.json" }]]), - mapping: { - file: "./dist/index.js", - handlers: [ - { - handler: "handleEvmEvent", - kind: "substrate/FrontierEvmEvent", - filter: { - topics: [ - "Transfer(address indexed from,address indexed to,uint256 value)", - ], - }, - }, - { - handler: "handleEvmCall", - kind: "substrate/FrontierEvmCall", - filter: { - function: "approve(address to,uint256 value)", - }, - }, - ], - }, - }, - ], -}; - -// Must set default to the project instance -export default project; diff --git a/Astar/astar-evm-starter/schema.graphql b/Astar/astar-evm-starter/schema.graphql index 24d64105..220915d9 100644 --- a/Astar/astar-evm-starter/schema.graphql +++ b/Astar/astar-evm-starter/schema.graphql @@ -1,17 +1,28 @@ -type Transaction @entity { - id: ID! # Unique identifier - transactionHash: String! - value: BigInt - to: String - from: String - blockHeight: String +# 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 ERC20TokenTransfer @entity { + id: ID! + value: BigInt! + to: String! + from: String! contractAddress: String! } -type Approval @entity { - id: ID! # Unique identifier - value: BigInt +type ERC20Approval @entity { + id: ID! + value: BigInt! owner: String! spender: String! contractAddress: String! } + +type SubstrateTransfer @entity { + id: ID! + amount: BigInt! + blockNumber: Int! + date: Date! + from: String! + to: String! +} diff --git a/Astar/astar-evm-starter/src/mappings/mappingHandlers.ts b/Astar/astar-evm-starter/src/mappings/mappingHandlers.ts index 68b5e75c..80267659 100644 --- a/Astar/astar-evm-starter/src/mappings/mappingHandlers.ts +++ b/Astar/astar-evm-starter/src/mappings/mappingHandlers.ts @@ -1,53 +1,61 @@ -import { Approval, Transaction } from "../types"; -import { - FrontierEvmEvent, - FrontierEvmCall, -} from "@subql/frontier-evm-processor"; -import { BigNumber } from "ethers"; +import { ERC20TokenTransfer, ERC20Approval, SubstrateTransfer } from "../types"; +import { TransferLog } from "../types/abi-interfaces/Erc20Abi"; +import { ApproveTransaction } from "../types/abi-interfaces/Erc20Abi"; import assert from "assert"; +import { SubstrateEvent } from "@subql/types"; +import { Balance } from "@polkadot/types/interfaces"; -// Setup types from ABI -type TransferEventArgs = [string, string, BigNumber] & { - from: string; - to: string; - value: BigNumber; -}; +export async function handleEVMLog(log: TransferLog): Promise { + logger.info(`New transfer transaction log at block ${log.blockNumber}`); + assert(log.args, "No log.args"); -type ApproveCallArgs = [string, BigNumber] & { - _spender: string; - _value: BigNumber; -}; - -export async function handleEvmEvent( - event: FrontierEvmEvent, -): Promise { - assert(event.transactionHash, "No transactionHash"); - - const transaction = Transaction.create({ - id: `${event.blockNumber}-${event.transactionHash}-${event.logIndex}`, - value: event.args?.value.toBigInt(), - from: event.args?.from, - to: event.args?.to, - blockHeight: event.blockNumber.toString(), - contractAddress: event.address, - transactionHash: event.transactionHash, + const transaction = ERC20TokenTransfer.create({ + id: log.transactionHash, + to: log.args.to, + from: log.args.from, + value: log.args.value.toBigInt(), + contractAddress: log.address, }); + await transaction.save(); } -export async function handleEvmCall( - event: FrontierEvmCall, +export async function handleEVMTransaction( + tx: ApproveTransaction ): Promise { - assert(event.args, "No event.args"); - assert(event.to, "No event.to"); - - const approval = Approval.create({ - id: event.hash, - owner: event.from, - value: event.args._value.toBigInt(), - spender: event.args._spender, - contractAddress: event.to, + logger.info(`New Approval transaction at block ${tx.blockNumber}`); + assert(tx.args, "No tx.args"); + + const approval = ERC20Approval.create({ + id: tx.hash, + owner: tx.from, + spender: await tx.args[0], + value: BigInt(await tx.args[1].toString()), + contractAddress: tx.to, }); await approval.save(); } + +export async function handleEvent(event: SubstrateEvent): Promise { + logger.info( + `New transfer event found at block ${event.block.block.header.number.toString()}` + ); + const { + event: { + data: [from, to, amount], + }, + } = event; + + const blockNumber: number = event.block.block.header.number.toNumber(); + const transfer = SubstrateTransfer.create({ + id: `${event.block.block.header.number.toNumber()}-${event.idx}`, + blockNumber, + date: event.block.timestamp, + from: from.toString(), + to: to.toString(), + amount: (amount as Balance).toBigInt(), + }); + + await transfer.save(); +} diff --git a/Astar/astar-evm-starter/subquery-multichain.yaml b/Astar/astar-evm-starter/subquery-multichain.yaml new file mode 100644 index 00000000..d2b3c932 --- /dev/null +++ b/Astar/astar-evm-starter/subquery-multichain.yaml @@ -0,0 +1,7 @@ +specVersion: 1.0.0 +query: + name: '@subql/query' + version: '*' +projects: + - substrate.yaml + - evm.yaml diff --git a/Astar/astar-evm-starter/substrate.yaml b/Astar/astar-evm-starter/substrate.yaml new file mode 100644 index 00000000..f5b7b351 --- /dev/null +++ b/Astar/astar-evm-starter/substrate.yaml @@ -0,0 +1,34 @@ +# // Auto-generated , DO NOT EDIT +specVersion: 1.0.0 +version: 0.0.1 +name: astar-evm-starter +description: >- + This project can be used as a starting point for developing your SubQuery + project +runner: + node: + name: "@subql/node" + version: ">=3.0.1" + query: + name: "@subql/query" + version: "*" +schema: + file: ./schema.graphql +network: + chainId: "0x9eb76c5184c4ab8679d2d5d819fdf90b9c001403e9e17da2e14b6d8aec4029c6" + endpoint: + - wss://astar.api.onfinality.io/public-ws + - wss://rpc.astar.network + chaintypes: + file: ./dist/chaintypes.js +dataSources: + - kind: substrate/Runtime + startBlock: 1 + mapping: + file: ./dist/index.js + handlers: + - kind: substrate/EventHandler + handler: handleEvent + filter: + module: balances + method: Transfer diff --git a/Humanode/Humanode-starter/README.md b/Humanode/Humanode-starter/README.md index ffb47dac..7c9798e7 100644 --- a/Humanode/Humanode-starter/README.md +++ b/Humanode/Humanode-starter/README.md @@ -41,42 +41,39 @@ For this project, you can try to query with the following GraphQL code to get a ```graphql { query { - transactions(first: 1, orderBy: VALUE_DESC) { - totalCount + eRC20TokenTransfers(first: 3) { nodes { id - transactionHash - blockHeight from to value contractAddress } } - } - approvals(first: 1) { - nodes { - id - owner - spender - value - contractAddress + eRC20Approvals(first: 3) { + nodes { + id + value + owner + spender + contractAddress + } } - } - bioauthNewAuthentications(first: 1) { - nodes { - id - validatorPublicKey - timestamp - blockNumber + bioauthNewAuthentications(first: 1) { + nodes { + id + validatorPublicKey + timestamp + blockNumber + } } - } - imOnlineSomeOfflines(first: 1) { - nodes { - id - accountIds - timestamp - blockNumber + imOnlineSomeOfflines(first: 1) { + nodes { + id + accountIds + timestamp + blockNumber + } } } } @@ -88,41 +85,52 @@ Afterward, anticipate receiving a result resembling this: { "data": { "query": { - "transactions": { + "eRC20TokenTransfers": { + "nodes": [ + { + "id": "0x1272f33847946221216ba1cb4ce9171ea0da551780ab632988e5b2f7a65d6ff6", + "from": "0x8C20a3F5C9A5926d4C83592c25317f602b385441", + "to": "0xF52838e033a20295b69F8fBf75b00E0E5a482b4b", + "value": "1000000000000000000", + "contractAddress": "0x0000000000000000000000000000000000000802" + }, + { + "id": "0x581084e04b4d939db3c1cb5dc2b009c4755a73af0b8929fe9eb3a24c7a1eddaa", + "from": "0x8C20a3F5C9A5926d4C83592c25317f602b385441", + "to": "0xF52838e033a20295b69F8fBf75b00E0E5a482b4b", + "value": "5499999999999999725", + "contractAddress": "0x0000000000000000000000000000000000000802" + }, + { + "id": "0x60590c52429ecec6145a801622cea200e9454eb79d2ebf229bcf59c2e3c7c21a", + "from": "0x8C20a3F5C9A5926d4C83592c25317f602b385441", + "to": "0xF52838e033a20295b69F8fBf75b00E0E5a482b4b", + "value": "10000000000000000000", + "contractAddress": "0x0000000000000000000000000000000000000802" + } + ] + }, + "eRC20Approvals": { "nodes": [ { - "id": "7487952-0x030d4ab19a9fa75e093bcbc400f1a10a6e377e52f673bfd1cd490572e9874282-0", - "transactionHash": "0x030d4ab19a9fa75e093bcbc400f1a10a6e377e52f673bfd1cd490572e9874282", - "blockHeight": "7487952", - "from": "0xf591da380c911C7bE9Ba48bD14c451bF784886F7", - "to": "0xe48Cc340B8f1AC0a326577B3c2d1Fe5229ebb1c2", - "value": "9800000000000000000000", + "id": "0x5fbb64a3341b2abf82cbaf89ba2f0d1855803852dd7ead903fd979a4a765b4d6", + "value": "194067188645000000000", + "owner": "0xF52838e033a20295b69F8fBf75b00E0E5a482b4b", + "spender": "0x8C20a3F5C9A5926d4C83592c25317f602b385441", "contractAddress": "0x0000000000000000000000000000000000000802" } ] - } - }, - "approvals": { - "nodes": [ - { - "id": "0x909a9c2d5eead83eeba78f8b4cfd789cf1b2fcfc543a33b63a792fe4a8a53b37", - "owner": "0xd5b2bceeaaaccb2bf152207f7e8c4abcaa7d5881", - "spender": "0x8C20a3F5C9A5926d4C83592c25317f602b385441", - "value": "100000000000000000000", - "contractAddress": "0x0000000000000000000000000000000000000802" - } - ] - }, - "bioauthNewAuthentications": { - "nodes": [ - { - "id": "7489527-1", - "validatorPublicKey": "hmsxpGvLUfSbUZxUYFZF9dNm3Jf9xUBdhN1p229qAr4xiktFP", - "timestamp": "2024-04-26T13:34:18", - "blockNumber": 7489527 - } - ] - }, + }, + "bioauthNewAuthentications": { + "nodes": [ + { + "id": "4792181-1", + "validatorPublicKey": "hmpRQiS4p7pPr44ibxr25kQ6VqgWGL7whRJ3xx2dsZDJSQ932", + "timestamp": "2023-10-18T09:38:12", + "blockNumber": 4792181 + } + ] + }, "imOnlineSomeOfflines": { "nodes": [ { diff --git a/Moonbeam/moonbeam-evm-starter/erc20.abi.json b/Humanode/Humanode-starter/abis/erc20.abi.json similarity index 100% rename from Moonbeam/moonbeam-evm-starter/erc20.abi.json rename to Humanode/Humanode-starter/abis/erc20.abi.json diff --git a/Humanode/Humanode-starter/docker-compose.yml b/Humanode/Humanode-starter/docker-compose.yml index 57a72876..b526d223 100644 --- a/Humanode/Humanode-starter/docker-compose.yml +++ b/Humanode/Humanode-starter/docker-compose.yml @@ -17,7 +17,38 @@ services: timeout: 5s retries: 5 - subquery-node: + subquery-node-evm: + image: subquerynetwork/subql-node-ethereum: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: + - --multi-chain + - --db-schema=multi-chain + - --disable-historical + - -f=app/evm.yaml + - --batch-size=30 + - --workers=4 + healthcheck: + test: + - CMD + - curl + - -f + - http://subquery-node-ethereum:3000/ready + interval: 3s + timeout: 5s + retries: 10 + + subquery-node-substrate: image: subquerynetwork/subql-node-substrate:latest depends_on: "postgres": @@ -32,14 +63,16 @@ services: volumes: - ./:/app command: - - ${SUB_COMMAND:-} # set SUB_COMMAND env variable to "test" to run tests - - -f=/app - - --db-schema=app - - --workers=4 - - --batch-size=30 - - --unfinalized-blocks=true + - -f=app/substrate.yaml + - --multi-chain + - --db-schema=multi-chain + - --disable-historical healthcheck: - test: ["CMD", "curl", "-f", "http://subquery-node:3000/ready"] + test: + - CMD + - curl + - -f + - http://subquery-node-project-kusama:3000/ready interval: 3s timeout: 5s retries: 10 @@ -51,9 +84,7 @@ services: depends_on: "postgres": condition: service_healthy - "subquery-node": - condition: service_healthy - restart: always + restart: unless-stopped environment: DB_USER: postgres DB_PASS: postgres @@ -61,6 +92,5 @@ services: DB_HOST: postgres DB_PORT: 5432 command: - - --name=app + - --name=multi-chain - --playground - - --indexer=http://subquery-node:3000 diff --git a/Humanode/Humanode-starter/evm.yaml b/Humanode/Humanode-starter/evm.yaml new file mode 100644 index 00000000..d2b2c57e --- /dev/null +++ b/Humanode/Humanode-starter/evm.yaml @@ -0,0 +1,41 @@ +# // Auto-generated , DO NOT EDIT +specVersion: 1.0.0 +version: 0.0.1 +name: humanode-starter +description: >- + This project can be use as a starting point for developing your new Ethereum + SubQuery project +runner: + node: + name: "@subql/node-ethereum" + version: ">=3.0.0" + query: + name: "@subql/query" + version: "*" +schema: + file: ./schema.graphql +network: + chainId: "5234" + endpoint: + - wss://explorer-rpc-ws.mainnet.stages.humanode.io +dataSources: + - kind: ethereum/Runtime + startBlock: 1 + options: + abi: erc20 + address: "0x0000000000000000000000000000000000000802" + assets: + erc20: + file: ./abis/erc20.abi.json + mapping: + file: ./dist/index.js + handlers: + - handler: handleEVMLog + kind: ethereum/LogHandler + filter: + topics: + - Transfer(address indexed from,address indexed to,uint256 value) + - handler: handleEVMTransaction + kind: ethereum/TransactionHandler + filter: + function: approve(address to,uint256 value) diff --git a/Humanode/Humanode-starter/package.json b/Humanode/Humanode-starter/package.json index 54a69408..7e0bb224 100644 --- a/Humanode/Humanode-starter/package.json +++ b/Humanode/Humanode-starter/package.json @@ -1,7 +1,7 @@ { - "name": "peaq-starter", + "name": "humanode-starter", "version": "1.0.0", - "description": "A basic Frontier EVM example project with an event and call handler. Read more about this at https://academy.subquery.network/create/frontier/. This project can be use as a starting point for developing your SubQuery project", + "description": "A basic 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", "main": "dist/index.js", "scripts": { "build": "subql build", @@ -11,8 +11,6 @@ "prepack": "rm -rf dist && npm run build", "test": "subql build && subql-node test" }, - "homepage": "https://github.com/subquery/subql-starter", - "repository": "github:subquery/subql-starter", "files": [ "dist", "schema.graphql", @@ -24,14 +22,14 @@ "ipfs-unixfs": "6.0.6" }, "devDependencies": { - "@polkadot/api": "^10", "@subql/cli": "latest", - "@subql/frontier-evm-processor": "latest", - "@subql/node": "latest", - "@subql/testing": "latest", "@subql/types": "latest", - "@subql/types-ethereum": "latest", - "typescript": "^5.2.2" + "@subql/testing": "latest", + "@subql/node-ethereum": "latest", + "ethers": "^5.7.2", + "@polkadot/api": "^10", + "typescript": "^5.2.2", + "@subql/node": "latest" }, "dependencies": { "assert": "^2.0.0" diff --git a/Humanode/Humanode-starter/project.ts b/Humanode/Humanode-starter/project.ts deleted file mode 100644 index 3d9cdb62..00000000 --- a/Humanode/Humanode-starter/project.ts +++ /dev/null @@ -1,105 +0,0 @@ -import { - SubstrateDatasourceKind, - SubstrateHandlerKind, - SubstrateProject, -} from "@subql/types"; - -import { FrontierEvmDatasource } from "@subql/frontier-evm-processor"; - -// Can expand the Datasource processor types via the genreic param -const project: SubstrateProject = { - specVersion: "1.0.0", - version: "0.0.1", - name: "humanode-starter", - description: `This project can be used as a starting point for developing your SubQuery project. It indexes all transfers, bioauthentication events, and online validator nodes from Humanode chain. Moreover, it indexes the approvals and transfers of HMND token.`, - runner: { - node: { - name: "@subql/node", - version: ">=3.0.1", - }, - query: { - name: "@subql/query", - version: "*", - }, - }, - schema: { - file: "./schema.graphql", - }, - network: { - /* The genesis hash of the network (hash of block 0) */ - chainId: - "0xc56fa32442b2dad76f214b3ae07998e4ca09736e4813724bfb0717caae2c8bee", - /** - * These endpoint(s) should be public non-pruned archive node - * We recommend providing more than one endpoint for improved reliability, performance, and uptime - * Public nodes may be rate limited, which can affect indexing speed - * When developing your project we suggest getting a private API key - * If you use a rate limited endpoint, adjust the --batch-size and --workers parameters - * These settings can be found in your docker-compose.yaml, they will slow indexing but prevent your project being rate limited - */ - endpoint: ["wss://explorer-rpc-ws.mainnet.stages.humanode.io"], - }, - dataSources: [ - { - kind: "substrate/FrontierEvm", - startBlock: 1, - processor: { - file: "./node_modules/@subql/frontier-evm-processor/dist/bundle.js", - options: { - abi: "erc20", - address: "0x0000000000000000000000000000000000000802", // A specific contract to index - }, - }, - assets: new Map([["erc20", { file: "./erc20.abi.json" }]]), - mapping: { - file: "./dist/index.js", - handlers: [ - { - handler: "handleEvmEvent", - kind: "substrate/FrontierEvmEvent", - filter: { - topics: [ - "Transfer(address indexed from,address indexed to,uint256 value)", - ], - }, - }, - { - handler: "handleEvmCall", - kind: "substrate/FrontierEvmCall", - filter: { - function: "approve(address to,uint256 value)", - }, - }, - ], - }, - }, - { - kind: SubstrateDatasourceKind.Runtime, - startBlock: 1, - mapping: { - file: "./dist/index.js", - handlers: [ - { - kind: SubstrateHandlerKind.Event, - handler: "handleBioauthNewAuthenticationEvent", - filter: { - module: "bioauth", - method: "NewAuthentication", - }, - }, - { - kind: SubstrateHandlerKind.Event, - handler: "handleImonlineSomeOfflineEvent", - filter: { - module: "imOnline", - method: "SomeOffline", - }, - }, - ], - }, - }, - ], -}; - -// Must set default to the project instance -export default project; diff --git a/Humanode/Humanode-starter/schema.graphql b/Humanode/Humanode-starter/schema.graphql index 9d615020..75aa191a 100644 --- a/Humanode/Humanode-starter/schema.graphql +++ b/Humanode/Humanode-starter/schema.graphql @@ -1,16 +1,14 @@ -type Transaction @entity { +type ERC20TokenTransfer @entity { id: ID! - transactionHash: String! - value: BigInt - to: String - from: String - blockHeight: String + value: BigInt! + to: String! + from: String! contractAddress: String! } -type Approval @entity { +type ERC20Approval @entity { id: ID! - value: BigInt + value: BigInt! owner: String! spender: String! contractAddress: String! diff --git a/Humanode/Humanode-starter/src/chaintypes.ts b/Humanode/Humanode-starter/src/chaintypes.ts deleted file mode 100644 index e69de29b..00000000 diff --git a/Humanode/Humanode-starter/src/mappings/mappingHandlers.ts b/Humanode/Humanode-starter/src/mappings/mappingHandlers.ts index 9385d413..6d4be8ae 100644 --- a/Humanode/Humanode-starter/src/mappings/mappingHandlers.ts +++ b/Humanode/Humanode-starter/src/mappings/mappingHandlers.ts @@ -1,59 +1,43 @@ -import { - Approval, - Transaction, - BioauthNewAuthentication, - ImOnlineSomeOffline, -} from "../types"; -import { - FrontierEvmEvent, - FrontierEvmCall, -} from "@subql/frontier-evm-processor"; -import { BigNumber } from "ethers"; import assert from "assert"; import { Codec } from "@polkadot/types/types"; import { Vec } from "@polkadot/types-codec"; import { SubstrateEvent } from "@subql/types"; +import { + ERC20TokenTransfer, + ERC20Approval, + BioauthNewAuthentication, + ImOnlineSomeOffline, +} from "../types"; +import { TransferLog } from "../types/abi-interfaces/Erc20Abi"; +import { ApproveTransaction } from "../types/abi-interfaces/Erc20Abi"; -type TransferEventArgs = [string, string, BigNumber] & { - from: string; - to: string; - value: BigNumber; -}; - -type ApproveCallArgs = [string, BigNumber] & { - _spender: string; - _value: BigNumber; -}; - -export async function handleEvmEvent( - event: FrontierEvmEvent -): Promise { - assert(event.transactionHash, "No transactionHash"); +export async function handleEVMLog(log: TransferLog): Promise { + logger.info(`New transfer transaction log at block ${log.blockNumber}`); + assert(log.args, "No log.args"); - const transaction = Transaction.create({ - id: `${event.blockNumber}-${event.transactionHash}-${event.logIndex}`, - value: event.args?.value.toBigInt(), - from: event.args?.from, - to: event.args?.to, - blockHeight: event.blockNumber.toString(), - contractAddress: event.address, - transactionHash: event.transactionHash, + const transaction = ERC20TokenTransfer.create({ + id: log.transactionHash, + to: log.args.to, + from: log.args.from, + value: log.args.value.toBigInt(), + contractAddress: log.address, }); + await transaction.save(); } -export async function handleEvmCall( - event: FrontierEvmCall +export async function handleEVMTransaction( + tx: ApproveTransaction ): Promise { - assert(event.args, "No event.args"); - assert(event.to, "No event.to"); + logger.info(`New Approval transaction at block ${tx.blockNumber}`); + assert(tx.args, "No tx.args"); - const approval = Approval.create({ - id: event.hash, - owner: event.from, - value: event.args._value.toBigInt(), - spender: event.args._spender, - contractAddress: event.to, + const approval = ERC20Approval.create({ + id: tx.hash, + owner: tx.from, + spender: await tx.args[0], + value: BigInt(await tx.args[1].toString()), + contractAddress: tx.to, }); await approval.save(); diff --git a/Humanode/Humanode-starter/subquery-multichain.yaml b/Humanode/Humanode-starter/subquery-multichain.yaml new file mode 100644 index 00000000..d2b3c932 --- /dev/null +++ b/Humanode/Humanode-starter/subquery-multichain.yaml @@ -0,0 +1,7 @@ +specVersion: 1.0.0 +query: + name: '@subql/query' + version: '*' +projects: + - substrate.yaml + - evm.yaml diff --git a/Humanode/Humanode-starter/substrate.yaml b/Humanode/Humanode-starter/substrate.yaml new file mode 100644 index 00000000..7e87244d --- /dev/null +++ b/Humanode/Humanode-starter/substrate.yaml @@ -0,0 +1,36 @@ +# // Auto-generated , DO NOT EDIT +specVersion: 1.0.0 +version: 0.0.1 +name: humanode-starter +description: >- + This project can be used as a starting point for developing your SubQuery + project +runner: + node: + name: "@subql/node" + version: ">=3.0.1" + query: + name: "@subql/query" + version: "*" +schema: + file: ./schema.graphql +network: + chainId: "0xc56fa32442b2dad76f214b3ae07998e4ca09736e4813724bfb0717caae2c8bee" + endpoint: + - wss://explorer-rpc-ws.mainnet.stages.humanode.io +dataSources: + - kind: substrate/Runtime + startBlock: 1 + mapping: + file: ./dist/index.js + handlers: + - kind: substrate/EventHandler + handler: handleBioauthNewAuthenticationEvent + filter: + module: bioauth + method: NewAuthentication + - kind: substrate/EventHandler + handler: handleImonlineSomeOfflineEvent + filter: + module: imOnline + method: SomeOffline diff --git a/Moonbeam/moonbeam-evm-starter/README.md b/Moonbeam/moonbeam-evm-starter/README.md index d28d6346..7d49523f 100644 --- a/Moonbeam/moonbeam-evm-starter/README.md +++ b/Moonbeam/moonbeam-evm-starter/README.md @@ -2,7 +2,7 @@ [SubQuery](https://subquery.network) is a fast, flexible, and reliable open-source data indexer that provides you with custom APIs for your web3 project across all of our supported networks. To learn about how to get started with SubQuery, [visit our docs](https://academy.subquery.network). -**This SubQuery project indexes all transfers and approval events for the [Solarflare token](https://moonscan.io/token/0xe3e43888fa7803cdc7bea478ab327cf1a0dc11a7) (`0xe3e43888fa7803cdc7bea478ab327cf1a0dc11a7`) on Moonbeam's EVM** +**This SubQuery project indexes all transfers and approval events for the [Solarflare token](https://moonscan.io/token/0xe3e43888fa7803cdc7bea478ab327cf1a0dc11a7) (`0xe3e43888fa7803cdc7bea478ab327cf1a0dc11a7`) on Moonbeam's EVM as well as transfers related to Substrate** ## Start @@ -41,8 +41,7 @@ For this project, you can try to query with the following GraphQL code to get a ```graphql { query { - transactions(first: 5, orderBy: VALUE_DESC) { - totalCount + eRC20TokenTransfers(first: 3) { nodes { id from @@ -51,14 +50,23 @@ For this project, you can try to query with the following GraphQL code to get a contractAddress } } - } - approvals(first: 5) { - nodes { - id - owner - spender - value - contractAddress + eRC20Approvals(first: 3) { + nodes { + id + value + owner + spender + contractAddress + } + } + substrateTransfers(first: 3) { + nodes { + id + from + to + amount + date + } } } } diff --git a/Moonbeam/moonbeam-substrate-evm-starter/erc20.abi.json b/Moonbeam/moonbeam-evm-starter/abis/erc20.abi.json similarity index 100% rename from Moonbeam/moonbeam-substrate-evm-starter/erc20.abi.json rename to Moonbeam/moonbeam-evm-starter/abis/erc20.abi.json diff --git a/Moonbeam/moonbeam-evm-starter/docker-compose.yml b/Moonbeam/moonbeam-evm-starter/docker-compose.yml index 57a72876..b526d223 100644 --- a/Moonbeam/moonbeam-evm-starter/docker-compose.yml +++ b/Moonbeam/moonbeam-evm-starter/docker-compose.yml @@ -17,7 +17,38 @@ services: timeout: 5s retries: 5 - subquery-node: + subquery-node-evm: + image: subquerynetwork/subql-node-ethereum: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: + - --multi-chain + - --db-schema=multi-chain + - --disable-historical + - -f=app/evm.yaml + - --batch-size=30 + - --workers=4 + healthcheck: + test: + - CMD + - curl + - -f + - http://subquery-node-ethereum:3000/ready + interval: 3s + timeout: 5s + retries: 10 + + subquery-node-substrate: image: subquerynetwork/subql-node-substrate:latest depends_on: "postgres": @@ -32,14 +63,16 @@ services: volumes: - ./:/app command: - - ${SUB_COMMAND:-} # set SUB_COMMAND env variable to "test" to run tests - - -f=/app - - --db-schema=app - - --workers=4 - - --batch-size=30 - - --unfinalized-blocks=true + - -f=app/substrate.yaml + - --multi-chain + - --db-schema=multi-chain + - --disable-historical healthcheck: - test: ["CMD", "curl", "-f", "http://subquery-node:3000/ready"] + test: + - CMD + - curl + - -f + - http://subquery-node-project-kusama:3000/ready interval: 3s timeout: 5s retries: 10 @@ -51,9 +84,7 @@ services: depends_on: "postgres": condition: service_healthy - "subquery-node": - condition: service_healthy - restart: always + restart: unless-stopped environment: DB_USER: postgres DB_PASS: postgres @@ -61,6 +92,5 @@ services: DB_HOST: postgres DB_PORT: 5432 command: - - --name=app + - --name=multi-chain - --playground - - --indexer=http://subquery-node:3000 diff --git a/Moonbeam/moonbeam-evm-starter/evm.yaml b/Moonbeam/moonbeam-evm-starter/evm.yaml new file mode 100644 index 00000000..b9503671 --- /dev/null +++ b/Moonbeam/moonbeam-evm-starter/evm.yaml @@ -0,0 +1,42 @@ +# // Auto-generated , DO NOT EDIT +specVersion: 1.0.0 +version: 0.0.1 +name: ethereum-starter +description: >- + This project can be use as a starting point for developing your new Ethereum + SubQuery project +runner: + node: + name: "@subql/node-ethereum" + version: ">=3.0.0" + query: + name: "@subql/query" + version: "*" +schema: + file: ./schema.graphql +network: + chainId: "1284" + endpoint: + - wss://moonbeam.api.onfinality.io/public-ws + - wss://wss.api.moonbeam.network +dataSources: + - kind: ethereum/Runtime + startBlock: 752073 + options: + abi: erc20 + address: "0xe3e43888fa7803cdc7bea478ab327cf1a0dc11a7" + assets: + erc20: + file: ./abis/erc20.abi.json + mapping: + file: ./dist/index.js + handlers: + - handler: handleEVMLog + kind: ethereum/LogHandler + filter: + topics: + - Transfer(address indexed from,address indexed to,uint256 value) + - handler: handleEVMTransaction + kind: ethereum/TransactionHandler + filter: + function: approve(address to,uint256 value) diff --git a/Moonbeam/moonbeam-evm-starter/package.json b/Moonbeam/moonbeam-evm-starter/package.json index a94a30bc..9cd5be10 100644 --- a/Moonbeam/moonbeam-evm-starter/package.json +++ b/Moonbeam/moonbeam-evm-starter/package.json @@ -1,7 +1,7 @@ { "name": "moonbeam-evm-starter", "version": "1.0.0", - "description": "A basic Frontier 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", + "description": "A basic 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", "main": "dist/index.js", "scripts": { "build": "subql build", @@ -11,8 +11,6 @@ "prepack": "rm -rf dist && npm run build", "test": "subql build && subql-node test" }, - "homepage": "https://github.com/subquery/tutorials-frontier-evm-starter", - "repository": "github:subquery/tutorials-frontier-evm-starter", "files": [ "dist", "schema.graphql", @@ -24,19 +22,21 @@ "ipfs-unixfs": "6.0.6" }, "dependencies": { - "moonbeam-types-bundle": "^2.0.7" + "moonbeam-types-bundle": "^2.0.7", + "@subql/types-ethereum": "latest", + "assert": "^2.0.0" }, "devDependencies": { - "@polkadot/api": "^10", "@subql/cli": "latest", - "@subql/frontier-evm-processor": "latest", - "@subql/node": "latest", - "@subql/testing": "latest", "@subql/types": "latest", - "@subql/types-ethereum": "latest", - "typescript": "^5.2.2" + "@subql/testing": "latest", + "@subql/node-ethereum": "latest", + "ethers": "^5.7.2", + "@polkadot/api": "^10", + "typescript": "^5.2.2", + "@subql/node": "latest" }, "exports": { "chaintypes": "src/chaintypes.ts" } -} +} \ No newline at end of file diff --git a/Moonbeam/moonbeam-evm-starter/project.ts b/Moonbeam/moonbeam-evm-starter/project.ts deleted file mode 100644 index c9f0e443..00000000 --- a/Moonbeam/moonbeam-evm-starter/project.ts +++ /dev/null @@ -1,89 +0,0 @@ -import { - SubstrateDatasourceKind, - SubstrateHandlerKind, - SubstrateProject, -} from "@subql/types"; - -import { FrontierEvmDatasource } from "@subql/frontier-evm-processor"; - -// Can expand the Datasource processor types via the genreic param -const project: SubstrateProject = { - specVersion: "1.0.0", - version: "0.0.1", - name: "moonbeam-evm-starter", - description: `A basic Frontier EVM example project with an event and call handler. Read more - about this at https://university.subquery.network/create/frontier/. This - project can be use as a starting point for developing your SubQuery project`, - runner: { - node: { - name: "@subql/node", - version: ">=3.0.1", - }, - query: { - name: "@subql/query", - version: "*", - }, - }, - schema: { - file: "./schema.graphql", - }, - network: { - /* The genesis hash of the network (hash of block 0) */ - chainId: - "0xfe58ea77779b7abda7da4ec526d14db9b1e9cd40a217c34892af80a9b332b76d", - /** - * These endpoint(s) should be public non-pruned archive node - * We recommend providing more than one endpoint for improved reliability, performance, and uptime - * Public nodes may be rate limited, which can affect indexing speed - * When developing your project we suggest getting a private API key - * If you use a rate limited endpoint, adjust the --batch-size and --workers parameters - * These settings can be found in your docker-compose.yaml, they will slow indexing but prevent your project being rate limited - */ - endpoint: [ - "wss://moonbeam.api.onfinality.io/public-ws", - "wss://wss.api.moonbeam.network", - ], - chaintypes: { - file: "./dist/chaintypes.js", - }, - }, - dataSources: [ - { - // This is the datasource for Moonbeam's Native Substrate processor - kind: "substrate/FrontierEvm", - startBlock: 752073, - processor: { - file: "./node_modules/@subql/frontier-evm-processor/dist/bundle.js", - options: { - abi: "erc20", - address: "0xe3e43888fa7803cdc7bea478ab327cf1a0dc11a7", // FLARE token https://moonscan.io/token/0xe3e43888fa7803cdc7bea478ab327cf1a0dc11a7 - }, - }, - assets: new Map([["erc20", { file: "./erc20.abi.json" }]]), - mapping: { - file: "./dist/index.js", - handlers: [ - { - handler: "handleEvmEvent", - kind: "substrate/FrontierEvmEvent", - filter: { - topics: [ - "Transfer(address indexed from,address indexed to,uint256 value)", - ], - }, - }, - { - handler: "handleEvmCall", - kind: "substrate/FrontierEvmCall", - filter: { - function: "approve(address to,uint256 value)", - }, - }, - ], - }, - }, - ], -}; - -// Must set default to the project instance -export default project; diff --git a/Moonbeam/moonbeam-evm-starter/schema.graphql b/Moonbeam/moonbeam-evm-starter/schema.graphql index 3f184a46..220915d9 100644 --- a/Moonbeam/moonbeam-evm-starter/schema.graphql +++ b/Moonbeam/moonbeam-evm-starter/schema.graphql @@ -2,18 +2,27 @@ # 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 +type ERC20TokenTransfer @entity { + id: ID! value: BigInt! to: String! from: String! contractAddress: String! } -type Approval @entity { - id: ID! # Transaction hash +type ERC20Approval @entity { + id: ID! value: BigInt! owner: String! spender: String! contractAddress: String! } + +type SubstrateTransfer @entity { + id: ID! + amount: BigInt! + blockNumber: Int! + date: Date! + from: String! + to: String! +} diff --git a/Moonbeam/moonbeam-evm-starter/src/mappings/mappingHandlers.ts b/Moonbeam/moonbeam-evm-starter/src/mappings/mappingHandlers.ts index 0c0a244f..80267659 100644 --- a/Moonbeam/moonbeam-evm-starter/src/mappings/mappingHandlers.ts +++ b/Moonbeam/moonbeam-evm-starter/src/mappings/mappingHandlers.ts @@ -1,50 +1,61 @@ -import { Approval, Transaction } from "../types"; -import { - FrontierEvmEvent, - FrontierEvmCall, -} from "@subql/frontier-evm-processor"; -import { BigNumber } from "ethers"; +import { ERC20TokenTransfer, ERC20Approval, SubstrateTransfer } from "../types"; +import { TransferLog } from "../types/abi-interfaces/Erc20Abi"; +import { ApproveTransaction } from "../types/abi-interfaces/Erc20Abi"; import assert from "assert"; +import { SubstrateEvent } from "@subql/types"; +import { Balance } from "@polkadot/types/interfaces"; -// Setup types from ABI -type TransferEventArgs = [string, string, BigNumber] & { - from: string; - to: string; - value: BigNumber; -}; -type ApproveCallArgs = [string, BigNumber] & { - _spender: string; - _value: BigNumber; -}; - -export async function handleFrontierEvmEvent( - event: FrontierEvmEvent, -): Promise { - assert(event.transactionHash, "No transactionHash"); - assert(event.args, "No event.args"); - - const transaction = Transaction.create({ - id: event.transactionHash, - value: event.args.value.toBigInt(), - from: event.args.from, - to: event.args.to, - contractAddress: event.address, +export async function handleEVMLog(log: TransferLog): Promise { + logger.info(`New transfer transaction log at block ${log.blockNumber}`); + assert(log.args, "No log.args"); + + const transaction = ERC20TokenTransfer.create({ + id: log.transactionHash, + to: log.args.to, + from: log.args.from, + value: log.args.value.toBigInt(), + contractAddress: log.address, }); + await transaction.save(); } -export async function handleFrontierEvmCall( - event: FrontierEvmCall, +export async function handleEVMTransaction( + tx: ApproveTransaction ): Promise { - assert(event.args, "No event.args"); - assert(event.to, "No event.to"); - - const approval = Approval.create({ - id: event.hash, - owner: event.from, - value: event.args._value.toBigInt(), - spender: event.args._spender, - contractAddress: event.to, + logger.info(`New Approval transaction at block ${tx.blockNumber}`); + assert(tx.args, "No tx.args"); + + const approval = ERC20Approval.create({ + id: tx.hash, + owner: tx.from, + spender: await tx.args[0], + value: BigInt(await tx.args[1].toString()), + contractAddress: tx.to, }); + await approval.save(); } + +export async function handleEvent(event: SubstrateEvent): Promise { + logger.info( + `New transfer event found at block ${event.block.block.header.number.toString()}` + ); + const { + event: { + data: [from, to, amount], + }, + } = event; + + const blockNumber: number = event.block.block.header.number.toNumber(); + const transfer = SubstrateTransfer.create({ + id: `${event.block.block.header.number.toNumber()}-${event.idx}`, + blockNumber, + date: event.block.timestamp, + from: from.toString(), + to: to.toString(), + amount: (amount as Balance).toBigInt(), + }); + + await transfer.save(); +} diff --git a/Moonbeam/moonbeam-evm-starter/subquery-multichain.yaml b/Moonbeam/moonbeam-evm-starter/subquery-multichain.yaml new file mode 100644 index 00000000..d2b3c932 --- /dev/null +++ b/Moonbeam/moonbeam-evm-starter/subquery-multichain.yaml @@ -0,0 +1,7 @@ +specVersion: 1.0.0 +query: + name: '@subql/query' + version: '*' +projects: + - substrate.yaml + - evm.yaml diff --git a/Moonbeam/moonbeam-evm-starter/substrate.yaml b/Moonbeam/moonbeam-evm-starter/substrate.yaml new file mode 100644 index 00000000..4c99e954 --- /dev/null +++ b/Moonbeam/moonbeam-evm-starter/substrate.yaml @@ -0,0 +1,34 @@ +# // Auto-generated , DO NOT EDIT +specVersion: 1.0.0 +version: 0.0.1 +name: moonbeam-starter +description: >- + This project can be used as a starting point for developing your SubQuery + project. It indexes all transfers on Moonbeam network +runner: + node: + name: '@subql/node' + version: '>=3.0.1' + query: + name: '@subql/query' + version: '*' +schema: + file: ./schema.graphql +network: + chainId: '0xfe58ea77779b7abda7da4ec526d14db9b1e9cd40a217c34892af80a9b332b76d' + endpoint: + - wss://moonbeam.api.onfinality.io/public-ws + - wss://wss.api.moonbeam.network + chaintypes: + file: ./dist/chaintypes.js +dataSources: + - kind: substrate/Runtime + startBlock: 1 + mapping: + file: ./dist/index.js + handlers: + - kind: substrate/EventHandler + handler: handleEvent + filter: + module: balances + method: Transfer 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 9615e3cf..00000000 --- a/Moonbeam/moonbeam-substrate-evm-starter/.gitignore +++ /dev/null @@ -1,58 +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 - -# Generated files -target/ -dist/ -src/types -project.yaml - -# 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 -.eslintcache diff --git a/Moonbeam/moonbeam-substrate-evm-starter/.project-cid b/Moonbeam/moonbeam-substrate-evm-starter/.project-cid deleted file mode 100644 index 0fac55f4..00000000 --- a/Moonbeam/moonbeam-substrate-evm-starter/.project-cid +++ /dev/null @@ -1 +0,0 @@ -QmcL3wVRtwgNYpgyfUfDJX3ZVUAe5j3qAmma9NN5DmCYtd \ No newline at end of file diff --git a/Moonbeam/moonbeam-substrate-evm-starter/README.md b/Moonbeam/moonbeam-substrate-evm-starter/README.md deleted file mode 100644 index e3cc07fd..00000000 --- a/Moonbeam/moonbeam-substrate-evm-starter/README.md +++ /dev/null @@ -1,85 +0,0 @@ -# SubQuery - Example Project for Moonbeam EVM - -[SubQuery](https://subquery.network) is a fast, flexible, and reliable open-source data indexer that provides you with custom APIs for your web3 project across all of our supported networks. To learn about how to get started with SubQuery, [visit our docs](https://academy.subquery.network). - -**This SubQuery project indexes all transfers for the [FRAX token](https://moonscan.io/token/0x322E86852e492a7Ee17f28a78c663da38FB33bfb) (`0x322E86852e492a7Ee17f28a78c663da38FB33bfb`) on Moonbeam's EVM as well as all active Collators in Moonbeam's Native Substrate processor** - -## Start - -First, install SubQuery CLI globally on your terminal by using NPM `npm install -g @subql/cli` - -You can either clone this GitHub repo, or use the `subql` CLI to bootstrap a clean project in the network of your choosing by running `subql init` and following the prompts. - -Don't forget to install dependencies with `npm install` or `yarn install`! - -## Editing your SubQuery project - -Although this is a working example SubQuery project, you can edit the SubQuery project by changing the following files: - -- The project manifest in `project.yaml` defines the key project configuration and mapping handler filters -- The GraphQL Schema (`schema.graphql`) defines the shape of the resulting data that you are using SubQuery to index -- The Mapping functions in `src/mappings/` directory are typescript functions that handle transformation logic - -SubQuery supports various layer-1 blockchain networks and provides [dedicated quick start guides](https://academy.subquery.network/quickstart/quickstart.html) as well as [detailed technical documentation](https://academy.subquery.network/build/introduction.html) for each of them. - -## Run your project - -_If you get stuck, find out how to get help below._ - -The simplest way to run your project is by running `yarn dev` or `npm run-script dev`. This does all of the following: - -1. `yarn codegen` - Generates types from the GraphQL schema definition and contract ABIs and saves them in the `/src/types` directory. This must be done after each change to the `schema.graphql` file or the contract ABIs -2. `yarn build` - Builds and packages the SubQuery project into the `/dist` directory -3. `docker-compose pull && docker-compose up` - Runs a Docker container with an indexer, PostgeSQL DB, and a query service. This requires [Docker to be installed](https://docs.docker.com/engine/install) and running locally. The configuration for this container is set from your `docker-compose.yml` - -You can observe the three services start, and once all are running (it may take a few minutes on your first start), please open your browser and head to [http://localhost:3000](http://localhost:3000) - you should see a GraphQL playground showing with the schemas ready to query. [Read the docs for more information](https://academy.subquery.network/run_publish/run.html) or [explore the possible service configuration for running SubQuery](https://academy.subquery.network/run_publish/references.html). - -## Query your project - -For this project, you can try to query with the following GraphQL code to get a taste of how it works. - -```graphql -{ - query { - erc20Transfers(first: 5, orderBy: AMOUNT_DESC) { - totalCount - nodes { - id - from - to - amount - contractAddress - } - } - } - collators(first: 5, orderBy: JOINED_DATE_DESC) { - nodes { - id - joinedDate - } - } -} -``` - -You can explore the different possible queries and entities to help you with GraphQL using the documentation draw on the right. - -## Publish your project - -SubQuery is open-source, meaning you have the freedom to run it in the following three ways: - -- Locally on your own computer (or a cloud provider of your choosing), [view the instructions on how to run SubQuery Locally](https://academy.subquery.network/run_publish/run.html) -- By publishing it to our enterprise-level [Managed Service](https://managedservice.subquery.network), where we'll host your SubQuery project in production ready services for mission critical data with zero-downtime blue/green deployments. We even have a generous free tier. [Find out how](https://academy.subquery.network/run_publish/publish.html) -- [Coming Soon] By publishing it to the decentralised [SubQuery Network](https://subquery.network/network), the most open, performant, reliable, and scalable data service for dApp developers. The SubQuery Network indexes and services data to the global community in an incentivised and verifiable way - -## What Next? - -Take a look at some of our advanced features to take your project to the next level! - -- [**Multi-chain indexing support**](https://academy.subquery.network/build/multi-chain.html) - SubQuery allows you to index data from across different layer-1 networks into the same database, this allows you to query a single endpoint to get data for all supported networks. -- [**Dynamic Data Sources**](https://academy.subquery.network/build/dynamicdatasources.html) - When you want to index factory contracts, for example on a DEX or generative NFT project. -- [**Project Optimisation Advice**](https://academy.subquery.network/build/optimisation.html) - Some common tips on how to tweak your project to maximise performance. -- [**GraphQL Subscriptions**](https://academy.subquery.network/run_publish/subscription.html) - Build more reactive front end applications that subscribe to changes in your SubQuery project. - -## Need Help? - -The fastest way to get support is by [searching our documentation](https://academy.subquery.network), or by [joining our discord](https://discord.com/invite/subquery) and messaging us in the `#technical-support` channel. 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 57a72876..00000000 --- a/Moonbeam/moonbeam-substrate-evm-starter/docker-compose.yml +++ /dev/null @@ -1,66 +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: subquerynetwork/subql-node-substrate:latest - depends_on: - "postgres": - condition: service_healthy - restart: unless-stopped - 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 - - --workers=4 - - --batch-size=30 - - --unfinalized-blocks=true - healthcheck: - test: ["CMD", "curl", "-f", "http://subquery-node:3000/ready"] - interval: 3s - timeout: 5s - retries: 10 - - graphql-engine: - image: subquerynetwork/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" < = { - specVersion: "1.0.0", - version: "0.0.1", - name: "moonbeam-substrate-evm-starter", - description: `A basic Frontier EVM example project with an event and call handler. Read more - about this at https://university.subquery.network/create/frontier/. This - project can be use as a starting point for developing your SubQuery project`, - runner: { - node: { - name: "@subql/node", - version: ">=3.0.1", - }, - query: { - name: "@subql/query", - version: "*", - }, - }, - schema: { - file: "./schema.graphql", - }, - network: { - /* The genesis hash of the network (hash of block 0) */ - chainId: - "0xfe58ea77779b7abda7da4ec526d14db9b1e9cd40a217c34892af80a9b332b76d", - /** - * These endpoint(s) should be public non-pruned archive node - * We recommend providing more than one endpoint for improved reliability, performance, and uptime - * Public nodes may be rate limited, which can affect indexing speed - * When developing your project we suggest getting a private API key - * If you use a rate limited endpoint, adjust the --batch-size and --workers parameters - * These settings can be found in your docker-compose.yaml, they will slow indexing but prevent your project being rate limited - */ - endpoint: [ - "wss://moonbeam.api.onfinality.io/public-ws", - "wss://wss.api.moonbeam.network", - ], - chaintypes: { - file: "./dist/chaintypes.js", - }, - }, - dataSources: [ - { - kind: SubstrateDatasourceKind.Runtime, - startBlock: 1, - mapping: { - file: "./dist/index.js", - handlers: [ - { - handler: "handleCollatorJoined", - kind: SubstrateHandlerKind.Call, - filter: { - module: "staking", - method: "joinCandidates", - }, - }, - { - handler: "handleCollatorLeft", - kind: SubstrateHandlerKind.Call, - filter: { - module: "staking", - method: "executeLeaveCandidates", - }, - }, - ], - }, - }, - { - kind: "substrate/FrontierEvm", - startBlock: 189831, - processor: { - file: "./node_modules/@subql/frontier-evm-processor/dist/bundle.js", - options: { - abi: "erc20", - // Contract address of $FRAX - address: "0x322E86852e492a7Ee17f28a78c663da38FB33bfb", - }, - }, - assets: new Map([["erc20", { file: "./erc20.abi.json" }]]), - mapping: { - file: "./dist/index.js", - handlers: [ - { - handler: "handleErc20Transfer", - kind: "substrate/FrontierEvmEvent", - filter: { - topics: [ - "Transfer(address indexed from,address indexed to,uint256 value)", - ], - }, - }, - ], - }, - }, - ], -}; - -// Must set default to the project instance -export default project; diff --git a/Moonbeam/moonbeam-substrate-evm-starter/schema.graphql b/Moonbeam/moonbeam-substrate-evm-starter/schema.graphql deleted file mode 100644 index e7458e99..00000000 --- a/Moonbeam/moonbeam-substrate-evm-starter/schema.graphql +++ /dev/null @@ -1,16 +0,0 @@ -# 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 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/chaintypes.ts b/Moonbeam/moonbeam-substrate-evm-starter/src/chaintypes.ts deleted file mode 100644 index d90fbf8e..00000000 --- a/Moonbeam/moonbeam-substrate-evm-starter/src/chaintypes.ts +++ /dev/null @@ -1,3 +0,0 @@ -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 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 fb319708..00000000 --- a/Moonbeam/moonbeam-substrate-evm-starter/src/mappings/mappingHandlers.ts +++ /dev/null @@ -1,56 +0,0 @@ -import { Erc20Transfer, Collator } from "../types"; -import { FrontierEvmEvent } from "@subql/frontier-evm-processor"; - -import { SubstrateExtrinsic, SubstrateEvent } from "@subql/types"; - -global.atob = require("atob"); -global.Blob = require("node-blob"); -import { BigNumber } from "ethers"; -import assert from "assert"; - -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(); - - const collator = Collator.create({ - id: address, - joinedDate: call.block.timestamp, - }); - - await collator.save(); -} - -export async function handleCollatorLeft( - 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(); - await Collator.remove(address); -} - -export async function handleErc20Transfer( - event: FrontierEvmEvent< - [string, string, BigNumber] & { from: string; to: string; value: BigNumber } - >, -): 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()}`); - assert(event.transactionHash, "Missing event.transaction"); - assert(event.args, "Missing event.args"); - - 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/src/tests/mappingHandlers.test.ts b/Moonbeam/moonbeam-substrate-evm-starter/src/tests/mappingHandlers.test.ts deleted file mode 100644 index d3c8ed58..00000000 --- a/Moonbeam/moonbeam-substrate-evm-starter/src/tests/mappingHandlers.test.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { subqlTest } from "@subql/testing"; - -// See https://academy.subquery.network/build/testing.html - -subqlTest( - "handleTransfer test", // Test name - 191, // Block height to test at - [], // 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 3837c009..00000000 --- a/Moonbeam/moonbeam-substrate-evm-starter/tsconfig.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "compilerOptions": { - "emitDecoratorMetadata": true, - "experimentalDecorators": true, - "esModuleInterop": true, - "declaration": true, - "importHelpers": true, - "resolveJsonModule": true, - "module": "commonjs", - "outDir": "dist", - "rootDir": "src", - "target": "es2017", - "strict": true, - }, - "include": [ - "src/**/*", - "node_modules/@subql/types-core/dist/global.d.ts", - "node_modules/@subql/types/dist/global.d.ts", - ], -} diff --git a/Moonriver/moonriver-evm-starter/README.md b/Moonriver/moonriver-evm-starter/README.md index 42fd4666..7d22330b 100644 --- a/Moonriver/moonriver-evm-starter/README.md +++ b/Moonriver/moonriver-evm-starter/README.md @@ -2,7 +2,7 @@ [SubQuery](https://subquery.network) is a fast, flexible, and reliable open-source data indexer that provides you with custom APIs for your web3 project across all of our supported networks. To learn about how to get started with SubQuery, [visit our docs](https://academy.subquery.network). -**This SubQuery project indexes all transfers and approval events for the [SolarBeam token](https://moonriver.moonscan.io/address/0x6bd193ee6d2104f14f94e2ca6efefae561a4334b) (`0x6bd193ee6d2104f14f94e2ca6efefae561a4334b`) on Moonriver's EVM** +**This SubQuery project indexes all transfers and approval events for the [SolarBeam token](https://moonriver.moonscan.io/address/0x6bd193ee6d2104f14f94e2ca6efefae561a4334b) (`0x6bd193ee6d2104f14f94e2ca6efefae561a4334b`) on Moonriver's EVM as well as transfers related to Substrate** ## Start @@ -41,8 +41,7 @@ For this project, you can try to query with the following GraphQL code to get a ```graphql { query { - transactions(first: 5, orderBy: VALUE_DESC) { - totalCount + eRC20TokenTransfers(first: 3) { nodes { id from @@ -51,14 +50,23 @@ For this project, you can try to query with the following GraphQL code to get a contractAddress } } - } - approvals(first: 5) { - nodes { - id - owner - spender - value - contractAddress + eRC20Approvals(first: 3) { + nodes { + id + value + owner + spender + contractAddress + } + } + substrateTransfers(first: 3) { + nodes { + id + from + to + amount + date + } } } } diff --git a/Moonriver/moonriver-evm-starter/erc20.abi.json b/Moonriver/moonriver-evm-starter/abis/erc20.abi.json similarity index 100% rename from Moonriver/moonriver-evm-starter/erc20.abi.json rename to Moonriver/moonriver-evm-starter/abis/erc20.abi.json diff --git a/Moonriver/moonriver-evm-starter/docker-compose.yml b/Moonriver/moonriver-evm-starter/docker-compose.yml index 57a72876..b526d223 100644 --- a/Moonriver/moonriver-evm-starter/docker-compose.yml +++ b/Moonriver/moonriver-evm-starter/docker-compose.yml @@ -17,7 +17,38 @@ services: timeout: 5s retries: 5 - subquery-node: + subquery-node-evm: + image: subquerynetwork/subql-node-ethereum: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: + - --multi-chain + - --db-schema=multi-chain + - --disable-historical + - -f=app/evm.yaml + - --batch-size=30 + - --workers=4 + healthcheck: + test: + - CMD + - curl + - -f + - http://subquery-node-ethereum:3000/ready + interval: 3s + timeout: 5s + retries: 10 + + subquery-node-substrate: image: subquerynetwork/subql-node-substrate:latest depends_on: "postgres": @@ -32,14 +63,16 @@ services: volumes: - ./:/app command: - - ${SUB_COMMAND:-} # set SUB_COMMAND env variable to "test" to run tests - - -f=/app - - --db-schema=app - - --workers=4 - - --batch-size=30 - - --unfinalized-blocks=true + - -f=app/substrate.yaml + - --multi-chain + - --db-schema=multi-chain + - --disable-historical healthcheck: - test: ["CMD", "curl", "-f", "http://subquery-node:3000/ready"] + test: + - CMD + - curl + - -f + - http://subquery-node-project-kusama:3000/ready interval: 3s timeout: 5s retries: 10 @@ -51,9 +84,7 @@ services: depends_on: "postgres": condition: service_healthy - "subquery-node": - condition: service_healthy - restart: always + restart: unless-stopped environment: DB_USER: postgres DB_PASS: postgres @@ -61,6 +92,5 @@ services: DB_HOST: postgres DB_PORT: 5432 command: - - --name=app + - --name=multi-chain - --playground - - --indexer=http://subquery-node:3000 diff --git a/Moonriver/moonriver-evm-starter/evm.yaml b/Moonriver/moonriver-evm-starter/evm.yaml new file mode 100644 index 00000000..2e886474 --- /dev/null +++ b/Moonriver/moonriver-evm-starter/evm.yaml @@ -0,0 +1,42 @@ +# // Auto-generated , DO NOT EDIT +specVersion: 1.0.0 +version: 0.0.1 +name: moonriver-evm-starter +description: >- + This project can be use as a starting point for developing your new Ethereum + SubQuery project +runner: + node: + name: "@subql/node-ethereum" + version: ">=3.0.0" + query: + name: "@subql/query" + version: "*" +schema: + file: ./schema.graphql +network: + chainId: "1285" + endpoint: + - wss://moonriver.api.onfinality.io/public-ws + - wss://wss.api.moonriver.moonbeam.network +dataSources: + - kind: ethereum/Runtime + startBlock: 752073 + options: + abi: erc20 + address: "0x6bd193ee6d2104f14f94e2ca6efefae561a4334b" + assets: + erc20: + file: ./abis/erc20.abi.json + mapping: + file: ./dist/index.js + handlers: + - handler: handleEVMLog + kind: ethereum/LogHandler + filter: + topics: + - Transfer(address indexed from,address indexed to,uint256 value) + - handler: handleEVMTransaction + kind: ethereum/TransactionHandler + filter: + function: approve(address to,uint256 value) diff --git a/Moonriver/moonriver-evm-starter/package.json b/Moonriver/moonriver-evm-starter/package.json index e89140fa..8055b2c0 100644 --- a/Moonriver/moonriver-evm-starter/package.json +++ b/Moonriver/moonriver-evm-starter/package.json @@ -1,7 +1,7 @@ { "name": "moonriver-evm-starter", "version": "1.0.0", - "description": "A basic Frontier 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", + "description": "A basic 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", "main": "dist/index.js", "scripts": { "build": "subql build", @@ -11,8 +11,6 @@ "prepack": "rm -rf dist && npm run build", "test": "subql build && subql-node test" }, - "homepage": "https://github.com/subquery/tutorials-frontier-evm-starter", - "repository": "github:subquery/tutorials-frontier-evm-starter", "files": [ "dist", "schema.graphql", @@ -24,18 +22,21 @@ "ipfs-unixfs": "6.0.6" }, "dependencies": { - "moonbeam-types-bundle": "^2.0.7" + "moonbeam-types-bundle": "^2.0.7", + "@subql/types-ethereum": "latest", + "assert": "^2.0.0" }, "devDependencies": { - "@polkadot/api": "^10", "@subql/cli": "latest", - "@subql/frontier-evm-processor": "latest", "@subql/types": "latest", - "typescript": "^5.2.2", "@subql/testing": "latest", + "@subql/node-ethereum": "latest", + "ethers": "^5.7.2", + "@polkadot/api": "^10", + "typescript": "^5.2.2", "@subql/node": "latest" }, "exports": { "chaintypes": "src/chaintypes.ts" } -} +} \ No newline at end of file diff --git a/Moonriver/moonriver-evm-starter/project.ts b/Moonriver/moonriver-evm-starter/project.ts deleted file mode 100644 index d5727181..00000000 --- a/Moonriver/moonriver-evm-starter/project.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { - SubstrateDatasourceKind, - SubstrateHandlerKind, - SubstrateProject, -} from "@subql/types"; - -import { FrontierEvmDatasource } from "@subql/frontier-evm-processor"; - -// Can expand the Datasource processor types via the genreic param -const project: SubstrateProject = { - specVersion: "1.0.0", - version: "0.0.1", - name: "moonriver-evm-starter", - description: `A basic Frontier EVM example project with an event and call handler. Read more - about this at https://university.subquery.network/create/frontier/. This - project can be use as a starting point for developing your SubQuery project`, - runner: { - node: { - name: "@subql/node", - version: ">=3.0.1", - }, - query: { - name: "@subql/query", - version: "*", - }, - }, - schema: { - file: "./schema.graphql", - }, - network: { - /* The genesis hash of the network (hash of block 0) */ - chainId: - "0x401a1f9dca3da46f5c4091016c8a2f26dcea05865116b286f60f668207d1474b", - /** - * These endpoint(s) should be public non-pruned archive node - * We recommend providing more than one endpoint for improved reliability, performance, and uptime - * Public nodes may be rate limited, which can affect indexing speed - * When developing your project we suggest getting a private API key - * If you use a rate limited endpoint, adjust the --batch-size and --workers parameters - * These settings can be found in your docker-compose.yaml, they will slow indexing but prevent your project being rate limited - */ - endpoint: [ - "wss://moonriver.api.onfinality.io/public-ws", - "wss://wss.api.moonriver.moonbeam.network", - ], - chaintypes: { - file: "./dist/chaintypes.js", - }, - }, - dataSources: [ - { - kind: "substrate/FrontierEvm", - startBlock: 752073, - processor: { - file: "./node_modules/@subql/frontier-evm-processor/dist/bundle.js", - options: { - abi: "erc20", - address: "0x6bd193ee6d2104f14f94e2ca6efefae561a4334b", // Solarbeam token https://moonriver.moonscan.io/address/0x6bd193ee6d2104f14f94e2ca6efefae561a4334b - }, - }, - assets: new Map([["erc20", { file: "./erc20.abi.json" }]]), - mapping: { - file: "./dist/index.js", - handlers: [ - { - handler: "handleEvmEvent", - kind: "substrate/FrontierEvmEvent", - filter: { - topics: [ - "Transfer(address indexed from,address indexed to,uint256 value)", - ], - }, - }, - { - handler: "handleEvmCall", - kind: "substrate/FrontierEvmCall", - filter: { - function: "approve(address to,uint256 value)", - }, - }, - ], - }, - }, - ], -}; - -// Must set default to the project instance -export default project; diff --git a/Moonriver/moonriver-evm-starter/schema.graphql b/Moonriver/moonriver-evm-starter/schema.graphql index 3f184a46..220915d9 100644 --- a/Moonriver/moonriver-evm-starter/schema.graphql +++ b/Moonriver/moonriver-evm-starter/schema.graphql @@ -2,18 +2,27 @@ # 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 +type ERC20TokenTransfer @entity { + id: ID! value: BigInt! to: String! from: String! contractAddress: String! } -type Approval @entity { - id: ID! # Transaction hash +type ERC20Approval @entity { + id: ID! value: BigInt! owner: String! spender: String! contractAddress: String! } + +type SubstrateTransfer @entity { + id: ID! + amount: BigInt! + blockNumber: Int! + date: Date! + from: String! + to: String! +} diff --git a/Moonriver/moonriver-evm-starter/src/mappings/mappingHandlers.ts b/Moonriver/moonriver-evm-starter/src/mappings/mappingHandlers.ts index b664c0c7..80267659 100644 --- a/Moonriver/moonriver-evm-starter/src/mappings/mappingHandlers.ts +++ b/Moonriver/moonriver-evm-starter/src/mappings/mappingHandlers.ts @@ -1,52 +1,61 @@ -import { Approval, Transaction } from "../types"; -import { - FrontierEvmEvent, - FrontierEvmCall, -} from "@subql/frontier-evm-processor"; -import { BigNumber } from "ethers"; +import { ERC20TokenTransfer, ERC20Approval, SubstrateTransfer } from "../types"; +import { TransferLog } from "../types/abi-interfaces/Erc20Abi"; +import { ApproveTransaction } from "../types/abi-interfaces/Erc20Abi"; import assert from "assert"; +import { SubstrateEvent } from "@subql/types"; +import { Balance } from "@polkadot/types/interfaces"; -// Setup types from ABI -type TransferEventArgs = [string, string, BigNumber] & { - from: string; - to: string; - value: BigNumber; -}; -type ApproveCallArgs = [string, BigNumber] & { - _spender: string; - _value: BigNumber; -}; - -export async function handleFrontierEvmEvent( - event: FrontierEvmEvent, -): Promise { - assert(event.transactionHash, "No transactionHash"); - assert(event.args, "No event.args"); - - const transaction = Transaction.create({ - id: event.transactionHash, - value: event.args.value.toBigInt(), - from: event.args.from, - to: event.args.to, - contractAddress: event.address, +export async function handleEVMLog(log: TransferLog): Promise { + logger.info(`New transfer transaction log at block ${log.blockNumber}`); + assert(log.args, "No log.args"); + + const transaction = ERC20TokenTransfer.create({ + id: log.transactionHash, + to: log.args.to, + from: log.args.from, + value: log.args.value.toBigInt(), + contractAddress: log.address, }); await transaction.save(); } -export async function handleFrontierEvmCall( - event: FrontierEvmCall, +export async function handleEVMTransaction( + tx: ApproveTransaction ): Promise { - assert(event.args, "No event.args"); - assert(event.to, "No event.to"); - - const approval = Approval.create({ - id: event.hash, - owner: event.from, - value: event.args._value.toBigInt(), - spender: event.args._spender, - contractAddress: event.to, + logger.info(`New Approval transaction at block ${tx.blockNumber}`); + assert(tx.args, "No tx.args"); + + const approval = ERC20Approval.create({ + id: tx.hash, + owner: tx.from, + spender: await tx.args[0], + value: BigInt(await tx.args[1].toString()), + contractAddress: tx.to, }); await approval.save(); } + +export async function handleEvent(event: SubstrateEvent): Promise { + logger.info( + `New transfer event found at block ${event.block.block.header.number.toString()}` + ); + const { + event: { + data: [from, to, amount], + }, + } = event; + + const blockNumber: number = event.block.block.header.number.toNumber(); + const transfer = SubstrateTransfer.create({ + id: `${event.block.block.header.number.toNumber()}-${event.idx}`, + blockNumber, + date: event.block.timestamp, + from: from.toString(), + to: to.toString(), + amount: (amount as Balance).toBigInt(), + }); + + await transfer.save(); +} diff --git a/Moonriver/moonriver-evm-starter/subquery-multichain.yaml b/Moonriver/moonriver-evm-starter/subquery-multichain.yaml new file mode 100644 index 00000000..d2b3c932 --- /dev/null +++ b/Moonriver/moonriver-evm-starter/subquery-multichain.yaml @@ -0,0 +1,7 @@ +specVersion: 1.0.0 +query: + name: '@subql/query' + version: '*' +projects: + - substrate.yaml + - evm.yaml diff --git a/Moonriver/moonriver-evm-starter/substrate.yaml b/Moonriver/moonriver-evm-starter/substrate.yaml new file mode 100644 index 00000000..76b8d7c3 --- /dev/null +++ b/Moonriver/moonriver-evm-starter/substrate.yaml @@ -0,0 +1,34 @@ +# // Auto-generated , DO NOT EDIT +specVersion: 1.0.0 +version: 0.0.1 +name: moonriver-evm-starter +description: >- + This project can be used as a starting point for developing your SubQuery + project +runner: + node: + name: "@subql/node" + version: ">=3.0.1" + query: + name: "@subql/query" + version: "*" +schema: + file: ./schema.graphql +network: + chainId: "0x401a1f9dca3da46f5c4091016c8a2f26dcea05865116b286f60f668207d1474b" + endpoint: + - wss://moonriver.api.onfinality.io/public-ws + - wss://wss.api.moonriver.moonbeam.network + chaintypes: + file: ./dist/chaintypes.js +dataSources: + - kind: substrate/Runtime + startBlock: 1 + mapping: + file: ./dist/index.js + handlers: + - kind: substrate/EventHandler + handler: handleEvent + filter: + module: balances + method: Transfer diff --git a/Peaq/peaq-starter/README.md b/Peaq/peaq-starter/README.md index bf3886b6..4eba52d1 100644 --- a/Peaq/peaq-starter/README.md +++ b/Peaq/peaq-starter/README.md @@ -2,7 +2,7 @@ [SubQuery](https://subquery.network) is a fast, flexible, and reliable open-source data indexer that provides you with custom APIs for your web3 project across all of our supported networks. To learn about how to get started with SubQuery, [visit our docs](https://academy.subquery.network). -**This SubQuery project indexes all transfers and approval events for all ERC20 tokens on Peaq's EVM** +**This SubQuery project indexes all transfers and approval events for all ERC20 tokens on Peaq's EVM as well as transfers related to Substrate** ## Start @@ -41,26 +41,32 @@ For this project, you can try to query with the following GraphQL code to get a ```graphql { query { - transactions(first: 5, orderBy: VALUE_DESC) { - totalCount + eRC20TokenTransfers(first: 3) { nodes { id - transactionHash - blockHeight from to value contractAddress } } - } - approvals(first: 5) { - nodes { - id - owner - spender - value - contractAddress + eRC20Approvals(first: 3) { + nodes { + id + value + owner + spender + contractAddress + } + } + substrateTransfers(first: 3) { + nodes { + id + from + to + amount + date + } } } } diff --git a/Peaq/peaq-starter/erc20.abi.json b/Peaq/peaq-starter/abis/erc20.abi.json similarity index 100% rename from Peaq/peaq-starter/erc20.abi.json rename to Peaq/peaq-starter/abis/erc20.abi.json diff --git a/Peaq/peaq-starter/docker-compose.yml b/Peaq/peaq-starter/docker-compose.yml index 57a72876..b526d223 100644 --- a/Peaq/peaq-starter/docker-compose.yml +++ b/Peaq/peaq-starter/docker-compose.yml @@ -17,7 +17,38 @@ services: timeout: 5s retries: 5 - subquery-node: + subquery-node-evm: + image: subquerynetwork/subql-node-ethereum: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: + - --multi-chain + - --db-schema=multi-chain + - --disable-historical + - -f=app/evm.yaml + - --batch-size=30 + - --workers=4 + healthcheck: + test: + - CMD + - curl + - -f + - http://subquery-node-ethereum:3000/ready + interval: 3s + timeout: 5s + retries: 10 + + subquery-node-substrate: image: subquerynetwork/subql-node-substrate:latest depends_on: "postgres": @@ -32,14 +63,16 @@ services: volumes: - ./:/app command: - - ${SUB_COMMAND:-} # set SUB_COMMAND env variable to "test" to run tests - - -f=/app - - --db-schema=app - - --workers=4 - - --batch-size=30 - - --unfinalized-blocks=true + - -f=app/substrate.yaml + - --multi-chain + - --db-schema=multi-chain + - --disable-historical healthcheck: - test: ["CMD", "curl", "-f", "http://subquery-node:3000/ready"] + test: + - CMD + - curl + - -f + - http://subquery-node-project-kusama:3000/ready interval: 3s timeout: 5s retries: 10 @@ -51,9 +84,7 @@ services: depends_on: "postgres": condition: service_healthy - "subquery-node": - condition: service_healthy - restart: always + restart: unless-stopped environment: DB_USER: postgres DB_PASS: postgres @@ -61,6 +92,5 @@ services: DB_HOST: postgres DB_PORT: 5432 command: - - --name=app + - --name=multi-chain - --playground - - --indexer=http://subquery-node:3000 diff --git a/Peaq/peaq-starter/evm.yaml b/Peaq/peaq-starter/evm.yaml new file mode 100644 index 00000000..eed0f024 --- /dev/null +++ b/Peaq/peaq-starter/evm.yaml @@ -0,0 +1,40 @@ +# // Auto-generated , DO NOT EDIT +specVersion: 1.0.0 +version: 0.0.1 +name: astar-evm-starter +description: >- + This project can be use as a starting point for developing your new Ethereum + SubQuery project +runner: + node: + name: "@subql/node-ethereum" + version: ">=3.0.0" + query: + name: "@subql/query" + version: "*" +schema: + file: ./schema.graphql +network: + chainId: "3338" + endpoint: + - wss://mpfn1.peaq.network +dataSources: + - kind: ethereum/Runtime + startBlock: 1 + options: + abi: erc20 + assets: + erc20: + file: ./abis/erc20.abi.json + mapping: + file: ./dist/index.js + handlers: + - handler: handleEVMLog + kind: ethereum/LogHandler + filter: + topics: + - Transfer(address indexed from,address indexed to,uint256 value) + - handler: handleEVMTransaction + kind: ethereum/TransactionHandler + filter: + function: approve(address to,uint256 value) diff --git a/Peaq/peaq-starter/package.json b/Peaq/peaq-starter/package.json index 6cd74e18..560edc87 100644 --- a/Peaq/peaq-starter/package.json +++ b/Peaq/peaq-starter/package.json @@ -24,17 +24,14 @@ "ipfs-unixfs": "6.0.6" }, "devDependencies": { - "@polkadot/api": "^10", "@subql/cli": "latest", - "@subql/frontier-evm-processor": "latest", - "@subql/node": "latest", - "@subql/testing": "latest", "@subql/types": "latest", - "@subql/types-ethereum": "latest", - "typescript": "^5.2.2" - }, - "exports": { - "chaintypes": "src/chaintypes.ts" + "@subql/testing": "latest", + "@subql/node-ethereum": "latest", + "ethers": "^5.7.2", + "@polkadot/api": "^10", + "typescript": "^5.2.2", + "@subql/node": "latest" }, "dependencies": { "assert": "^2.0.0" diff --git a/Peaq/peaq-starter/project.ts b/Peaq/peaq-starter/project.ts deleted file mode 100644 index a56cc9b9..00000000 --- a/Peaq/peaq-starter/project.ts +++ /dev/null @@ -1,82 +0,0 @@ -import { - SubstrateDatasourceKind, - SubstrateHandlerKind, - SubstrateProject, -} from "@subql/types"; - -import { FrontierEvmDatasource } from "@subql/frontier-evm-processor"; - -// Can expand the Datasource processor types via the genreic param -const project: SubstrateProject = { - specVersion: "1.0.0", - version: "0.0.1", - name: "peaq-starter", - description: `A basic Frontier EVM example project with an event and call handler. Read more - about this at https://academy.subquery.network/create/frontier/. This - project can be use as a starting point for developing your SubQuery project`, - runner: { - node: { - name: "@subql/node", - version: ">=3.0.1", - }, - query: { - name: "@subql/query", - version: "*", - }, - }, - schema: { - file: "./schema.graphql", - }, - network: { - /* The genesis hash of the network (hash of block 0) */ - chainId: - "0xd2a5d385932d1f650dae03ef8e2748983779ee342c614f80854d32b8cd8fa48c", - /** - * These endpoint(s) should be public non-pruned archive node - * We recommend providing more than one endpoint for improved reliability, performance, and uptime - * Public nodes may be rate limited, which can affect indexing speed - * When developing your project we suggest getting a private API key - * If you use a rate limited endpoint, adjust the --batch-size and --workers parameters - * These settings can be found in your docker-compose.yaml, they will slow indexing but prevent your project being rate limited - */ - endpoint: ["wss://mpfn1.peaq.network"], - }, - dataSources: [ - { - kind: "substrate/FrontierEvm", - startBlock: 1, - processor: { - file: "./node_modules/@subql/frontier-evm-processor/dist/bundle.js", - options: { - abi: "erc20", - // address: '0x0000000000000000000000000000000000000000' // A specific contract to index - }, - }, - assets: new Map([["erc20", { file: "./erc20.abi.json" }]]), - mapping: { - file: "./dist/index.js", - handlers: [ - { - handler: "handleEvmEvent", - kind: "substrate/FrontierEvmEvent", - filter: { - topics: [ - "Transfer(address indexed from,address indexed to,uint256 value)", - ], - }, - }, - { - handler: "handleEvmCall", - kind: "substrate/FrontierEvmCall", - filter: { - function: "approve(address to,uint256 value)", - }, - }, - ], - }, - }, - ], -}; - -// Must set default to the project instance -export default project; diff --git a/Peaq/peaq-starter/schema.graphql b/Peaq/peaq-starter/schema.graphql index 24d64105..220915d9 100644 --- a/Peaq/peaq-starter/schema.graphql +++ b/Peaq/peaq-starter/schema.graphql @@ -1,17 +1,28 @@ -type Transaction @entity { - id: ID! # Unique identifier - transactionHash: String! - value: BigInt - to: String - from: String - blockHeight: String +# 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 ERC20TokenTransfer @entity { + id: ID! + value: BigInt! + to: String! + from: String! contractAddress: String! } -type Approval @entity { - id: ID! # Unique identifier - value: BigInt +type ERC20Approval @entity { + id: ID! + value: BigInt! owner: String! spender: String! contractAddress: String! } + +type SubstrateTransfer @entity { + id: ID! + amount: BigInt! + blockNumber: Int! + date: Date! + from: String! + to: String! +} diff --git a/Peaq/peaq-starter/src/mappings/mappingHandlers.ts b/Peaq/peaq-starter/src/mappings/mappingHandlers.ts index 68b5e75c..80267659 100644 --- a/Peaq/peaq-starter/src/mappings/mappingHandlers.ts +++ b/Peaq/peaq-starter/src/mappings/mappingHandlers.ts @@ -1,53 +1,61 @@ -import { Approval, Transaction } from "../types"; -import { - FrontierEvmEvent, - FrontierEvmCall, -} from "@subql/frontier-evm-processor"; -import { BigNumber } from "ethers"; +import { ERC20TokenTransfer, ERC20Approval, SubstrateTransfer } from "../types"; +import { TransferLog } from "../types/abi-interfaces/Erc20Abi"; +import { ApproveTransaction } from "../types/abi-interfaces/Erc20Abi"; import assert from "assert"; +import { SubstrateEvent } from "@subql/types"; +import { Balance } from "@polkadot/types/interfaces"; -// Setup types from ABI -type TransferEventArgs = [string, string, BigNumber] & { - from: string; - to: string; - value: BigNumber; -}; +export async function handleEVMLog(log: TransferLog): Promise { + logger.info(`New transfer transaction log at block ${log.blockNumber}`); + assert(log.args, "No log.args"); -type ApproveCallArgs = [string, BigNumber] & { - _spender: string; - _value: BigNumber; -}; - -export async function handleEvmEvent( - event: FrontierEvmEvent, -): Promise { - assert(event.transactionHash, "No transactionHash"); - - const transaction = Transaction.create({ - id: `${event.blockNumber}-${event.transactionHash}-${event.logIndex}`, - value: event.args?.value.toBigInt(), - from: event.args?.from, - to: event.args?.to, - blockHeight: event.blockNumber.toString(), - contractAddress: event.address, - transactionHash: event.transactionHash, + const transaction = ERC20TokenTransfer.create({ + id: log.transactionHash, + to: log.args.to, + from: log.args.from, + value: log.args.value.toBigInt(), + contractAddress: log.address, }); + await transaction.save(); } -export async function handleEvmCall( - event: FrontierEvmCall, +export async function handleEVMTransaction( + tx: ApproveTransaction ): Promise { - assert(event.args, "No event.args"); - assert(event.to, "No event.to"); - - const approval = Approval.create({ - id: event.hash, - owner: event.from, - value: event.args._value.toBigInt(), - spender: event.args._spender, - contractAddress: event.to, + logger.info(`New Approval transaction at block ${tx.blockNumber}`); + assert(tx.args, "No tx.args"); + + const approval = ERC20Approval.create({ + id: tx.hash, + owner: tx.from, + spender: await tx.args[0], + value: BigInt(await tx.args[1].toString()), + contractAddress: tx.to, }); await approval.save(); } + +export async function handleEvent(event: SubstrateEvent): Promise { + logger.info( + `New transfer event found at block ${event.block.block.header.number.toString()}` + ); + const { + event: { + data: [from, to, amount], + }, + } = event; + + const blockNumber: number = event.block.block.header.number.toNumber(); + const transfer = SubstrateTransfer.create({ + id: `${event.block.block.header.number.toNumber()}-${event.idx}`, + blockNumber, + date: event.block.timestamp, + from: from.toString(), + to: to.toString(), + amount: (amount as Balance).toBigInt(), + }); + + await transfer.save(); +} diff --git a/Peaq/peaq-starter/subquery-multichain.yaml b/Peaq/peaq-starter/subquery-multichain.yaml new file mode 100644 index 00000000..d2b3c932 --- /dev/null +++ b/Peaq/peaq-starter/subquery-multichain.yaml @@ -0,0 +1,7 @@ +specVersion: 1.0.0 +query: + name: '@subql/query' + version: '*' +projects: + - substrate.yaml + - evm.yaml diff --git a/Peaq/peaq-starter/substrate.yaml b/Peaq/peaq-starter/substrate.yaml new file mode 100644 index 00000000..17d1c36a --- /dev/null +++ b/Peaq/peaq-starter/substrate.yaml @@ -0,0 +1,31 @@ +# // Auto-generated , DO NOT EDIT +specVersion: 1.0.0 +version: 0.0.1 +name: peaq-starter +description: >- + This project can be used as a starting point for developing your SubQuery + project +runner: + node: + name: "@subql/node" + version: ">=3.0.1" + query: + name: "@subql/query" + version: "*" +schema: + file: ./schema.graphql +network: + chainId: "0xd2a5d385932d1f650dae03ef8e2748983779ee342c614f80854d32b8cd8fa48c" + endpoint: + - wss://mpfn1.peaq.network +dataSources: + - kind: substrate/Runtime + startBlock: 1 + mapping: + file: ./dist/index.js + handlers: + - kind: substrate/EventHandler + handler: handleEvent + filter: + module: balances + method: Transfer From be73f8c98d012d2dc6a83e5260cac9814699bb80 Mon Sep 17 00:00:00 2001 From: James Bayly Date: Tue, 21 May 2024 09:12:58 +0800 Subject: [PATCH 2/4] Update Astar/astar-evm-starter/README.md --- Astar/astar-evm-starter/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Astar/astar-evm-starter/README.md b/Astar/astar-evm-starter/README.md index 699584ba..6dd1c66e 100644 --- a/Astar/astar-evm-starter/README.md +++ b/Astar/astar-evm-starter/README.md @@ -2,7 +2,9 @@ [SubQuery](https://subquery.network) is a fast, flexible, and reliable open-source data indexer that provides you with custom APIs for your web3 project across all of our supported networks. To learn about how to get started with SubQuery, [visit our docs](https://academy.subquery.network). -**This SubQuery project indexes all transfers and approval events for all ERC20 tokens on Astar's EVM as well as transfers related to Substrate** +**This SubQuery project indexes all transfers and approval events for all ERC20 tokens on Astar's EVM as well as transfers related to Substrate.** + +**In order to index both Substrate and EVM, we run this as a [multi-chain project](https://academy.subquery.network/build/multi-chain.html). You may decide to delete one manifest (`.yaml`) file in order to run this as a single chain project.** ## Start From c592b164b1694f0d0265119ed58c9ec25e0fc0db Mon Sep 17 00:00:00 2001 From: James Bayly Date: Tue, 21 May 2024 09:14:35 +0800 Subject: [PATCH 3/4] Update Moonbeam/moonbeam-evm-starter/README.md --- Moonbeam/moonbeam-evm-starter/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Moonbeam/moonbeam-evm-starter/README.md b/Moonbeam/moonbeam-evm-starter/README.md index 7d49523f..d6fb28f0 100644 --- a/Moonbeam/moonbeam-evm-starter/README.md +++ b/Moonbeam/moonbeam-evm-starter/README.md @@ -4,6 +4,8 @@ **This SubQuery project indexes all transfers and approval events for the [Solarflare token](https://moonscan.io/token/0xe3e43888fa7803cdc7bea478ab327cf1a0dc11a7) (`0xe3e43888fa7803cdc7bea478ab327cf1a0dc11a7`) on Moonbeam's EVM as well as transfers related to Substrate** +**In order to index both Substrate and EVM, we run this as a [multi-chain project](https://academy.subquery.network/build/multi-chain.html). You may decide to delete one manifest (`.yaml`) file in order to run this as a single chain project.** + ## Start First, install SubQuery CLI globally on your terminal by using NPM `npm install -g @subql/cli` From d86be43f3198427f3560e3352f8fcca27e03a157 Mon Sep 17 00:00:00 2001 From: James Bayly Date: Tue, 21 May 2024 09:14:41 +0800 Subject: [PATCH 4/4] Update Peaq/peaq-starter/README.md --- Peaq/peaq-starter/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Peaq/peaq-starter/README.md b/Peaq/peaq-starter/README.md index 4eba52d1..e9291e89 100644 --- a/Peaq/peaq-starter/README.md +++ b/Peaq/peaq-starter/README.md @@ -4,6 +4,8 @@ **This SubQuery project indexes all transfers and approval events for all ERC20 tokens on Peaq's EVM as well as transfers related to Substrate** +**In order to index both Substrate and EVM, we run this as a [multi-chain project](https://academy.subquery.network/build/multi-chain.html). You may decide to delete one manifest (`.yaml`) file in order to run this as a single chain project.** + ## Start First, install SubQuery CLI globally on your terminal by using NPM `npm install -g @subql/cli`