From 73281207f3692a212bbe02dc2e5621fbe1aeb743 Mon Sep 17 00:00:00 2001 From: Leister Francisco Alvarez Campos Date: Fri, 14 Jul 2023 11:03:10 -0600 Subject: [PATCH 01/75] feat(hapi-evm): base structure --- .env.telos | 9 + docker-compose.yaml | 20 + hapi-evm/.dockerignore | 5 + hapi-evm/.eslintignore | 2 + hapi-evm/.eslintrc | 16 + hapi-evm/.gitignore | 11 + hapi-evm/.husky/pre-commit | 4 + hapi-evm/.prettierrc | 8 + hapi-evm/Dockerfile | 16 + hapi-evm/LICENSE | 21 + hapi-evm/makefile | 42 + hapi-evm/nodemon.json | 6 + hapi-evm/package.json | 45 + hapi-evm/src/config/eos.config.ts | 8 + hapi-evm/src/config/hasura.config.ts | 8 + hapi-evm/src/config/index.ts | 3 + hapi-evm/src/config/server.config.ts | 2 + hapi-evm/src/index.ts | 33 + hapi-evm/src/models/index.ts | 0 hapi-evm/src/routes/index.ts | 9 + hapi-evm/src/routes/server.route.ts | 11 + hapi-evm/src/routes/v1/index.ts | 9 + hapi-evm/src/services/index.ts | 0 hapi-evm/src/utils/core/axios.core.ts | 11 + hapi-evm/src/utils/core/hasura.core.ts | 33 + hapi-evm/src/utils/core/index.ts | 2 + hapi-evm/src/utils/eos.util.ts | 232 +++ hapi-evm/src/utils/eosjs-api.d.ts | 1 + hapi-evm/src/utils/index.ts | 3 + hapi-evm/src/utils/time.util.ts | 3 + hapi-evm/src/utils/wallet.util.ts | 60 + hapi-evm/tsconfig.json | 19 + hapi-evm/yarn.lock | 2118 ++++++++++++++++++++++++ makefile | 11 +- 34 files changed, 2780 insertions(+), 1 deletion(-) create mode 100644 hapi-evm/.dockerignore create mode 100644 hapi-evm/.eslintignore create mode 100644 hapi-evm/.eslintrc create mode 100644 hapi-evm/.gitignore create mode 100755 hapi-evm/.husky/pre-commit create mode 100644 hapi-evm/.prettierrc create mode 100644 hapi-evm/Dockerfile create mode 100644 hapi-evm/LICENSE create mode 100644 hapi-evm/makefile create mode 100644 hapi-evm/nodemon.json create mode 100644 hapi-evm/package.json create mode 100644 hapi-evm/src/config/eos.config.ts create mode 100644 hapi-evm/src/config/hasura.config.ts create mode 100644 hapi-evm/src/config/index.ts create mode 100644 hapi-evm/src/config/server.config.ts create mode 100644 hapi-evm/src/index.ts create mode 100644 hapi-evm/src/models/index.ts create mode 100644 hapi-evm/src/routes/index.ts create mode 100644 hapi-evm/src/routes/server.route.ts create mode 100644 hapi-evm/src/routes/v1/index.ts create mode 100644 hapi-evm/src/services/index.ts create mode 100644 hapi-evm/src/utils/core/axios.core.ts create mode 100644 hapi-evm/src/utils/core/hasura.core.ts create mode 100644 hapi-evm/src/utils/core/index.ts create mode 100644 hapi-evm/src/utils/eos.util.ts create mode 100644 hapi-evm/src/utils/eosjs-api.d.ts create mode 100644 hapi-evm/src/utils/index.ts create mode 100644 hapi-evm/src/utils/time.util.ts create mode 100644 hapi-evm/src/utils/wallet.util.ts create mode 100644 hapi-evm/tsconfig.json create mode 100644 hapi-evm/yarn.lock diff --git a/.env.telos b/.env.telos index 2ca8e33d..4ee36893 100644 --- a/.env.telos +++ b/.env.telos @@ -55,6 +55,15 @@ HAPI_RE_CAPTCHA_PROJECT_ID= HAPI_PUBLIC_RE_CAPTCHA_KEY= HAPI_CREATE_ACCOUNT_ACTION_NAME= +# hapi-evm +HAPI_EVM_SERVER_PORT=9090 +HAPI_EVM_SERVER_ADDRESS=hapi-evm +HAPI_EVM_API_ENDPOINTS=["https://telos.greymass.com","https://telos.eosphere.io","telos.caleos.io","mainnet.telosusa.io"] +HAPI_EVM_NETWORK_CHAIN_ID=4667b205c6838ef70ff7988f6e8257e8be0e1284a2f59699054a018f743b1d11 +HAPI_EVM_EOS_EVM_ACCOUNT=eosio.evm +HAPI_EVM_HASURA_URL=http://hasura:8080/v1/graphql +HAPI_EVM_HASURA_ADMIN_SECRET=myadminsecretkey + #webapp PORT=3000 REACT_APP_VERSION=dev diff --git a/docker-compose.yaml b/docker-compose.yaml index 621bc166..a146493d 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -72,6 +72,26 @@ services: HAPI_EOS_MAX_CPU_BLOCK: '${HAPI_EOS_MAX_CPU_BLOCK}' HAPI_EOS_MAX_NET_BLOCK: '${HAPI_EOS_MAX_NET_BLOCK}' HAPI_EOS_MISSED_BLOCKS_ENABLED: '${HAPI_EOS_MISSED_BLOCKS_ENABLED}' + hapi-evm: + container_name: '${STAGE}-${APP_NAME}-hapi-evm' + build: ./hapi-evm + ports: + - '9091:9090' + volumes: + - ./tmp/hapi-evm/node_modules/:/app/node_modules/ + - type: bind + source: ./hapi-evm + target: /app + working_dir: /app + command: bash -c "yarn && yarn start:dev" + environment: + HAPI_EVM_SERVER_PORT: '${HAPI_EVM_SERVER_PORT}' + HAPI_EVM_SERVER_ADDRESS: '${HAPI_EVM_SERVER_ADDRESS}' + HAPI_EVM_API_ENDPOINTS: '${HAPI_EVM_API_ENDPOINTS}' + HAPI_EVM_NETWORK_CHAIN_ID: '${HAPI_EVM_NETWORK_CHAIN_ID}' + HAPI_EVM_EOS_EVM_ACCOUNT: '${HAPI_EVM_EOS_EVM_ACCOUNT}' + HAPI_EVM_HASURA_URL: '${HAPI_EVM_HASURA_URL}' + HAPI_EVM_HASURA_ADMIN_SECRET: '${HAPI_EVM_HASURA_ADMIN_SECRET}' hasura: container_name: '${STAGE}-${APP_NAME}-hasura' image: hasura/graphql-engine:v2.16.0.cli-migrations-v3 diff --git a/hapi-evm/.dockerignore b/hapi-evm/.dockerignore new file mode 100644 index 00000000..9ed8767f --- /dev/null +++ b/hapi-evm/.dockerignore @@ -0,0 +1,5 @@ +node_modules/ +.git/ +.gitignore +.eslintrc +Dockerfile diff --git a/hapi-evm/.eslintignore b/hapi-evm/.eslintignore new file mode 100644 index 00000000..f06235c4 --- /dev/null +++ b/hapi-evm/.eslintignore @@ -0,0 +1,2 @@ +node_modules +dist diff --git a/hapi-evm/.eslintrc b/hapi-evm/.eslintrc new file mode 100644 index 00000000..b15054c9 --- /dev/null +++ b/hapi-evm/.eslintrc @@ -0,0 +1,16 @@ +{ + // "root": true, + "parser": "@typescript-eslint/parser", + "plugins": [ + "@typescript-eslint" + ], + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/eslint-recommended", + "plugin:@typescript-eslint/recommended", + "plugin:prettier/recommended" + ], + "parserOptions": { + "ecmaVersion": 2020 + } +} \ No newline at end of file diff --git a/hapi-evm/.gitignore b/hapi-evm/.gitignore new file mode 100644 index 00000000..9aac2c75 --- /dev/null +++ b/hapi-evm/.gitignore @@ -0,0 +1,11 @@ +# See https://help.github.com/ignore-files/ for more about ignoring files. + +# dependencies +node_modules + +yarn-debug.log* +yarn-error.log* + +resources/**/* +# yarn +dist \ No newline at end of file diff --git a/hapi-evm/.husky/pre-commit b/hapi-evm/.husky/pre-commit new file mode 100755 index 00000000..2e1ac1ea --- /dev/null +++ b/hapi-evm/.husky/pre-commit @@ -0,0 +1,4 @@ +#!/usr/bin/env sh +. "$(dirname -- "$0")/_/husky.sh" + +cd hapi && yarn lint-staged diff --git a/hapi-evm/.prettierrc b/hapi-evm/.prettierrc new file mode 100644 index 00000000..e4b0ccf0 --- /dev/null +++ b/hapi-evm/.prettierrc @@ -0,0 +1,8 @@ +{ + "trailingComma": "none", + "endOfLine": "auto", + "tabWidth": 2, + "singleQuote": true, + "semi": false, + "arrowParens": "avoid" +} diff --git a/hapi-evm/Dockerfile b/hapi-evm/Dockerfile new file mode 100644 index 00000000..bddff6bb --- /dev/null +++ b/hapi-evm/Dockerfile @@ -0,0 +1,16 @@ +# ---------- Base ---------- +FROM node:16.20.0 as base +WORKDIR /app + +# ---------- Builder ---------- +FROM base AS builder +COPY package.json yarn.lock ./ +RUN yarn --ignore-optional +COPY ./src ./src + +# ---------- Release ---------- +FROM base AS release +COPY --from=builder /app/node_modules ./node_modules +COPY --from=builder /app/src ./src +USER node +CMD ["node", "./src/index.js"] diff --git a/hapi-evm/LICENSE b/hapi-evm/LICENSE new file mode 100644 index 00000000..ea23db29 --- /dev/null +++ b/hapi-evm/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 EOS Costa Rica + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/hapi-evm/makefile b/hapi-evm/makefile new file mode 100644 index 00000000..c6d78f46 --- /dev/null +++ b/hapi-evm/makefile @@ -0,0 +1,42 @@ +include ../utils/meta.mk ../utils/help.mk + +LATEST_TAG ?= latest + +install: ##@local Install all dependencies +install: + @npm install + +clean-install: ##@local Reinstalls all dependencies +clean-install: + @rm -Rf node_modules + @npm install + +run: ##@local Run the project locally (without docker) +run: node_modules + @$(SHELL_EXPORT) npm run dev + +build-docker: ##@devops Build the docker image +build-docker: ./Dockerfile + @docker pull $(DOCKER_REGISTRY)/$(IMAGE_NAME_HAPI):$(VERSION) || true + @docker build \ + --target release \ + -t $(DOCKER_REGISTRY)/$(IMAGE_NAME_HAPI):$(VERSION) \ + -t $(DOCKER_REGISTRY)/$(IMAGE_NAME_HAPI):$(LATEST_TAG) \ + . + +pull-image: ##@devops Pull the latest image from registry for caching +pull-image: + @docker pull $(DOCKER_REGISTRY)/$(IMAGE_NAME_HAPI):$(LATEST_TAG) || true + +build-docker-cached: ##@devops Build the docker image using cached layers +build-docker-cached: ./Dockerfile + @docker build \ + --target prod-stage \ + --cache-from $(DOCKER_REGISTRY)/$(IMAGE_NAME_HAPI):$(LATEST_TAG) \ + -t $(DOCKER_REGISTRY)/$(IMAGE_NAME_HAPI):$(VERSION) \ + -t $(DOCKER_REGISTRY)/$(IMAGE_NAME_HAPI):$(LATEST_TAG) \ + . + +push-image: ##@devops Push the freshly built image and tag with release or latest tag +push-image: + @docker push $(DOCKER_REGISTRY)/$(IMAGE_NAME_HAPI):$(VERSION) diff --git a/hapi-evm/nodemon.json b/hapi-evm/nodemon.json new file mode 100644 index 00000000..07b2f249 --- /dev/null +++ b/hapi-evm/nodemon.json @@ -0,0 +1,6 @@ +{ + "watch": ["src"], + "ext": ".ts,.js", + "ignore": [], + "exec": "ts-node ./src/index.ts" +} \ No newline at end of file diff --git a/hapi-evm/package.json b/hapi-evm/package.json new file mode 100644 index 00000000..171437d8 --- /dev/null +++ b/hapi-evm/package.json @@ -0,0 +1,45 @@ +{ + "name": "backend-boilerplate", + "version": "1.0.0", + "description": "AntelopeIO Boilerplate for backend development", + "main": "dist/index.js", + "author": "edenia.com", + "license": "MIT", + "scripts": { + "build": "tsc", + "start": "tsc && node dist/index.js", + "start:dev": "nodemon", + "prepare": "cd .. && husky install hapi/.husky" + }, + "lint-staged": { + "*.ts": [ + "eslint . --ext .ts", + "prettier --write" + ] + }, + "dependencies": { + "@hapi/boom": "^10.0.1", + "@hapi/hapi": "^21.3.2", + "axios": "^1.4.0", + "eosjs": "^22.1.0", + "eosjs-api": "^7.0.4", + "graphql": "16", + "graphql-request": "^6.0.0", + "joi": "^17.9.2", + "node-fetch": "^3.3.1" + }, + "devDependencies": { + "@types/node": "^20.1.5", + "@typescript-eslint/eslint-plugin": "^5.59.6", + "@typescript-eslint/parser": "^5.59.6", + "eslint": "^8.40.0", + "eslint-config-prettier": "^8.8.0", + "eslint-plugin-prettier": "^4.2.1", + "husky": "^8.0.3", + "lint-staged": "^13.2.2", + "nodemon": "^2.0.22", + "prettier": "^2.8.8", + "ts-node": "^10.9.1", + "typescript": "^5.0.4" + } +} diff --git a/hapi-evm/src/config/eos.config.ts b/hapi-evm/src/config/eos.config.ts new file mode 100644 index 00000000..4f99af81 --- /dev/null +++ b/hapi-evm/src/config/eos.config.ts @@ -0,0 +1,8 @@ +export const endpoint = process.env.HAPI_NETWORK_API || 'http://localhost:8888' +export const chainId = process.env.HAPI_NETWORK_CHAIN_ID || 'chainid1' +export const baseAccount = + process.env.HAPI_NETWORK_BASE_ACCOUNT || 'accountname1' +export const baseAccountPassword = + process.env.HAPI_NETWORK_BASE_PASSWORD || 'PW...' +export const walletUrl = + process.env.HAPI_NETWORK_WALLET_URL || 'http://localhost:8888' diff --git a/hapi-evm/src/config/hasura.config.ts b/hapi-evm/src/config/hasura.config.ts new file mode 100644 index 00000000..e0067fe6 --- /dev/null +++ b/hapi-evm/src/config/hasura.config.ts @@ -0,0 +1,8 @@ +export const url = + process.env.HAPI_HASURA_URL || 'http://hasura:8080/v1/graphql' +export const adminSecret = + process.env.HAPI_HASURA_ADMIN_SECRET || 'myadminsecretkey' + +if (!url || !adminSecret) { + throw new Error('Missing required hasura env variables') +} diff --git a/hapi-evm/src/config/index.ts b/hapi-evm/src/config/index.ts new file mode 100644 index 00000000..a237a2f7 --- /dev/null +++ b/hapi-evm/src/config/index.ts @@ -0,0 +1,3 @@ +export * as serverConfig from './server.config' +export * as hasuraConfig from './hasura.config' +export * as eosConfig from './eos.config' diff --git a/hapi-evm/src/config/server.config.ts b/hapi-evm/src/config/server.config.ts new file mode 100644 index 00000000..a6ea4c5a --- /dev/null +++ b/hapi-evm/src/config/server.config.ts @@ -0,0 +1,2 @@ +export const port = process.env.HAPI_EVM_SERVER_PORT +export const host = process.env.HAPI_EVM_SERVER_ADDRESS diff --git a/hapi-evm/src/index.ts b/hapi-evm/src/index.ts new file mode 100644 index 00000000..7739e214 --- /dev/null +++ b/hapi-evm/src/index.ts @@ -0,0 +1,33 @@ +import Hapi from '@hapi/hapi' +import { Server } from '@hapi/hapi' + +import routes from './routes' +import { serverConfig } from './config' + +const init = async () => { + const server: Server = Hapi.server({ + port: serverConfig.port, + host: serverConfig.host, + routes: { + cors: { origin: ['*'] } + }, + debug: { request: ['handler'] } + }) + + routes(server) + + await server.start() + + console.log(`🚀 Server ready at ${server.info.uri}`) + server.table().forEach(route => console.log(`${route.method}\t${route.path}`)) +} + +process.on('uncaughtException', (err, origin) => { + console.log('Uncaught Exception:', err, 'Exception origin:', origin) +}) + +process.on('unhandledRejection', (reason, promise) => { + console.log('Unhandled Rejection:', promise, 'reason:', reason) +}) + +init() diff --git a/hapi-evm/src/models/index.ts b/hapi-evm/src/models/index.ts new file mode 100644 index 00000000..e69de29b diff --git a/hapi-evm/src/routes/index.ts b/hapi-evm/src/routes/index.ts new file mode 100644 index 00000000..4845e31e --- /dev/null +++ b/hapi-evm/src/routes/index.ts @@ -0,0 +1,9 @@ +import { Server } from '@hapi/hapi' + +import * as serverRoute from './server.route' + +const routes = (server: Server) => { + serverRoute.routes(server) +} + +export default routes diff --git a/hapi-evm/src/routes/server.route.ts b/hapi-evm/src/routes/server.route.ts new file mode 100644 index 00000000..bd1f2cbe --- /dev/null +++ b/hapi-evm/src/routes/server.route.ts @@ -0,0 +1,11 @@ +import { Server } from '@hapi/hapi' + +export const routes = (server: Server) => { + server.route({ + method: 'GET', + path: '/healthz', + handler: () => { + return 'OK' + } + }) +} diff --git a/hapi-evm/src/routes/v1/index.ts b/hapi-evm/src/routes/v1/index.ts new file mode 100644 index 00000000..ad108971 --- /dev/null +++ b/hapi-evm/src/routes/v1/index.ts @@ -0,0 +1,9 @@ +import { Server } from '@hapi/hapi' + +// import * as exampleRoutes from './example.route' + +const baseRoute = '/v1' + +export default (server: Server) => { + // exampleRoutes.routes(server, baseRoute) +} diff --git a/hapi-evm/src/services/index.ts b/hapi-evm/src/services/index.ts new file mode 100644 index 00000000..e69de29b diff --git a/hapi-evm/src/utils/core/axios.core.ts b/hapi-evm/src/utils/core/axios.core.ts new file mode 100644 index 00000000..ee20909a --- /dev/null +++ b/hapi-evm/src/utils/core/axios.core.ts @@ -0,0 +1,11 @@ +import axios from 'axios' +import https from 'https' + +const instance = axios.create({ + timeout: 15000, + httpsAgent: new https.Agent({ + rejectUnauthorized: false + }) +}) + +export default instance diff --git a/hapi-evm/src/utils/core/hasura.core.ts b/hapi-evm/src/utils/core/hasura.core.ts new file mode 100644 index 00000000..50cb55e3 --- /dev/null +++ b/hapi-evm/src/utils/core/hasura.core.ts @@ -0,0 +1,33 @@ +import { GraphQLClient } from 'graphql-request' + +import { hasuraConfig } from '../../config' + +import { sleep } from '../time.util' + +import axiosUtil from './axios.core' + +export const hasuraAssembled = async () => { + let hasuraReady = false + + while (!hasuraReady) { + try { + await axiosUtil.get(hasuraConfig.url.replace('/v1/graphql', '/healthz')) + hasuraReady = true + } catch (error) { + hasuraReady = false + console.log( + 'waiting for hasura...', + hasuraConfig.url.replace('/v1/graphql', '/healthz') + ) + await sleep(5) + } + } +} + +const instance = new GraphQLClient(hasuraConfig.url, { + headers: { + 'x-hasura-admin-secret': hasuraConfig.adminSecret + } +}) + +export default instance diff --git a/hapi-evm/src/utils/core/index.ts b/hapi-evm/src/utils/core/index.ts new file mode 100644 index 00000000..2e940f83 --- /dev/null +++ b/hapi-evm/src/utils/core/index.ts @@ -0,0 +1,2 @@ +export * as axios from './axios.core' +export * as hasura from './hasura.core' diff --git a/hapi-evm/src/utils/eos.util.ts b/hapi-evm/src/utils/eos.util.ts new file mode 100644 index 00000000..2c33cf85 --- /dev/null +++ b/hapi-evm/src/utils/eos.util.ts @@ -0,0 +1,232 @@ +import { Api, JsonRpc } from 'eosjs' +import { JsSignatureProvider } from 'eosjs/dist/eosjs-jssig' +import fetch from 'node-fetch' +import EosApi from 'eosjs-api' + +import { eosConfig } from '../config' + +import walletUtil from './wallet.util' + +const rpc = new JsonRpc(eosConfig.endpoint, { fetch }) +const eosApi = EosApi({ + httpEndpoint: eosConfig.endpoint, + verbose: false, + fetchConfiguration: {} +}) + +const newAccount = async (accountName: string) => { + const password = await walletUtil.create(accountName) + const key = await walletUtil.createKey(accountName) + + try { + await walletUtil.unlock( + eosConfig.baseAccount, + eosConfig.baseAccountPassword + ) + } catch (error) { + console.log('Wallet already unlocked') + } + + const keys = await walletUtil.listKeys( + eosConfig.baseAccount, + eosConfig.baseAccountPassword + ) + const api = new Api({ + rpc, + chainId: eosConfig.chainId, + signatureProvider: new JsSignatureProvider(keys) + }) + const authorization = [ + { + actor: eosConfig.baseAccount, + permission: 'active' + } + ] + + const transaction = await api.transact( + { + actions: [ + { + authorization, + account: 'eosio', + name: 'newaccount', + data: { + creator: eosConfig.baseAccount, + name: accountName, + owner: { + threshold: 1, + keys: [ + { + key, + weight: 1 + } + ], + accounts: [], + waits: [] + }, + active: { + threshold: 1, + keys: [ + { + key, + weight: 1 + } + ], + accounts: [], + waits: [] + } + } + }, + { + authorization, + account: 'eosio', + name: 'buyrambytes', + data: { + payer: eosConfig.baseAccount, + receiver: accountName, + bytes: 4096 + } + }, + { + authorization, + account: 'eosio', + name: 'delegatebw', + data: { + from: eosConfig.baseAccount, + receiver: accountName, + stake_net_quantity: '1.0000 EOS', + stake_cpu_quantity: '1.0000 EOS', + transfer: false + } + } + ] + }, + { + blocksBehind: 3, + expireSeconds: 30 + } + ) + await walletUtil.lock(eosConfig.baseAccount) + + return { + password, + transaction + } +} + +const generateRandomAccountName = async (prefix = ''): Promise => { + const length = 12 + + if (prefix.length === 12) return prefix + + const characters = 'abcdefghijklmnopqrstuvwxyz12345' + let accountName = prefix + + while (accountName.length < length) { + accountName = `${accountName}${characters.charAt( + Math.floor(Math.random() * characters.length) + )}` + } + + try { + const account = await getAccount(accountName) + + return account ? generateRandomAccountName(prefix) : accountName + } catch (error) { + return accountName + } +} + +const getAbi = (account: string) => eosApi.getAbi(account) + +const getAccount = async (account: string) => { + try { + const accountInfo = await eosApi.getAccount(account) + + return accountInfo + } catch (error) { + return null + } +} + +const getBlock = async (blockNumber: number) => { + try { + const block = await eosApi.getBlock(blockNumber) + + return block + } catch (error) { + return null + } +} + +const getCodeHash = (account: string) => eosApi.getCodeHash(account) + +const getCurrencyBalance = (code: string, account: string, symbol: string) => + eosApi.getCurrencyBalance(code, account, symbol) + +const getTableRows = (options: any) => + eosApi.getTableRows({ json: true, ...options }) + +const transact = async (actions: any, auths: any) => { + try { + const keys = [] + + for (let index = 0; index < auths.length; index++) { + const auth = auths[index] + try { + await walletUtil.unlock(auth.account, auth.password) + } catch (error) { + console.log('Wallet already unlocked') + } + + try { + keys.push(...(await walletUtil.listKeys(auth.account, auth.password))) + } catch (error) { + console.log('Key already exists') + } + } + + const api = new Api({ + rpc, + chainId: eosConfig.chainId, + signatureProvider: new JsSignatureProvider(keys) + }) + + const transaction = await api.transact( + { + actions + }, + { + blocksBehind: 3, + expireSeconds: 30 + } + ) + + for (let index = 0; index < auths.length; index++) { + try { + const auth = auths[index] + await walletUtil.lock(auth.account) + } catch (error) { + console.log('Wallet already locked') + } + } + + return transaction + } catch (error: any) { + throw new Error( + error.message.replace(/assertion failure with message: /gi, '') + ) + } +} + +export default { + newAccount, + generateRandomAccountName, + getAccount, + getBlock, + getAbi, + getCodeHash, + getCurrencyBalance, + getTableRows, + transact +} diff --git a/hapi-evm/src/utils/eosjs-api.d.ts b/hapi-evm/src/utils/eosjs-api.d.ts new file mode 100644 index 00000000..610f2697 --- /dev/null +++ b/hapi-evm/src/utils/eosjs-api.d.ts @@ -0,0 +1 @@ +declare module 'eosjs-api' diff --git a/hapi-evm/src/utils/index.ts b/hapi-evm/src/utils/index.ts new file mode 100644 index 00000000..7874a180 --- /dev/null +++ b/hapi-evm/src/utils/index.ts @@ -0,0 +1,3 @@ +export * as coreUtil from './core' +export * as timeUtil from './time.util' +export * as walletUtil from './wallet.util' diff --git a/hapi-evm/src/utils/time.util.ts b/hapi-evm/src/utils/time.util.ts new file mode 100644 index 00000000..7b5eebb4 --- /dev/null +++ b/hapi-evm/src/utils/time.util.ts @@ -0,0 +1,3 @@ +export const sleep = (seconds: number) => { + return new Promise(resolve => setTimeout(resolve, seconds * 1000)) +} diff --git a/hapi-evm/src/utils/wallet.util.ts b/hapi-evm/src/utils/wallet.util.ts new file mode 100644 index 00000000..df63f7b8 --- /dev/null +++ b/hapi-evm/src/utils/wallet.util.ts @@ -0,0 +1,60 @@ +import fetch from 'node-fetch' + +import { eosConfig } from '../config' + +const post = async (endpoint: string, body: any = {}) => { + const res = await fetch(`${eosConfig.walletUrl}/v1/wallet${endpoint}`, { + body, + method: 'POST' + }) + const data: any = await res.json() + + if (data.code) { + throw new Error(`${data.error.name}: ${data.error.what}`) + } + + return data +} + +const create = async (walletName: string) => post('/create', `"${walletName}"`) + +const createKey = async (walletName: string) => + post('/create_key', `["${walletName}",""]`) + +// TODO: implement get_public_keys +// TODO: implement import_key + +const listKeys = async (walletName: string, walletPassword: string) => { + const keys = await post('/list_keys', `["${walletName}","${walletPassword}"]`) + + if (keys.length > 0) { + return keys.map((keypair: string[]) => keypair[1]) + } + + return [] +} + +const listWallets = async () => post('/list_wallets') + +const lock = async (walletName: string) => post('/lock', `"${walletName}"`) + +const lockAll = async () => post('/lock_all', {}) + +// TODO: implement open +// TODO: implement remove_key +// TODO: implement set_timeout +// TODO: implement sign_digest +// TODO: implement sign_transaction + +const unlock = async (walletName: string, walletPassword: string) => + post('/unlock', `["${walletName}","${walletPassword}"]`) + +export default { + create, + createKey, + listKeys, + listWallets, + lock, + lockAll, + unlock +} diff --git a/hapi-evm/tsconfig.json b/hapi-evm/tsconfig.json new file mode 100644 index 00000000..49c29d1e --- /dev/null +++ b/hapi-evm/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + + /* Projects */ + + /* Language and Environment */ + "target": "es2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, + + /* Modules */ + "module": "commonjs" /* Specify what module code is generated. */, + "rootDir": "./src" /* Specify the root folder within your source files. */, + "outDir": "./dist" /* Specify an output folder for all emitted files. */, + "esModuleInterop": true /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */, + "forceConsistentCasingInFileNames": true /* Ensure that casing is correct in imports. */, + "strict": true, + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + } +} diff --git a/hapi-evm/yarn.lock b/hapi-evm/yarn.lock new file mode 100644 index 00000000..26a617ea --- /dev/null +++ b/hapi-evm/yarn.lock @@ -0,0 +1,2118 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@aashutoshrathi/word-wrap@^1.2.3": + version "1.2.6" + resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" + integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== + +"@cspotcode/source-map-support@^0.8.0": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" + integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== + dependencies: + "@jridgewell/trace-mapping" "0.3.9" + +"@eslint-community/eslint-utils@^4.2.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" + integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== + dependencies: + eslint-visitor-keys "^3.3.0" + +"@eslint-community/regexpp@^4.4.0": + version "4.5.1" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.5.1.tgz#cdd35dce4fa1a89a4fd42b1599eb35b3af408884" + integrity sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ== + +"@eslint/eslintrc@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.0.tgz#82256f164cc9e0b59669efc19d57f8092706841d" + integrity sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A== + dependencies: + ajv "^6.12.4" + debug "^4.3.2" + espree "^9.6.0" + globals "^13.19.0" + ignore "^5.2.0" + import-fresh "^3.2.1" + js-yaml "^4.1.0" + minimatch "^3.1.2" + strip-json-comments "^3.1.1" + +"@eslint/js@8.44.0": + version "8.44.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.44.0.tgz#961a5903c74139390478bdc808bcde3fc45ab7af" + integrity sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw== + +"@graphql-typed-document-node/core@^3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@graphql-typed-document-node/core/-/core-3.2.0.tgz#5f3d96ec6b2354ad6d8a28bf216a1d97b5426861" + integrity sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ== + +"@hapi/accept@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/@hapi/accept/-/accept-6.0.1.tgz#36378307a67fe38a626fbfaf7f130cdb654d0385" + integrity sha512-aLkYj7zzgC3CSlEVOs84eBOEE3i9xZK2tdQEP+TOj2OFzMWCi9zjkRet82V3GGjecE//zFrCLKIykuaE0uM4bg== + dependencies: + "@hapi/boom" "^10.0.1" + "@hapi/hoek" "^11.0.2" + +"@hapi/ammo@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/@hapi/ammo/-/ammo-6.0.1.tgz#1bc9f7102724ff288ca03b721854fc5393ad123a" + integrity sha512-pmL+nPod4g58kXrMcsGLp05O2jF4P2Q3GiL8qYV7nKYEh3cGf+rV4P5Jyi2Uq0agGhVU63GtaSAfBEZOlrJn9w== + dependencies: + "@hapi/hoek" "^11.0.2" + +"@hapi/b64@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/@hapi/b64/-/b64-6.0.1.tgz#786b47dc070e14465af49e2428c1025bd06ed3df" + integrity sha512-ZvjX4JQReUmBheeCq+S9YavcnMMHWqx3S0jHNXWIM1kQDxB9cyfSycpVvjfrKcIS8Mh5N3hmu/YKo4Iag9g2Kw== + dependencies: + "@hapi/hoek" "^11.0.2" + +"@hapi/boom@^10.0.0", "@hapi/boom@^10.0.1": + version "10.0.1" + resolved "https://registry.yarnpkg.com/@hapi/boom/-/boom-10.0.1.tgz#ebb14688275ae150aa6af788dbe482e6a6062685" + integrity sha512-ERcCZaEjdH3OgSJlyjVk8pHIFeus91CjKP3v+MpgBNp5IvGzP2l/bRiD78nqYcKPaZdbKkK5vDBVPd2ohHBlsA== + dependencies: + "@hapi/hoek" "^11.0.2" + +"@hapi/bounce@^3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@hapi/bounce/-/bounce-3.0.1.tgz#25a51bf95733749c557c6bf948048bffa66435e4" + integrity sha512-G+/Pp9c1Ha4FDP+3Sy/Xwg2O4Ahaw3lIZFSX+BL4uWi64CmiETuZPxhKDUD4xBMOUZbBlzvO8HjiK8ePnhBadA== + dependencies: + "@hapi/boom" "^10.0.1" + "@hapi/hoek" "^11.0.2" + +"@hapi/bourne@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@hapi/bourne/-/bourne-3.0.0.tgz#f11fdf7dda62fe8e336fa7c6642d9041f30356d7" + integrity sha512-Waj1cwPXJDucOib4a3bAISsKJVb15MKi9IvmTI/7ssVEm6sywXGjVJDhl6/umt1pK1ZS7PacXU3A1PmFKHEZ2w== + +"@hapi/call@^9.0.1": + version "9.0.1" + resolved "https://registry.yarnpkg.com/@hapi/call/-/call-9.0.1.tgz#569b87d5b67abf0e58fb82a3894a61aaed3ca92e" + integrity sha512-uPojQRqEL1GRZR4xXPqcLMujQGaEpyVPRyBlD8Pp5rqgIwLhtveF9PkixiKru2THXvuN8mUrLeet5fqxKAAMGg== + dependencies: + "@hapi/boom" "^10.0.1" + "@hapi/hoek" "^11.0.2" + +"@hapi/catbox-memory@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/@hapi/catbox-memory/-/catbox-memory-6.0.1.tgz#8f6b04c0cf2ce25da470324df360bd4e8d68b6ec" + integrity sha512-sVb+/ZxbZIvaMtJfAbdyY+QJUQg9oKTwamXpEg/5xnfG5WbJLTjvEn4kIGKz9pN3ENNbIL/bIdctmHmqi/AdGA== + dependencies: + "@hapi/boom" "^10.0.1" + "@hapi/hoek" "^11.0.2" + +"@hapi/catbox@^12.1.1": + version "12.1.1" + resolved "https://registry.yarnpkg.com/@hapi/catbox/-/catbox-12.1.1.tgz#9339dca0a5b18b3ca0a825ac5dfc916dbc5bab83" + integrity sha512-hDqYB1J+R0HtZg4iPH3LEnldoaBsar6bYp0EonBmNQ9t5CO+1CqgCul2ZtFveW1ReA5SQuze9GPSU7/aecERhw== + dependencies: + "@hapi/boom" "^10.0.1" + "@hapi/hoek" "^11.0.2" + "@hapi/podium" "^5.0.0" + "@hapi/validate" "^2.0.1" + +"@hapi/content@^6.0.0": + version "6.0.0" + resolved "https://registry.yarnpkg.com/@hapi/content/-/content-6.0.0.tgz#2427af3bac8a2f743512fce2a70cbdc365af29df" + integrity sha512-CEhs7j+H0iQffKfe5Htdak5LBOz/Qc8TRh51cF+BFv0qnuph3Em4pjGVzJMkI2gfTDdlJKWJISGWS1rK34POGA== + dependencies: + "@hapi/boom" "^10.0.0" + +"@hapi/cryptiles@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/@hapi/cryptiles/-/cryptiles-6.0.1.tgz#7868a9d4233567ed66f0a9caf85fdcc56e980621" + integrity sha512-9GM9ECEHfR8lk5ASOKG4+4ZsEzFqLfhiryIJ2ISePVB92OHLp/yne4m+zn7z9dgvM98TLpiFebjDFQ0UHcqxXQ== + dependencies: + "@hapi/boom" "^10.0.1" + +"@hapi/file@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@hapi/file/-/file-3.0.0.tgz#f1fd824493ac89a6fceaf89c824afc5ae2121c09" + integrity sha512-w+lKW+yRrLhJu620jT3y+5g2mHqnKfepreykvdOcl9/6up8GrQQn+l3FRTsjHTKbkbfQFkuksHpdv2EcpKcJ4Q== + +"@hapi/hapi@^21.3.2": + version "21.3.2" + resolved "https://registry.yarnpkg.com/@hapi/hapi/-/hapi-21.3.2.tgz#f9f94c1c28ccad1444c838d04070fa1cd0409b33" + integrity sha512-tbm0zmsdUj8iw4NzFV30FST/W4qzh/Lsw6Q5o5gAhOuoirWvxm8a4G3o60bqBw8nXvRNJ8uLtE0RKLlZINxHcQ== + dependencies: + "@hapi/accept" "^6.0.1" + "@hapi/ammo" "^6.0.1" + "@hapi/boom" "^10.0.1" + "@hapi/bounce" "^3.0.1" + "@hapi/call" "^9.0.1" + "@hapi/catbox" "^12.1.1" + "@hapi/catbox-memory" "^6.0.1" + "@hapi/heavy" "^8.0.1" + "@hapi/hoek" "^11.0.2" + "@hapi/mimos" "^7.0.1" + "@hapi/podium" "^5.0.1" + "@hapi/shot" "^6.0.1" + "@hapi/somever" "^4.1.1" + "@hapi/statehood" "^8.1.1" + "@hapi/subtext" "^8.1.0" + "@hapi/teamwork" "^6.0.0" + "@hapi/topo" "^6.0.1" + "@hapi/validate" "^2.0.1" + +"@hapi/heavy@^8.0.1": + version "8.0.1" + resolved "https://registry.yarnpkg.com/@hapi/heavy/-/heavy-8.0.1.tgz#e2be4a6a249005b5a587f7604aafa8ed02461fb6" + integrity sha512-gBD/NANosNCOp6RsYTsjo2vhr5eYA3BEuogk6cxY0QdhllkkTaJFYtTXv46xd6qhBVMbMMqcSdtqey+UQU3//w== + dependencies: + "@hapi/boom" "^10.0.1" + "@hapi/hoek" "^11.0.2" + "@hapi/validate" "^2.0.1" + +"@hapi/hoek@^11.0.2": + version "11.0.2" + resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-11.0.2.tgz#cb3ea547daac7de5c9cf1d960c3f35c34f065427" + integrity sha512-aKmlCO57XFZ26wso4rJsW4oTUnrgTFw2jh3io7CAtO9w4UltBNwRXvXIVzzyfkaaLRo3nluP/19msA8vDUUuKw== + +"@hapi/hoek@^9.0.0": + version "9.3.0" + resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.3.0.tgz#8368869dcb735be2e7f5cb7647de78e167a251fb" + integrity sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ== + +"@hapi/iron@^7.0.1": + version "7.0.1" + resolved "https://registry.yarnpkg.com/@hapi/iron/-/iron-7.0.1.tgz#f74bace8dad9340c7c012c27c078504f070f14b5" + integrity sha512-tEZnrOujKpS6jLKliyWBl3A9PaE+ppuL/+gkbyPPDb/l2KSKQyH4lhMkVb+sBhwN+qaxxlig01JRqB8dk/mPxQ== + dependencies: + "@hapi/b64" "^6.0.1" + "@hapi/boom" "^10.0.1" + "@hapi/bourne" "^3.0.0" + "@hapi/cryptiles" "^6.0.1" + "@hapi/hoek" "^11.0.2" + +"@hapi/mimos@^7.0.1": + version "7.0.1" + resolved "https://registry.yarnpkg.com/@hapi/mimos/-/mimos-7.0.1.tgz#5b65c76bb9da28ba34b0092215891f2c72bc899d" + integrity sha512-b79V+BrG0gJ9zcRx1VGcCI6r6GEzzZUgiGEJVoq5gwzuB2Ig9Cax8dUuBauQCFKvl2YWSWyOc8mZ8HDaJOtkew== + dependencies: + "@hapi/hoek" "^11.0.2" + mime-db "^1.52.0" + +"@hapi/nigel@^5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@hapi/nigel/-/nigel-5.0.1.tgz#a6dfe357e9d48d944e2ffc552bd95cb701d79ee9" + integrity sha512-uv3dtYuB4IsNaha+tigWmN8mQw/O9Qzl5U26Gm4ZcJVtDdB1AVJOwX3X5wOX+A07qzpEZnOMBAm8jjSqGsU6Nw== + dependencies: + "@hapi/hoek" "^11.0.2" + "@hapi/vise" "^5.0.1" + +"@hapi/pez@^6.1.0": + version "6.1.0" + resolved "https://registry.yarnpkg.com/@hapi/pez/-/pez-6.1.0.tgz#64d9f95580fc7d8f1d13437ee4a8676709954fda" + integrity sha512-+FE3sFPYuXCpuVeHQ/Qag1b45clR2o54QoonE/gKHv9gukxQ8oJJZPR7o3/ydDTK6racnCJXxOyT1T93FCJMIg== + dependencies: + "@hapi/b64" "^6.0.1" + "@hapi/boom" "^10.0.1" + "@hapi/content" "^6.0.0" + "@hapi/hoek" "^11.0.2" + "@hapi/nigel" "^5.0.1" + +"@hapi/podium@^5.0.0", "@hapi/podium@^5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@hapi/podium/-/podium-5.0.1.tgz#f292b4c0ca3118747394a102c6c3340bda96662f" + integrity sha512-eznFTw6rdBhAijXFIlBOMJJd+lXTvqbrBIS4Iu80r2KTVIo4g+7fLy4NKp/8+UnSt5Ox6mJtAlKBU/Sf5080TQ== + dependencies: + "@hapi/hoek" "^11.0.2" + "@hapi/teamwork" "^6.0.0" + "@hapi/validate" "^2.0.1" + +"@hapi/shot@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/@hapi/shot/-/shot-6.0.1.tgz#ea84d1810b7c8599d5517c23b4ec55a529d7dc16" + integrity sha512-s5ynMKZXYoDd3dqPw5YTvOR/vjHvMTxc388+0qL0jZZP1+uwXuUD32o9DuuuLsmTlyXCWi02BJl1pBpwRuUrNA== + dependencies: + "@hapi/hoek" "^11.0.2" + "@hapi/validate" "^2.0.1" + +"@hapi/somever@^4.1.1": + version "4.1.1" + resolved "https://registry.yarnpkg.com/@hapi/somever/-/somever-4.1.1.tgz#b492c78408303c72cd1a39c5060f35d18a404b27" + integrity sha512-lt3QQiDDOVRatS0ionFDNrDIv4eXz58IibQaZQDOg4DqqdNme8oa0iPWcE0+hkq/KTeBCPtEOjDOBKBKwDumVg== + dependencies: + "@hapi/bounce" "^3.0.1" + "@hapi/hoek" "^11.0.2" + +"@hapi/statehood@^8.1.1": + version "8.1.1" + resolved "https://registry.yarnpkg.com/@hapi/statehood/-/statehood-8.1.1.tgz#db4bd14c90810a1389763cb0b0b8f221aa4179c1" + integrity sha512-YbK7PSVUA59NArAW5Np0tKRoIZ5VNYUicOk7uJmWZF6XyH5gGL+k62w77SIJb0AoAJ0QdGQMCQ/WOGL1S3Ydow== + dependencies: + "@hapi/boom" "^10.0.1" + "@hapi/bounce" "^3.0.1" + "@hapi/bourne" "^3.0.0" + "@hapi/cryptiles" "^6.0.1" + "@hapi/hoek" "^11.0.2" + "@hapi/iron" "^7.0.1" + "@hapi/validate" "^2.0.1" + +"@hapi/subtext@^8.1.0": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@hapi/subtext/-/subtext-8.1.0.tgz#58733020a6655bc4d978df9e2f75e31696ff3f91" + integrity sha512-PyaN4oSMtqPjjVxLny1k0iYg4+fwGusIhaom9B2StinBclHs7v46mIW706Y+Wo21lcgulGyXbQrmT/w4dus6ww== + dependencies: + "@hapi/boom" "^10.0.1" + "@hapi/bourne" "^3.0.0" + "@hapi/content" "^6.0.0" + "@hapi/file" "^3.0.0" + "@hapi/hoek" "^11.0.2" + "@hapi/pez" "^6.1.0" + "@hapi/wreck" "^18.0.1" + +"@hapi/teamwork@^6.0.0": + version "6.0.0" + resolved "https://registry.yarnpkg.com/@hapi/teamwork/-/teamwork-6.0.0.tgz#b3a173cf811ba59fc6ee22318a1b51f4561f06e0" + integrity sha512-05HumSy3LWfXpmJ9cr6HzwhAavrHkJ1ZRCmNE2qJMihdM5YcWreWPfyN0yKT2ZjCM92au3ZkuodjBxOibxM67A== + +"@hapi/topo@^5.0.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-5.1.0.tgz#dc448e332c6c6e37a4dc02fd84ba8d44b9afb012" + integrity sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg== + dependencies: + "@hapi/hoek" "^9.0.0" + +"@hapi/topo@^6.0.1": + version "6.0.2" + resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-6.0.2.tgz#f219c1c60da8430228af4c1f2e40c32a0d84bbb4" + integrity sha512-KR3rD5inZbGMrHmgPxsJ9dbi6zEK+C3ZwUwTa+eMwWLz7oijWUTWD2pMSNNYJAU6Qq+65NkxXjqHr/7LM2Xkqg== + dependencies: + "@hapi/hoek" "^11.0.2" + +"@hapi/validate@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@hapi/validate/-/validate-2.0.1.tgz#45cf228c4c8cfc61ba2da7e0a5ba93ff3b9afff1" + integrity sha512-NZmXRnrSLK8MQ9y/CMqE9WSspgB9xA41/LlYR0k967aSZebWr4yNrpxIbov12ICwKy4APSlWXZga9jN5p6puPA== + dependencies: + "@hapi/hoek" "^11.0.2" + "@hapi/topo" "^6.0.1" + +"@hapi/vise@^5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@hapi/vise/-/vise-5.0.1.tgz#5c9f16bcf1c039ddd4b6cad5f32d71eeb6bb7dac" + integrity sha512-XZYWzzRtINQLedPYlIkSkUr7m5Ddwlu99V9elh8CSygXstfv3UnWIXT0QD+wmR0VAG34d2Vx3olqcEhRRoTu9A== + dependencies: + "@hapi/hoek" "^11.0.2" + +"@hapi/wreck@^18.0.1": + version "18.0.1" + resolved "https://registry.yarnpkg.com/@hapi/wreck/-/wreck-18.0.1.tgz#6df04532be25fd128c5244e72ccc21438cf8bb65" + integrity sha512-OLHER70+rZxvDl75xq3xXOfd3e8XIvz8fWY0dqg92UvhZ29zo24vQgfqgHSYhB5ZiuFpSLeriOisAlxAo/1jWg== + dependencies: + "@hapi/boom" "^10.0.1" + "@hapi/bourne" "^3.0.0" + "@hapi/hoek" "^11.0.2" + +"@humanwhocodes/config-array@^0.11.10": + version "0.11.10" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.10.tgz#5a3ffe32cc9306365fb3fd572596cd602d5e12d2" + integrity sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ== + dependencies: + "@humanwhocodes/object-schema" "^1.2.1" + debug "^4.1.1" + minimatch "^3.0.5" + +"@humanwhocodes/module-importer@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" + integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== + +"@humanwhocodes/object-schema@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" + integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== + +"@jridgewell/resolve-uri@^3.0.3": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" + integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== + +"@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.15" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== + +"@jridgewell/trace-mapping@0.3.9": + version "0.3.9" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" + integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@sideway/address@^4.1.3": + version "4.1.4" + resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.4.tgz#03dccebc6ea47fdc226f7d3d1ad512955d4783f0" + integrity sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw== + dependencies: + "@hapi/hoek" "^9.0.0" + +"@sideway/formula@^3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@sideway/formula/-/formula-3.0.1.tgz#80fcbcbaf7ce031e0ef2dd29b1bfc7c3f583611f" + integrity sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg== + +"@sideway/pinpoint@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@sideway/pinpoint/-/pinpoint-2.0.0.tgz#cff8ffadc372ad29fd3f78277aeb29e632cc70df" + integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ== + +"@tsconfig/node10@^1.0.7": + version "1.0.9" + resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" + integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA== + +"@tsconfig/node12@^1.0.7": + version "1.0.11" + resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d" + integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== + +"@tsconfig/node14@^1.0.0": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1" + integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== + +"@tsconfig/node16@^1.0.2": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9" + integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== + +"@types/json-schema@^7.0.9": + version "7.0.12" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.12.tgz#d70faba7039d5fca54c83c7dbab41051d2b6f6cb" + integrity sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA== + +"@types/node@^20.1.5": + version "20.4.2" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.4.2.tgz#129cc9ae69f93824f92fac653eebfb4812ab4af9" + integrity sha512-Dd0BYtWgnWJKwO1jkmTrzofjK2QXXcai0dmtzvIBhcA+RsG5h8R3xlyta0kGOZRNfL9GuRtb1knmPEhQrePCEw== + +"@types/semver@^7.3.12": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.0.tgz#591c1ce3a702c45ee15f47a42ade72c2fd78978a" + integrity sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw== + +"@typescript-eslint/eslint-plugin@^5.59.6": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz#aeef0328d172b9e37d9bab6dbc13b87ed88977db" + integrity sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag== + dependencies: + "@eslint-community/regexpp" "^4.4.0" + "@typescript-eslint/scope-manager" "5.62.0" + "@typescript-eslint/type-utils" "5.62.0" + "@typescript-eslint/utils" "5.62.0" + debug "^4.3.4" + graphemer "^1.4.0" + ignore "^5.2.0" + natural-compare-lite "^1.4.0" + semver "^7.3.7" + tsutils "^3.21.0" + +"@typescript-eslint/parser@^5.59.6": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.62.0.tgz#1b63d082d849a2fcae8a569248fbe2ee1b8a56c7" + integrity sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA== + dependencies: + "@typescript-eslint/scope-manager" "5.62.0" + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/typescript-estree" "5.62.0" + debug "^4.3.4" + +"@typescript-eslint/scope-manager@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz#d9457ccc6a0b8d6b37d0eb252a23022478c5460c" + integrity sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w== + dependencies: + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/visitor-keys" "5.62.0" + +"@typescript-eslint/type-utils@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz#286f0389c41681376cdad96b309cedd17d70346a" + integrity sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew== + dependencies: + "@typescript-eslint/typescript-estree" "5.62.0" + "@typescript-eslint/utils" "5.62.0" + debug "^4.3.4" + tsutils "^3.21.0" + +"@typescript-eslint/types@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.62.0.tgz#258607e60effa309f067608931c3df6fed41fd2f" + integrity sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ== + +"@typescript-eslint/typescript-estree@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz#7d17794b77fabcac615d6a48fb143330d962eb9b" + integrity sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA== + dependencies: + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/visitor-keys" "5.62.0" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + semver "^7.3.7" + tsutils "^3.21.0" + +"@typescript-eslint/utils@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.62.0.tgz#141e809c71636e4a75daa39faed2fb5f4b10df86" + integrity sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + "@types/json-schema" "^7.0.9" + "@types/semver" "^7.3.12" + "@typescript-eslint/scope-manager" "5.62.0" + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/typescript-estree" "5.62.0" + eslint-scope "^5.1.1" + semver "^7.3.7" + +"@typescript-eslint/visitor-keys@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz#2174011917ce582875954ffe2f6912d5931e353e" + integrity sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw== + dependencies: + "@typescript-eslint/types" "5.62.0" + eslint-visitor-keys "^3.3.0" + +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + +acorn-jsx@^5.3.2: + version "5.3.2" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== + +acorn-walk@^8.1.1: + version "8.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" + integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== + +acorn@^8.4.1, acorn@^8.9.0: + version "8.10.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" + integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== + +aggregate-error@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" + integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== + dependencies: + clean-stack "^2.0.0" + indent-string "^4.0.0" + +ajv@^6.10.0, ajv@^6.12.4: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ansi-escapes@^4.3.0: + version "4.3.2" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== + dependencies: + type-fest "^0.21.3" + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-regex@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" + integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +ansi-styles@^6.0.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" + integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== + +anymatch@~3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +arg@^4.1.0: + version "4.1.3" + resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" + integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +astral-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" + integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== + +axios@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.4.0.tgz#38a7bf1224cd308de271146038b551d725f0be1f" + integrity sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA== + dependencies: + follow-redirects "^1.15.0" + form-data "^4.0.0" + proxy-from-env "^1.1.0" + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +bn.js@5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.0.tgz#358860674396c6997771a9d051fcc1b57d4ae002" + integrity sha512-D7iWRBvnZE8ecXiLj/9wbxH7Tk79fAh8IHaTNq1RWRixsS02W+5qS+iE9yq6RYl0asXx5tw0bLhmT5pIfbSquw== + +bn.js@^4.11.9: + version "4.12.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" + integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^3.0.2, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +brorand@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camel-case@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-3.0.0.tgz#ca3c3688a4e9cf3a4cda777dc4dcbc713249cf73" + integrity sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w== + dependencies: + no-case "^2.2.0" + upper-case "^1.1.1" + +chalk@5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.2.0.tgz#249623b7d66869c673699fb66d65723e54dfcfb3" + integrity sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA== + +chalk@^4.0.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chokidar@^3.5.2: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +clean-stack@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" + integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== + +cli-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" + integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== + dependencies: + restore-cursor "^3.1.0" + +cli-truncate@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-2.1.0.tgz#c39e28bf05edcde5be3b98992a22deed5a2b93c7" + integrity sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg== + dependencies: + slice-ansi "^3.0.0" + string-width "^4.2.0" + +cli-truncate@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-3.1.0.tgz#3f23ab12535e3d73e839bb43e73c9de487db1389" + integrity sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA== + dependencies: + slice-ansi "^5.0.0" + string-width "^5.0.0" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +colorette@^2.0.19: + version "2.0.20" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" + integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== + +combined-stream@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +commander@^10.0.0: + version "10.0.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06" + integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +create-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" + integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== + +cross-fetch@^3.1.5: + version "3.1.8" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.8.tgz#0327eba65fd68a7d119f8fb2bf9334a1a7956f82" + integrity sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg== + dependencies: + node-fetch "^2.6.12" + +cross-spawn@^7.0.2, cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +data-uri-to-buffer@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz#d8feb2b2881e6a4f58c2e08acfd0e2834e26222e" + integrity sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A== + +debug@^3.2.7: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + +debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +deep-is@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== + +diff@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +eastasianwidth@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" + integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== + +elliptic@6.5.4: + version "6.5.4" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" + integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== + dependencies: + bn.js "^4.11.9" + brorand "^1.1.0" + hash.js "^1.0.0" + hmac-drbg "^1.0.1" + inherits "^2.0.4" + minimalistic-assert "^1.0.1" + minimalistic-crypto-utils "^1.0.1" + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== + +encoding@^0.1.11: + version "0.1.13" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" + integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== + dependencies: + iconv-lite "^0.6.2" + +eosjs-api@^7.0.4: + version "7.0.4" + resolved "https://registry.yarnpkg.com/eosjs-api/-/eosjs-api-7.0.4.tgz#dc3a7206d4ac3e6818f0a950b8d24333175ac7c9" + integrity sha512-oLbM39rcyWYkqu6nIEQ50I92yT2vvD7WZPZ3FujbydG2ssR5Re/uSvbkFfZTB02g3I4D+UDUA1jd65HlM7r3MQ== + dependencies: + camel-case "^3.0.0" + isomorphic-fetch "^2.2.1" + +eosjs@^22.1.0: + version "22.1.0" + resolved "https://registry.yarnpkg.com/eosjs/-/eosjs-22.1.0.tgz#7ac40e2f1f959fab70539c30ac8ae46c9038aa3c" + integrity sha512-Ka8KO7akC3RxNdSg/3dkGWuUWUQESTzSUzQljBdVP16UG548vmQoBqSGnZdnjlZyfcab8VOu2iEt+JjyfYc5+A== + dependencies: + bn.js "5.2.0" + elliptic "6.5.4" + hash.js "1.1.7" + pako "2.0.3" + +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +eslint-config-prettier@^8.8.0: + version "8.8.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.8.0.tgz#bfda738d412adc917fd7b038857110efe98c9348" + integrity sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA== + +eslint-plugin-prettier@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz#651cbb88b1dab98bfd42f017a12fa6b2d993f94b" + integrity sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ== + dependencies: + prettier-linter-helpers "^1.0.0" + +eslint-scope@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + +eslint-scope@^7.2.0: + version "7.2.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.1.tgz#936821d3462675f25a18ac5fd88a67cc15b393bd" + integrity sha512-CvefSOsDdaYYvxChovdrPo/ZGt8d5lrJWleAc1diXRKhHGiTYEI26cvo8Kle/wGnsizoCJjK73FMg1/IkIwiNA== + dependencies: + esrecurse "^4.3.0" + estraverse "^5.2.0" + +eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz#c22c48f48942d08ca824cc526211ae400478a994" + integrity sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA== + +eslint@^8.40.0: + version "8.45.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.45.0.tgz#bab660f90d18e1364352c0a6b7c6db8edb458b78" + integrity sha512-pd8KSxiQpdYRfYa9Wufvdoct3ZPQQuVuU5O6scNgMuOMYuxvH0IGaYK0wUFjo4UYYQQCUndlXiMbnxopwvvTiw== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + "@eslint-community/regexpp" "^4.4.0" + "@eslint/eslintrc" "^2.1.0" + "@eslint/js" "8.44.0" + "@humanwhocodes/config-array" "^0.11.10" + "@humanwhocodes/module-importer" "^1.0.1" + "@nodelib/fs.walk" "^1.2.8" + ajv "^6.10.0" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.3.2" + doctrine "^3.0.0" + escape-string-regexp "^4.0.0" + eslint-scope "^7.2.0" + eslint-visitor-keys "^3.4.1" + espree "^9.6.0" + esquery "^1.4.2" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + find-up "^5.0.0" + glob-parent "^6.0.2" + globals "^13.19.0" + graphemer "^1.4.0" + ignore "^5.2.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + is-path-inside "^3.0.3" + js-yaml "^4.1.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.1.2" + natural-compare "^1.4.0" + optionator "^0.9.3" + strip-ansi "^6.0.1" + text-table "^0.2.0" + +espree@^9.6.0: + version "9.6.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" + integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== + dependencies: + acorn "^8.9.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^3.4.1" + +esquery@^1.4.2: + version "1.5.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" + integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== + dependencies: + estraverse "^5.1.0" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + +estraverse@^5.1.0, estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +execa@^7.0.0: + version "7.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-7.1.1.tgz#3eb3c83d239488e7b409d48e8813b76bb55c9c43" + integrity sha512-wH0eMf/UXckdUYnO21+HDztteVv05rq2GXksxT4fCGeHkBhw1DROXh40wcjMcRqDOWE7iPJ4n3M7e2+YFP+76Q== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.1" + human-signals "^4.3.0" + is-stream "^3.0.0" + merge-stream "^2.0.0" + npm-run-path "^5.1.0" + onetime "^6.0.0" + signal-exit "^3.0.7" + strip-final-newline "^3.0.0" + +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-diff@^1.1.2: + version "1.3.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" + integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== + +fast-glob@^3.2.9: + version "3.3.0" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.0.tgz#7c40cb491e1e2ed5664749e87bfb516dbe8727c0" + integrity sha512-ChDuvbOypPuNjO8yIDf36x7BlZX1smcUMTTcyoIjycexOxd6DFsKsg21qVBzEmr3G7fUKIRy2/psii+CIUt7FA== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== + +fastq@^1.6.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" + integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== + dependencies: + reusify "^1.0.4" + +fetch-blob@^3.1.2, fetch-blob@^3.1.4: + version "3.2.0" + resolved "https://registry.yarnpkg.com/fetch-blob/-/fetch-blob-3.2.0.tgz#f09b8d4bbd45adc6f0c20b7e787e793e309dcce9" + integrity sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ== + dependencies: + node-domexception "^1.0.0" + web-streams-polyfill "^3.0.3" + +file-entry-cache@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== + dependencies: + flat-cache "^3.0.4" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +flat-cache@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" + integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== + dependencies: + flatted "^3.1.0" + rimraf "^3.0.2" + +flatted@^3.1.0: + version "3.2.7" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" + integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== + +follow-redirects@^1.15.0: + version "1.15.2" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" + integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== + +form-data@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + +formdata-polyfill@^4.0.10: + version "4.0.10" + resolved "https://registry.yarnpkg.com/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz#24807c31c9d402e002ab3d8c720144ceb8848423" + integrity sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g== + dependencies: + fetch-blob "^3.1.2" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +get-stream@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +glob-parent@^5.1.2, glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-parent@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + dependencies: + is-glob "^4.0.3" + +glob@^7.1.3: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^13.19.0: + version "13.20.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.20.0.tgz#ea276a1e508ffd4f1612888f9d1bad1e2717bf82" + integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ== + dependencies: + type-fest "^0.20.2" + +globby@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.2.9" + ignore "^5.2.0" + merge2 "^1.4.1" + slash "^3.0.0" + +graphemer@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" + integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== + +graphql-request@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/graphql-request/-/graphql-request-6.1.0.tgz#f4eb2107967af3c7a5907eb3131c671eac89be4f" + integrity sha512-p+XPfS4q7aIpKVcgmnZKhMNqhltk20hfXtkaIkTfjjmiKMJ5xrt5c743cL03y/K7y1rg3WrIC49xGiEQ4mxdNw== + dependencies: + "@graphql-typed-document-node/core" "^3.2.0" + cross-fetch "^3.1.5" + +graphql@16: + version "16.7.1" + resolved "https://registry.yarnpkg.com/graphql/-/graphql-16.7.1.tgz#11475b74a7bff2aefd4691df52a0eca0abd9b642" + integrity sha512-DRYR9tf+UGU0KOsMcKAlXeFfX89UiiIZ0dRU3mR0yJfu6OjZqUcp68NnFLnqQU5RexygFoDy1EW+ccOYcPfmHg== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + +hmac-drbg@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg== + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +human-signals@^4.3.0: + version "4.3.1" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-4.3.1.tgz#ab7f811e851fca97ffbd2c1fe9a958964de321b2" + integrity sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ== + +husky@^8.0.3: + version "8.0.3" + resolved "https://registry.yarnpkg.com/husky/-/husky-8.0.3.tgz#4936d7212e46d1dea28fef29bb3a108872cd9184" + integrity sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg== + +iconv-lite@^0.6.2: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + +ignore-by-default@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" + integrity sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA== + +ignore@^5.2.0: + version "5.2.4" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" + integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== + +import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== + +indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@^2.0.3, inherits@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-fullwidth-code-point@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz#fae3167c729e7463f8461ce512b080a49268aa88" + integrity sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ== + +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-path-inside@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + +is-stream@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ== + +is-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac" + integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +isomorphic-fetch@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9" + integrity sha512-9c4TNAKYXM5PRyVcwUZrF3W09nQ+sO7+jydgs4ZGW9dhsLG2VOlISJABombdQqQRXCwuYG3sYV/puGf5rp0qmA== + dependencies: + node-fetch "^1.0.1" + whatwg-fetch ">=0.10.0" + +joi@^17.9.2: + version "17.9.2" + resolved "https://registry.yarnpkg.com/joi/-/joi-17.9.2.tgz#8b2e4724188369f55451aebd1d0b1d9482470690" + integrity sha512-Itk/r+V4Dx0V3c7RLFdRh12IOjySm2/WGPMubBT92cQvRfYZhPM2W0hZlctjj72iES8jsRCwp7S/cRmWBnJ4nw== + dependencies: + "@hapi/hoek" "^9.0.0" + "@hapi/topo" "^5.0.0" + "@sideway/address" "^4.1.3" + "@sideway/formula" "^3.0.1" + "@sideway/pinpoint" "^2.0.0" + +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== + +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + +lilconfig@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52" + integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ== + +lint-staged@^13.2.2: + version "13.2.3" + resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-13.2.3.tgz#f899aad6c093473467e9c9e316e3c2d8a28f87a7" + integrity sha512-zVVEXLuQIhr1Y7R7YAWx4TZLdvuzk7DnmrsTNL0fax6Z3jrpFcas+vKbzxhhvp6TA55m1SQuWkpzI1qbfDZbAg== + dependencies: + chalk "5.2.0" + cli-truncate "^3.1.0" + commander "^10.0.0" + debug "^4.3.4" + execa "^7.0.0" + lilconfig "2.1.0" + listr2 "^5.0.7" + micromatch "^4.0.5" + normalize-path "^3.0.0" + object-inspect "^1.12.3" + pidtree "^0.6.0" + string-argv "^0.3.1" + yaml "^2.2.2" + +listr2@^5.0.7: + version "5.0.8" + resolved "https://registry.yarnpkg.com/listr2/-/listr2-5.0.8.tgz#a9379ffeb4bd83a68931a65fb223a11510d6ba23" + integrity sha512-mC73LitKHj9w6v30nLNGPetZIlfpUniNSsxxrbaPcWOjDb92SHPzJPi/t+v1YC/lxKz/AJ9egOjww0qUuFxBpA== + dependencies: + cli-truncate "^2.1.0" + colorette "^2.0.19" + log-update "^4.0.0" + p-map "^4.0.0" + rfdc "^1.3.0" + rxjs "^7.8.0" + through "^2.3.8" + wrap-ansi "^7.0.0" + +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + +log-update@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/log-update/-/log-update-4.0.0.tgz#589ecd352471f2a1c0c570287543a64dfd20e0a1" + integrity sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg== + dependencies: + ansi-escapes "^4.3.0" + cli-cursor "^3.1.0" + slice-ansi "^4.0.0" + wrap-ansi "^6.2.0" + +lower-case@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac" + integrity sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA== + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +make-error@^1.1.1: + version "1.3.6" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + +merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + +merge2@^1.3.0, merge2@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +micromatch@^4.0.4, micromatch@^4.0.5: + version "4.0.5" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + +mime-db@1.52.0, mime-db@^1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.12: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + +mimic-fn@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-4.0.0.tgz#60a90550d5cb0b239cca65d893b1a53b29871ecc" + integrity sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw== + +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + +minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== + +minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +natural-compare-lite@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4" + integrity sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g== + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== + +no-case@^2.2.0: + version "2.3.2" + resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac" + integrity sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ== + dependencies: + lower-case "^1.1.1" + +node-domexception@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5" + integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ== + +node-fetch@^1.0.1: + version "1.7.3" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.7.3.tgz#980f6f72d85211a5347c6b2bc18c5b84c3eb47ef" + integrity sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ== + dependencies: + encoding "^0.1.11" + is-stream "^1.0.1" + +node-fetch@^2.6.12: + version "2.6.12" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.12.tgz#02eb8e22074018e3d5a83016649d04df0e348fba" + integrity sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g== + dependencies: + whatwg-url "^5.0.0" + +node-fetch@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-3.3.1.tgz#b3eea7b54b3a48020e46f4f88b9c5a7430d20b2e" + integrity sha512-cRVc/kyto/7E5shrWca1Wsea4y6tL9iYJE5FBCius3JQfb/4P4I295PfhgbJQBLTx6lATE4z+wK0rPM4VS2uow== + dependencies: + data-uri-to-buffer "^4.0.0" + fetch-blob "^3.1.4" + formdata-polyfill "^4.0.10" + +nodemon@^2.0.22: + version "2.0.22" + resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.22.tgz#182c45c3a78da486f673d6c1702e00728daf5258" + integrity sha512-B8YqaKMmyuCO7BowF1Z1/mkPqLk6cs/l63Ojtd6otKjMx47Dq1utxfRxcavH1I7VSaL8n5BUaoutadnsX3AAVQ== + dependencies: + chokidar "^3.5.2" + debug "^3.2.7" + ignore-by-default "^1.0.1" + minimatch "^3.1.2" + pstree.remy "^1.1.8" + semver "^5.7.1" + simple-update-notifier "^1.0.7" + supports-color "^5.5.0" + touch "^3.1.0" + undefsafe "^2.0.5" + +nopt@~1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" + integrity sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg== + dependencies: + abbrev "1" + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +npm-run-path@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-5.1.0.tgz#bc62f7f3f6952d9894bd08944ba011a6ee7b7e00" + integrity sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q== + dependencies: + path-key "^4.0.0" + +object-inspect@^1.12.3: + version "1.12.3" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9" + integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +onetime@^5.1.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + +onetime@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-6.0.0.tgz#7c24c18ed1fd2e9bca4bd26806a33613c77d34b4" + integrity sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ== + dependencies: + mimic-fn "^4.0.0" + +optionator@^0.9.3: + version "0.9.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" + integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== + dependencies: + "@aashutoshrathi/word-wrap" "^1.2.3" + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +p-map@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" + integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== + dependencies: + aggregate-error "^3.0.0" + +pako@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/pako/-/pako-2.0.3.tgz#cdf475e31b678565251406de9e759196a0ea7a43" + integrity sha512-WjR1hOeg+kki3ZIOjaf4b5WVcay1jaliKSYiEaB1XzwhMQZJxRdQRv0V31EKBYlxb4T7SK3hjfc/jxyU64BoSw== + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-key@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-4.0.0.tgz#295588dc3aee64154f877adb9d780b81c554bf18" + integrity sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ== + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pidtree@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.6.0.tgz#90ad7b6d42d5841e69e0a2419ef38f8883aa057c" + integrity sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g== + +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + +prettier-linter-helpers@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" + integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== + dependencies: + fast-diff "^1.1.2" + +prettier@^2.8.8: + version "2.8.8" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" + integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== + +proxy-from-env@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + +pstree.remy@^1.1.8: + version "1.1.8" + resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.8.tgz#c242224f4a67c21f686839bbdb4ac282b8373d3a" + integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w== + +punycode@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" + integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +restore-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" + integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== + dependencies: + onetime "^5.1.0" + signal-exit "^3.0.2" + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rfdc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b" + integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA== + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +rxjs@^7.8.0: + version "7.8.1" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543" + integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== + dependencies: + tslib "^2.1.0" + +"safer-buffer@>= 2.1.2 < 3.0.0": + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + +semver@^5.7.1: + version "5.7.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" + integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== + +semver@^7.3.7: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + +semver@~7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" + integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +signal-exit@^3.0.2, signal-exit@^3.0.7: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +simple-update-notifier@^1.0.7: + version "1.1.0" + resolved "https://registry.yarnpkg.com/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz#67694c121de354af592b347cdba798463ed49c82" + integrity sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg== + dependencies: + semver "~7.0.0" + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +slice-ansi@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-3.0.0.tgz#31ddc10930a1b7e0b67b08c96c2f49b77a789787" + integrity sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ== + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + +slice-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" + integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + +slice-ansi@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-5.0.0.tgz#b73063c57aa96f9cd881654b15294d95d285c42a" + integrity sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ== + dependencies: + ansi-styles "^6.0.0" + is-fullwidth-code-point "^4.0.0" + +string-argv@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.2.tgz#2b6d0ef24b656274d957d54e0a4bbf6153dc02b6" + integrity sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q== + +string-width@^4.1.0, string-width@^4.2.0: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@^5.0.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" + integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== + dependencies: + eastasianwidth "^0.2.0" + emoji-regex "^9.2.2" + strip-ansi "^7.0.1" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^7.0.1: + version "7.1.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" + integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== + dependencies: + ansi-regex "^6.0.1" + +strip-final-newline@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz#52894c313fbff318835280aed60ff71ebf12b8fd" + integrity sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw== + +strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +supports-color@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== + +through@^2.3.8: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +touch@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" + integrity sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA== + dependencies: + nopt "~1.0.10" + +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== + +ts-node@^10.9.1: + version "10.9.1" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" + integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== + dependencies: + "@cspotcode/source-map-support" "^0.8.0" + "@tsconfig/node10" "^1.0.7" + "@tsconfig/node12" "^1.0.7" + "@tsconfig/node14" "^1.0.0" + "@tsconfig/node16" "^1.0.2" + acorn "^8.4.1" + acorn-walk "^8.1.1" + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + v8-compile-cache-lib "^3.0.1" + yn "3.1.1" + +tslib@^1.8.1: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + +tslib@^2.1.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.0.tgz#b295854684dbda164e181d259a22cd779dcd7bc3" + integrity sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA== + +tsutils@^3.21.0: + version "3.21.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" + integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== + dependencies: + tslib "^1.8.1" + +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + +type-fest@^0.21.3: + version "0.21.3" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== + +typescript@^5.0.4: + version "5.1.6" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274" + integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA== + +undefsafe@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c" + integrity sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA== + +upper-case@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598" + integrity sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA== + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +v8-compile-cache-lib@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" + integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== + +web-streams-polyfill@^3.0.3: + version "3.2.1" + resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz#71c2718c52b45fd49dbeee88634b3a60ceab42a6" + integrity sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q== + +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== + +whatwg-fetch@>=0.10.0: + version "3.6.2" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz#dced24f37f2624ed0281725d51d0e2e3fe677f8c" + integrity sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA== + +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wrap-ansi@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" + integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yaml@^2.2.2: + version "2.3.1" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.3.1.tgz#02fe0975d23cd441242aa7204e09fc28ac2ac33b" + integrity sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ== + +yn@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" + integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== diff --git a/makefile b/makefile index 17d391f3..da60fd19 100644 --- a/makefile +++ b/makefile @@ -20,6 +20,7 @@ clean: @docker-compose stop @rm -rf tmp/postgres @rm -rf tmp/hapi + @rm -rf tmp/hapi-evm @rm -rf tmp/webapp @docker system prune @@ -100,6 +101,7 @@ start: make start-postgres make start-wallet make start-hapi + make start-hapi-evm make start-hasura make -j 3 start-hasura-cli start-logs start-webapp @@ -112,6 +114,9 @@ start-wallet: start-hapi: @docker-compose up -d --build hapi +start-hapi-evm: + @docker-compose up -d --build hapi-evm + start-hasura: $(eval -include .env) @until \ @@ -122,6 +127,10 @@ start-hasura: curl http://localhost:9090/healthz; \ do echo "$(BLUE)$(STAGE)-$(APP_NAME)-hasura |$(RESET) waiting for hapi service"; \ sleep 5; done; + @until \ + curl http://localhost:9091/healthz; \ + do echo "$(BLUE)$(STAGE)-$(APP_NAME)-hasura |$(RESET) waiting for hapi-evm service"; \ + sleep 5; done; @echo "..." @docker-compose stop hasura @docker-compose up -d --build hasura @@ -145,7 +154,7 @@ start-webapp: @echo "done webapp" start-logs: - @docker-compose logs -f hapi webapp + @docker-compose logs -f hapi hapi-evm webapp build-kubernetes: ##@devops Generate proper k8s files based on the templates build-kubernetes: ./kubernetes From 239d73a92b97d2b82d51fe4d9f941411aa205a25 Mon Sep 17 00:00:00 2001 From: Leister Francisco Alvarez Campos Date: Fri, 14 Jul 2023 11:21:13 -0600 Subject: [PATCH 02/75] chore(hapi-evm): update packages to newer version --- docker-compose.yaml | 1 - hapi-evm/package.json | 10 +- hapi-evm/yarn.lock | 374 +++++++++++++++++++++++++++++------------- 3 files changed, 266 insertions(+), 119 deletions(-) diff --git a/docker-compose.yaml b/docker-compose.yaml index a146493d..db521591 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -78,7 +78,6 @@ services: ports: - '9091:9090' volumes: - - ./tmp/hapi-evm/node_modules/:/app/node_modules/ - type: bind source: ./hapi-evm target: /app diff --git a/hapi-evm/package.json b/hapi-evm/package.json index 171437d8..be82bf1a 100644 --- a/hapi-evm/package.json +++ b/hapi-evm/package.json @@ -30,15 +30,15 @@ }, "devDependencies": { "@types/node": "^20.1.5", - "@typescript-eslint/eslint-plugin": "^5.59.6", - "@typescript-eslint/parser": "^5.59.6", + "@typescript-eslint/eslint-plugin": "^6.0.0", + "@typescript-eslint/parser": "^6.0.0", "eslint": "^8.40.0", "eslint-config-prettier": "^8.8.0", - "eslint-plugin-prettier": "^4.2.1", + "eslint-plugin-prettier": "^5.0.0", "husky": "^8.0.3", "lint-staged": "^13.2.2", - "nodemon": "^2.0.22", - "prettier": "^2.8.8", + "nodemon": "^3.0.1", + "prettier": "^3.0.0", "ts-node": "^10.9.1", "typescript": "^5.0.4" } diff --git a/hapi-evm/yarn.lock b/hapi-evm/yarn.lock index 26a617ea..2e2ecaa1 100644 --- a/hapi-evm/yarn.lock +++ b/hapi-evm/yarn.lock @@ -14,14 +14,14 @@ dependencies: "@jridgewell/trace-mapping" "0.3.9" -"@eslint-community/eslint-utils@^4.2.0": +"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.3.0": version "4.4.0" resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== dependencies: eslint-visitor-keys "^3.3.0" -"@eslint-community/regexpp@^4.4.0": +"@eslint-community/regexpp@^4.4.0", "@eslint-community/regexpp@^4.5.0": version "4.5.1" resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.5.1.tgz#cdd35dce4fa1a89a4fd42b1599eb35b3af408884" integrity sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ== @@ -371,6 +371,18 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" +"@pkgr/utils@^2.3.1": + version "2.4.2" + resolved "https://registry.yarnpkg.com/@pkgr/utils/-/utils-2.4.2.tgz#9e638bbe9a6a6f165580dc943f138fd3309a2cbc" + integrity sha512-POgTXhjrTfbTV63DiFXav4lBHiICLKKwDeaKn9Nphwj7WH6m0hMMCaJkMyRWjgtPFyRKRVoMXXjczsTQRDEhYw== + dependencies: + cross-spawn "^7.0.3" + fast-glob "^3.3.0" + is-glob "^4.0.3" + open "^9.1.0" + picocolors "^1.0.0" + tslib "^2.6.0" + "@sideway/address@^4.1.3": version "4.1.4" resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.4.tgz#03dccebc6ea47fdc226f7d3d1ad512955d4783f0" @@ -408,7 +420,7 @@ resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9" integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== -"@types/json-schema@^7.0.9": +"@types/json-schema@^7.0.11": version "7.0.12" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.12.tgz#d70faba7039d5fca54c83c7dbab41051d2b6f6cb" integrity sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA== @@ -423,89 +435,93 @@ resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.0.tgz#591c1ce3a702c45ee15f47a42ade72c2fd78978a" integrity sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw== -"@typescript-eslint/eslint-plugin@^5.59.6": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz#aeef0328d172b9e37d9bab6dbc13b87ed88977db" - integrity sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag== - dependencies: - "@eslint-community/regexpp" "^4.4.0" - "@typescript-eslint/scope-manager" "5.62.0" - "@typescript-eslint/type-utils" "5.62.0" - "@typescript-eslint/utils" "5.62.0" +"@typescript-eslint/eslint-plugin@^6.0.0": + version "6.0.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.0.0.tgz#19ff4f1cab8d6f8c2c1825150f7a840bc5d9bdc4" + integrity sha512-xuv6ghKGoiq856Bww/yVYnXGsKa588kY3M0XK7uUW/3fJNNULKRfZfSBkMTSpqGG/8ZCXCadfh8G/z/B4aqS/A== + dependencies: + "@eslint-community/regexpp" "^4.5.0" + "@typescript-eslint/scope-manager" "6.0.0" + "@typescript-eslint/type-utils" "6.0.0" + "@typescript-eslint/utils" "6.0.0" + "@typescript-eslint/visitor-keys" "6.0.0" debug "^4.3.4" + grapheme-splitter "^1.0.4" graphemer "^1.4.0" - ignore "^5.2.0" + ignore "^5.2.4" + natural-compare "^1.4.0" natural-compare-lite "^1.4.0" - semver "^7.3.7" - tsutils "^3.21.0" + semver "^7.5.0" + ts-api-utils "^1.0.1" -"@typescript-eslint/parser@^5.59.6": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.62.0.tgz#1b63d082d849a2fcae8a569248fbe2ee1b8a56c7" - integrity sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA== +"@typescript-eslint/parser@^6.0.0": + version "6.0.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.0.0.tgz#46b2600fd1f67e62fc00a28093a75f41bf7effc4" + integrity sha512-TNaufYSPrr1U8n+3xN+Yp9g31vQDJqhXzzPSHfQDLcaO4tU+mCfODPxCwf4H530zo7aUBE3QIdxCXamEnG04Tg== dependencies: - "@typescript-eslint/scope-manager" "5.62.0" - "@typescript-eslint/types" "5.62.0" - "@typescript-eslint/typescript-estree" "5.62.0" + "@typescript-eslint/scope-manager" "6.0.0" + "@typescript-eslint/types" "6.0.0" + "@typescript-eslint/typescript-estree" "6.0.0" + "@typescript-eslint/visitor-keys" "6.0.0" debug "^4.3.4" -"@typescript-eslint/scope-manager@5.62.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz#d9457ccc6a0b8d6b37d0eb252a23022478c5460c" - integrity sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w== +"@typescript-eslint/scope-manager@6.0.0": + version "6.0.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.0.0.tgz#8ede47a37cb2b7ed82d329000437abd1113b5e11" + integrity sha512-o4q0KHlgCZTqjuaZ25nw5W57NeykZT9LiMEG4do/ovwvOcPnDO1BI5BQdCsUkjxFyrCL0cSzLjvIMfR9uo7cWg== dependencies: - "@typescript-eslint/types" "5.62.0" - "@typescript-eslint/visitor-keys" "5.62.0" + "@typescript-eslint/types" "6.0.0" + "@typescript-eslint/visitor-keys" "6.0.0" -"@typescript-eslint/type-utils@5.62.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz#286f0389c41681376cdad96b309cedd17d70346a" - integrity sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew== +"@typescript-eslint/type-utils@6.0.0": + version "6.0.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.0.0.tgz#0478d8a94f05e51da2877cc0500f1b3c27ac7e18" + integrity sha512-ah6LJvLgkoZ/pyJ9GAdFkzeuMZ8goV6BH7eC9FPmojrnX9yNCIsfjB+zYcnex28YO3RFvBkV6rMV6WpIqkPvoQ== dependencies: - "@typescript-eslint/typescript-estree" "5.62.0" - "@typescript-eslint/utils" "5.62.0" + "@typescript-eslint/typescript-estree" "6.0.0" + "@typescript-eslint/utils" "6.0.0" debug "^4.3.4" - tsutils "^3.21.0" + ts-api-utils "^1.0.1" -"@typescript-eslint/types@5.62.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.62.0.tgz#258607e60effa309f067608931c3df6fed41fd2f" - integrity sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ== +"@typescript-eslint/types@6.0.0": + version "6.0.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.0.0.tgz#19795f515f8decbec749c448b0b5fc76d82445a1" + integrity sha512-Zk9KDggyZM6tj0AJWYYKgF0yQyrcnievdhG0g5FqyU3Y2DRxJn4yWY21sJC0QKBckbsdKKjYDV2yVrrEvuTgxg== -"@typescript-eslint/typescript-estree@5.62.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz#7d17794b77fabcac615d6a48fb143330d962eb9b" - integrity sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA== +"@typescript-eslint/typescript-estree@6.0.0": + version "6.0.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.0.0.tgz#1e09aab7320e404fb9f83027ea568ac24e372f81" + integrity sha512-2zq4O7P6YCQADfmJ5OTDQTP3ktajnXIRrYAtHM9ofto/CJZV3QfJ89GEaM2BNGeSr1KgmBuLhEkz5FBkS2RQhQ== dependencies: - "@typescript-eslint/types" "5.62.0" - "@typescript-eslint/visitor-keys" "5.62.0" + "@typescript-eslint/types" "6.0.0" + "@typescript-eslint/visitor-keys" "6.0.0" debug "^4.3.4" globby "^11.1.0" is-glob "^4.0.3" - semver "^7.3.7" - tsutils "^3.21.0" + semver "^7.5.0" + ts-api-utils "^1.0.1" -"@typescript-eslint/utils@5.62.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.62.0.tgz#141e809c71636e4a75daa39faed2fb5f4b10df86" - integrity sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ== +"@typescript-eslint/utils@6.0.0": + version "6.0.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.0.0.tgz#27a16d0d8f2719274a39417b9782f7daa3802db0" + integrity sha512-SOr6l4NB6HE4H/ktz0JVVWNXqCJTOo/mHnvIte1ZhBQ0Cvd04x5uKZa3zT6tiodL06zf5xxdK8COiDvPnQ27JQ== dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - "@types/json-schema" "^7.0.9" + "@eslint-community/eslint-utils" "^4.3.0" + "@types/json-schema" "^7.0.11" "@types/semver" "^7.3.12" - "@typescript-eslint/scope-manager" "5.62.0" - "@typescript-eslint/types" "5.62.0" - "@typescript-eslint/typescript-estree" "5.62.0" + "@typescript-eslint/scope-manager" "6.0.0" + "@typescript-eslint/types" "6.0.0" + "@typescript-eslint/typescript-estree" "6.0.0" eslint-scope "^5.1.1" - semver "^7.3.7" + semver "^7.5.0" -"@typescript-eslint/visitor-keys@5.62.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz#2174011917ce582875954ffe2f6912d5931e353e" - integrity sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw== +"@typescript-eslint/visitor-keys@6.0.0": + version "6.0.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.0.0.tgz#0b49026049fbd096d2c00c5e784866bc69532a31" + integrity sha512-cvJ63l8c0yXdeT5POHpL0Q1cZoRcmRKFCtSjNGJxPkcP571EfZMcNbzWAc7oK3D1dRzm/V5EwtkANTZxqvuuUA== dependencies: - "@typescript-eslint/types" "5.62.0" - eslint-visitor-keys "^3.3.0" + "@typescript-eslint/types" "6.0.0" + eslint-visitor-keys "^3.4.1" abbrev@1: version "1.1.1" @@ -621,6 +637,11 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== +big-integer@^1.6.44: + version "1.6.51" + resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.51.tgz#0df92a5d9880560d3ff2d5fd20245c889d130686" + integrity sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg== + binary-extensions@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" @@ -636,6 +657,13 @@ bn.js@^4.11.9: resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== +bplist-parser@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/bplist-parser/-/bplist-parser-0.2.0.tgz#43a9d183e5bf9d545200ceac3e712f79ebbe8d0e" + integrity sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw== + dependencies: + big-integer "^1.6.44" + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -656,6 +684,13 @@ brorand@^1.1.0: resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== +bundle-name@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bundle-name/-/bundle-name-3.0.0.tgz#ba59bcc9ac785fb67ccdbf104a2bf60c099f0e1a" + integrity sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw== + dependencies: + run-applescript "^5.0.0" + callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" @@ -804,6 +839,29 @@ deep-is@^0.1.3: resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== +default-browser-id@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/default-browser-id/-/default-browser-id-3.0.0.tgz#bee7bbbef1f4e75d31f98f4d3f1556a14cea790c" + integrity sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA== + dependencies: + bplist-parser "^0.2.0" + untildify "^4.0.0" + +default-browser@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/default-browser/-/default-browser-4.0.0.tgz#53c9894f8810bf86696de117a6ce9085a3cbc7da" + integrity sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA== + dependencies: + bundle-name "^3.0.0" + default-browser-id "^3.0.0" + execa "^7.1.1" + titleize "^3.0.0" + +define-lazy-prop@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz#dbb19adfb746d7fc6d734a06b72f4a00d021255f" + integrity sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg== + delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -891,12 +949,13 @@ eslint-config-prettier@^8.8.0: resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.8.0.tgz#bfda738d412adc917fd7b038857110efe98c9348" integrity sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA== -eslint-plugin-prettier@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz#651cbb88b1dab98bfd42f017a12fa6b2d993f94b" - integrity sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ== +eslint-plugin-prettier@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-5.0.0.tgz#6887780ed95f7708340ec79acfdf60c35b9be57a" + integrity sha512-AgaZCVuYDXHUGxj/ZGu1u8H8CYgDY3iG6w5kUFw4AzMVXzB7VvbKgYR4nATIN+OvUrghMbiDLeimVjVY5ilq3w== dependencies: prettier-linter-helpers "^1.0.0" + synckit "^0.8.5" eslint-scope@^5.1.1: version "5.1.1" @@ -1000,7 +1059,22 @@ esutils@^2.0.2: resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== -execa@^7.0.0: +execa@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + +execa@^7.0.0, execa@^7.1.1: version "7.1.1" resolved "https://registry.yarnpkg.com/execa/-/execa-7.1.1.tgz#3eb3c83d239488e7b409d48e8813b76bb55c9c43" integrity sha512-wH0eMf/UXckdUYnO21+HDztteVv05rq2GXksxT4fCGeHkBhw1DROXh40wcjMcRqDOWE7iPJ4n3M7e2+YFP+76Q== @@ -1025,7 +1099,7 @@ fast-diff@^1.1.2: resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== -fast-glob@^3.2.9: +fast-glob@^3.2.9, fast-glob@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.0.tgz#7c40cb491e1e2ed5664749e87bfb516dbe8727c0" integrity sha512-ChDuvbOypPuNjO8yIDf36x7BlZX1smcUMTTcyoIjycexOxd6DFsKsg21qVBzEmr3G7fUKIRy2/psii+CIUt7FA== @@ -1127,7 +1201,7 @@ fsevents@~2.3.2: resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== -get-stream@^6.0.1: +get-stream@^6.0.0, get-stream@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== @@ -1177,6 +1251,11 @@ globby@^11.1.0: merge2 "^1.4.1" slash "^3.0.0" +grapheme-splitter@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" + integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== + graphemer@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" @@ -1222,6 +1301,11 @@ hmac-drbg@^1.0.1: minimalistic-assert "^1.0.0" minimalistic-crypto-utils "^1.0.1" +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + human-signals@^4.3.0: version "4.3.1" resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-4.3.1.tgz#ab7f811e851fca97ffbd2c1fe9a958964de321b2" @@ -1244,7 +1328,7 @@ ignore-by-default@^1.0.1: resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" integrity sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA== -ignore@^5.2.0: +ignore@^5.2.0, ignore@^5.2.4: version "5.2.4" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== @@ -1287,6 +1371,16 @@ is-binary-path@~2.1.0: dependencies: binary-extensions "^2.0.0" +is-docker@^2.0.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + +is-docker@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-3.0.0.tgz#90093aa3106277d8a77a5910dbae71747e15a200" + integrity sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ== + is-extglob@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" @@ -1309,6 +1403,13 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" +is-inside-container@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-inside-container/-/is-inside-container-1.0.0.tgz#e81fba699662eb31dbdaf26766a61d4814717ea4" + integrity sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA== + dependencies: + is-docker "^3.0.0" + is-number@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" @@ -1324,11 +1425,23 @@ is-stream@^1.0.1: resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" integrity sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ== +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + is-stream@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac" integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA== +is-wsl@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + isexe@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" @@ -1568,18 +1681,18 @@ node-fetch@^3.3.1: fetch-blob "^3.1.4" formdata-polyfill "^4.0.10" -nodemon@^2.0.22: - version "2.0.22" - resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.22.tgz#182c45c3a78da486f673d6c1702e00728daf5258" - integrity sha512-B8YqaKMmyuCO7BowF1Z1/mkPqLk6cs/l63Ojtd6otKjMx47Dq1utxfRxcavH1I7VSaL8n5BUaoutadnsX3AAVQ== +nodemon@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-3.0.1.tgz#affe822a2c5f21354466b2fc8ae83277d27dadc7" + integrity sha512-g9AZ7HmkhQkqXkRc20w+ZfQ73cHLbE8hnPbtaFbFtCumZsjyMhKk9LajQ07U5Ux28lvFjZ5X7HvWR1xzU8jHVw== dependencies: chokidar "^3.5.2" debug "^3.2.7" ignore-by-default "^1.0.1" minimatch "^3.1.2" pstree.remy "^1.1.8" - semver "^5.7.1" - simple-update-notifier "^1.0.7" + semver "^7.5.3" + simple-update-notifier "^2.0.0" supports-color "^5.5.0" touch "^3.1.0" undefsafe "^2.0.5" @@ -1596,6 +1709,13 @@ normalize-path@^3.0.0, normalize-path@~3.0.0: resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== +npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + npm-run-path@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-5.1.0.tgz#bc62f7f3f6952d9894bd08944ba011a6ee7b7e00" @@ -1615,7 +1735,7 @@ once@^1.3.0: dependencies: wrappy "1" -onetime@^5.1.0: +onetime@^5.1.0, onetime@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== @@ -1629,6 +1749,16 @@ onetime@^6.0.0: dependencies: mimic-fn "^4.0.0" +open@^9.1.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/open/-/open-9.1.0.tgz#684934359c90ad25742f5a26151970ff8c6c80b6" + integrity sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg== + dependencies: + default-browser "^4.0.0" + define-lazy-prop "^3.0.0" + is-inside-container "^1.0.0" + is-wsl "^2.2.0" + optionator@^0.9.3: version "0.9.3" resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" @@ -1684,7 +1814,7 @@ path-is-absolute@^1.0.0: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== -path-key@^3.1.0: +path-key@^3.0.0, path-key@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== @@ -1699,6 +1829,11 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" @@ -1721,10 +1856,10 @@ prettier-linter-helpers@^1.0.0: dependencies: fast-diff "^1.1.2" -prettier@^2.8.8: - version "2.8.8" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" - integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== +prettier@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.0.0.tgz#e7b19f691245a21d618c68bc54dc06122f6105ae" + integrity sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g== proxy-from-env@^1.1.0: version "1.1.0" @@ -1783,6 +1918,13 @@ rimraf@^3.0.2: dependencies: glob "^7.1.3" +run-applescript@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/run-applescript/-/run-applescript-5.0.0.tgz#e11e1c932e055d5c6b40d98374e0268d9b11899c" + integrity sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg== + dependencies: + execa "^5.0.0" + run-parallel@^1.1.9: version "1.2.0" resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" @@ -1802,23 +1944,13 @@ rxjs@^7.8.0: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -semver@^5.7.1: - version "5.7.2" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" - integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== - -semver@^7.3.7: +semver@^7.5.0, semver@^7.5.3: version "7.5.4" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== dependencies: lru-cache "^6.0.0" -semver@~7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" - integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== - shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" @@ -1831,17 +1963,17 @@ shebang-regex@^3.0.0: resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== -signal-exit@^3.0.2, signal-exit@^3.0.7: +signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: version "3.0.7" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== -simple-update-notifier@^1.0.7: - version "1.1.0" - resolved "https://registry.yarnpkg.com/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz#67694c121de354af592b347cdba798463ed49c82" - integrity sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg== +simple-update-notifier@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/simple-update-notifier/-/simple-update-notifier-2.0.0.tgz#d70b92bdab7d6d90dfd73931195a30b6e3d7cebb" + integrity sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w== dependencies: - semver "~7.0.0" + semver "^7.5.3" slash@^3.0.0: version "3.0.0" @@ -1911,6 +2043,11 @@ strip-ansi@^7.0.1: dependencies: ansi-regex "^6.0.1" +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + strip-final-newline@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-3.0.0.tgz#52894c313fbff318835280aed60ff71ebf12b8fd" @@ -1935,6 +2072,14 @@ supports-color@^7.1.0: dependencies: has-flag "^4.0.0" +synckit@^0.8.5: + version "0.8.5" + resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.8.5.tgz#b7f4358f9bb559437f9f167eb6bc46b3c9818fa3" + integrity sha512-L1dapNV6vu2s/4Sputv8xGsCdAVlb5nRDMFU/E27D44l5U6cw1g0dGd45uLc+OXjNMmF4ntiMdCimzcjFKQI8Q== + dependencies: + "@pkgr/utils" "^2.3.1" + tslib "^2.5.0" + text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" @@ -1945,6 +2090,11 @@ through@^2.3.8: resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== +titleize@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/titleize/-/titleize-3.0.0.tgz#71c12eb7fdd2558aa8a44b0be83b8a76694acd53" + integrity sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ== + to-regex-range@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" @@ -1964,6 +2114,11 @@ tr46@~0.0.3: resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== +ts-api-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.0.1.tgz#8144e811d44c749cd65b2da305a032510774452d" + integrity sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A== + ts-node@^10.9.1: version "10.9.1" resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" @@ -1983,23 +2138,11 @@ ts-node@^10.9.1: v8-compile-cache-lib "^3.0.1" yn "3.1.1" -tslib@^1.8.1: - version "1.14.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" - integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== - -tslib@^2.1.0: +tslib@^2.1.0, tslib@^2.5.0, tslib@^2.6.0: version "2.6.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.0.tgz#b295854684dbda164e181d259a22cd779dcd7bc3" integrity sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA== -tsutils@^3.21.0: - version "3.21.0" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" - integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== - dependencies: - tslib "^1.8.1" - type-check@^0.4.0, type-check@~0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" @@ -2027,6 +2170,11 @@ undefsafe@^2.0.5: resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c" integrity sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA== +untildify@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/untildify/-/untildify-4.0.0.tgz#2bc947b953652487e4600949fb091e3ae8cd919b" + integrity sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw== + upper-case@^1.1.1: version "1.1.3" resolved "https://registry.yarnpkg.com/upper-case/-/upper-case-1.1.3.tgz#f6b4501c2ec4cdd26ba78be7222961de77621598" From e20a89eec9a699aa01d7b451d2191e2c74abad26 Mon Sep 17 00:00:00 2001 From: Leister Francisco Alvarez Campos Date: Fri, 21 Jul 2023 09:36:22 -0600 Subject: [PATCH 03/75] feat(hapi-evm): structure and base logic --- .env.telos | 4 +- docker-compose.yaml | 2 + hapi-evm/package.json | 5 +- hapi-evm/src/cache/index.ts | 0 hapi-evm/src/cache/v1/index.ts | 0 hapi-evm/src/config/eos.config.ts | 8 - hapi-evm/src/config/index.ts | 2 +- hapi-evm/src/config/network.config.ts | 9 + hapi-evm/src/index.ts | 3 + hapi-evm/src/models/block/index.ts | 2 + hapi-evm/src/models/block/interfaces.ts | 9 + hapi-evm/src/models/block/queries.ts | 92 +++ hapi-evm/src/models/default.model.ts | 20 + hapi-evm/src/models/gas/index.ts | 2 + hapi-evm/src/models/gas/interfaces.ts | 3 + hapi-evm/src/models/gas/queries.ts | 1 + hapi-evm/src/models/index.ts | 4 + hapi-evm/src/models/transaction/index.ts | 2 + hapi-evm/src/models/transaction/interfaces.ts | 9 + hapi-evm/src/models/transaction/queries.ts | 97 +++ hapi-evm/src/routes/v1/index.ts | 24 + hapi-evm/src/services/block.service.ts | 98 +++ hapi-evm/src/services/gas.service.ts | 3 + hapi-evm/src/services/worker/index.ts | 28 + hapi-evm/src/utils/index.ts | 1 - hapi-evm/src/utils/wallet.util.ts | 60 -- hapi-evm/tsconfig.json | 2 +- hapi-evm/yarn.lock | 769 +++++++++++++++++- hasura/metadata/databases/databases.yaml | 4 +- .../public_block_history_by_producer.yaml | 2 +- .../databases/default/tables/evm_block.yaml | 13 + .../default/tables/evm_transaction.yaml | 3 + ...public_block_history_by_producer_type.yaml | 2 +- .../databases/default/tables/public_cpu.yaml | 2 +- .../default/tables/public_demux_state.yaml | 2 +- .../default/tables/public_endpoint.yaml | 2 +- .../databases/default/tables/public_node.yaml | 6 +- .../default/tables/public_node_info.yaml | 2 +- .../default/tables/public_round_history.yaml | 2 +- .../tables/public_schedule_history.yaml | 2 +- .../default/tables/public_setting.yaml | 2 +- .../databases/default/tables/tables.yaml | 2 + hasura/metadata/rest_endpoints.yaml | 6 +- .../1689614416757_create_schema_evm/down.sql | 1 + .../1689614416757_create_schema_evm/up.sql | 1 + .../down.sql | 1 + .../up.sql | 1 + .../down.sql | 1 + .../up.sql | 1 + .../down.sql | 1 + .../up.sql | 1 + .../down.sql | 1 + .../up.sql | 1 + .../down.sql | 2 + .../up.sql | 2 + .../down.sql | 1 + .../up.sql | 5 + makefile | 2 +- 58 files changed, 1241 insertions(+), 92 deletions(-) create mode 100644 hapi-evm/src/cache/index.ts create mode 100644 hapi-evm/src/cache/v1/index.ts delete mode 100644 hapi-evm/src/config/eos.config.ts create mode 100644 hapi-evm/src/config/network.config.ts create mode 100644 hapi-evm/src/models/block/index.ts create mode 100644 hapi-evm/src/models/block/interfaces.ts create mode 100644 hapi-evm/src/models/block/queries.ts create mode 100644 hapi-evm/src/models/default.model.ts create mode 100644 hapi-evm/src/models/gas/index.ts create mode 100644 hapi-evm/src/models/gas/interfaces.ts create mode 100644 hapi-evm/src/models/gas/queries.ts create mode 100644 hapi-evm/src/models/transaction/index.ts create mode 100644 hapi-evm/src/models/transaction/interfaces.ts create mode 100644 hapi-evm/src/models/transaction/queries.ts create mode 100644 hapi-evm/src/services/block.service.ts create mode 100644 hapi-evm/src/services/gas.service.ts create mode 100644 hapi-evm/src/services/worker/index.ts delete mode 100644 hapi-evm/src/utils/wallet.util.ts create mode 100644 hasura/metadata/databases/default/tables/evm_block.yaml create mode 100644 hasura/metadata/databases/default/tables/evm_transaction.yaml create mode 100644 hasura/migrations/default/1689614416757_create_schema_evm/down.sql create mode 100644 hasura/migrations/default/1689614416757_create_schema_evm/up.sql create mode 100644 hasura/migrations/default/1689614424151_create_table_evm_block/down.sql create mode 100644 hasura/migrations/default/1689614424151_create_table_evm_block/up.sql create mode 100644 hasura/migrations/default/1689614988390_alter_table_evm_block_alter_column_gasUsed/down.sql create mode 100644 hasura/migrations/default/1689614988390_alter_table_evm_block_alter_column_gasUsed/up.sql create mode 100644 hasura/migrations/default/1689615011869_alter_table_evm_block_add_unique_number/down.sql create mode 100644 hasura/migrations/default/1689615011869_alter_table_evm_block_add_unique_number/up.sql create mode 100644 hasura/migrations/default/1689615116520_create_table_evm_transaction/down.sql create mode 100644 hasura/migrations/default/1689615116520_create_table_evm_transaction/up.sql create mode 100644 hasura/migrations/default/1689615410384_alter_table_evm_block_add_unique_number_hash/down.sql create mode 100644 hasura/migrations/default/1689615410384_alter_table_evm_block_add_unique_number_hash/up.sql create mode 100644 hasura/migrations/default/1689615432215_set_fk_evm_transaction_block_number_block_hash/down.sql create mode 100644 hasura/migrations/default/1689615432215_set_fk_evm_transaction_block_number_block_hash/up.sql diff --git a/.env.telos b/.env.telos index 4ee36893..3d717acf 100644 --- a/.env.telos +++ b/.env.telos @@ -58,11 +58,13 @@ HAPI_CREATE_ACCOUNT_ACTION_NAME= # hapi-evm HAPI_EVM_SERVER_PORT=9090 HAPI_EVM_SERVER_ADDRESS=hapi-evm +HAPI_EVM_ENDPOINT=https://testnet.telos.net/evm HAPI_EVM_API_ENDPOINTS=["https://telos.greymass.com","https://telos.eosphere.io","telos.caleos.io","mainnet.telosusa.io"] HAPI_EVM_NETWORK_CHAIN_ID=4667b205c6838ef70ff7988f6e8257e8be0e1284a2f59699054a018f743b1d11 HAPI_EVM_EOS_EVM_ACCOUNT=eosio.evm -HAPI_EVM_HASURA_URL=http://hasura:8080/v1/graphql +HAPI_EVM_HASURA_URL=http://hasura:8080/v1/graphql/evm HAPI_EVM_HASURA_ADMIN_SECRET=myadminsecretkey +HAPI_BLOCK_INTERVAL_SEC=0.3 #webapp PORT=3000 diff --git a/docker-compose.yaml b/docker-compose.yaml index db521591..01686599 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -86,11 +86,13 @@ services: environment: HAPI_EVM_SERVER_PORT: '${HAPI_EVM_SERVER_PORT}' HAPI_EVM_SERVER_ADDRESS: '${HAPI_EVM_SERVER_ADDRESS}' + HAPI_EVM_ENDPOINT: '${HAPI_EVM_ENDPOINT}' HAPI_EVM_API_ENDPOINTS: '${HAPI_EVM_API_ENDPOINTS}' HAPI_EVM_NETWORK_CHAIN_ID: '${HAPI_EVM_NETWORK_CHAIN_ID}' HAPI_EVM_EOS_EVM_ACCOUNT: '${HAPI_EVM_EOS_EVM_ACCOUNT}' HAPI_EVM_HASURA_URL: '${HAPI_EVM_HASURA_URL}' HAPI_EVM_HASURA_ADMIN_SECRET: '${HAPI_EVM_HASURA_ADMIN_SECRET}' + HAPI_BLOCK_INTERVAL_SEC: '${HAPI_BLOCK_INTERVAL_SEC}' hasura: container_name: '${STAGE}-${APP_NAME}-hasura' image: hasura/graphql-engine:v2.16.0.cli-migrations-v3 diff --git a/hapi-evm/package.json b/hapi-evm/package.json index be82bf1a..e0f1340a 100644 --- a/hapi-evm/package.json +++ b/hapi-evm/package.json @@ -20,13 +20,16 @@ "dependencies": { "@hapi/boom": "^10.0.1", "@hapi/hapi": "^21.3.2", + "@types/web3": "^1.2.2", "axios": "^1.4.0", "eosjs": "^22.1.0", "eosjs-api": "^7.0.4", "graphql": "16", "graphql-request": "^6.0.0", "joi": "^17.9.2", - "node-fetch": "^3.3.1" + "node-fetch": "^3.3.1", + "web3": "^4.0.3", + "websocket": "^1.0.34" }, "devDependencies": { "@types/node": "^20.1.5", diff --git a/hapi-evm/src/cache/index.ts b/hapi-evm/src/cache/index.ts new file mode 100644 index 00000000..e69de29b diff --git a/hapi-evm/src/cache/v1/index.ts b/hapi-evm/src/cache/v1/index.ts new file mode 100644 index 00000000..e69de29b diff --git a/hapi-evm/src/config/eos.config.ts b/hapi-evm/src/config/eos.config.ts deleted file mode 100644 index 4f99af81..00000000 --- a/hapi-evm/src/config/eos.config.ts +++ /dev/null @@ -1,8 +0,0 @@ -export const endpoint = process.env.HAPI_NETWORK_API || 'http://localhost:8888' -export const chainId = process.env.HAPI_NETWORK_CHAIN_ID || 'chainid1' -export const baseAccount = - process.env.HAPI_NETWORK_BASE_ACCOUNT || 'accountname1' -export const baseAccountPassword = - process.env.HAPI_NETWORK_BASE_PASSWORD || 'PW...' -export const walletUrl = - process.env.HAPI_NETWORK_WALLET_URL || 'http://localhost:8888' diff --git a/hapi-evm/src/config/index.ts b/hapi-evm/src/config/index.ts index a237a2f7..cf916619 100644 --- a/hapi-evm/src/config/index.ts +++ b/hapi-evm/src/config/index.ts @@ -1,3 +1,3 @@ export * as serverConfig from './server.config' export * as hasuraConfig from './hasura.config' -export * as eosConfig from './eos.config' +export * as networkConfig from './network.config' diff --git a/hapi-evm/src/config/network.config.ts b/hapi-evm/src/config/network.config.ts new file mode 100644 index 00000000..f056ae73 --- /dev/null +++ b/hapi-evm/src/config/network.config.ts @@ -0,0 +1,9 @@ +export const evmEndpoint = + process.env.HAPI_EVM_ENDPOINT || 'http://localhost/evm' +export const chainId = process.env.HAPI_NETWORK_CHAIN_ID || 'chainid1' +export const evmAccount = process.env.HAPI_EVM_EOS_EVM_ACCOUNT || 'eosio.evm' +export const eosEndpoints = + process.env.HAPI_EVM_EOS_EVM_ACCOUNT?.split(',') || [] +export const blockIntervalSec = parseFloat( + process.env.HAPI_BLOCK_INTERVAL_SEC || '0.5' +) diff --git a/hapi-evm/src/index.ts b/hapi-evm/src/index.ts index 7739e214..51a2d106 100644 --- a/hapi-evm/src/index.ts +++ b/hapi-evm/src/index.ts @@ -3,6 +3,7 @@ import { Server } from '@hapi/hapi' import routes from './routes' import { serverConfig } from './config' +import workerService from './services/worker' const init = async () => { const server: Server = Hapi.server({ @@ -18,6 +19,8 @@ const init = async () => { await server.start() + workerService.init() + console.log(`🚀 Server ready at ${server.info.uri}`) server.table().forEach(route => console.log(`${route.method}\t${route.path}`)) } diff --git a/hapi-evm/src/models/block/index.ts b/hapi-evm/src/models/block/index.ts new file mode 100644 index 00000000..5e08e0f1 --- /dev/null +++ b/hapi-evm/src/models/block/index.ts @@ -0,0 +1,2 @@ +export * as interfaces from './interfaces' +export * as queries from './queries' diff --git a/hapi-evm/src/models/block/interfaces.ts b/hapi-evm/src/models/block/interfaces.ts new file mode 100644 index 00000000..46b4d811 --- /dev/null +++ b/hapi-evm/src/models/block/interfaces.ts @@ -0,0 +1,9 @@ +import { TransactionHash, TransactionInfo } from 'web3-types' + +export interface CappedBlock { + hash: string + gas_used: number + transactions: TransactionHash[] | TransactionInfo[] + number: number + timestamp: Date +} diff --git a/hapi-evm/src/models/block/queries.ts b/hapi-evm/src/models/block/queries.ts new file mode 100644 index 00000000..367ceec5 --- /dev/null +++ b/hapi-evm/src/models/block/queries.ts @@ -0,0 +1,92 @@ +import { gql } from 'graphql-request' + +import { coreUtil } from '../../utils' +import { OperationType, TableType, Operation } from '../default.model' +import { CappedBlock } from './interfaces' + +interface BlockAggregateResponse { + evm_block_aggregate: { + aggregate: { + count: number + } + } +} + +interface BlockResponse { + evm_block: CappedBlock[] +} + +interface BlockInsertOneResponse { + insert_evm_block_one: { + hash: string + } +} + +const internal_get = async ( + type: OperationType = Operation.query, + table: TableType, + parameters: string, + // TODO: not only accept where but also additional content + // such as limit, order, etc + where: object, + attributes: string, + operation?: string +): Promise => { + const query = gql` + ${type} (${parameters}) { + ${table}${operation ? `_${operation}` : ''}(where: $where) { + ${attributes} + } + } + ` + + return await coreUtil.hasura.default.request(query, { + where + }) +} + +export const exist = async (hash: string) => { + const result = await internal_get( + 'query', + 'evm_block', + '$where: evm_block_bool_exp!', + { hash: { _eq: hash } }, + 'aggregate { count }', + 'aggregate' + ) + + return result.evm_block_aggregate.aggregate.count > 0 +} + +const get = async (where: object, many = false) => { + const result = await internal_get( + 'query', + 'evm_block', + '$where: evm_block_bool_exp!', + where, + 'hash, gas_used, transactions, number, timestamp' + ) + + return many ? result.evm_block : result.evm_block[0] +} + +export const add_or_modify = async (block: CappedBlock) => { + const mutation = gql` + mutation ($evm_block: evm_block_insert_input!) { + insert_evm_block_one(object: $evm_block) { + hash + } + } + ` + const { insert_evm_block_one: data } = + await coreUtil.hasura.default.request(mutation, { + evm_block: block + }) + + return data +} + +export default { + exist, + get +} diff --git a/hapi-evm/src/models/default.model.ts b/hapi-evm/src/models/default.model.ts new file mode 100644 index 00000000..26922425 --- /dev/null +++ b/hapi-evm/src/models/default.model.ts @@ -0,0 +1,20 @@ +export const Operation = { + query: 'query', + mutation: 'mutation', + subscription: 'subscription' +} as const + +export type OperationType = keyof typeof Operation + +export const Tables = { + evm_block: 'evm_block', + evm_transaction: 'evm_transaction' +} as const + +export type TableType = keyof typeof Tables + +export interface Worker { + name: string + intervalSec: number + action: () => Promise +} diff --git a/hapi-evm/src/models/gas/index.ts b/hapi-evm/src/models/gas/index.ts new file mode 100644 index 00000000..5e08e0f1 --- /dev/null +++ b/hapi-evm/src/models/gas/index.ts @@ -0,0 +1,2 @@ +export * as interfaces from './interfaces' +export * as queries from './queries' diff --git a/hapi-evm/src/models/gas/interfaces.ts b/hapi-evm/src/models/gas/interfaces.ts new file mode 100644 index 00000000..344c070b --- /dev/null +++ b/hapi-evm/src/models/gas/interfaces.ts @@ -0,0 +1,3 @@ +export interface I { + +} \ No newline at end of file diff --git a/hapi-evm/src/models/gas/queries.ts b/hapi-evm/src/models/gas/queries.ts new file mode 100644 index 00000000..b1c6ea43 --- /dev/null +++ b/hapi-evm/src/models/gas/queries.ts @@ -0,0 +1 @@ +export default {} diff --git a/hapi-evm/src/models/index.ts b/hapi-evm/src/models/index.ts index e69de29b..86b6f80f 100644 --- a/hapi-evm/src/models/index.ts +++ b/hapi-evm/src/models/index.ts @@ -0,0 +1,4 @@ +export * as gasModel from './gas' +export * as blockModel from './block' +export * as transactionModel from './transaction' +export * as defaultModel from './default.model' diff --git a/hapi-evm/src/models/transaction/index.ts b/hapi-evm/src/models/transaction/index.ts new file mode 100644 index 00000000..5e08e0f1 --- /dev/null +++ b/hapi-evm/src/models/transaction/index.ts @@ -0,0 +1,2 @@ +export * as interfaces from './interfaces' +export * as queries from './queries' diff --git a/hapi-evm/src/models/transaction/interfaces.ts b/hapi-evm/src/models/transaction/interfaces.ts new file mode 100644 index 00000000..a353326f --- /dev/null +++ b/hapi-evm/src/models/transaction/interfaces.ts @@ -0,0 +1,9 @@ +import { TransactionHash, Address } from 'web3-types' + +export interface CappedTransaction { + block_hash: Address + block_number: number + gas: number + gas_price: number + hash: TransactionHash +} diff --git a/hapi-evm/src/models/transaction/queries.ts b/hapi-evm/src/models/transaction/queries.ts new file mode 100644 index 00000000..a5ba8686 --- /dev/null +++ b/hapi-evm/src/models/transaction/queries.ts @@ -0,0 +1,97 @@ +import { gql } from 'graphql-request' + +import { coreUtil } from '../../utils' +import { OperationType, TableType, Operation } from '../default.model' + +import { CappedTransaction } from './interfaces' + +interface TransactionResponse { + evm_transaction: CappedTransaction[] +} + +interface TransactionAggregateResponse { + evm_transaction_aggregate: { + aggregate: { + count: number + } + } +} + +interface TransactionInsertOneResponse { + insert_evm_transaction_one: { + hash: string + } +} + +const internal_get = async ( + type: OperationType = Operation.query, + table: TableType, + parameters: string, + // TODO: not only accept where but also additional content + // such as limit, order, etc + where: object, + attributes: string, + operation?: string +): Promise => { + const gqlObj = gql` + ${type} (${parameters}) { + ${table}${operation ? `_${operation}` : ''}(where: $where) { + ${attributes} + } + } + ` + + return await coreUtil.hasura.default.request(gqlObj, { + where + }) +} + +export const exist = async (hash: string) => { + const result = await internal_get( + Operation.query, + 'evm_transaction', + '$where: evm_transaction_bool_exp!', + { hash: { _eq: hash } }, + 'aggregate { count }', + 'aggregate' + ) + + return result.evm_transaction_aggregate.aggregate.count > 0 +} + +const get = async (where: object, many = false) => { + const result = await internal_get( + 'query', + 'evm_transaction', + '$where: evm_transaction_bool_exp!', + where, + 'hash, gas_used, transactions, number, timestamp' + ) + + return many ? result.evm_transaction : result.evm_transaction[0] +} + +export const add_or_modify = async (transaction: CappedTransaction) => { + const mutation = gql` + mutation ($evm_transaction: evm_transaction_insert_input!) { + insert_evm_transaction_one(object: $evm_transaction) { + hash + } + } + ` + const { insert_evm_transaction_one: data } = + await coreUtil.hasura.default.request( + mutation, + { + evm_transaction: transaction + } + ) + + return data +} + +export default { + exist, + get, + add_or_modify +} diff --git a/hapi-evm/src/routes/v1/index.ts b/hapi-evm/src/routes/v1/index.ts index ad108971..134ce4f5 100644 --- a/hapi-evm/src/routes/v1/index.ts +++ b/hapi-evm/src/routes/v1/index.ts @@ -4,6 +4,30 @@ import { Server } from '@hapi/hapi' const baseRoute = '/v1' +// tables +// evm-params +// - max blocks +// - last block synced +// - sync blocks interval +// - update stats interval (in case of a table that stores the metricts of the last certain blocks) + +// evm-blocks +// - block number +// - block hash + +// evm-transactions +// - block number +// - transaction hash + +// evm-global +// - last block number +// - ATH + +// Average gas usage: Show to average gas usage in the last 100 blocks. +// Average transactions per second (block and eosio.token -> ERC20). +// Daily transactions. +// ATH. + export default (server: Server) => { // exampleRoutes.routes(server, baseRoute) } diff --git a/hapi-evm/src/services/block.service.ts b/hapi-evm/src/services/block.service.ts new file mode 100644 index 00000000..5e5de0bc --- /dev/null +++ b/hapi-evm/src/services/block.service.ts @@ -0,0 +1,98 @@ +import { Web3 } from 'web3' +import { Block, TransactionInfo, TransactionHash } from 'web3-types' + +import { defaultModel, blockModel, transactionModel } from '../models' +import { networkConfig } from '../config' + +const httpProvider = new Web3.providers.HttpProvider(networkConfig.evmEndpoint) +const web3 = new Web3(httpProvider) + +// const test = async () => { +// const tempBlock: Block = await web3.eth.getBlock(246383575) +// console.log('🚀 ~ tempBlock:', tempBlock) + +// const trx: TransactionInfo = await web3.eth.getTransaction( +// '0x4b00d79018d46210b31829285541ae72653e03229a9cff67f362416e5a1c274c' +// ) +// console.log('🚀 ~ trx:', trx) +// console.log('🚀 ~ gas:', Number(trx.gas)) +// } + +// test() + +const getBlock = async () => { + const blockNumber = await web3.eth.getBlockNumber() + const block: Block = await web3.eth.getBlock(blockNumber) + + if (!block.hash) { + throw new Error('Wrong block format') + } + + const blockExist = await blockModel.queries.exist(block.hash.toString()) + console.log(`🚀 ~ blockExist(${block.hash.toString()}): ${blockExist}`) + + if (blockExist) return + + const cappedBlock = { + hash: block.hash.toString(), + gas_used: Number(block.gasUsed), + transactions: (block.transactions || []) as TransactionHash[], + number: Number(block.number), + timestamp: new Date(Number(block.timestamp) * 1000) + } + + await blockModel.queries.add_or_modify(cappedBlock) + + // TODO: review this logic + + const transactionsPromises = [ + cappedBlock.transactions.reduce( + async ( + acc: Promise, + trxHash: TransactionHash + ): Promise => { + const transactionExist = await transactionModel.queries.exist(trxHash) + console.log('🚀 ~ getBlock ~ transactionExist:', transactionExist) + + if (transactionExist) { + return acc + } + + const trx: TransactionInfo = await web3.eth.getTransaction( + trxHash.toString() + ) + + const customTrx: transactionModel.interfaces.CappedTransaction = { + block_hash: trx.blockHash!.toString(), + block_number: Number(trx.blockNumber), + gas: Number(trx.gas), + gas_price: Number(trx.gasPrice), + hash: trx.hash.toString() + } + + await transactionModel.queries.add_or_modify(customTrx) + + return [...(await acc), customTrx] + }, + Promise.resolve([]) + ) + ] + + await Promise.all(transactionsPromises) +} + +const blockWorker = async () => { + getBlock() +} + +const syncBlockWorker = (): defaultModel.Worker => { + return { + name: 'SYNC BLOCK WORKER', + intervalSec: networkConfig.blockIntervalSec, + action: blockWorker + } +} + +export default { + syncBlockWorker +} diff --git a/hapi-evm/src/services/gas.service.ts b/hapi-evm/src/services/gas.service.ts new file mode 100644 index 00000000..81ffcb11 --- /dev/null +++ b/hapi-evm/src/services/gas.service.ts @@ -0,0 +1,3 @@ +import {hasura} from '../utils/core'; + + diff --git a/hapi-evm/src/services/worker/index.ts b/hapi-evm/src/services/worker/index.ts new file mode 100644 index 00000000..f23460ff --- /dev/null +++ b/hapi-evm/src/services/worker/index.ts @@ -0,0 +1,28 @@ +import { timeUtil, coreUtil } from '../../utils' +import { defaultModel } from '../../models' +import blockService from '../block.service' + +const run = async (worker: defaultModel.Worker) => { + try { + await worker.action() + } catch (error: any) { + console.log(`${name} ERROR =>`, error.message) + } + + if (!worker.intervalSec) { + return + } + + await timeUtil.sleep(worker.intervalSec) + run(worker) +} + +const init = async () => { + await coreUtil.hasura.hasuraAssembled() + + run(blockService.syncBlockWorker()) +} + +export default { + init +} diff --git a/hapi-evm/src/utils/index.ts b/hapi-evm/src/utils/index.ts index 7874a180..e2c85405 100644 --- a/hapi-evm/src/utils/index.ts +++ b/hapi-evm/src/utils/index.ts @@ -1,3 +1,2 @@ export * as coreUtil from './core' export * as timeUtil from './time.util' -export * as walletUtil from './wallet.util' diff --git a/hapi-evm/src/utils/wallet.util.ts b/hapi-evm/src/utils/wallet.util.ts deleted file mode 100644 index df63f7b8..00000000 --- a/hapi-evm/src/utils/wallet.util.ts +++ /dev/null @@ -1,60 +0,0 @@ -import fetch from 'node-fetch' - -import { eosConfig } from '../config' - -const post = async (endpoint: string, body: any = {}) => { - const res = await fetch(`${eosConfig.walletUrl}/v1/wallet${endpoint}`, { - body, - method: 'POST' - }) - const data: any = await res.json() - - if (data.code) { - throw new Error(`${data.error.name}: ${data.error.what}`) - } - - return data -} - -const create = async (walletName: string) => post('/create', `"${walletName}"`) - -const createKey = async (walletName: string) => - post('/create_key', `["${walletName}",""]`) - -// TODO: implement get_public_keys -// TODO: implement import_key - -const listKeys = async (walletName: string, walletPassword: string) => { - const keys = await post('/list_keys', `["${walletName}","${walletPassword}"]`) - - if (keys.length > 0) { - return keys.map((keypair: string[]) => keypair[1]) - } - - return [] -} - -const listWallets = async () => post('/list_wallets') - -const lock = async (walletName: string) => post('/lock', `"${walletName}"`) - -const lockAll = async () => post('/lock_all', {}) - -// TODO: implement open -// TODO: implement remove_key -// TODO: implement set_timeout -// TODO: implement sign_digest -// TODO: implement sign_transaction - -const unlock = async (walletName: string, walletPassword: string) => - post('/unlock', `["${walletName}","${walletPassword}"]`) - -export default { - create, - createKey, - listKeys, - listWallets, - lock, - lockAll, - unlock -} diff --git a/hapi-evm/tsconfig.json b/hapi-evm/tsconfig.json index 49c29d1e..0218363e 100644 --- a/hapi-evm/tsconfig.json +++ b/hapi-evm/tsconfig.json @@ -5,7 +5,7 @@ /* Projects */ /* Language and Environment */ - "target": "es2016" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, + "target": "es2017" /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */, /* Modules */ "module": "commonjs" /* Specify what module code is generated. */, diff --git a/hapi-evm/yarn.lock b/hapi-evm/yarn.lock index 2e2ecaa1..2bff766c 100644 --- a/hapi-evm/yarn.lock +++ b/hapi-evm/yarn.lock @@ -7,6 +7,11 @@ resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== +"@adraffy/ens-normalize@^1.8.8": + version "1.9.2" + resolved "https://registry.yarnpkg.com/@adraffy/ens-normalize/-/ens-normalize-1.9.2.tgz#60111a5d9db45b2e5cbb6231b0bb8d97e8659316" + integrity sha512-0h+FrQDqe2Wn+IIGFkTCd4aAwTJ+7834Ek1COohCyV26AXhwQ7WQaz+4F/nLOeVl/3BtWHOHLPsq46V8YB46Eg== + "@cspotcode/source-map-support@^0.8.0": version "0.8.1" resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" @@ -46,6 +51,188 @@ resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.44.0.tgz#961a5903c74139390478bdc808bcde3fc45ab7af" integrity sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw== +"@ethereumjs/rlp@^4.0.1": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@ethereumjs/rlp/-/rlp-4.0.1.tgz#626fabfd9081baab3d0a3074b0c7ecaf674aaa41" + integrity sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw== + +"@ethersproject/abi@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.7.0.tgz#b3f3e045bbbeed1af3947335c247ad625a44e449" + integrity sha512-351ktp42TiRcYB3H1OP8yajPeAQstMW/yCFokj/AthP9bLHzQFPlOrxOcwYEDkUAICmOHljvN4K39OMTMUa9RA== + dependencies: + "@ethersproject/address" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/constants" "^5.7.0" + "@ethersproject/hash" "^5.7.0" + "@ethersproject/keccak256" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + +"@ethersproject/abstract-provider@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.7.0.tgz#b0a8550f88b6bf9d51f90e4795d48294630cb9ef" + integrity sha512-R41c9UkchKCpAqStMYUpdunjo3pkEvZC3FAwZn5S5MGbXoMQOHIdHItezTETxAO5bevtMApSyEhn9+CHcDsWBw== + dependencies: + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/networks" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/transactions" "^5.7.0" + "@ethersproject/web" "^5.7.0" + +"@ethersproject/abstract-signer@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.7.0.tgz#13f4f32117868452191a4649723cb086d2b596b2" + integrity sha512-a16V8bq1/Cz+TGCkE2OPMTOUDLS3grCpdjoJCYNnVBbdYEMSgKrU0+B90s8b6H+ByYTBZN7a3g76jdIJi7UfKQ== + dependencies: + "@ethersproject/abstract-provider" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + +"@ethersproject/address@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.7.0.tgz#19b56c4d74a3b0a46bfdbb6cfcc0a153fc697f37" + integrity sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA== + dependencies: + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/keccak256" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/rlp" "^5.7.0" + +"@ethersproject/base64@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.7.0.tgz#ac4ee92aa36c1628173e221d0d01f53692059e1c" + integrity sha512-Dr8tcHt2mEbsZr/mwTPIQAf3Ai0Bks/7gTw9dSqk1mQvhW3XvRlmDJr/4n+wg1JmCl16NZue17CDh8xb/vZ0sQ== + dependencies: + "@ethersproject/bytes" "^5.7.0" + +"@ethersproject/bignumber@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.7.0.tgz#e2f03837f268ba655ffba03a57853e18a18dc9c2" + integrity sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + bn.js "^5.2.1" + +"@ethersproject/bytes@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.7.0.tgz#a00f6ea8d7e7534d6d87f47188af1148d71f155d" + integrity sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A== + dependencies: + "@ethersproject/logger" "^5.7.0" + +"@ethersproject/constants@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.7.0.tgz#df80a9705a7e08984161f09014ea012d1c75295e" + integrity sha512-DHI+y5dBNvkpYUMiRQyxRBYBefZkJfo70VUkUAsRjcPs47muV9evftfZ0PJVCXYbAiCgght0DtcF9srFQmIgWA== + dependencies: + "@ethersproject/bignumber" "^5.7.0" + +"@ethersproject/hash@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.7.0.tgz#eb7aca84a588508369562e16e514b539ba5240a7" + integrity sha512-qX5WrQfnah1EFnO5zJv1v46a8HW0+E5xuBBDTwMFZLuVTx0tbU2kkx15NqdjxecrLGatQN9FGQKpb1FKdHCt+g== + dependencies: + "@ethersproject/abstract-signer" "^5.7.0" + "@ethersproject/address" "^5.7.0" + "@ethersproject/base64" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/keccak256" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + +"@ethersproject/keccak256@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.7.0.tgz#3186350c6e1cd6aba7940384ec7d6d9db01f335a" + integrity sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg== + dependencies: + "@ethersproject/bytes" "^5.7.0" + js-sha3 "0.8.0" + +"@ethersproject/logger@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.7.0.tgz#6ce9ae168e74fecf287be17062b590852c311892" + integrity sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig== + +"@ethersproject/networks@^5.7.0": + version "5.7.1" + resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.7.1.tgz#118e1a981d757d45ccea6bb58d9fd3d9db14ead6" + integrity sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ== + dependencies: + "@ethersproject/logger" "^5.7.0" + +"@ethersproject/properties@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.7.0.tgz#a6e12cb0439b878aaf470f1902a176033067ed30" + integrity sha512-J87jy8suntrAkIZtecpxEPxY//szqr1mlBaYlQ0r4RCaiD2hjheqF9s1LVE8vVuJCXisjIP+JgtK/Do54ej4Sw== + dependencies: + "@ethersproject/logger" "^5.7.0" + +"@ethersproject/rlp@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.7.0.tgz#de39e4d5918b9d74d46de93af80b7685a9c21304" + integrity sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + +"@ethersproject/signing-key@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.7.0.tgz#06b2df39411b00bc57c7c09b01d1e41cf1b16ab3" + integrity sha512-MZdy2nL3wO0u7gkB4nA/pEf8lu1TlFswPNmy8AiYkfKTdO6eXBJyUdmHO/ehm/htHw9K/qF8ujnTyUAD+Ry54Q== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + bn.js "^5.2.1" + elliptic "6.5.4" + hash.js "1.1.7" + +"@ethersproject/strings@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.7.0.tgz#54c9d2a7c57ae8f1205c88a9d3a56471e14d5ed2" + integrity sha512-/9nu+lj0YswRNSH0NXYqrh8775XNyEdUQAuf3f+SmOrnVewcJ5SBNAjF7lpgehKi4abvNNXyf+HX86czCdJ8Mg== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/constants" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + +"@ethersproject/transactions@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.7.0.tgz#91318fc24063e057885a6af13fdb703e1f993d3b" + integrity sha512-kmcNicCp1lp8qanMTC3RIikGgoJ80ztTyvtsFvCYpSCfkjhD0jZ2LOrnbcuxuToLIUYYf+4XwD1rP+B/erDIhQ== + dependencies: + "@ethersproject/address" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/constants" "^5.7.0" + "@ethersproject/keccak256" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/rlp" "^5.7.0" + "@ethersproject/signing-key" "^5.7.0" + +"@ethersproject/web@^5.7.0": + version "5.7.1" + resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.7.1.tgz#de1f285b373149bee5928f4eb7bcb87ee5fbb4ae" + integrity sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w== + dependencies: + "@ethersproject/base64" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/properties" "^5.7.0" + "@ethersproject/strings" "^5.7.0" + "@graphql-typed-document-node/core@^3.2.0": version "3.2.0" resolved "https://registry.yarnpkg.com/@graphql-typed-document-node/core/-/core-3.2.0.tgz#5f3d96ec6b2354ad6d8a28bf216a1d97b5426861" @@ -350,6 +537,18 @@ "@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/sourcemap-codec" "^1.4.10" +"@noble/curves@1.1.0", "@noble/curves@~1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@noble/curves/-/curves-1.1.0.tgz#f13fc667c89184bc04cccb9b11e8e7bae27d8c3d" + integrity sha512-091oBExgENk/kGj3AZmtBDMpxQPDtxQABR2B9lb1JbVTs6ytdzZNwvhxQ4MWasRNEzlbEH8jCWFCwhF/Obj5AA== + dependencies: + "@noble/hashes" "1.3.1" + +"@noble/hashes@1.3.1", "@noble/hashes@~1.3.0", "@noble/hashes@~1.3.1": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.1.tgz#8831ef002114670c603c458ab8b11328406953a9" + integrity sha512-EbqwksQwz9xDRGfDST86whPBgM65E0OH/pCgqW0GBVzO22bNE+NuIbeTb714+IfSjU3aRk47EUvXIb5bTsenKA== + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -383,6 +582,28 @@ picocolors "^1.0.0" tslib "^2.6.0" +"@scure/base@~1.1.0": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@scure/base/-/base-1.1.1.tgz#ebb651ee52ff84f420097055f4bf46cfba403938" + integrity sha512-ZxOhsSyxYwLJj3pLZCefNitxsj093tb2vq90mp2txoYeBqbcjDjqFhyM8eUjq/uFm6zJ+mUuqxlS2FkuSY1MTA== + +"@scure/bip32@1.3.1": + version "1.3.1" + resolved "https://registry.yarnpkg.com/@scure/bip32/-/bip32-1.3.1.tgz#7248aea723667f98160f593d621c47e208ccbb10" + integrity sha512-osvveYtyzdEVbt3OfwwXFr4P2iVBL5u1Q3q4ONBfDY/UpOuXmOlbgwc1xECEboY8wIays8Yt6onaWMUdUbfl0A== + dependencies: + "@noble/curves" "~1.1.0" + "@noble/hashes" "~1.3.1" + "@scure/base" "~1.1.0" + +"@scure/bip39@1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@scure/bip39/-/bip39-1.2.1.tgz#5cee8978656b272a917b7871c981e0541ad6ac2a" + integrity sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg== + dependencies: + "@noble/hashes" "~1.3.0" + "@scure/base" "~1.1.0" + "@sideway/address@^4.1.3": version "4.1.4" resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.4.tgz#03dccebc6ea47fdc226f7d3d1ad512955d4783f0" @@ -425,7 +646,7 @@ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.12.tgz#d70faba7039d5fca54c83c7dbab41051d2b6f6cb" integrity sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA== -"@types/node@^20.1.5": +"@types/node@*", "@types/node@^20.1.5": version "20.4.2" resolved "https://registry.yarnpkg.com/@types/node/-/node-20.4.2.tgz#129cc9ae69f93824f92fac653eebfb4812ab4af9" integrity sha512-Dd0BYtWgnWJKwO1jkmTrzofjK2QXXcai0dmtzvIBhcA+RsG5h8R3xlyta0kGOZRNfL9GuRtb1knmPEhQrePCEw== @@ -435,6 +656,20 @@ resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.0.tgz#591c1ce3a702c45ee15f47a42ade72c2fd78978a" integrity sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw== +"@types/web3@^1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@types/web3/-/web3-1.2.2.tgz#d95a101547ce625c5ebd0470baa5dbd4b9f3c015" + integrity sha512-eFiYJKggNrOl0nsD+9cMh2MLk4zVBfXfGnVeRFbpiZzBE20eet4KLA3fXcjSuHaBn0RnQzwLAGdgzgzdet4C0A== + dependencies: + web3 "*" + +"@types/ws@^8.5.3": + version "8.5.5" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.5.tgz#af587964aa06682702ee6dcbc7be41a80e4b28eb" + integrity sha512-lwhs8hktwxSjf9UaZ9tG5M03PGogvFaH8gUgLNbN9HKIg0dvv6q+gkSuJ8HN4/VbyxkuLzCjlN7GquQ0gUJfIg== + dependencies: + "@types/node" "*" + "@typescript-eslint/eslint-plugin@^6.0.0": version "6.0.0" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.0.0.tgz#19ff4f1cab8d6f8c2c1825150f7a840bc5d9bdc4" @@ -623,6 +858,11 @@ asynckit@^0.4.0: resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== +available-typed-arrays@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" + integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== + axios@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/axios/-/axios-1.4.0.tgz#38a7bf1224cd308de271146038b551d725f0be1f" @@ -657,6 +897,11 @@ bn.js@^4.11.9: resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== +bn.js@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" + integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== + bplist-parser@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/bplist-parser/-/bplist-parser-0.2.0.tgz#43a9d183e5bf9d545200ceac3e712f79ebbe8d0e" @@ -684,6 +929,13 @@ brorand@^1.1.0: resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== +bufferutil@^4.0.1: + version "4.0.7" + resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.7.tgz#60c0d19ba2c992dd8273d3f73772ffc894c153ad" + integrity sha512-kukuqc39WOHtdxtw4UScxF/WVnMFVSQVKhtx3AjZJzhd0RGZZldcrfSEbVsWWe6KNH253574cq5F+wpv0G9pJw== + dependencies: + node-gyp-build "^4.3.0" + bundle-name@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/bundle-name/-/bundle-name-3.0.0.tgz#ba59bcc9ac785fb67ccdbf104a2bf60c099f0e1a" @@ -691,6 +943,14 @@ bundle-name@^3.0.0: dependencies: run-applescript "^5.0.0" +call-bind@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" + integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== + dependencies: + function-bind "^1.1.1" + get-intrinsic "^1.0.2" + callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" @@ -794,6 +1054,11 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== +crc-32@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/crc-32/-/crc-32-1.2.2.tgz#3cad35a934b8bf71f25ca524b6da51fb7eace2ff" + integrity sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ== + create-require@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" @@ -815,11 +1080,26 @@ cross-spawn@^7.0.2, cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" +d@1, d@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" + integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== + dependencies: + es5-ext "^0.10.50" + type "^1.0.1" + data-uri-to-buffer@^4.0.0: version "4.0.1" resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz#d8feb2b2881e6a4f58c2e08acfd0e2834e26222e" integrity sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A== +debug@^2.2.0: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + debug@^3.2.7: version "3.2.7" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" @@ -939,6 +1219,32 @@ eosjs@^22.1.0: hash.js "1.1.7" pako "2.0.3" +es5-ext@^0.10.35, es5-ext@^0.10.50: + version "0.10.62" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.62.tgz#5e6adc19a6da524bf3d1e02bbc8960e5eb49a9a5" + integrity sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA== + dependencies: + es6-iterator "^2.0.3" + es6-symbol "^3.1.3" + next-tick "^1.1.0" + +es6-iterator@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + integrity sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g== + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + +es6-symbol@^3.1.1, es6-symbol@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" + integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== + dependencies: + d "^1.0.1" + ext "^1.1.2" + escape-string-regexp@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" @@ -1059,6 +1365,16 @@ esutils@^2.0.2: resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== +ethereum-cryptography@^2.0.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ethereum-cryptography/-/ethereum-cryptography-2.1.2.tgz#18fa7108622e56481157a5cb7c01c0c6a672eb67" + integrity sha512-Z5Ba0T0ImZ8fqXrJbpHcbpAvIswRte2wGNR/KePnu8GbbvgJ47lMxT/ZZPG6i9Jaht4azPDop4HaM00J0J59ug== + dependencies: + "@noble/curves" "1.1.0" + "@noble/hashes" "1.3.1" + "@scure/bip32" "1.3.1" + "@scure/bip39" "1.2.1" + execa@^5.0.0: version "5.1.1" resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" @@ -1089,6 +1405,13 @@ execa@^7.0.0, execa@^7.1.1: signal-exit "^3.0.7" strip-final-newline "^3.0.0" +ext@^1.1.2: + version "1.7.0" + resolved "https://registry.yarnpkg.com/ext/-/ext-1.7.0.tgz#0ea4383c0103d60e70be99e9a7f11027a33c4f5f" + integrity sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw== + dependencies: + type "^2.7.2" + fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" @@ -1175,6 +1498,13 @@ follow-redirects@^1.15.0: resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== +for-each@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" + integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== + dependencies: + is-callable "^1.1.3" + form-data@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" @@ -1201,6 +1531,35 @@ fsevents@~2.3.2: resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +generate-function@^2.0.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.3.1.tgz#f069617690c10c868e73b8465746764f97c3479f" + integrity sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ== + dependencies: + is-property "^1.0.2" + +generate-object-property@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0" + integrity sha512-TuOwZWgJ2VAMEGJvAyPWvpqxSANF0LDpmyHauMjFYzaACvn+QTT/AZomvPCzVBV7yDN3OmwHQ5OvHaeLKre3JQ== + dependencies: + is-property "^1.0.0" + +get-intrinsic@^1.0.2, get-intrinsic@^1.1.3: + version "1.2.1" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.1.tgz#d295644fed4505fc9cde952c37ee12b477a83d82" + integrity sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-proto "^1.0.1" + has-symbols "^1.0.3" + get-stream@^6.0.0, get-stream@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" @@ -1251,6 +1610,13 @@ globby@^11.1.0: merge2 "^1.4.1" slash "^3.0.0" +gopd@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" + integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== + dependencies: + get-intrinsic "^1.1.3" + grapheme-splitter@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" @@ -1284,6 +1650,30 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== +has-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" + integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== + +has-symbols@^1.0.2, has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + +has-tostringtag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" + integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== + dependencies: + has-symbols "^1.0.2" + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + hash.js@1.1.7, hash.js@^1.0.0, hash.js@^1.0.3: version "1.1.7" resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" @@ -1364,6 +1754,14 @@ inherits@2, inherits@^2.0.3, inherits@^2.0.4: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +is-arguments@^1.0.4: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" + integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + is-binary-path@~2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" @@ -1371,6 +1769,11 @@ is-binary-path@~2.1.0: dependencies: binary-extensions "^2.0.0" +is-callable@^1.1.3: + version "1.2.7" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" + integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== + is-docker@^2.0.0: version "2.2.1" resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" @@ -1396,6 +1799,13 @@ is-fullwidth-code-point@^4.0.0: resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz#fae3167c729e7463f8461ce512b080a49268aa88" integrity sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ== +is-generator-function@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" + integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== + dependencies: + has-tostringtag "^1.0.0" + is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: version "4.0.3" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" @@ -1410,6 +1820,22 @@ is-inside-container@^1.0.0: dependencies: is-docker "^3.0.0" +is-my-ip-valid@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-my-ip-valid/-/is-my-ip-valid-1.0.1.tgz#f7220d1146257c98672e6fba097a9f3f2d348442" + integrity sha512-jxc8cBcOWbNK2i2aTkCZP6i7wkHF1bqKFrwEHuN5Jtg5BSaZHUZQ/JTOJwoV41YvHnOaRyWWh72T/KvfNz9DJg== + +is-my-json-valid@^2.20.6: + version "2.20.6" + resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.20.6.tgz#a9d89e56a36493c77bda1440d69ae0dc46a08387" + integrity sha512-1JQwulVNjx8UqkPE/bqDaxtH4PXCe/2VRh/y3p99heOV87HG4Id5/VfDswd+YiAfHcRTfDlWgISycnHuhZq1aw== + dependencies: + generate-function "^2.0.0" + generate-object-property "^1.1.0" + is-my-ip-valid "^1.0.0" + jsonpointer "^5.0.0" + xtend "^4.0.0" + is-number@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" @@ -1420,6 +1846,11 @@ is-path-inside@^3.0.3: resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== +is-property@^1.0.0, is-property@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84" + integrity sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g== + is-stream@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" @@ -1435,6 +1866,22 @@ is-stream@^3.0.0: resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-3.0.0.tgz#e6bfd7aa6bef69f4f472ce9bb681e3e57b4319ac" integrity sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA== +is-typed-array@^1.1.10, is-typed-array@^1.1.3: + version "1.1.10" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.10.tgz#36a5b5cb4189b575d1a3e4b08536bfb485801e3f" + integrity sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + for-each "^0.3.3" + gopd "^1.0.1" + has-tostringtag "^1.0.0" + +is-typedarray@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== + is-wsl@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" @@ -1455,6 +1902,11 @@ isomorphic-fetch@^2.2.1: node-fetch "^1.0.1" whatwg-fetch ">=0.10.0" +isomorphic-ws@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz#e5529148912ecb9b451b46ed44d53dae1ce04bbf" + integrity sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw== + joi@^17.9.2: version "17.9.2" resolved "https://registry.yarnpkg.com/joi/-/joi-17.9.2.tgz#8b2e4724188369f55451aebd1d0b1d9482470690" @@ -1466,6 +1918,11 @@ joi@^17.9.2: "@sideway/formula" "^3.0.1" "@sideway/pinpoint" "^2.0.0" +js-sha3@0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" + integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== + js-yaml@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" @@ -1483,6 +1940,11 @@ json-stable-stringify-without-jsonify@^1.0.1: resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== +jsonpointer@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-5.0.1.tgz#2110e0af0900fd37467b5907ecd13a7884a1b559" + integrity sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ== + levn@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" @@ -1625,6 +2087,11 @@ minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: dependencies: brace-expansion "^1.1.7" +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + ms@2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" @@ -1645,6 +2112,11 @@ natural-compare@^1.4.0: resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== +next-tick@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb" + integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ== + no-case@^2.2.0: version "2.3.2" resolved "https://registry.yarnpkg.com/no-case/-/no-case-2.3.2.tgz#60b813396be39b3f1288a4c1ed5d1e7d28b464ac" @@ -1681,6 +2153,11 @@ node-fetch@^3.3.1: fetch-blob "^3.1.4" formdata-polyfill "^4.0.10" +node-gyp-build@^4.3.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.6.0.tgz#0c52e4cbf54bbd28b709820ef7b6a3c2d6209055" + integrity sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ== + nodemon@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-3.0.1.tgz#affe822a2c5f21354466b2fc8ae83277d27dadc7" @@ -1951,6 +2428,11 @@ semver@^7.5.0, semver@^7.5.3: dependencies: lru-cache "^6.0.0" +setimmediate@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== + shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" @@ -2160,6 +2642,23 @@ type-fest@^0.21.3: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== +type@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" + integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== + +type@^2.7.2: + version "2.7.2" + resolved "https://registry.yarnpkg.com/type/-/type-2.7.2.tgz#2376a15a3a28b1efa0f5350dcf72d24df6ef98d0" + integrity sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw== + +typedarray-to-buffer@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== + dependencies: + is-typedarray "^1.0.0" + typescript@^5.0.4: version "5.1.6" resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274" @@ -2187,6 +2686,24 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" +utf-8-validate@^5.0.2: + version "5.0.10" + resolved "https://registry.yarnpkg.com/utf-8-validate/-/utf-8-validate-5.0.10.tgz#d7d10ea39318171ca982718b6b96a8d2442571a2" + integrity sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ== + dependencies: + node-gyp-build "^4.3.0" + +util@^0.12.5: + version "0.12.5" + resolved "https://registry.yarnpkg.com/util/-/util-0.12.5.tgz#5f17a6059b73db61a875668781a1c2b136bd6fbc" + integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA== + dependencies: + inherits "^2.0.3" + is-arguments "^1.0.4" + is-generator-function "^1.0.7" + is-typed-array "^1.1.3" + which-typed-array "^1.1.2" + v8-compile-cache-lib@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" @@ -2197,11 +2714,234 @@ web-streams-polyfill@^3.0.3: resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz#71c2718c52b45fd49dbeee88634b3a60ceab42a6" integrity sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q== +web3-core@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/web3-core/-/web3-core-4.0.3.tgz#eab6cc23a43ff202d8f38bbd9801a7a2ec750cc2" + integrity sha512-KJaH1+ajm/gelvhImkXZx8HrBaGZDERqhOCRpikuwReVDTf4X3TlXqF+oKt153qf5HUXWR4CUL6NkNKNQWjhbA== + dependencies: + web3-errors "^1.0.2" + web3-eth-iban "^4.0.3" + web3-providers-http "^4.0.3" + web3-providers-ws "^4.0.3" + web3-types "^1.0.2" + web3-utils "^4.0.3" + web3-validator "^1.0.2" + optionalDependencies: + web3-providers-ipc "^4.0.3" + +web3-errors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/web3-errors/-/web3-errors-1.0.2.tgz#e8ce6e22dfdfd9aeaf8d7535653e55b094b5accd" + integrity sha512-LtRUASAQKeCKyxHRhfyU5xiE9asUmo7KJ9bEzzaPlkVYLl5lzhUXzd6lvnQfSaSXJnlzoUXvhI5I0Hpzc8Lohg== + dependencies: + web3-types "^1.0.2" + +web3-eth-abi@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/web3-eth-abi/-/web3-eth-abi-4.0.3.tgz#cc06cc39868d8bcc181528aa46ae9d5c80ed93b6" + integrity sha512-is1sKkTna5LQri25iRbxJ43kQ6qlFR/Syi6dnpwsFua0qAyKuDTxLZDoMaBfdH8NvxvjuGWFUWALwuSk8gk5Xg== + dependencies: + "@ethersproject/abi" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + web3-errors "^1.0.2" + web3-types "^1.0.2" + web3-utils "^4.0.3" + +web3-eth-accounts@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/web3-eth-accounts/-/web3-eth-accounts-4.0.3.tgz#7e570b3170aca052b358975235637a94b5313826" + integrity sha512-qS4r25weJYlKzHPIneL3g33LG+I6QkRCs25ZtooK6elurlZY4HyRE04BIWv12xZswtsvdmMt4HysMUNKgLrgPg== + dependencies: + "@ethereumjs/rlp" "^4.0.1" + crc-32 "^1.2.2" + ethereum-cryptography "^2.0.0" + web3-errors "^1.0.2" + web3-types "^1.0.2" + web3-utils "^4.0.3" + web3-validator "^1.0.2" + +web3-eth-contract@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/web3-eth-contract/-/web3-eth-contract-4.0.3.tgz#667e8f8052034f49a9130e0f286976bcf43c5d77" + integrity sha512-x8YsIVVUeONwLCnUmswk5KD3luYxaKuN/xnSzxpb8fE4/KBA6eJswYcIGPrK9QILrVR26yDV/QQpgLU1IJS14g== + dependencies: + web3-core "^4.0.3" + web3-errors "^1.0.2" + web3-eth "^4.0.3" + web3-eth-abi "^4.0.3" + web3-types "^1.0.2" + web3-utils "^4.0.3" + web3-validator "^1.0.2" + +web3-eth-ens@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/web3-eth-ens/-/web3-eth-ens-4.0.3.tgz#9b17bdcdc262ddcb5b9fd0b4893c0a9a56bf07ca" + integrity sha512-1tk1WWJB6lsViRFxHR9kt8qgfMV0cySeNBa8H/bZ9/HZ1G8L/c2cboVrG4D0QsPO1im1jQl4Cf3ceKH0PW1KZg== + dependencies: + "@adraffy/ens-normalize" "^1.8.8" + web3-core "^4.0.3" + web3-errors "^1.0.2" + web3-eth "^4.0.3" + web3-eth-contract "^4.0.3" + web3-net "^4.0.3" + web3-types "^1.0.2" + web3-utils "^4.0.3" + web3-validator "^1.0.2" + +web3-eth-iban@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/web3-eth-iban/-/web3-eth-iban-4.0.3.tgz#3fca87323c00a29f1b3870d397153803eb0bcf4e" + integrity sha512-9gn6fb034fh3DvQeutuhaG3J9+ZSriPC/O/H7K+lgUWJZh/lpaZy5A06nhHzNcleCWC07Q6J7d7VZlNjaBPtOA== + dependencies: + web3-errors "^1.0.2" + web3-types "^1.0.2" + web3-utils "^4.0.3" + web3-validator "^1.0.2" + +web3-eth-personal@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/web3-eth-personal/-/web3-eth-personal-4.0.3.tgz#df4c59bf2a0e07cd6966259d1312be6b5b61846e" + integrity sha512-Gugz45w/D4wlUNbUth8iHWkv0c5fFZGWZqFvpACJul0z9h0Ou8HzuJMUv3U0xFOQJF5fniVegfp6l0FJQ3hGrQ== + dependencies: + web3-core "^4.0.3" + web3-eth "^4.0.3" + web3-rpc-methods "^1.0.2" + web3-types "^1.0.2" + web3-utils "^4.0.3" + web3-validator "^1.0.2" + +web3-eth@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/web3-eth/-/web3-eth-4.0.3.tgz#b7f311eba95151f547ccce285893af9917da9e35" + integrity sha512-4t1+lpqzk3ljubr0CKE9Ila82p2Pim6Bn7ZIruVfMt9AOA5wL6M0OeMTy0fWBODLJiZJ7R77Ugm0kvEVWD3lqg== + dependencies: + setimmediate "^1.0.5" + web3-core "^4.0.3" + web3-errors "^1.0.2" + web3-eth-abi "^4.0.3" + web3-eth-accounts "^4.0.3" + web3-net "^4.0.3" + web3-providers-ws "^4.0.3" + web3-rpc-methods "^1.0.2" + web3-types "^1.0.2" + web3-utils "^4.0.3" + web3-validator "^1.0.2" + +web3-net@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/web3-net/-/web3-net-4.0.3.tgz#9aeed6fa3d48adcf63d8377900acbe3e64020154" + integrity sha512-qe+stvVgYhO8AiPgDykZW5gS4mZ3GRWdQ8xn3eTvderresIMvdZYSAoUla2jWl1CgpcqzaoOSO9Pf8t43fr8SA== + dependencies: + web3-core "^4.0.3" + web3-rpc-methods "^1.0.2" + web3-types "^1.0.2" + web3-utils "^4.0.3" + +web3-providers-http@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/web3-providers-http/-/web3-providers-http-4.0.3.tgz#c6c8364ed56c4183e6bed58de20c1972f513c7ae" + integrity sha512-5E6nKjWrwlJdhGImOxyTnFDT6UcZu4waO6AJrENBRh2vdoCfP/Piiv3PLywHs71gwTMsAjy6CNPL5lZdGf+JQA== + dependencies: + cross-fetch "^3.1.5" + web3-errors "^1.0.2" + web3-types "^1.0.2" + web3-utils "^4.0.3" + +web3-providers-ipc@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/web3-providers-ipc/-/web3-providers-ipc-4.0.3.tgz#d7af699a2afae0f7396d08ef8cc82b5ab4374398" + integrity sha512-v+Ugp5XXUVcAQju/u4ThdjI3FM9lq674F6cJ7yz3R6uTel+wNPDiT47Se8hvm5grgHid7z3MbVYCQpDCiiAFHw== + dependencies: + web3-errors "^1.0.2" + web3-types "^1.0.2" + web3-utils "^4.0.3" + +web3-providers-ws@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/web3-providers-ws/-/web3-providers-ws-4.0.3.tgz#c611a0ae81ac022d8ccb01f71da761f7b4decd85" + integrity sha512-V2bYiMvhv+xBYxFdf8V1zGTwhJoAkBQNMECVGNjQIz1qBKuqu6hXHasmkYSJV780LD6qoL58KlfTggjf4SUSaA== + dependencies: + "@types/ws" "^8.5.3" + isomorphic-ws "^5.0.0" + web3-errors "^1.0.2" + web3-types "^1.0.2" + web3-utils "^4.0.3" + ws "^8.8.1" + +web3-rpc-methods@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/web3-rpc-methods/-/web3-rpc-methods-1.0.2.tgz#3ff35c5d4e38ad31ef3cf77eb3fe2fd08e2a3f4a" + integrity sha512-VhLHvgR62JUNgo0op8hP4LcRkvdF0WaHD9xhcEKGLcri9VfYvR1yTZ3CVh6NTgRCmfDePObbp5blHfbla1cC5Q== + dependencies: + web3-core "^4.0.3" + web3-types "^1.0.2" + web3-validator "^1.0.2" + +web3-types@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/web3-types/-/web3-types-1.0.2.tgz#1655a400d31984153fc26ca1f8960f547ca1f2df" + integrity sha512-tLzA9vevGGWdHlxXvPRJjEIIR0UnZBI5Kq9qiENRS/vSekTHAHp7u+WGDxt+6kP105gKlbep50TogQIvJqLfnA== + +web3-utils@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/web3-utils/-/web3-utils-4.0.3.tgz#80c077e56c0841528ea4513c67d83e460217b379" + integrity sha512-clBvm/vWR2mAc9nPnsPYBZMikIhVG9RAsXdrxvXI4e2jAQ3DTtHKMhqy+Cl214dQaAdAEYyVb5ILW5lKKqk2vA== + dependencies: + ethereum-cryptography "^2.0.0" + web3-errors "^1.0.2" + web3-types "^1.0.2" + web3-validator "^1.0.2" + +web3-validator@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/web3-validator/-/web3-validator-1.0.2.tgz#ca7d247b49f4f690db86e5b953272a627dc5950a" + integrity sha512-orx1CQAEnwJUnl/8iF2II2zSA4wiooNJvFmVE0Dbmt/kE370SugIDViQP76snhxtouG2AXzz4GyKbPCMlLGh/A== + dependencies: + ethereum-cryptography "^2.0.0" + is-my-json-valid "^2.20.6" + util "^0.12.5" + web3-errors "^1.0.2" + web3-types "^1.0.2" + +web3@*, web3@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/web3/-/web3-4.0.3.tgz#afeb977c9f883ff683d630ab9f5937eb56bc7cf4" + integrity sha512-rUMxui5f52yPWjiMRQV6xqIrTQSovYM2CNhl57y+xj/fGXNLbI1D5FsLPnUMZjMaFHJBTteaBxq/sTEaw/1jNA== + dependencies: + web3-core "^4.0.3" + web3-errors "^1.0.2" + web3-eth "^4.0.3" + web3-eth-abi "^4.0.3" + web3-eth-accounts "^4.0.3" + web3-eth-contract "^4.0.3" + web3-eth-ens "^4.0.3" + web3-eth-iban "^4.0.3" + web3-eth-personal "^4.0.3" + web3-net "^4.0.3" + web3-providers-http "^4.0.3" + web3-providers-ws "^4.0.3" + web3-rpc-methods "^1.0.2" + web3-types "^1.0.2" + web3-utils "^4.0.3" + web3-validator "^1.0.2" + webidl-conversions@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== +websocket@^1.0.34: + version "1.0.34" + resolved "https://registry.yarnpkg.com/websocket/-/websocket-1.0.34.tgz#2bdc2602c08bf2c82253b730655c0ef7dcab3111" + integrity sha512-PRDso2sGwF6kM75QykIesBijKSVceR6jL2G8NGYyq2XrItNC2P5/qL5XeR056GhA+Ly7JMFvJb9I312mJfmqnQ== + dependencies: + bufferutil "^4.0.1" + debug "^2.2.0" + es5-ext "^0.10.50" + typedarray-to-buffer "^3.1.5" + utf-8-validate "^5.0.2" + yaeti "^0.0.6" + whatwg-fetch@>=0.10.0: version "3.6.2" resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz#dced24f37f2624ed0281725d51d0e2e3fe677f8c" @@ -2215,6 +2955,18 @@ whatwg-url@^5.0.0: tr46 "~0.0.3" webidl-conversions "^3.0.0" +which-typed-array@^1.1.2: + version "1.1.10" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.10.tgz#74baa2789991905c2076abb317103b866c64e69e" + integrity sha512-uxoA5vLUfRPdjCuJ1h5LlYdmTLbYfums398v3WLkM+i/Wltl2/XyZpQWKbN++ck5L64SR/grOHqtXCUKmlZPNA== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + for-each "^0.3.3" + gopd "^1.0.1" + has-tostringtag "^1.0.0" + is-typed-array "^1.1.10" + which@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" @@ -2245,6 +2997,21 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== +ws@^8.8.1: + version "8.13.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0" + integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA== + +xtend@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + +yaeti@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/yaeti/-/yaeti-0.0.6.tgz#f26f484d72684cf42bedfb76970aa1608fbf9577" + integrity sha512-MvQa//+KcZCUkBTIC9blM+CU9J2GzuTytsOUwf2lidtvkx/6gnEp1QvJv34t9vdjhFmha/mUiNDbN0D0mJWdug== + yallist@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" diff --git a/hasura/metadata/databases/databases.yaml b/hasura/metadata/databases/databases.yaml index 65adeb32..e0f5d8a9 100644 --- a/hasura/metadata/databases/databases.yaml +++ b/hasura/metadata/databases/databases.yaml @@ -2,14 +2,14 @@ kind: postgres configuration: connection_info: - use_prepared_statements: true database_url: from_env: HASURA_GRAPHQL_DATABASE_URL isolation_level: read-committed pool_settings: connection_lifetime: 600 - retries: 1 idle_timeout: 180 max_connections: 50 + retries: 1 + use_prepared_statements: true tables: "!include default/tables/tables.yaml" functions: "!include default/functions/functions.yaml" diff --git a/hasura/metadata/databases/default/functions/public_block_history_by_producer.yaml b/hasura/metadata/databases/default/functions/public_block_history_by_producer.yaml index 6b3aa64f..5d2adcb9 100644 --- a/hasura/metadata/databases/default/functions/public_block_history_by_producer.yaml +++ b/hasura/metadata/databases/default/functions/public_block_history_by_producer.yaml @@ -1,3 +1,3 @@ function: - schema: public name: block_history_by_producer + schema: public diff --git a/hasura/metadata/databases/default/tables/evm_block.yaml b/hasura/metadata/databases/default/tables/evm_block.yaml new file mode 100644 index 00000000..4cc9e58a --- /dev/null +++ b/hasura/metadata/databases/default/tables/evm_block.yaml @@ -0,0 +1,13 @@ +table: + name: block + schema: evm +object_relationships: + - name: BlockToTransaction + using: + manual_configuration: + column_mapping: + hash: block_hash + insertion_order: null + remote_table: + name: transaction + schema: evm diff --git a/hasura/metadata/databases/default/tables/evm_transaction.yaml b/hasura/metadata/databases/default/tables/evm_transaction.yaml new file mode 100644 index 00000000..b455b1c6 --- /dev/null +++ b/hasura/metadata/databases/default/tables/evm_transaction.yaml @@ -0,0 +1,3 @@ +table: + name: transaction + schema: evm diff --git a/hasura/metadata/databases/default/tables/public_block_history_by_producer_type.yaml b/hasura/metadata/databases/default/tables/public_block_history_by_producer_type.yaml index 4f117ad6..7784dd2d 100644 --- a/hasura/metadata/databases/default/tables/public_block_history_by_producer_type.yaml +++ b/hasura/metadata/databases/default/tables/public_block_history_by_producer_type.yaml @@ -1,3 +1,3 @@ table: - schema: public name: block_history_by_producer_type + schema: public diff --git a/hasura/metadata/databases/default/tables/public_cpu.yaml b/hasura/metadata/databases/default/tables/public_cpu.yaml index 2c1b954b..69cd8e50 100644 --- a/hasura/metadata/databases/default/tables/public_cpu.yaml +++ b/hasura/metadata/databases/default/tables/public_cpu.yaml @@ -1,3 +1,3 @@ table: - schema: public name: cpu + schema: public diff --git a/hasura/metadata/databases/default/tables/public_demux_state.yaml b/hasura/metadata/databases/default/tables/public_demux_state.yaml index 0a9123ab..3cd0819b 100644 --- a/hasura/metadata/databases/default/tables/public_demux_state.yaml +++ b/hasura/metadata/databases/default/tables/public_demux_state.yaml @@ -1,3 +1,3 @@ table: - schema: public name: demux_state + schema: public diff --git a/hasura/metadata/databases/default/tables/public_endpoint.yaml b/hasura/metadata/databases/default/tables/public_endpoint.yaml index 625a45d1..5a39a0c7 100644 --- a/hasura/metadata/databases/default/tables/public_endpoint.yaml +++ b/hasura/metadata/databases/default/tables/public_endpoint.yaml @@ -1,6 +1,6 @@ table: - schema: public name: endpoint + schema: public object_relationships: - name: node using: diff --git a/hasura/metadata/databases/default/tables/public_node.yaml b/hasura/metadata/databases/default/tables/public_node.yaml index e102efe0..c6ef2985 100644 --- a/hasura/metadata/databases/default/tables/public_node.yaml +++ b/hasura/metadata/databases/default/tables/public_node.yaml @@ -1,6 +1,6 @@ table: - schema: public name: node + schema: public object_relationships: - name: producer using: @@ -11,15 +11,15 @@ array_relationships: foreign_key_constraint_on: column: node_id table: - schema: public name: endpoint + schema: public - name: node_info using: foreign_key_constraint_on: column: node_id table: - schema: public name: node_info + schema: public select_permissions: - role: guest permission: diff --git a/hasura/metadata/databases/default/tables/public_node_info.yaml b/hasura/metadata/databases/default/tables/public_node_info.yaml index 1a7e0039..bfb39b25 100644 --- a/hasura/metadata/databases/default/tables/public_node_info.yaml +++ b/hasura/metadata/databases/default/tables/public_node_info.yaml @@ -1,6 +1,6 @@ table: - schema: public name: node_info + schema: public object_relationships: - name: node using: diff --git a/hasura/metadata/databases/default/tables/public_round_history.yaml b/hasura/metadata/databases/default/tables/public_round_history.yaml index 2d2e8e84..c2e29e4e 100644 --- a/hasura/metadata/databases/default/tables/public_round_history.yaml +++ b/hasura/metadata/databases/default/tables/public_round_history.yaml @@ -1,3 +1,3 @@ table: - schema: public name: round_history + schema: public diff --git a/hasura/metadata/databases/default/tables/public_schedule_history.yaml b/hasura/metadata/databases/default/tables/public_schedule_history.yaml index be1c7fa7..d68a13b9 100644 --- a/hasura/metadata/databases/default/tables/public_schedule_history.yaml +++ b/hasura/metadata/databases/default/tables/public_schedule_history.yaml @@ -1,3 +1,3 @@ table: - schema: public name: schedule_history + schema: public diff --git a/hasura/metadata/databases/default/tables/public_setting.yaml b/hasura/metadata/databases/default/tables/public_setting.yaml index 404f9387..1db17336 100644 --- a/hasura/metadata/databases/default/tables/public_setting.yaml +++ b/hasura/metadata/databases/default/tables/public_setting.yaml @@ -1,6 +1,6 @@ table: - schema: public name: setting + schema: public select_permissions: - role: guest permission: diff --git a/hasura/metadata/databases/default/tables/tables.yaml b/hasura/metadata/databases/default/tables/tables.yaml index 244cf61c..46489b16 100644 --- a/hasura/metadata/databases/default/tables/tables.yaml +++ b/hasura/metadata/databases/default/tables/tables.yaml @@ -1,3 +1,5 @@ +- "!include evm_block.yaml" +- "!include evm_transaction.yaml" - "!include public_block_history.yaml" - "!include public_block_history_by_producer_type.yaml" - "!include public_check_history_by_endpoint.yaml" diff --git a/hasura/metadata/rest_endpoints.yaml b/hasura/metadata/rest_endpoints.yaml index eb7fac18..7578e851 100644 --- a/hasura/metadata/rest_endpoints.yaml +++ b/hasura/metadata/rest_endpoints.yaml @@ -1,9 +1,9 @@ -- definition: +- comment: null + definition: query: collection_name: allowed-queries query_name: get-producers-info - url: get-producers-info methods: - POST name: get-producers-info - comment: null + url: get-producers-info diff --git a/hasura/migrations/default/1689614416757_create_schema_evm/down.sql b/hasura/migrations/default/1689614416757_create_schema_evm/down.sql new file mode 100644 index 00000000..5cc73238 --- /dev/null +++ b/hasura/migrations/default/1689614416757_create_schema_evm/down.sql @@ -0,0 +1 @@ +drop schema "evm" cascade; diff --git a/hasura/migrations/default/1689614416757_create_schema_evm/up.sql b/hasura/migrations/default/1689614416757_create_schema_evm/up.sql new file mode 100644 index 00000000..212bc0a8 --- /dev/null +++ b/hasura/migrations/default/1689614416757_create_schema_evm/up.sql @@ -0,0 +1 @@ +create schema "evm"; diff --git a/hasura/migrations/default/1689614424151_create_table_evm_block/down.sql b/hasura/migrations/default/1689614424151_create_table_evm_block/down.sql new file mode 100644 index 00000000..dcdc9c9d --- /dev/null +++ b/hasura/migrations/default/1689614424151_create_table_evm_block/down.sql @@ -0,0 +1 @@ +DROP TABLE "evm"."block"; diff --git a/hasura/migrations/default/1689614424151_create_table_evm_block/up.sql b/hasura/migrations/default/1689614424151_create_table_evm_block/up.sql new file mode 100644 index 00000000..68c24cf9 --- /dev/null +++ b/hasura/migrations/default/1689614424151_create_table_evm_block/up.sql @@ -0,0 +1 @@ +CREATE TABLE "evm"."block" ("hash" varchar NOT NULL, "gasUsed" numeric NOT NULL, "transactions" jsonb NOT NULL, "number" numeric NOT NULL, "timestamp" timestamptz NOT NULL, PRIMARY KEY ("hash") ); diff --git a/hasura/migrations/default/1689614988390_alter_table_evm_block_alter_column_gasUsed/down.sql b/hasura/migrations/default/1689614988390_alter_table_evm_block_alter_column_gasUsed/down.sql new file mode 100644 index 00000000..f8f6ceeb --- /dev/null +++ b/hasura/migrations/default/1689614988390_alter_table_evm_block_alter_column_gasUsed/down.sql @@ -0,0 +1 @@ +alter table "evm"."block" rename column "gas_used" to "gasUsed"; diff --git a/hasura/migrations/default/1689614988390_alter_table_evm_block_alter_column_gasUsed/up.sql b/hasura/migrations/default/1689614988390_alter_table_evm_block_alter_column_gasUsed/up.sql new file mode 100644 index 00000000..927317d1 --- /dev/null +++ b/hasura/migrations/default/1689614988390_alter_table_evm_block_alter_column_gasUsed/up.sql @@ -0,0 +1 @@ +alter table "evm"."block" rename column "gasUsed" to "gas_used"; diff --git a/hasura/migrations/default/1689615011869_alter_table_evm_block_add_unique_number/down.sql b/hasura/migrations/default/1689615011869_alter_table_evm_block_add_unique_number/down.sql new file mode 100644 index 00000000..bda7f6e8 --- /dev/null +++ b/hasura/migrations/default/1689615011869_alter_table_evm_block_add_unique_number/down.sql @@ -0,0 +1 @@ +alter table "evm"."block" drop constraint "block_number_key"; diff --git a/hasura/migrations/default/1689615011869_alter_table_evm_block_add_unique_number/up.sql b/hasura/migrations/default/1689615011869_alter_table_evm_block_add_unique_number/up.sql new file mode 100644 index 00000000..f9f18195 --- /dev/null +++ b/hasura/migrations/default/1689615011869_alter_table_evm_block_add_unique_number/up.sql @@ -0,0 +1 @@ +alter table "evm"."block" add constraint "block_number_key" unique ("number"); diff --git a/hasura/migrations/default/1689615116520_create_table_evm_transaction/down.sql b/hasura/migrations/default/1689615116520_create_table_evm_transaction/down.sql new file mode 100644 index 00000000..e7458dbe --- /dev/null +++ b/hasura/migrations/default/1689615116520_create_table_evm_transaction/down.sql @@ -0,0 +1 @@ +DROP TABLE "evm"."transaction"; diff --git a/hasura/migrations/default/1689615116520_create_table_evm_transaction/up.sql b/hasura/migrations/default/1689615116520_create_table_evm_transaction/up.sql new file mode 100644 index 00000000..55d9bbf9 --- /dev/null +++ b/hasura/migrations/default/1689615116520_create_table_evm_transaction/up.sql @@ -0,0 +1 @@ +CREATE TABLE "evm"."transaction" ("block_hash" varchar NOT NULL, "block_number" numeric NOT NULL, "gas" numeric NOT NULL, "gas_price" numeric NOT NULL, "hash" varchar NOT NULL, PRIMARY KEY ("hash") ); diff --git a/hasura/migrations/default/1689615410384_alter_table_evm_block_add_unique_number_hash/down.sql b/hasura/migrations/default/1689615410384_alter_table_evm_block_add_unique_number_hash/down.sql new file mode 100644 index 00000000..2fb4743d --- /dev/null +++ b/hasura/migrations/default/1689615410384_alter_table_evm_block_add_unique_number_hash/down.sql @@ -0,0 +1,2 @@ +alter table "evm"."block" drop constraint "block_number_hash_key"; +alter table "evm"."block" add constraint "block_number_key" unique ("number"); diff --git a/hasura/migrations/default/1689615410384_alter_table_evm_block_add_unique_number_hash/up.sql b/hasura/migrations/default/1689615410384_alter_table_evm_block_add_unique_number_hash/up.sql new file mode 100644 index 00000000..4e0f0f1c --- /dev/null +++ b/hasura/migrations/default/1689615410384_alter_table_evm_block_add_unique_number_hash/up.sql @@ -0,0 +1,2 @@ +alter table "evm"."block" drop constraint "block_number_key"; +alter table "evm"."block" add constraint "block_number_hash_key" unique ("number", "hash"); diff --git a/hasura/migrations/default/1689615432215_set_fk_evm_transaction_block_number_block_hash/down.sql b/hasura/migrations/default/1689615432215_set_fk_evm_transaction_block_number_block_hash/down.sql new file mode 100644 index 00000000..9298915c --- /dev/null +++ b/hasura/migrations/default/1689615432215_set_fk_evm_transaction_block_number_block_hash/down.sql @@ -0,0 +1 @@ +alter table "evm"."transaction" drop constraint "transaction_block_number_block_hash_fkey"; diff --git a/hasura/migrations/default/1689615432215_set_fk_evm_transaction_block_number_block_hash/up.sql b/hasura/migrations/default/1689615432215_set_fk_evm_transaction_block_number_block_hash/up.sql new file mode 100644 index 00000000..f2cee2b1 --- /dev/null +++ b/hasura/migrations/default/1689615432215_set_fk_evm_transaction_block_number_block_hash/up.sql @@ -0,0 +1,5 @@ +alter table "evm"."transaction" + add constraint "transaction_block_number_block_hash_fkey" + foreign key ("block_number", "block_hash") + references "evm"."block" + ("number", "hash") on update restrict on delete restrict; diff --git a/makefile b/makefile index da60fd19..73382ea5 100644 --- a/makefile +++ b/makefile @@ -99,7 +99,7 @@ stop: start: make start-postgres - make start-wallet + # make start-wallet make start-hapi make start-hapi-evm make start-hasura From a4e957e4e1398c24513b4396addabeee5f2f1f73 Mon Sep 17 00:00:00 2001 From: Leister Francisco Alvarez Campos Date: Fri, 21 Jul 2023 09:51:42 -0600 Subject: [PATCH 04/75] feat(hapi-evm): extending comment instructions --- hapi-evm/src/routes/v1/index.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hapi-evm/src/routes/v1/index.ts b/hapi-evm/src/routes/v1/index.ts index 134ce4f5..69aa6dd8 100644 --- a/hapi-evm/src/routes/v1/index.ts +++ b/hapi-evm/src/routes/v1/index.ts @@ -25,6 +25,9 @@ const baseRoute = '/v1' // Average gas usage: Show to average gas usage in the last 100 blocks. // Average transactions per second (block and eosio.token -> ERC20). +// - internal TLOS transactions. (tEVM address -> tEVM address) +// - incoming TLOS transactions. (EOS address -> tEVM address) +// - outgoing TLOS transactions. (tEVM address -> EOS address) HOW? // Daily transactions. // ATH. From 142056e24e4d192bb587e595d390827ba172e685 Mon Sep 17 00:00:00 2001 From: Leister Francisco Alvarez Campos Date: Fri, 21 Jul 2023 11:50:12 -0600 Subject: [PATCH 05/75] chore(hapi-evm): add todo --- hapi-evm/src/routes/v1/index.ts | 14 +++++++------- hapi-evm/src/services/block.service.ts | 4 +++- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/hapi-evm/src/routes/v1/index.ts b/hapi-evm/src/routes/v1/index.ts index 69aa6dd8..a2123c73 100644 --- a/hapi-evm/src/routes/v1/index.ts +++ b/hapi-evm/src/routes/v1/index.ts @@ -23,13 +23,13 @@ const baseRoute = '/v1' // - last block number // - ATH -// Average gas usage: Show to average gas usage in the last 100 blocks. -// Average transactions per second (block and eosio.token -> ERC20). -// - internal TLOS transactions. (tEVM address -> tEVM address) -// - incoming TLOS transactions. (EOS address -> tEVM address) -// - outgoing TLOS transactions. (tEVM address -> EOS address) HOW? -// Daily transactions. -// ATH. +// (OK) Average gas usage: Show to average gas usage in the last 100 blocks. +// () Average transactions per second (block and eosio.token -> ERC20). +// - () internal TLOS transactions. (tEVM address -> tEVM address) +// - () incoming TLOS transactions. (EOS address -> tEVM address) +// - () outgoing TLOS transactions. (tEVM address -> EOS address) HOW? +// (OK) Daily transactions. +// (OK) ATH. export default (server: Server) => { // exampleRoutes.routes(server, baseRoute) diff --git a/hapi-evm/src/services/block.service.ts b/hapi-evm/src/services/block.service.ts index 5e5de0bc..d3e7066e 100644 --- a/hapi-evm/src/services/block.service.ts +++ b/hapi-evm/src/services/block.service.ts @@ -8,7 +8,7 @@ const httpProvider = new Web3.providers.HttpProvider(networkConfig.evmEndpoint) const web3 = new Web3(httpProvider) // const test = async () => { -// const tempBlock: Block = await web3.eth.getBlock(246383575) +// const tempBlock: Block = await web3.eth.getBlock(0) // console.log('🚀 ~ tempBlock:', tempBlock) // const trx: TransactionInfo = await web3.eth.getTransaction( @@ -20,6 +20,8 @@ const web3 = new Web3(httpProvider) // test() +// TODO: syncronize passed blocks + const getBlock = async () => { const blockNumber = await web3.eth.getBlockNumber() const block: Block = await web3.eth.getBlock(blockNumber) From 86a6a9294abbddeee50457f8e26a9a770e67e610 Mon Sep 17 00:00:00 2001 From: Leister Francisco Alvarez Campos Date: Fri, 21 Jul 2023 19:10:36 -0600 Subject: [PATCH 06/75] feat(hapi-evm): add hyperion --- hapi-evm/package.json | 1 + hapi-evm/src/config/hyperion.config.ts | 4 + hapi-evm/src/config/index.ts | 1 + hapi-evm/src/models/default.model.ts | 2 +- hapi-evm/src/models/gas/interfaces.ts | 3 - hapi-evm/src/models/gas/queries.ts | 1 - .../models/{gas => hyperion-state}/index.ts | 0 .../src/models/hyperion-state/interfaces.ts | 4 + hapi-evm/src/models/hyperion-state/queries.ts | 94 ++++++++++ .../src/models/incoming-transfer/index.ts | 2 + .../models/incoming-transfer/interfaces.ts | 12 ++ .../src/models/incoming-transfer/queries.ts | 34 ++++ hapi-evm/src/models/index.ts | 5 +- hapi-evm/src/routes/v1/index.ts | 4 +- hapi-evm/src/services/hyperion/index.ts | 170 ++++++++++++++++++ .../src/services/hyperion/updaters/index.ts | 3 + .../updaters/token-transfer.updater.ts | 29 +++ hapi-evm/src/services/worker/index.ts | 6 +- hapi-evm/yarn.lock | 5 + .../default/tables/evm_hyperion_state.yaml | 3 + .../default/tables/evm_incoming_transfer.yaml | 3 + .../databases/default/tables/evm_param.yaml | 3 + .../databases/default/tables/evm_params.yaml | 3 + .../databases/default/tables/tables.yaml | 3 + .../down.sql | 1 + .../up.sql | 2 + .../down.sql | 1 + .../up.sql | 1 + .../down.sql | 1 + .../up.sql | 18 ++ .../down.sql | 1 + .../up.sql | 2 + .../down.sql | 4 + .../up.sql | 2 + 34 files changed, 417 insertions(+), 11 deletions(-) create mode 100644 hapi-evm/src/config/hyperion.config.ts delete mode 100644 hapi-evm/src/models/gas/interfaces.ts delete mode 100644 hapi-evm/src/models/gas/queries.ts rename hapi-evm/src/models/{gas => hyperion-state}/index.ts (100%) create mode 100644 hapi-evm/src/models/hyperion-state/interfaces.ts create mode 100644 hapi-evm/src/models/hyperion-state/queries.ts create mode 100644 hapi-evm/src/models/incoming-transfer/index.ts create mode 100644 hapi-evm/src/models/incoming-transfer/interfaces.ts create mode 100644 hapi-evm/src/models/incoming-transfer/queries.ts create mode 100644 hapi-evm/src/services/hyperion/index.ts create mode 100644 hapi-evm/src/services/hyperion/updaters/index.ts create mode 100644 hapi-evm/src/services/hyperion/updaters/token-transfer.updater.ts create mode 100644 hasura/metadata/databases/default/tables/evm_hyperion_state.yaml create mode 100644 hasura/metadata/databases/default/tables/evm_incoming_transfer.yaml create mode 100644 hasura/metadata/databases/default/tables/evm_param.yaml create mode 100644 hasura/metadata/databases/default/tables/evm_params.yaml create mode 100644 hasura/migrations/default/1689963835559_create_table_evm_params/down.sql create mode 100644 hasura/migrations/default/1689963835559_create_table_evm_params/up.sql create mode 100644 hasura/migrations/default/1689963954957_rename_table_evm_params/down.sql create mode 100644 hasura/migrations/default/1689963954957_rename_table_evm_params/up.sql create mode 100644 hasura/migrations/default/1689964045956_create_table_evm_hyperion_state/down.sql create mode 100644 hasura/migrations/default/1689964045956_create_table_evm_hyperion_state/up.sql create mode 100644 hasura/migrations/default/1689983709652_create_table_evm_incoming_transfer/down.sql create mode 100644 hasura/migrations/default/1689983709652_create_table_evm_incoming_transfer/up.sql create mode 100644 hasura/migrations/default/1689984918750_alter_table_evm_incoming_transfer_add_column_timestamp/down.sql create mode 100644 hasura/migrations/default/1689984918750_alter_table_evm_incoming_transfer_add_column_timestamp/up.sql diff --git a/hapi-evm/package.json b/hapi-evm/package.json index e0f1340a..e1348ec9 100644 --- a/hapi-evm/package.json +++ b/hapi-evm/package.json @@ -27,6 +27,7 @@ "graphql": "16", "graphql-request": "^6.0.0", "joi": "^17.9.2", + "moment": "^2.29.4", "node-fetch": "^3.3.1", "web3": "^4.0.3", "websocket": "^1.0.34" diff --git a/hapi-evm/src/config/hyperion.config.ts b/hapi-evm/src/config/hyperion.config.ts new file mode 100644 index 00000000..aa4f6e2d --- /dev/null +++ b/hapi-evm/src/config/hyperion.config.ts @@ -0,0 +1,4 @@ +export const api = + process.env.HAPI_HYPERION_API || 'https://test.telos.eosusa.io' +export const startAt = + process.env.HAPI_HYPERION_START_AT || '2021-06-02T00:00:00.000+00:00' diff --git a/hapi-evm/src/config/index.ts b/hapi-evm/src/config/index.ts index cf916619..0f6d6dc9 100644 --- a/hapi-evm/src/config/index.ts +++ b/hapi-evm/src/config/index.ts @@ -1,3 +1,4 @@ export * as serverConfig from './server.config' export * as hasuraConfig from './hasura.config' export * as networkConfig from './network.config' +export * as hyperionConfig from './hyperion.config' diff --git a/hapi-evm/src/models/default.model.ts b/hapi-evm/src/models/default.model.ts index 26922425..4e2cf927 100644 --- a/hapi-evm/src/models/default.model.ts +++ b/hapi-evm/src/models/default.model.ts @@ -15,6 +15,6 @@ export type TableType = keyof typeof Tables export interface Worker { name: string - intervalSec: number + intervalSec?: number action: () => Promise } diff --git a/hapi-evm/src/models/gas/interfaces.ts b/hapi-evm/src/models/gas/interfaces.ts deleted file mode 100644 index 344c070b..00000000 --- a/hapi-evm/src/models/gas/interfaces.ts +++ /dev/null @@ -1,3 +0,0 @@ -export interface I { - -} \ No newline at end of file diff --git a/hapi-evm/src/models/gas/queries.ts b/hapi-evm/src/models/gas/queries.ts deleted file mode 100644 index b1c6ea43..00000000 --- a/hapi-evm/src/models/gas/queries.ts +++ /dev/null @@ -1 +0,0 @@ -export default {} diff --git a/hapi-evm/src/models/gas/index.ts b/hapi-evm/src/models/hyperion-state/index.ts similarity index 100% rename from hapi-evm/src/models/gas/index.ts rename to hapi-evm/src/models/hyperion-state/index.ts diff --git a/hapi-evm/src/models/hyperion-state/interfaces.ts b/hapi-evm/src/models/hyperion-state/interfaces.ts new file mode 100644 index 00000000..63ef36a0 --- /dev/null +++ b/hapi-evm/src/models/hyperion-state/interfaces.ts @@ -0,0 +1,4 @@ +export interface HyperionState { + id: string + last_synced_at: string +} diff --git a/hapi-evm/src/models/hyperion-state/queries.ts b/hapi-evm/src/models/hyperion-state/queries.ts new file mode 100644 index 00000000..9a02199f --- /dev/null +++ b/hapi-evm/src/models/hyperion-state/queries.ts @@ -0,0 +1,94 @@ +import { gql } from 'graphql-request' + +import { coreUtil } from '../../utils' +import { HyperionState } from './interfaces' + +interface HyperionStateResponse { + evm_hyperion_state: HyperionState[] +} + +interface HyperionStateInsertOneResponse { + insert_evm_hyperion_state_one: { + id: string + } +} + +export const save = async (lastSyncedAt: string) => { + const mutation = gql` + mutation ($payload: evm_hyperion_state_insert_input!) { + insert_evm_hyperion_state_one(object: $payload) { + id + } + } + ` + + const data = + await coreUtil.hasura.default.request( + mutation, + { + payload: { + last_synced_at: lastSyncedAt + } + } + ) + + return data.insert_evm_hyperion_state_one +} + +export const update = async (id: string, lastSyncedAt: string) => { + const mutation = gql` + mutation ($id: uuid!, $payload: evm_hyperion_state_set_input) { + update_evm_hyperion_state_by_pk(pk_columns: { id: $id }, _set: $payload) { + id + last_synced_at + } + } + ` + + await coreUtil.hasura.default.request(mutation, { + id, + payload: { + last_synced_at: lastSyncedAt + } + }) +} + +export const getState = async () => { + const query = gql` + query { + evm_hyperion_state( + where: { id: { _neq: "00000000-0000-0000-0000-000000000000" } } + limit: 1 + ) { + id + last_synced_at + } + } + ` + const data = await coreUtil.hasura.default.request( + query + ) + + if (!data.evm_hyperion_state.length) { + return + } + + const state = data.evm_hyperion_state[0] + + return { + id: state.id, + lastSyncedAt: state.last_synced_at + } +} + +export const saveOrUpdate = async (lastSyncedAt: string) => { + const currentState = await getState() + + if (!currentState) { + await save(lastSyncedAt) + + return + } + + await update(currentState.id, lastSyncedAt) +} diff --git a/hapi-evm/src/models/incoming-transfer/index.ts b/hapi-evm/src/models/incoming-transfer/index.ts new file mode 100644 index 00000000..5e08e0f1 --- /dev/null +++ b/hapi-evm/src/models/incoming-transfer/index.ts @@ -0,0 +1,2 @@ +export * as interfaces from './interfaces' +export * as queries from './queries' diff --git a/hapi-evm/src/models/incoming-transfer/interfaces.ts b/hapi-evm/src/models/incoming-transfer/interfaces.ts new file mode 100644 index 00000000..3504923f --- /dev/null +++ b/hapi-evm/src/models/incoming-transfer/interfaces.ts @@ -0,0 +1,12 @@ +export interface IncomingTransfer { + id?: string + block: number + transaction_id: string + from: string + to: string + amount: number + symbol: string + memo: string + quantity: string + timestamp: string +} diff --git a/hapi-evm/src/models/incoming-transfer/queries.ts b/hapi-evm/src/models/incoming-transfer/queries.ts new file mode 100644 index 00000000..ba1eaa3e --- /dev/null +++ b/hapi-evm/src/models/incoming-transfer/queries.ts @@ -0,0 +1,34 @@ +import { gql } from 'graphql-request' + +import { coreUtil } from '../../utils' +import { IncomingTransfer } from './interfaces' + +// interface IncomingTransferResponse { +// evm_incoming_transfer: IncomingTransfer[] +// } + +interface IncomingTransferInsertOneResponse { + insert_evm_incoming_transfer_one: { + id: string + } +} + +export const save = async (payload: IncomingTransfer) => { + const mutation = gql` + mutation ($payload: evm_incoming_transfer_insert_input!) { + insert_evm_incoming_transfer_one(object: $payload) { + id + } + } + ` + + const data = + await coreUtil.hasura.default.request( + mutation, + { + payload + } + ) + + return data.insert_evm_incoming_transfer_one +} diff --git a/hapi-evm/src/models/index.ts b/hapi-evm/src/models/index.ts index 86b6f80f..dc6d58a6 100644 --- a/hapi-evm/src/models/index.ts +++ b/hapi-evm/src/models/index.ts @@ -1,4 +1,5 @@ -export * as gasModel from './gas' +export * as defaultModel from './default.model' export * as blockModel from './block' export * as transactionModel from './transaction' -export * as defaultModel from './default.model' +export * as hyperionStateModel from './hyperion-state' +export * as incomingTransferModel from './incoming-transfer' diff --git a/hapi-evm/src/routes/v1/index.ts b/hapi-evm/src/routes/v1/index.ts index a2123c73..6e2abe3d 100644 --- a/hapi-evm/src/routes/v1/index.ts +++ b/hapi-evm/src/routes/v1/index.ts @@ -25,8 +25,8 @@ const baseRoute = '/v1' // (OK) Average gas usage: Show to average gas usage in the last 100 blocks. // () Average transactions per second (block and eosio.token -> ERC20). -// - () internal TLOS transactions. (tEVM address -> tEVM address) -// - () incoming TLOS transactions. (EOS address -> tEVM address) +// - (NO) internal TLOS transactions. (tEVM address -> tEVM address) +// - (OK) incoming TLOS transactions. (EOS address -> tEVM address) // - () outgoing TLOS transactions. (tEVM address -> EOS address) HOW? // (OK) Daily transactions. // (OK) ATH. diff --git a/hapi-evm/src/services/hyperion/index.ts b/hapi-evm/src/services/hyperion/index.ts new file mode 100644 index 00000000..59c18092 --- /dev/null +++ b/hapi-evm/src/services/hyperion/index.ts @@ -0,0 +1,170 @@ +import moment, { DurationInputArg2 } from 'moment' + +import { hyperionConfig } from '../../config' +import { coreUtil, timeUtil } from '../../utils' +import { hyperionStateModel } from '../../models' + +import updaters from './updaters' + +interface GetActionsParams { + after: string + before: string + skip: number +} + +interface GetActionsResponse { + hasMore: boolean + actions: any[] +} + +const TIME_BEFORE_IRREVERSIBILITY = 164 + +const getLastSyncedAt = async () => { + const state = await hyperionStateModel.queries.getState() + + if (state) { + return state.lastSyncedAt + } + + await hyperionStateModel.queries.saveOrUpdate(hyperionConfig.startAt) + + return hyperionConfig.startAt +} + +const getGap = (lastSyncedAt: string) => { + if (moment().diff(moment(lastSyncedAt), 'days') > 0) { + return { + amount: 1, + unit: 'day' + } + } + + if (moment().diff(moment(lastSyncedAt), 'hours') > 0) { + return { + amount: 1, + unit: 'hour' + } + } + + if ( + moment().diff(moment(lastSyncedAt), 'seconds') >= + TIME_BEFORE_IRREVERSIBILITY * 2 + ) { + return { + amount: TIME_BEFORE_IRREVERSIBILITY, + unit: 'seconds' + } + } + + if ( + moment().diff(moment(lastSyncedAt), 'seconds') >= + TIME_BEFORE_IRREVERSIBILITY + 10 + ) { + return { + amount: 10, + unit: 'seconds' + } + } + + return { + amount: 1, + unit: 'seconds' + } +} + +const getActions = async ( + params: GetActionsParams +): Promise => { + const limit = 100 + const { data } = await coreUtil.axios.default.get( + `${hyperionConfig.api}/v2/history/get_actions`, + { + params: { + ...params, + account: 'eosio.evm', // TODO: get it from updater using the notified_account field + limit, + filter: updaters.map(updater => updater.type).join(','), + sort: 'asc', + simple: true, + checkLib: true + } + } + ) + + const notIrreversible = data.simple_actions.find( + (item: any) => !item.irreversible + ) + + if (notIrreversible) { + await timeUtil.sleep(1) + + return getActions(params) + } + + return { + hasMore: data.total.value > limit + params.skip || false, + actions: data.simple_actions + } +} + +const runUpdaters = async (actions: any[]) => { + for (let index = 0; index < actions.length; index++) { + const action = actions[index] + const updater = updaters.find(item => + item.type.startsWith(`${action.contract}:${action.action}`) + ) + + if (!updater) { + continue + } + + await updater.apply(action) + } +} + +const sync = async (): Promise => { + console.log('SYNCING') + await coreUtil.hasura.hasuraAssembled() + const lastSyncedAt = await getLastSyncedAt() + const gap = getGap(lastSyncedAt) + const after = moment(lastSyncedAt).toISOString() + const before = moment(after) + .add(gap.amount, gap.unit as DurationInputArg2) + .toISOString() + const diff = moment().diff(moment(before), 'seconds') + let skip = 0 + let hasMore = true + let actions = [] + + if (diff < TIME_BEFORE_IRREVERSIBILITY) { + await timeUtil.sleep(TIME_BEFORE_IRREVERSIBILITY - diff) + + return sync() + } + + try { + while (hasMore) { + ;({ hasMore, actions } = await getActions({ after, before, skip })) + skip += actions.length + await runUpdaters(actions) + } + } catch (error: any) { + console.error('hyperion error', error.message) + await timeUtil.sleep(5) + + return sync() + } + + await hyperionStateModel.queries.saveOrUpdate(before) + + return sync() +} + +const syncWorker = () => { + return { + name: 'SYNC ACTIONS', + action: sync + } +} + +export default { syncWorker } diff --git a/hapi-evm/src/services/hyperion/updaters/index.ts b/hapi-evm/src/services/hyperion/updaters/index.ts new file mode 100644 index 00000000..d3a15943 --- /dev/null +++ b/hapi-evm/src/services/hyperion/updaters/index.ts @@ -0,0 +1,3 @@ +import tokenTransferUpdater from './token-transfer.updater' + +export default [tokenTransferUpdater] diff --git a/hapi-evm/src/services/hyperion/updaters/token-transfer.updater.ts b/hapi-evm/src/services/hyperion/updaters/token-transfer.updater.ts new file mode 100644 index 00000000..8191062e --- /dev/null +++ b/hapi-evm/src/services/hyperion/updaters/token-transfer.updater.ts @@ -0,0 +1,29 @@ +import { isAddress } from 'web3-validator' + +import { incomingTransferModel } from '../../../models' + +export default { + type: `eosio.token:transfer,act.data.to=eosio.evm`, + notified_account: `eosio.evm`, + apply: async (action: any) => { + if (!isAddress(action.data.memo)) { + return + } + + try { + await incomingTransferModel.queries.save({ + block: action.block, + transaction_id: action.transaction_id, + timestamp: action.timestamp, + from: action.data.from, + to: action.data.to, + amount: action.data.amount, + symbol: action.data.symbol, + memo: action.data.memo, + quantity: action.data.quantity + }) + } catch (error: any) { + console.error(`error to sync ${action.action}: ${error.message}`) + } + } +} diff --git a/hapi-evm/src/services/worker/index.ts b/hapi-evm/src/services/worker/index.ts index f23460ff..1ad8fcc4 100644 --- a/hapi-evm/src/services/worker/index.ts +++ b/hapi-evm/src/services/worker/index.ts @@ -1,12 +1,13 @@ import { timeUtil, coreUtil } from '../../utils' import { defaultModel } from '../../models' import blockService from '../block.service' +import hyperionService from '../hyperion' const run = async (worker: defaultModel.Worker) => { try { await worker.action() } catch (error: any) { - console.log(`${name} ERROR =>`, error.message) + console.log(`${worker.name} ERROR =>`, error.message) } if (!worker.intervalSec) { @@ -20,7 +21,8 @@ const run = async (worker: defaultModel.Worker) => { const init = async () => { await coreUtil.hasura.hasuraAssembled() - run(blockService.syncBlockWorker()) + // run(blockService.syncBlockWorker()) + run(hyperionService.syncWorker()) } export default { diff --git a/hapi-evm/yarn.lock b/hapi-evm/yarn.lock index 2bff766c..1e9b13c9 100644 --- a/hapi-evm/yarn.lock +++ b/hapi-evm/yarn.lock @@ -2087,6 +2087,11 @@ minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: dependencies: brace-expansion "^1.1.7" +moment@^2.29.4: + version "2.29.4" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108" + integrity sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w== + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" diff --git a/hasura/metadata/databases/default/tables/evm_hyperion_state.yaml b/hasura/metadata/databases/default/tables/evm_hyperion_state.yaml new file mode 100644 index 00000000..4dd64e45 --- /dev/null +++ b/hasura/metadata/databases/default/tables/evm_hyperion_state.yaml @@ -0,0 +1,3 @@ +table: + name: hyperion_state + schema: evm diff --git a/hasura/metadata/databases/default/tables/evm_incoming_transfer.yaml b/hasura/metadata/databases/default/tables/evm_incoming_transfer.yaml new file mode 100644 index 00000000..8f2369de --- /dev/null +++ b/hasura/metadata/databases/default/tables/evm_incoming_transfer.yaml @@ -0,0 +1,3 @@ +table: + name: incoming_transfer + schema: evm diff --git a/hasura/metadata/databases/default/tables/evm_param.yaml b/hasura/metadata/databases/default/tables/evm_param.yaml new file mode 100644 index 00000000..e5a5d86b --- /dev/null +++ b/hasura/metadata/databases/default/tables/evm_param.yaml @@ -0,0 +1,3 @@ +table: + name: param + schema: evm diff --git a/hasura/metadata/databases/default/tables/evm_params.yaml b/hasura/metadata/databases/default/tables/evm_params.yaml new file mode 100644 index 00000000..51c501a4 --- /dev/null +++ b/hasura/metadata/databases/default/tables/evm_params.yaml @@ -0,0 +1,3 @@ +table: + name: params + schema: evm diff --git a/hasura/metadata/databases/default/tables/tables.yaml b/hasura/metadata/databases/default/tables/tables.yaml index 46489b16..4cf2b197 100644 --- a/hasura/metadata/databases/default/tables/tables.yaml +++ b/hasura/metadata/databases/default/tables/tables.yaml @@ -1,4 +1,7 @@ - "!include evm_block.yaml" +- "!include evm_hyperion_state.yaml" +- "!include evm_incoming_transfer.yaml" +- "!include evm_param.yaml" - "!include evm_transaction.yaml" - "!include public_block_history.yaml" - "!include public_block_history_by_producer_type.yaml" diff --git a/hasura/migrations/default/1689963835559_create_table_evm_params/down.sql b/hasura/migrations/default/1689963835559_create_table_evm_params/down.sql new file mode 100644 index 00000000..746c729e --- /dev/null +++ b/hasura/migrations/default/1689963835559_create_table_evm_params/down.sql @@ -0,0 +1 @@ +DROP TABLE "evm"."params"; diff --git a/hasura/migrations/default/1689963835559_create_table_evm_params/up.sql b/hasura/migrations/default/1689963835559_create_table_evm_params/up.sql new file mode 100644 index 00000000..aaba3008 --- /dev/null +++ b/hasura/migrations/default/1689963835559_create_table_evm_params/up.sql @@ -0,0 +1,2 @@ +CREATE TABLE "evm"."params" ("id" uuid NOT NULL DEFAULT gen_random_uuid(), "last_block_synced" numeric NOT NULL, PRIMARY KEY ("id") ); +CREATE EXTENSION IF NOT EXISTS pgcrypto; diff --git a/hasura/migrations/default/1689963954957_rename_table_evm_params/down.sql b/hasura/migrations/default/1689963954957_rename_table_evm_params/down.sql new file mode 100644 index 00000000..bfaa32fb --- /dev/null +++ b/hasura/migrations/default/1689963954957_rename_table_evm_params/down.sql @@ -0,0 +1 @@ +alter table "evm"."param" rename to "params"; diff --git a/hasura/migrations/default/1689963954957_rename_table_evm_params/up.sql b/hasura/migrations/default/1689963954957_rename_table_evm_params/up.sql new file mode 100644 index 00000000..6ff3d5cd --- /dev/null +++ b/hasura/migrations/default/1689963954957_rename_table_evm_params/up.sql @@ -0,0 +1 @@ +alter table "evm"."params" rename to "param"; diff --git a/hasura/migrations/default/1689964045956_create_table_evm_hyperion_state/down.sql b/hasura/migrations/default/1689964045956_create_table_evm_hyperion_state/down.sql new file mode 100644 index 00000000..7e7c39fb --- /dev/null +++ b/hasura/migrations/default/1689964045956_create_table_evm_hyperion_state/down.sql @@ -0,0 +1 @@ +DROP TABLE "evm"."hyperion_state"; diff --git a/hasura/migrations/default/1689964045956_create_table_evm_hyperion_state/up.sql b/hasura/migrations/default/1689964045956_create_table_evm_hyperion_state/up.sql new file mode 100644 index 00000000..4f40f17e --- /dev/null +++ b/hasura/migrations/default/1689964045956_create_table_evm_hyperion_state/up.sql @@ -0,0 +1,18 @@ +CREATE TABLE "evm"."hyperion_state" ("id" uuid NOT NULL DEFAULT gen_random_uuid(), "last_synced_at" timestamptz NOT NULL, "created_at" timestamptz NOT NULL DEFAULT now(), "updated_at" timestamptz NOT NULL DEFAULT now(), PRIMARY KEY ("id") ); +CREATE OR REPLACE FUNCTION "evm"."set_current_timestamp_updated_at"() +RETURNS TRIGGER AS $$ +DECLARE + _new record; +BEGIN + _new := NEW; + _new."updated_at" = NOW(); + RETURN _new; +END; +$$ LANGUAGE plpgsql; +CREATE TRIGGER "set_evm_hyperion_state_updated_at" +BEFORE UPDATE ON "evm"."hyperion_state" +FOR EACH ROW +EXECUTE PROCEDURE "evm"."set_current_timestamp_updated_at"(); +COMMENT ON TRIGGER "set_evm_hyperion_state_updated_at" ON "evm"."hyperion_state" +IS 'trigger to set value of column "updated_at" to current timestamp on row update'; +CREATE EXTENSION IF NOT EXISTS pgcrypto; diff --git a/hasura/migrations/default/1689983709652_create_table_evm_incoming_transfer/down.sql b/hasura/migrations/default/1689983709652_create_table_evm_incoming_transfer/down.sql new file mode 100644 index 00000000..5b3a9650 --- /dev/null +++ b/hasura/migrations/default/1689983709652_create_table_evm_incoming_transfer/down.sql @@ -0,0 +1 @@ +DROP TABLE "evm"."incoming_transfer"; diff --git a/hasura/migrations/default/1689983709652_create_table_evm_incoming_transfer/up.sql b/hasura/migrations/default/1689983709652_create_table_evm_incoming_transfer/up.sql new file mode 100644 index 00000000..012716d0 --- /dev/null +++ b/hasura/migrations/default/1689983709652_create_table_evm_incoming_transfer/up.sql @@ -0,0 +1,2 @@ +CREATE TABLE "evm"."incoming_transfer" ("id" uuid NOT NULL DEFAULT gen_random_uuid(), "block" numeric NOT NULL, "transaction_id" varchar NOT NULL, "from" varchar NOT NULL, "to" varchar NOT NULL, "amount" numeric NOT NULL, "symbol" varchar NOT NULL, "memo" varchar NOT NULL, "quantity" varchar NOT NULL, PRIMARY KEY ("id") );COMMENT ON TABLE "evm"."incoming_transfer" IS E'Incoming TLOS token transfer. (EOS account -> tEVM address)'; +CREATE EXTENSION IF NOT EXISTS pgcrypto; diff --git a/hasura/migrations/default/1689984918750_alter_table_evm_incoming_transfer_add_column_timestamp/down.sql b/hasura/migrations/default/1689984918750_alter_table_evm_incoming_transfer_add_column_timestamp/down.sql new file mode 100644 index 00000000..df06c440 --- /dev/null +++ b/hasura/migrations/default/1689984918750_alter_table_evm_incoming_transfer_add_column_timestamp/down.sql @@ -0,0 +1,4 @@ +-- Could not auto-generate a down migration. +-- Please write an appropriate down migration for the SQL below: +-- alter table "evm"."incoming_transfer" add column "timestamp" timestamptz +-- not null; diff --git a/hasura/migrations/default/1689984918750_alter_table_evm_incoming_transfer_add_column_timestamp/up.sql b/hasura/migrations/default/1689984918750_alter_table_evm_incoming_transfer_add_column_timestamp/up.sql new file mode 100644 index 00000000..9fbbb6b1 --- /dev/null +++ b/hasura/migrations/default/1689984918750_alter_table_evm_incoming_transfer_add_column_timestamp/up.sql @@ -0,0 +1,2 @@ +alter table "evm"."incoming_transfer" add column "timestamp" timestamptz + not null; From 7d3328cc756848fbe98cf66efeb83b768edd0bb4 Mon Sep 17 00:00:00 2001 From: Leister Francisco Alvarez Campos Date: Wed, 26 Jul 2023 13:03:29 -0600 Subject: [PATCH 07/75] feat(hapi-evm): track incoming and outgoing token transactions --- .../models/incoming-transfer/interfaces.ts | 12 ---- .../src/models/incoming-transfer/queries.ts | 34 ---------- hapi-evm/src/models/index.ts | 2 +- .../{incoming-transfer => transfer}/index.ts | 0 hapi-evm/src/models/transfer/interfaces.ts | 20 ++++++ hapi-evm/src/models/transfer/queries.ts | 33 +++++++++ hapi-evm/src/routes/v1/index.ts | 2 +- hapi-evm/src/services/block.service.ts | 2 - .../updaters/eosio-evm-transfer.updater.ts | 34 ++++++++++ .../src/services/hyperion/updaters/index.ts | 3 +- .../updaters/token-transfer.updater.ts | 10 ++- .../databases/default/tables/evm_stats.yaml | 3 + .../default/tables/evm_transfer.yaml | 3 + .../databases/default/tables/tables.yaml | 3 +- .../down.sql | 67 +++++++++++++++++++ .../up.sql | 65 ++++++++++++++++++ .../down.sql | 67 +++++++++++++++++++ .../up.sql | 65 ++++++++++++++++++ .../down.sql | 4 ++ .../up.sql | 2 + .../down.sql | 1 + .../up.sql | 1 + .../down.sql | 29 ++++++++ .../up.sql | 27 ++++++++ 24 files changed, 434 insertions(+), 55 deletions(-) delete mode 100644 hapi-evm/src/models/incoming-transfer/interfaces.ts delete mode 100644 hapi-evm/src/models/incoming-transfer/queries.ts rename hapi-evm/src/models/{incoming-transfer => transfer}/index.ts (100%) create mode 100644 hapi-evm/src/models/transfer/interfaces.ts create mode 100644 hapi-evm/src/models/transfer/queries.ts create mode 100644 hapi-evm/src/services/hyperion/updaters/eosio-evm-transfer.updater.ts create mode 100644 hasura/metadata/databases/default/tables/evm_stats.yaml create mode 100644 hasura/metadata/databases/default/tables/evm_transfer.yaml create mode 100644 hasura/migrations/default/1690322260794_create_evm_stats_view/down.sql create mode 100644 hasura/migrations/default/1690322260794_create_evm_stats_view/up.sql create mode 100644 hasura/migrations/default/1690322582361_create_evm_stats_view_v2/down.sql create mode 100644 hasura/migrations/default/1690322582361_create_evm_stats_view_v2/up.sql create mode 100644 hasura/migrations/default/1690396057707_alter_table_evm_incoming_transfer_add_column_type/down.sql create mode 100644 hasura/migrations/default/1690396057707_alter_table_evm_incoming_transfer_add_column_type/up.sql create mode 100644 hasura/migrations/default/1690396062626_rename_table_evm_incoming_transfer/down.sql create mode 100644 hasura/migrations/default/1690396062626_rename_table_evm_incoming_transfer/up.sql create mode 100644 hasura/migrations/default/1690397773824_create_evm_stats_view_v3/down.sql create mode 100644 hasura/migrations/default/1690397773824_create_evm_stats_view_v3/up.sql diff --git a/hapi-evm/src/models/incoming-transfer/interfaces.ts b/hapi-evm/src/models/incoming-transfer/interfaces.ts deleted file mode 100644 index 3504923f..00000000 --- a/hapi-evm/src/models/incoming-transfer/interfaces.ts +++ /dev/null @@ -1,12 +0,0 @@ -export interface IncomingTransfer { - id?: string - block: number - transaction_id: string - from: string - to: string - amount: number - symbol: string - memo: string - quantity: string - timestamp: string -} diff --git a/hapi-evm/src/models/incoming-transfer/queries.ts b/hapi-evm/src/models/incoming-transfer/queries.ts deleted file mode 100644 index ba1eaa3e..00000000 --- a/hapi-evm/src/models/incoming-transfer/queries.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { gql } from 'graphql-request' - -import { coreUtil } from '../../utils' -import { IncomingTransfer } from './interfaces' - -// interface IncomingTransferResponse { -// evm_incoming_transfer: IncomingTransfer[] -// } - -interface IncomingTransferInsertOneResponse { - insert_evm_incoming_transfer_one: { - id: string - } -} - -export const save = async (payload: IncomingTransfer) => { - const mutation = gql` - mutation ($payload: evm_incoming_transfer_insert_input!) { - insert_evm_incoming_transfer_one(object: $payload) { - id - } - } - ` - - const data = - await coreUtil.hasura.default.request( - mutation, - { - payload - } - ) - - return data.insert_evm_incoming_transfer_one -} diff --git a/hapi-evm/src/models/index.ts b/hapi-evm/src/models/index.ts index dc6d58a6..49ef529d 100644 --- a/hapi-evm/src/models/index.ts +++ b/hapi-evm/src/models/index.ts @@ -2,4 +2,4 @@ export * as defaultModel from './default.model' export * as blockModel from './block' export * as transactionModel from './transaction' export * as hyperionStateModel from './hyperion-state' -export * as incomingTransferModel from './incoming-transfer' +export * as transferModel from './transfer' diff --git a/hapi-evm/src/models/incoming-transfer/index.ts b/hapi-evm/src/models/transfer/index.ts similarity index 100% rename from hapi-evm/src/models/incoming-transfer/index.ts rename to hapi-evm/src/models/transfer/index.ts diff --git a/hapi-evm/src/models/transfer/interfaces.ts b/hapi-evm/src/models/transfer/interfaces.ts new file mode 100644 index 00000000..7e93f6d9 --- /dev/null +++ b/hapi-evm/src/models/transfer/interfaces.ts @@ -0,0 +1,20 @@ +export const Type = { + incoming: 'incoming', + outgoing: 'outgoing' +} as const + +export type TransferType = keyof typeof Type + +export interface Transfer { + id?: string + block: number + transaction_id: string + from: string + to: string + amount: number + symbol: string + memo: string + quantity: string + timestamp: string + type: TransferType +} diff --git a/hapi-evm/src/models/transfer/queries.ts b/hapi-evm/src/models/transfer/queries.ts new file mode 100644 index 00000000..aa2c9157 --- /dev/null +++ b/hapi-evm/src/models/transfer/queries.ts @@ -0,0 +1,33 @@ +import { gql } from 'graphql-request' + +import { coreUtil } from '../../utils' +import { Transfer } from './interfaces' + +// interface TransferResponse { +// evm_transfer: Transfer[] +// } + +interface TransferInsertOneResponse { + insert_evm_transfer_one: { + id: string + } +} + +export const save = async (payload: Transfer) => { + const mutation = gql` + mutation ($payload: evm_transfer_insert_input!) { + insert_evm_transfer_one(object: $payload) { + id + } + } + ` + + const data = await coreUtil.hasura.default.request( + mutation, + { + payload + } + ) + + return data.insert_evm_transfer_one +} diff --git a/hapi-evm/src/routes/v1/index.ts b/hapi-evm/src/routes/v1/index.ts index 6e2abe3d..b5fff73e 100644 --- a/hapi-evm/src/routes/v1/index.ts +++ b/hapi-evm/src/routes/v1/index.ts @@ -27,7 +27,7 @@ const baseRoute = '/v1' // () Average transactions per second (block and eosio.token -> ERC20). // - (NO) internal TLOS transactions. (tEVM address -> tEVM address) // - (OK) incoming TLOS transactions. (EOS address -> tEVM address) -// - () outgoing TLOS transactions. (tEVM address -> EOS address) HOW? +// - (OK) outgoing TLOS transactions. (tEVM address -> EOS address) HOW? // (OK) Daily transactions. // (OK) ATH. diff --git a/hapi-evm/src/services/block.service.ts b/hapi-evm/src/services/block.service.ts index d3e7066e..2ba59ab4 100644 --- a/hapi-evm/src/services/block.service.ts +++ b/hapi-evm/src/services/block.service.ts @@ -31,7 +31,6 @@ const getBlock = async () => { } const blockExist = await blockModel.queries.exist(block.hash.toString()) - console.log(`🚀 ~ blockExist(${block.hash.toString()}): ${blockExist}`) if (blockExist) return @@ -54,7 +53,6 @@ const getBlock = async () => { trxHash: TransactionHash ): Promise => { const transactionExist = await transactionModel.queries.exist(trxHash) - console.log('🚀 ~ getBlock ~ transactionExist:', transactionExist) if (transactionExist) { return acc diff --git a/hapi-evm/src/services/hyperion/updaters/eosio-evm-transfer.updater.ts b/hapi-evm/src/services/hyperion/updaters/eosio-evm-transfer.updater.ts new file mode 100644 index 00000000..cfc009cd --- /dev/null +++ b/hapi-evm/src/services/hyperion/updaters/eosio-evm-transfer.updater.ts @@ -0,0 +1,34 @@ +import { isAddress } from 'web3-validator' + +import { transferModel } from '../../../models' + +// TODO: handle this as a network function, for example, base on the +// network config, the action type and logic will be different + +// TODO: move this to env +const defaultMemo = 'Withdraw balance for' + +export default { + type: `eosio.evm:withdraw`, + notified_account: `eosio.evm`, + apply: async (action: any) => { + const [amount, symbol] = action.data.quantity.split(' ') + + try { + await transferModel.queries.save({ + block: action.block, + transaction_id: action.transaction_id, + timestamp: action.timestamp, + from: 'eosio.evm', + to: action.data.to, + amount: amount, + symbol: symbol, + memo: `${defaultMemo}: ${action.data.to}`, + quantity: action.data.quantity, + type: transferModel.interfaces.Type.outgoing + }) + } catch (error: any) { + console.error(`error to sync ${action.action}: ${error.message}`) + } + } +} diff --git a/hapi-evm/src/services/hyperion/updaters/index.ts b/hapi-evm/src/services/hyperion/updaters/index.ts index d3a15943..0565f3f8 100644 --- a/hapi-evm/src/services/hyperion/updaters/index.ts +++ b/hapi-evm/src/services/hyperion/updaters/index.ts @@ -1,3 +1,4 @@ import tokenTransferUpdater from './token-transfer.updater' +import eosioEvmWithdrawUpdater from './eosio-evm-transfer.updater' -export default [tokenTransferUpdater] +export default [tokenTransferUpdater, eosioEvmWithdrawUpdater] diff --git a/hapi-evm/src/services/hyperion/updaters/token-transfer.updater.ts b/hapi-evm/src/services/hyperion/updaters/token-transfer.updater.ts index 8191062e..f546f401 100644 --- a/hapi-evm/src/services/hyperion/updaters/token-transfer.updater.ts +++ b/hapi-evm/src/services/hyperion/updaters/token-transfer.updater.ts @@ -1,6 +1,9 @@ import { isAddress } from 'web3-validator' -import { incomingTransferModel } from '../../../models' +import { transferModel } from '../../../models' + +// TODO: handle this as a network function, for example, base on the +// network config, the action type and logic will be different export default { type: `eosio.token:transfer,act.data.to=eosio.evm`, @@ -11,7 +14,7 @@ export default { } try { - await incomingTransferModel.queries.save({ + await transferModel.queries.save({ block: action.block, transaction_id: action.transaction_id, timestamp: action.timestamp, @@ -20,7 +23,8 @@ export default { amount: action.data.amount, symbol: action.data.symbol, memo: action.data.memo, - quantity: action.data.quantity + quantity: action.data.quantity, + type: transferModel.interfaces.Type.incoming }) } catch (error: any) { console.error(`error to sync ${action.action}: ${error.message}`) diff --git a/hasura/metadata/databases/default/tables/evm_stats.yaml b/hasura/metadata/databases/default/tables/evm_stats.yaml new file mode 100644 index 00000000..b99a0f1b --- /dev/null +++ b/hasura/metadata/databases/default/tables/evm_stats.yaml @@ -0,0 +1,3 @@ +table: + name: stats + schema: evm diff --git a/hasura/metadata/databases/default/tables/evm_transfer.yaml b/hasura/metadata/databases/default/tables/evm_transfer.yaml new file mode 100644 index 00000000..c7fc82a0 --- /dev/null +++ b/hasura/metadata/databases/default/tables/evm_transfer.yaml @@ -0,0 +1,3 @@ +table: + name: transfer + schema: evm diff --git a/hasura/metadata/databases/default/tables/tables.yaml b/hasura/metadata/databases/default/tables/tables.yaml index 4cf2b197..c741a2a0 100644 --- a/hasura/metadata/databases/default/tables/tables.yaml +++ b/hasura/metadata/databases/default/tables/tables.yaml @@ -1,8 +1,9 @@ - "!include evm_block.yaml" - "!include evm_hyperion_state.yaml" -- "!include evm_incoming_transfer.yaml" - "!include evm_param.yaml" +- "!include evm_stats.yaml" - "!include evm_transaction.yaml" +- "!include evm_transfer.yaml" - "!include public_block_history.yaml" - "!include public_block_history_by_producer_type.yaml" - "!include public_check_history_by_endpoint.yaml" diff --git a/hasura/migrations/default/1690322260794_create_evm_stats_view/down.sql b/hasura/migrations/default/1690322260794_create_evm_stats_view/down.sql new file mode 100644 index 00000000..d344e151 --- /dev/null +++ b/hasura/migrations/default/1690322260794_create_evm_stats_view/down.sql @@ -0,0 +1,67 @@ +-- Could not auto-generate a down migration. +-- Please write an appropriate down migration for the SQL below: +-- CREATE OR REPLACE VIEW "evm"."stats" AS +-- SELECT +-- evm_block.avg_gas_used AS block_gas_avg, +-- daily_transactions.total_transaction_count AS daily_transaction_count, +-- ath.max_transaction_sum AS ath_transaction_sum, +-- incoming_tlos.transfer_count AS incoming_tlos_count +-- FROM +-- ( +-- ( +-- ( +-- ( +-- SELECT AVG(subquery_alias.gas_used) AS avg_gas_used +-- FROM ( +-- SELECT gas_used, timestamp +-- FROM evm.block +-- ORDER BY timestamp DESC +-- LIMIT 100 +-- ) subquery_alias +-- ) evm_block +-- CROSS JOIN LATERAL ( +-- SELECT +-- sum(jsonb_array_length(block.transactions)) AS total_transaction_count +-- FROM +-- evm.block +-- WHERE +-- ( +-- block.timestamp >= (now() - '24:00:00' :: interval) +-- ) +-- ) daily_transactions +-- ) +-- CROSS JOIN LATERAL ( +-- SELECT +-- max(pairs_sum.total_transaction_count) AS max_transaction_sum +-- FROM +-- ( +-- SELECT +-- ( +-- (b1.number || ' and ' :: text) || (b1.number + (1) :: numeric) +-- ) AS block_pair, +-- sum( +-- ( +-- jsonb_array_length(b1.transactions) + jsonb_array_length(b2.transactions) +-- ) +-- ) AS total_transaction_count +-- FROM +-- ( +-- evm.block b1 +-- LEFT JOIN evm.block b2 ON ((b1.number = (b2.number - (1) :: numeric))) +-- ) +-- WHERE +-- ((b1.number % (2) :: numeric) = (0) :: numeric) +-- GROUP BY +-- ( +-- (b1.number || ' and ' :: text) || (b1.number + (1) :: numeric) +-- ) +-- ) pairs_sum +-- ) ath +-- ) +-- CROSS JOIN LATERAL ( +-- SELECT +-- count(incoming_transfer.id) AS transfer_count +-- FROM +-- evm.incoming_transfer +-- ) incoming_tlos +-- ); diff --git a/hasura/migrations/default/1690322260794_create_evm_stats_view/up.sql b/hasura/migrations/default/1690322260794_create_evm_stats_view/up.sql new file mode 100644 index 00000000..bbdcfd43 --- /dev/null +++ b/hasura/migrations/default/1690322260794_create_evm_stats_view/up.sql @@ -0,0 +1,65 @@ +CREATE OR REPLACE VIEW "evm"."stats" AS +SELECT + evm_block.avg_gas_used AS block_gas_avg, + daily_transactions.total_transaction_count AS daily_transaction_count, + ath.max_transaction_sum AS ath_transaction_sum, + incoming_tlos.transfer_count AS incoming_tlos_count +FROM + ( + ( + ( + ( + SELECT AVG(subquery_alias.gas_used) AS avg_gas_used + FROM ( + SELECT gas_used, timestamp + FROM evm.block + ORDER BY timestamp DESC + LIMIT 100 + ) subquery_alias + ) evm_block + CROSS JOIN LATERAL ( + SELECT + sum(jsonb_array_length(block.transactions)) AS total_transaction_count + FROM + evm.block + WHERE + ( + block.timestamp >= (now() - '24:00:00' :: interval) + ) + ) daily_transactions + ) + CROSS JOIN LATERAL ( + SELECT + max(pairs_sum.total_transaction_count) AS max_transaction_sum + FROM + ( + SELECT + ( + (b1.number || ' and ' :: text) || (b1.number + (1) :: numeric) + ) AS block_pair, + sum( + ( + jsonb_array_length(b1.transactions) + jsonb_array_length(b2.transactions) + ) + ) AS total_transaction_count + FROM + ( + evm.block b1 + LEFT JOIN evm.block b2 ON ((b1.number = (b2.number - (1) :: numeric))) + ) + WHERE + ((b1.number % (2) :: numeric) = (0) :: numeric) + GROUP BY + ( + (b1.number || ' and ' :: text) || (b1.number + (1) :: numeric) + ) + ) pairs_sum + ) ath + ) + CROSS JOIN LATERAL ( + SELECT + count(incoming_transfer.id) AS transfer_count + FROM + evm.incoming_transfer + ) incoming_tlos + ); diff --git a/hasura/migrations/default/1690322582361_create_evm_stats_view_v2/down.sql b/hasura/migrations/default/1690322582361_create_evm_stats_view_v2/down.sql new file mode 100644 index 00000000..97b59a23 --- /dev/null +++ b/hasura/migrations/default/1690322582361_create_evm_stats_view_v2/down.sql @@ -0,0 +1,67 @@ +-- Could not auto-generate a down migration. +-- Please write an appropriate down migration for the SQL below: +-- CREATE OR REPLACE VIEW "evm"."stats" AS +-- SELECT +-- COALESCE(evm_block.avg_gas_used, 0) AS block_gas_avg, +-- COALESCE(daily_transactions.total_transaction_count, 0) AS daily_transaction_count, +-- COALESCE(ath.max_transaction_sum, 0) AS ath_transaction_sum, +-- COALESCE(incoming_tlos.transfer_count, 0) AS incoming_tlos_count +-- FROM +-- ( +-- ( +-- ( +-- ( +-- SELECT AVG(subquery_alias.gas_used) AS avg_gas_used +-- FROM ( +-- SELECT gas_used, timestamp +-- FROM evm.block +-- ORDER BY timestamp DESC +-- LIMIT 100 +-- ) subquery_alias +-- ) evm_block +-- CROSS JOIN LATERAL ( +-- SELECT +-- sum(jsonb_array_length(block.transactions)) AS total_transaction_count +-- FROM +-- evm.block +-- WHERE +-- ( +-- block.timestamp >= (now() - '24:00:00' :: interval) +-- ) +-- ) daily_transactions +-- ) +-- CROSS JOIN LATERAL ( +-- SELECT +-- max(pairs_sum.total_transaction_count) AS max_transaction_sum +-- FROM +-- ( +-- SELECT +-- ( +-- (b1.number || ' and ' :: text) || (b1.number + (1) :: numeric) +-- ) AS block_pair, +-- sum( +-- ( +-- jsonb_array_length(b1.transactions) + jsonb_array_length(b2.transactions) +-- ) +-- ) AS total_transaction_count +-- FROM +-- ( +-- evm.block b1 +-- LEFT JOIN evm.block b2 ON ((b1.number = (b2.number - (1) :: numeric))) +-- ) +-- WHERE +-- ((b1.number % (2) :: numeric) = (0) :: numeric) +-- GROUP BY +-- ( +-- (b1.number || ' and ' :: text) || (b1.number + (1) :: numeric) +-- ) +-- ) pairs_sum +-- ) ath +-- ) +-- CROSS JOIN LATERAL ( +-- SELECT +-- count(incoming_transfer.id) AS transfer_count +-- FROM +-- evm.incoming_transfer +-- ) incoming_tlos +-- ); diff --git a/hasura/migrations/default/1690322582361_create_evm_stats_view_v2/up.sql b/hasura/migrations/default/1690322582361_create_evm_stats_view_v2/up.sql new file mode 100644 index 00000000..763f92f5 --- /dev/null +++ b/hasura/migrations/default/1690322582361_create_evm_stats_view_v2/up.sql @@ -0,0 +1,65 @@ +CREATE OR REPLACE VIEW "evm"."stats" AS +SELECT + COALESCE(evm_block.avg_gas_used, 0) AS block_gas_avg, + COALESCE(daily_transactions.total_transaction_count, 0) AS daily_transaction_count, + COALESCE(ath.max_transaction_sum, 0) AS ath_transaction_sum, + COALESCE(incoming_tlos.transfer_count, 0) AS incoming_tlos_count +FROM + ( + ( + ( + ( + SELECT AVG(subquery_alias.gas_used) AS avg_gas_used + FROM ( + SELECT gas_used, timestamp + FROM evm.block + ORDER BY timestamp DESC + LIMIT 100 + ) subquery_alias + ) evm_block + CROSS JOIN LATERAL ( + SELECT + sum(jsonb_array_length(block.transactions)) AS total_transaction_count + FROM + evm.block + WHERE + ( + block.timestamp >= (now() - '24:00:00' :: interval) + ) + ) daily_transactions + ) + CROSS JOIN LATERAL ( + SELECT + max(pairs_sum.total_transaction_count) AS max_transaction_sum + FROM + ( + SELECT + ( + (b1.number || ' and ' :: text) || (b1.number + (1) :: numeric) + ) AS block_pair, + sum( + ( + jsonb_array_length(b1.transactions) + jsonb_array_length(b2.transactions) + ) + ) AS total_transaction_count + FROM + ( + evm.block b1 + LEFT JOIN evm.block b2 ON ((b1.number = (b2.number - (1) :: numeric))) + ) + WHERE + ((b1.number % (2) :: numeric) = (0) :: numeric) + GROUP BY + ( + (b1.number || ' and ' :: text) || (b1.number + (1) :: numeric) + ) + ) pairs_sum + ) ath + ) + CROSS JOIN LATERAL ( + SELECT + count(incoming_transfer.id) AS transfer_count + FROM + evm.incoming_transfer + ) incoming_tlos + ); diff --git a/hasura/migrations/default/1690396057707_alter_table_evm_incoming_transfer_add_column_type/down.sql b/hasura/migrations/default/1690396057707_alter_table_evm_incoming_transfer_add_column_type/down.sql new file mode 100644 index 00000000..418d6181 --- /dev/null +++ b/hasura/migrations/default/1690396057707_alter_table_evm_incoming_transfer_add_column_type/down.sql @@ -0,0 +1,4 @@ +-- Could not auto-generate a down migration. +-- Please write an appropriate down migration for the SQL below: +-- alter table "evm"."incoming_transfer" add column "type" varchar +-- not null default 'incoming'; diff --git a/hasura/migrations/default/1690396057707_alter_table_evm_incoming_transfer_add_column_type/up.sql b/hasura/migrations/default/1690396057707_alter_table_evm_incoming_transfer_add_column_type/up.sql new file mode 100644 index 00000000..856ef635 --- /dev/null +++ b/hasura/migrations/default/1690396057707_alter_table_evm_incoming_transfer_add_column_type/up.sql @@ -0,0 +1,2 @@ +alter table "evm"."incoming_transfer" add column "type" varchar + not null default 'incoming'; diff --git a/hasura/migrations/default/1690396062626_rename_table_evm_incoming_transfer/down.sql b/hasura/migrations/default/1690396062626_rename_table_evm_incoming_transfer/down.sql new file mode 100644 index 00000000..4da99809 --- /dev/null +++ b/hasura/migrations/default/1690396062626_rename_table_evm_incoming_transfer/down.sql @@ -0,0 +1 @@ +alter table "evm"."transfer" rename to "incoming_transfer"; diff --git a/hasura/migrations/default/1690396062626_rename_table_evm_incoming_transfer/up.sql b/hasura/migrations/default/1690396062626_rename_table_evm_incoming_transfer/up.sql new file mode 100644 index 00000000..1508c275 --- /dev/null +++ b/hasura/migrations/default/1690396062626_rename_table_evm_incoming_transfer/up.sql @@ -0,0 +1 @@ +alter table "evm"."incoming_transfer" rename to "transfer"; diff --git a/hasura/migrations/default/1690397773824_create_evm_stats_view_v3/down.sql b/hasura/migrations/default/1690397773824_create_evm_stats_view_v3/down.sql new file mode 100644 index 00000000..c5a71f2f --- /dev/null +++ b/hasura/migrations/default/1690397773824_create_evm_stats_view_v3/down.sql @@ -0,0 +1,29 @@ +-- Could not auto-generate a down migration. +-- Please write an appropriate down migration for the SQL below: +-- CREATE OR REPLACE VIEW "evm"."stats" AS +-- SELECT COALESCE(evm_block.avg_gas_used, (0)::numeric) AS block_gas_avg, +-- COALESCE(daily_transactions.total_transaction_count, (0)::bigint) AS daily_transaction_count, +-- COALESCE(ath.max_transaction_sum, (0)::bigint) AS ath_transaction_sum, +-- COALESCE(incoming_tlos.incoming_transfer_count, (0)::bigint) AS incoming_tlos_count, +-- COALESCE(incoming_tlos.outgoing_transfer_count, (0)::bigint) AS outgoing_tlos_count +-- FROM (((( SELECT avg(subquery_alias.gas_used) AS avg_gas_used +-- FROM ( SELECT block.gas_used, +-- block."timestamp" +-- FROM evm.block +-- ORDER BY block."timestamp" DESC +-- LIMIT 100) subquery_alias) evm_block +-- CROSS JOIN LATERAL ( SELECT sum(jsonb_array_length(block.transactions)) AS total_transaction_count +-- FROM evm.block +-- WHERE (block."timestamp" >= (now() - '24:00:00'::interval))) daily_transactions) +-- CROSS JOIN LATERAL ( SELECT max(pairs_sum.total_transaction_count) AS max_transaction_sum +-- FROM ( SELECT ((b1.number || ' and '::text) || (b1.number + (1)::numeric)) AS block_pair, +-- sum((jsonb_array_length(b1.transactions) + jsonb_array_length(b2.transactions))) AS total_transaction_count +-- FROM (evm.block b1 +-- LEFT JOIN evm.block b2 ON ((b1.number = (b2.number - (1)::numeric)))) +-- WHERE ((b1.number % (2)::numeric) = (0)::numeric) +-- GROUP BY ((b1.number || ' and '::text) || (b1.number + (1)::numeric))) pairs_sum) ath) +-- CROSS JOIN LATERAL ( SELECT +-- COUNT(CASE WHEN transfer.type = 'incoming' THEN 1 END) AS incoming_transfer_count, +-- COUNT(CASE WHEN transfer.type = 'outgoing' THEN 1 END) AS outgoing_transfer_count +-- FROM +-- evm.transfer) incoming_tlos); diff --git a/hasura/migrations/default/1690397773824_create_evm_stats_view_v3/up.sql b/hasura/migrations/default/1690397773824_create_evm_stats_view_v3/up.sql new file mode 100644 index 00000000..9534b55f --- /dev/null +++ b/hasura/migrations/default/1690397773824_create_evm_stats_view_v3/up.sql @@ -0,0 +1,27 @@ +CREATE OR REPLACE VIEW "evm"."stats" AS + SELECT COALESCE(evm_block.avg_gas_used, (0)::numeric) AS block_gas_avg, + COALESCE(daily_transactions.total_transaction_count, (0)::bigint) AS daily_transaction_count, + COALESCE(ath.max_transaction_sum, (0)::bigint) AS ath_transaction_sum, + COALESCE(incoming_tlos.incoming_transfer_count, (0)::bigint) AS incoming_tlos_count, + COALESCE(incoming_tlos.outgoing_transfer_count, (0)::bigint) AS outgoing_tlos_count + FROM (((( SELECT avg(subquery_alias.gas_used) AS avg_gas_used + FROM ( SELECT block.gas_used, + block."timestamp" + FROM evm.block + ORDER BY block."timestamp" DESC + LIMIT 100) subquery_alias) evm_block + CROSS JOIN LATERAL ( SELECT sum(jsonb_array_length(block.transactions)) AS total_transaction_count + FROM evm.block + WHERE (block."timestamp" >= (now() - '24:00:00'::interval))) daily_transactions) + CROSS JOIN LATERAL ( SELECT max(pairs_sum.total_transaction_count) AS max_transaction_sum + FROM ( SELECT ((b1.number || ' and '::text) || (b1.number + (1)::numeric)) AS block_pair, + sum((jsonb_array_length(b1.transactions) + jsonb_array_length(b2.transactions))) AS total_transaction_count + FROM (evm.block b1 + LEFT JOIN evm.block b2 ON ((b1.number = (b2.number - (1)::numeric)))) + WHERE ((b1.number % (2)::numeric) = (0)::numeric) + GROUP BY ((b1.number || ' and '::text) || (b1.number + (1)::numeric))) pairs_sum) ath) + CROSS JOIN LATERAL ( SELECT + COUNT(CASE WHEN transfer.type = 'incoming' THEN 1 END) AS incoming_transfer_count, + COUNT(CASE WHEN transfer.type = 'outgoing' THEN 1 END) AS outgoing_transfer_count +FROM + evm.transfer) incoming_tlos); From 11803d746554b062468b0bca9f976d01ee221e30 Mon Sep 17 00:00:00 2001 From: Leister Francisco Alvarez Campos Date: Wed, 26 Jul 2023 14:34:07 -0600 Subject: [PATCH 08/75] chore(hapi-evm): clean code --- hapi-evm/src/routes/v1/index.ts | 27 --------------------------- hapi-evm/src/services/gas.service.ts | 3 --- makefile | 4 ++-- 3 files changed, 2 insertions(+), 32 deletions(-) delete mode 100644 hapi-evm/src/services/gas.service.ts diff --git a/hapi-evm/src/routes/v1/index.ts b/hapi-evm/src/routes/v1/index.ts index b5fff73e..ad108971 100644 --- a/hapi-evm/src/routes/v1/index.ts +++ b/hapi-evm/src/routes/v1/index.ts @@ -4,33 +4,6 @@ import { Server } from '@hapi/hapi' const baseRoute = '/v1' -// tables -// evm-params -// - max blocks -// - last block synced -// - sync blocks interval -// - update stats interval (in case of a table that stores the metricts of the last certain blocks) - -// evm-blocks -// - block number -// - block hash - -// evm-transactions -// - block number -// - transaction hash - -// evm-global -// - last block number -// - ATH - -// (OK) Average gas usage: Show to average gas usage in the last 100 blocks. -// () Average transactions per second (block and eosio.token -> ERC20). -// - (NO) internal TLOS transactions. (tEVM address -> tEVM address) -// - (OK) incoming TLOS transactions. (EOS address -> tEVM address) -// - (OK) outgoing TLOS transactions. (tEVM address -> EOS address) HOW? -// (OK) Daily transactions. -// (OK) ATH. - export default (server: Server) => { // exampleRoutes.routes(server, baseRoute) } diff --git a/hapi-evm/src/services/gas.service.ts b/hapi-evm/src/services/gas.service.ts deleted file mode 100644 index 81ffcb11..00000000 --- a/hapi-evm/src/services/gas.service.ts +++ /dev/null @@ -1,3 +0,0 @@ -import {hasura} from '../utils/core'; - - diff --git a/makefile b/makefile index 73382ea5..8e1f0810 100644 --- a/makefile +++ b/makefile @@ -99,9 +99,9 @@ stop: start: make start-postgres - # make start-wallet + make start-wallet make start-hapi - make start-hapi-evm + # make start-hapi-evm make start-hasura make -j 3 start-hasura-cli start-logs start-webapp From c1dd6daf16e17abf0faa684d77288fa7073c9205 Mon Sep 17 00:00:00 2001 From: Leister Francisco Alvarez Campos Date: Fri, 28 Jul 2023 13:24:58 -0600 Subject: [PATCH 09/75] perf(hapi-evm): sync old blocks structure --- hapi-evm/package.json | 4 +- hapi-evm/src/models/param/index.ts | 2 + hapi-evm/src/models/param/interfaces.ts | 4 + hapi-evm/src/models/param/queries.ts | 91 +++++++++++++++++++ hapi-evm/src/services/block.service.ts | 15 ++- hapi-evm/src/services/worker/index.ts | 1 + .../down.sql | 1 + .../up.sql | 1 + 8 files changed, 116 insertions(+), 3 deletions(-) create mode 100644 hapi-evm/src/models/param/index.ts create mode 100644 hapi-evm/src/models/param/interfaces.ts create mode 100644 hapi-evm/src/models/param/queries.ts create mode 100644 hasura/migrations/default/1690561974241_alter_table_evm_param_alter_column_last_block_synced/down.sql create mode 100644 hasura/migrations/default/1690561974241_alter_table_evm_param_alter_column_last_block_synced/up.sql diff --git a/hapi-evm/package.json b/hapi-evm/package.json index e1348ec9..44e95370 100644 --- a/hapi-evm/package.json +++ b/hapi-evm/package.json @@ -1,7 +1,7 @@ { - "name": "backend-boilerplate", + "name": "evm-backend", "version": "1.0.0", - "description": "AntelopeIO Boilerplate for backend development", + "description": "EVM Dashbaord Backend Service", "main": "dist/index.js", "author": "edenia.com", "license": "MIT", diff --git a/hapi-evm/src/models/param/index.ts b/hapi-evm/src/models/param/index.ts new file mode 100644 index 00000000..5e08e0f1 --- /dev/null +++ b/hapi-evm/src/models/param/index.ts @@ -0,0 +1,2 @@ +export * as interfaces from './interfaces' +export * as queries from './queries' diff --git a/hapi-evm/src/models/param/interfaces.ts b/hapi-evm/src/models/param/interfaces.ts new file mode 100644 index 00000000..85e10d01 --- /dev/null +++ b/hapi-evm/src/models/param/interfaces.ts @@ -0,0 +1,4 @@ +export interface Param { + id: string + next_block: number +} diff --git a/hapi-evm/src/models/param/queries.ts b/hapi-evm/src/models/param/queries.ts new file mode 100644 index 00000000..0afa4532 --- /dev/null +++ b/hapi-evm/src/models/param/queries.ts @@ -0,0 +1,91 @@ +import { gql } from 'graphql-request' + +import { coreUtil } from '../../utils' +import { Param } from './interfaces' + +interface ParamResponse { + evm_param: Param[] +} + +interface ParamOneResponse { + insert_evm_param_one: { + id: string + } +} + +export const save = async (nextBlock: number) => { + const mutation = gql` + mutation ($payload: evm_param_insert_input!) { + insert_evm_param_one(object: $payload) { + id + } + } + ` + + const data = await coreUtil.hasura.default.request( + mutation, + { + payload: { + next_block: nextBlock + } + } + ) + + return data.insert_evm_param_one +} + +export const update = async (id: string, nextBlock: number) => { + const mutation = gql` + mutation ($id: uuid!, $payload: evm_param_set_input) { + update_evm_param_by_pk(pk_columns: { id: $id }, _set: $payload) { + id + next_block + } + } + ` + + await coreUtil.hasura.default.request(mutation, { + id, + payload: { + next_block: nextBlock + } + }) +} + +export const getState = async () => { + const query = gql` + query { + evm_param( + where: { id: { _neq: "00000000-0000-0000-0000-000000000000" } } + limit: 1 + ) { + id + next_block + } + } + ` + const data = await coreUtil.hasura.default.request(query) + + if (!data.evm_param.length) { + return + } + + const state = data.evm_param[0] + + return { + id: state.id, + nextBlock: state.next_block + } +} + +export const saveOrUpdate = async (nextBlock: number): Promise => { + const currentState = await getState() + + if (!currentState) { + await save(nextBlock) + + return + } + + await update(currentState.id, nextBlock) +} diff --git a/hapi-evm/src/services/block.service.ts b/hapi-evm/src/services/block.service.ts index 2ba59ab4..692ee5c3 100644 --- a/hapi-evm/src/services/block.service.ts +++ b/hapi-evm/src/services/block.service.ts @@ -81,6 +81,10 @@ const getBlock = async () => { await Promise.all(transactionsPromises) } +const syncOldBlocks = async (): Promise => { + // code +} + const blockWorker = async () => { getBlock() } @@ -93,6 +97,15 @@ const syncBlockWorker = (): defaultModel.Worker => { } } +const syncOldBlockWorker = (): defaultModel.Worker => { + return { + name: 'SYNC OLD BLOCK WORKER', + intervalSec: 1, + action: syncOldBlocks + } +} + export default { - syncBlockWorker + syncBlockWorker, + syncOldBlockWorker } diff --git a/hapi-evm/src/services/worker/index.ts b/hapi-evm/src/services/worker/index.ts index 1ad8fcc4..65570ca1 100644 --- a/hapi-evm/src/services/worker/index.ts +++ b/hapi-evm/src/services/worker/index.ts @@ -21,6 +21,7 @@ const run = async (worker: defaultModel.Worker) => { const init = async () => { await coreUtil.hasura.hasuraAssembled() + run(blockService.syncOldBlockWorker()) // run(blockService.syncBlockWorker()) run(hyperionService.syncWorker()) } diff --git a/hasura/migrations/default/1690561974241_alter_table_evm_param_alter_column_last_block_synced/down.sql b/hasura/migrations/default/1690561974241_alter_table_evm_param_alter_column_last_block_synced/down.sql new file mode 100644 index 00000000..a06e7ffb --- /dev/null +++ b/hasura/migrations/default/1690561974241_alter_table_evm_param_alter_column_last_block_synced/down.sql @@ -0,0 +1 @@ +alter table "evm"."param" rename column "next_block" to "last_block_synced"; diff --git a/hasura/migrations/default/1690561974241_alter_table_evm_param_alter_column_last_block_synced/up.sql b/hasura/migrations/default/1690561974241_alter_table_evm_param_alter_column_last_block_synced/up.sql new file mode 100644 index 00000000..c3d5a473 --- /dev/null +++ b/hasura/migrations/default/1690561974241_alter_table_evm_param_alter_column_last_block_synced/up.sql @@ -0,0 +1 @@ +alter table "evm"."param" rename column "last_block_synced" to "next_block"; From 4808f8b5c3cc3143d72eced23bd426f2bf95c02c Mon Sep 17 00:00:00 2001 From: Leister Francisco Alvarez Campos Date: Fri, 28 Jul 2023 19:05:13 -0600 Subject: [PATCH 10/75] feat(hapi-evm): sync old blocks --- hapi-evm/src/models/block/queries.ts | 33 ++++++++++++-- hapi-evm/src/models/index.ts | 1 + hapi-evm/src/models/param/interfaces.ts | 1 + hapi-evm/src/models/param/queries.ts | 38 +++++++++++----- hapi-evm/src/services/block.service.ts | 43 ++++++++++++++++--- .../down.sql | 4 ++ .../up.sql | 2 + 7 files changed, 104 insertions(+), 18 deletions(-) create mode 100644 hasura/migrations/default/1690573147430_alter_table_evm_param_add_column_is_synced/down.sql create mode 100644 hasura/migrations/default/1690573147430_alter_table_evm_param_add_column_is_synced/up.sql diff --git a/hapi-evm/src/models/block/queries.ts b/hapi-evm/src/models/block/queries.ts index 367ceec5..883ece5d 100644 --- a/hapi-evm/src/models/block/queries.ts +++ b/hapi-evm/src/models/block/queries.ts @@ -45,12 +45,16 @@ const internal_get = async ( }) } -export const exist = async (hash: string) => { +export const exist = async (hashOrNumber: string | number) => { const result = await internal_get( 'query', 'evm_block', '$where: evm_block_bool_exp!', - { hash: { _eq: hash } }, + { + [typeof hashOrNumber === 'string' ? 'hash' : 'number']: { + _eq: hashOrNumber + } + }, 'aggregate { count }', 'aggregate' ) @@ -70,6 +74,28 @@ const get = async (where: object, many = false) => { return many ? result.evm_block : result.evm_block[0] } +const getCustom = async (query: string) => { + const data = await coreUtil.hasura.default.request(query) + + return data.evm_block +} + +const getNextBlock = async (block: number) => { + const query = gql` + query { + evm_block( + limit: 1 + order_by: { number: asc } + where: { number: { _gt: ${block} } } + ) { + number + } + } + ` + + return await getCustom(query) +} + export const add_or_modify = async (block: CappedBlock) => { const mutation = gql` mutation ($evm_block: evm_block_insert_input!) { @@ -88,5 +114,6 @@ export const add_or_modify = async (block: CappedBlock) => { export default { exist, - get + get, + getNextBlock } diff --git a/hapi-evm/src/models/index.ts b/hapi-evm/src/models/index.ts index 49ef529d..6621f500 100644 --- a/hapi-evm/src/models/index.ts +++ b/hapi-evm/src/models/index.ts @@ -3,3 +3,4 @@ export * as blockModel from './block' export * as transactionModel from './transaction' export * as hyperionStateModel from './hyperion-state' export * as transferModel from './transfer' +export * as paramModel from './param' diff --git a/hapi-evm/src/models/param/interfaces.ts b/hapi-evm/src/models/param/interfaces.ts index 85e10d01..08e89a86 100644 --- a/hapi-evm/src/models/param/interfaces.ts +++ b/hapi-evm/src/models/param/interfaces.ts @@ -1,4 +1,5 @@ export interface Param { id: string next_block: number + is_synced: boolean } diff --git a/hapi-evm/src/models/param/queries.ts b/hapi-evm/src/models/param/queries.ts index 0afa4532..4f7eb709 100644 --- a/hapi-evm/src/models/param/queries.ts +++ b/hapi-evm/src/models/param/queries.ts @@ -13,7 +13,13 @@ interface ParamOneResponse { } } -export const save = async (nextBlock: number) => { +const defaultParam = { + id: '00000000-0000-0000-0000-000000000000', + nextBlock: 0, + isSynced: false +} + +export const save = async (nextBlock: number, isSynced: boolean = false) => { const mutation = gql` mutation ($payload: evm_param_insert_input!) { insert_evm_param_one(object: $payload) { @@ -26,7 +32,8 @@ export const save = async (nextBlock: number) => { mutation, { payload: { - next_block: nextBlock + next_block: nextBlock, + is_synced: isSynced } } ) @@ -34,12 +41,17 @@ export const save = async (nextBlock: number) => { return data.insert_evm_param_one } -export const update = async (id: string, nextBlock: number) => { +export const update = async ( + id: string, + nextBlock: number, + isSynced: boolean = false +) => { const mutation = gql` mutation ($id: uuid!, $payload: evm_param_set_input) { update_evm_param_by_pk(pk_columns: { id: $id }, _set: $payload) { id next_block + is_synced } } ` @@ -47,7 +59,8 @@ export const update = async (id: string, nextBlock: number) => { await coreUtil.hasura.default.request(mutation, { id, payload: { - next_block: nextBlock + next_block: nextBlock, + is_synced: isSynced } }) } @@ -61,31 +74,36 @@ export const getState = async () => { ) { id next_block + is_synced } } ` const data = await coreUtil.hasura.default.request(query) if (!data.evm_param.length) { - return + return defaultParam } const state = data.evm_param[0] return { id: state.id, - nextBlock: state.next_block + nextBlock: state.next_block, + isSynced: state.is_synced } } -export const saveOrUpdate = async (nextBlock: number): Promise => { +export const saveOrUpdate = async ( + nextBlock: number, + isSynced: boolean +): Promise => { const currentState = await getState() - if (!currentState) { - await save(nextBlock) + if (currentState === defaultParam) { + await save(nextBlock, isSynced) return } - await update(currentState.id, nextBlock) + await update(currentState.id, nextBlock, isSynced) } diff --git a/hapi-evm/src/services/block.service.ts b/hapi-evm/src/services/block.service.ts index 692ee5c3..a5f9fb50 100644 --- a/hapi-evm/src/services/block.service.ts +++ b/hapi-evm/src/services/block.service.ts @@ -1,7 +1,12 @@ import { Web3 } from 'web3' import { Block, TransactionInfo, TransactionHash } from 'web3-types' -import { defaultModel, blockModel, transactionModel } from '../models' +import { + defaultModel, + blockModel, + transactionModel, + paramModel +} from '../models' import { networkConfig } from '../config' const httpProvider = new Web3.providers.HttpProvider(networkConfig.evmEndpoint) @@ -22,8 +27,7 @@ const web3 = new Web3(httpProvider) // TODO: syncronize passed blocks -const getBlock = async () => { - const blockNumber = await web3.eth.getBlockNumber() +const syncFullBlock = async (blockNumber: number | bigint) => { const block: Block = await web3.eth.getBlock(blockNumber) if (!block.hash) { @@ -81,8 +85,37 @@ const getBlock = async () => { await Promise.all(transactionsPromises) } +const getBlock = async () => { + const blockNumber = await web3.eth.getBlockNumber() + + await syncFullBlock(blockNumber) +} + const syncOldBlocks = async (): Promise => { - // code + const paramStats = await paramModel.queries.getState() + + if (paramStats.isSynced) return + + const nextBlock = paramStats.nextBlock + const isUpToDate = await blockModel.queries.default.get({ + number: { _eq: nextBlock } + }) + + if (!isUpToDate) { + const nextBlockTo = await blockModel.queries.default.getNextBlock(nextBlock) + const nextBlockToNumber = nextBlockTo[0].number || 0 + + if (nextBlockToNumber > nextBlock) { + console.log(`🚦 ${nextBlockToNumber - nextBlock} blocks behind`) + } + + await syncFullBlock(nextBlock) + } + + await paramModel.queries.saveOrUpdate( + nextBlock + 1 * Number(!isUpToDate), + !!isUpToDate + ) } const blockWorker = async () => { @@ -100,7 +133,7 @@ const syncBlockWorker = (): defaultModel.Worker => { const syncOldBlockWorker = (): defaultModel.Worker => { return { name: 'SYNC OLD BLOCK WORKER', - intervalSec: 1, + intervalSec: 0.1, action: syncOldBlocks } } diff --git a/hasura/migrations/default/1690573147430_alter_table_evm_param_add_column_is_synced/down.sql b/hasura/migrations/default/1690573147430_alter_table_evm_param_add_column_is_synced/down.sql new file mode 100644 index 00000000..0ec37ced --- /dev/null +++ b/hasura/migrations/default/1690573147430_alter_table_evm_param_add_column_is_synced/down.sql @@ -0,0 +1,4 @@ +-- Could not auto-generate a down migration. +-- Please write an appropriate down migration for the SQL below: +-- alter table "evm"."param" add column "is_synced" boolean +-- not null default 'false'; diff --git a/hasura/migrations/default/1690573147430_alter_table_evm_param_add_column_is_synced/up.sql b/hasura/migrations/default/1690573147430_alter_table_evm_param_add_column_is_synced/up.sql new file mode 100644 index 00000000..8718c408 --- /dev/null +++ b/hasura/migrations/default/1690573147430_alter_table_evm_param_add_column_is_synced/up.sql @@ -0,0 +1,2 @@ +alter table "evm"."param" add column "is_synced" boolean + not null default 'false'; From e2f0b2a60efab58b5a5188c7ef8a681c7779c0e4 Mon Sep 17 00:00:00 2001 From: Leister Francisco Alvarez Campos Date: Fri, 28 Jul 2023 19:17:09 -0600 Subject: [PATCH 11/75] refactor(hapi-evm): update console message --- hapi-evm/src/services/block.service.ts | 6 ++++-- hapi-evm/src/services/worker/index.ts | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/hapi-evm/src/services/block.service.ts b/hapi-evm/src/services/block.service.ts index a5f9fb50..7f8a2f61 100644 --- a/hapi-evm/src/services/block.service.ts +++ b/hapi-evm/src/services/block.service.ts @@ -103,10 +103,12 @@ const syncOldBlocks = async (): Promise => { if (!isUpToDate) { const nextBlockTo = await blockModel.queries.default.getNextBlock(nextBlock) - const nextBlockToNumber = nextBlockTo[0].number || 0 + const nextBlockToNumber = nextBlockTo[0]?.number || 0 if (nextBlockToNumber > nextBlock) { - console.log(`🚦 ${nextBlockToNumber - nextBlock} blocks behind`) + console.log( + `🚦 Syncing blocks behind, pending ${nextBlockToNumber - nextBlock} ` + ) } await syncFullBlock(nextBlock) diff --git a/hapi-evm/src/services/worker/index.ts b/hapi-evm/src/services/worker/index.ts index 65570ca1..043e7955 100644 --- a/hapi-evm/src/services/worker/index.ts +++ b/hapi-evm/src/services/worker/index.ts @@ -21,8 +21,8 @@ const run = async (worker: defaultModel.Worker) => { const init = async () => { await coreUtil.hasura.hasuraAssembled() + run(blockService.syncBlockWorker()) run(blockService.syncOldBlockWorker()) - // run(blockService.syncBlockWorker()) run(hyperionService.syncWorker()) } From 25e57423037a79483cdf872f860ae31dde7f466d Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Mon, 31 Jul 2023 10:21:08 -0600 Subject: [PATCH 12/75] refactor(webapp): refactor card components in the SimpleDataCard component --- webapp/src/components/NodesSummary/index.js | 49 +-- .../src/components/ProducersSummary/index.js | 42 +-- webapp/src/components/SimpleDataCard/index.js | 41 ++- .../src/components/SimpleDataCard/styles.js | 3 + .../components/TransactionsHistory/index.js | 289 ++++++++---------- .../components/TransactionsHistory/styles.js | 3 - webapp/src/routes/Home/BlockProducerInfo.js | 64 ++-- webapp/src/routes/Home/styles.js | 3 - 8 files changed, 229 insertions(+), 265 deletions(-) diff --git a/webapp/src/components/NodesSummary/index.js b/webapp/src/components/NodesSummary/index.js index 497ad28a..641d14fc 100644 --- a/webapp/src/components/NodesSummary/index.js +++ b/webapp/src/components/NodesSummary/index.js @@ -1,8 +1,6 @@ /* eslint camelcase: 0 */ import React, { memo, useEffect, useState } from 'react' import PropTypes from 'prop-types' -import Typography from '@mui/material/Typography' -import LinearProgress from '@mui/material/LinearProgress' import { useQuery } from '@apollo/client' import { useTranslation } from 'react-i18next' @@ -27,26 +25,6 @@ const NODES_ORDER = [ }, ] -const BodyGraphValue = ({ loading, value }) => { - if (loading) return - - return ( - - {value} - - ) -} - -BodyGraphValue.propTypes = { - loading: PropTypes.bool, - value: PropTypes.number, -} - -BodyGraphValue.defaultProps = { - value: 0, - loading: false, -} - const NodesSummary = ({ t }) => { const { data, loading } = useQuery(NODES_SUMMARY_QUERY) const { i18n } = useTranslation('translations') @@ -93,20 +71,23 @@ const NodesSummary = ({ t }) => { return ( <> - - {`${t('total')} ${t('nodes')}`} - - - + {nodes && nodes.map((node) => ( - - - {currentLanguaje === 'es' ? t('nodes') : ''} {t(node.type)}{' '} - {currentLanguaje !== 'es' ? t('nodes') : ''} - - - + ))} ) diff --git a/webapp/src/components/ProducersSummary/index.js b/webapp/src/components/ProducersSummary/index.js index c2976e17..eef1d4d1 100644 --- a/webapp/src/components/ProducersSummary/index.js +++ b/webapp/src/components/ProducersSummary/index.js @@ -1,33 +1,11 @@ /* eslint camelcase: 0 */ import React, { memo, useEffect, useState } from 'react' import PropTypes from 'prop-types' -import Typography from '@mui/material/Typography' -import LinearProgress from '@mui/material/LinearProgress' import { ENTITY_TYPE } from '../../utils/lacchain' import { eosConfig } from '../../config' import SimpleDataCard from '../SimpleDataCard' -const BodyGraphValue = ({ loading, value }) => { - if (loading) return - - return ( - - {value} - - ) -} - -BodyGraphValue.propTypes = { - loading: PropTypes.bool, - value: PropTypes.number, -} - -BodyGraphValue.defaultProps = { - value: 0, - loading: false, -} - const ProducersSummary = ({ t, data, loading, total }) => { const [nodes, setNodes] = useState([]) @@ -54,16 +32,18 @@ const ProducersSummary = ({ t, data, loading, total }) => { return ( <> - - {`${t('total')} ${t('producers')}`} - - - + {nodes.map((node, index) => ( - - {`${t(node.type)} ${t('producers')}`} - - + ))} ) diff --git a/webapp/src/components/SimpleDataCard/index.js b/webapp/src/components/SimpleDataCard/index.js index f7b92566..0fc16b1f 100644 --- a/webapp/src/components/SimpleDataCard/index.js +++ b/webapp/src/components/SimpleDataCard/index.js @@ -1,20 +1,43 @@ -import React from 'react' +import React, { memo } from 'react' import { makeStyles } from '@mui/styles' import PropTypes from 'prop-types' import Card from '@mui/material/Card' import CardContent from '@mui/material/CardContent' +import Typography from '@mui/material/Typography' +import LinearProgress from '@mui/material/LinearProgress' import styles from './styles' const useStyles = makeStyles(styles) -const SimpleDataCard = ({ header, children }) => { +const SimpleDataCard = ({ + header, + lowercase, + title, + value, + loading, + children, +}) => { const classes = useStyles() return ( -
+
- {children} + + {title && {title}} + {!loading ? ( + + {value} + {children} + + ) : ( + + )} +
) @@ -22,11 +45,19 @@ const SimpleDataCard = ({ header, children }) => { SimpleDataCard.propTypes = { header: PropTypes.bool, + lowercase: PropTypes.bool, + loading: PropTypes.bool, + title: PropTypes.string, + value: PropTypes.string, children: PropTypes.node, } SimpleDataCard.defaultProps = { header: false, + loading: false, + lowercase: false, + title: '', + value: '', } -export default SimpleDataCard +export default memo(SimpleDataCard) diff --git a/webapp/src/components/SimpleDataCard/styles.js b/webapp/src/components/SimpleDataCard/styles.js index f3211a2f..e14c383e 100644 --- a/webapp/src/components/SimpleDataCard/styles.js +++ b/webapp/src/components/SimpleDataCard/styles.js @@ -33,4 +33,7 @@ export default (theme) => ({ height: '100%', }, }, + lowercase: { + textTransform: 'lowercase !important', + }, }) diff --git a/webapp/src/components/TransactionsHistory/index.js b/webapp/src/components/TransactionsHistory/index.js index fba5e5e4..9fd821ee 100644 --- a/webapp/src/components/TransactionsHistory/index.js +++ b/webapp/src/components/TransactionsHistory/index.js @@ -17,30 +17,33 @@ import styles from './styles' const useStyles = makeStyles(styles) -const BodyGraphValue = ({ loading, value, classes, links }) => { +const BodyGraphValue = ({ loading, classes, links }) => { if (loading) return return ( - - {value} - {links && links.map((href, index) => ( - - - - ))} - + <> + {links && + links.map((href, index) => ( + + + + ))} + ) } BodyGraphValue.propTypes = { loading: PropTypes.bool, - value: PropTypes.any, classes: PropTypes.object, href: PropTypes.string, } BodyGraphValue.defaultProps = { - value: 0, loading: false, classes: {}, } @@ -54,169 +57,147 @@ const TransactionsHistory = ({ t, nodesChildren }) => {
{generalConfig.historyEnabled && ( <> - - {t('tpsAllTimeHigh')} + getBlockNumUrl(block))} - /> - - - {t('cpuUtilizationAllTimeHigh')} - getBlockNumUrl(block))} - loading={loading} - /> - - - {t('networkUtilizationAllTimeHigh')} - getBlockNumUrl(block))} - loading={loading} - /> - - - {`${t('transactions')} ${t('lastHour')}`} - - - - {`${t('transactions')} ${t('lastDay')}`} - + getBlockNumUrl(block), )} - loading={loading} /> - - {`${t('transactions')} ${t( - 'dailyAverage', - )}`} + + getBlockNumUrl(block), )} - loading={loading} /> - - {`${t('transactions')} ${t('lastWeek')}`} + + getBlockNumUrl(block), )} - loading={loading} - /> - - - {`${t('cpuUtilization')} ${t('lastHour')}`} - - - - {`${t('cpuUtilization')} ${t('lastDay')}`} - - - - {`${t('cpuUtilization')} ${t('lastWeek')}`} - - - - {`${t('netUtilization')} ${t('lastHour')}`} - - - - {`${t('netUtilization')} ${t('lastDay')}`} - - - - {`${t('netUtilization')} ${t('lastWeek')}`} - + + + + + + + + + + )} {nodesChildren && ( <> {nodesChildren} - - {`${t('uniqueLocations')}`} - - + )} - - {t('cpuUsage')} - - {`${formatWithThousandSeparator(tps[0]?.cpu, 2)} %`} - - - - - {t('netUsage')} - - {`${formatWithThousandSeparator(tps[0]?.net, 3)} %`} - - - - - {t('cpuLimitPerBlock')} - - {`${(info.block_cpu_limit * 0.001).toFixed(0)} ms`} - - - - {t('netLimitPerBlock')} - - {`${formatWithThousandSeparator(info.block_net_limit / 1024, 0)} KB`} - - - - {t('chainCpuLimit')} - - {`${(info.virtual_block_cpu_limit * 0.001).toFixed(0)} ms`} - - - - {t('chainNetLimit')} - - {`${formatWithThousandSeparator( - info.virtual_block_net_limit / 1024, - 0, - )} KB`} - - + + + + + +
) } diff --git a/webapp/src/components/TransactionsHistory/styles.js b/webapp/src/components/TransactionsHistory/styles.js index 67153c56..5c7c252f 100644 --- a/webapp/src/components/TransactionsHistory/styles.js +++ b/webapp/src/components/TransactionsHistory/styles.js @@ -3,9 +3,6 @@ export default (theme) => ({ fontSize: 18, marginLeft: theme.spacing(2), }, - lowercase: { - textTransform: 'lowercase !important', - }, wrapper: { display: 'flex', gap: '10px', diff --git a/webapp/src/routes/Home/BlockProducerInfo.js b/webapp/src/routes/Home/BlockProducerInfo.js index 70fdba1a..32417f69 100644 --- a/webapp/src/routes/Home/BlockProducerInfo.js +++ b/webapp/src/routes/Home/BlockProducerInfo.js @@ -84,30 +84,27 @@ const BlockProducerInfo = ({ t, classes }) => { return ( <>
- - {t('currentProducer')} - - {info.head_block_producer} - - - - {t('scheduleVersion')} - - {schedule?.version} - - - - {t('headBlock')} - - {formatWithThousandSeparator(info.head_block_num)} - - - - {t('lastBlock')} - - {formatWithThousandSeparator(info.last_irreversible_block_num)} - - + + + +
@@ -138,20 +135,17 @@ const BlockProducerInfo = ({ t, classes }) => { total={total} /> - - {t('timeToFinality')} - - {schedule.producers + - + : '0 s' + } + /> } /> diff --git a/webapp/src/routes/Home/styles.js b/webapp/src/routes/Home/styles.js index 6b67330b..455a0901 100644 --- a/webapp/src/routes/Home/styles.js +++ b/webapp/src/routes/Home/styles.js @@ -81,9 +81,6 @@ export default (theme) => ({ fontSize: 15, marginBottom: 2, }, - lowercase: { - textTransform: 'lowercase !important', - }, cardShadow: { boxShadow: '0px 1px 3px 1px rgba(0, 0, 0, 0.15) !important', }, From b06ec582bd05030ccd3fe88ebc35fd2c981a2098 Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Mon, 31 Jul 2023 13:27:29 -0600 Subject: [PATCH 13/75] refactor(webapp): remove unused style classes --- webapp/src/components/GeoMap/MainMap.js | 6 ++-- .../components/TransactionsHistory/index.js | 1 - webapp/src/routes/Home/BlockProducerInfo.js | 1 - webapp/src/routes/Home/styles.js | 35 ------------------- 4 files changed, 4 insertions(+), 39 deletions(-) diff --git a/webapp/src/components/GeoMap/MainMap.js b/webapp/src/components/GeoMap/MainMap.js index ed6c56a8..45508c1a 100644 --- a/webapp/src/components/GeoMap/MainMap.js +++ b/webapp/src/components/GeoMap/MainMap.js @@ -2,6 +2,7 @@ import React, { useEffect, useRef, useCallback } from 'react' import { makeStyles } from '@mui/styles' import { useTranslation } from 'react-i18next' import PropTypes from 'prop-types' +import { useTheme } from '@mui/material/styles' import { countries } from '../../utils/countries' @@ -14,6 +15,7 @@ const MainMap = ({ data, map, setMap }) => { const classes = useStyles() const { t } = useTranslation('mainMapComponent') const myRef = useRef() + const theme = useTheme() const setupMapData = useCallback( (data = [], map) => { @@ -61,7 +63,7 @@ const MainMap = ({ data, map, setMap }) => { }, states: { hover: { - color: '#1565C0', + color: theme.palette.primary.main, }, }, dataLabels: { @@ -84,7 +86,7 @@ const MainMap = ({ data, map, setMap }) => { new HighMapsWrapper['Map'](myRef.current, options) }, - [setMap, t], + [setMap, t, theme.palette], ) useEffect(() => { diff --git a/webapp/src/components/TransactionsHistory/index.js b/webapp/src/components/TransactionsHistory/index.js index 9fd821ee..f3806501 100644 --- a/webapp/src/components/TransactionsHistory/index.js +++ b/webapp/src/components/TransactionsHistory/index.js @@ -2,7 +2,6 @@ import React, { memo } from 'react' import { makeStyles } from '@mui/styles' import PropTypes from 'prop-types' -import Typography from '@mui/material/Typography' import LinearProgress from '@mui/material/LinearProgress' import LaunchIcon from '@mui/icons-material/Launch' import { useSubscription } from '@apollo/client' diff --git a/webapp/src/routes/Home/BlockProducerInfo.js b/webapp/src/routes/Home/BlockProducerInfo.js index 32417f69..0e6d5ac8 100644 --- a/webapp/src/routes/Home/BlockProducerInfo.js +++ b/webapp/src/routes/Home/BlockProducerInfo.js @@ -125,7 +125,6 @@ const BlockProducerInfo = ({ t, classes }) => { <> ({ display: 'block', }, }, - bottomRow: { - [theme.breakpoints.up('md')]: { - paddingTop: theme.spacing(1), - }, - }, - boxIrreversible: { - display: 'flex', - alignItems: 'baseline', - paddingTop: theme.spacing(3), - '& .MuiTypography-body1': { - marginBottom: '0 !important', - letterSpacing: '0.09px', - color: 'rgba(0, 0, 0, 0.54)', - '& strong': { - color: '#212121', - }, - }, - }, pauseButton: { display: 'flex', width: 75, @@ -67,20 +49,6 @@ export default (theme) => ({ width: 300, }, }, - cards: { - textTransform: 'capitalize', - minHeight: '90px', - '& .MuiTypography-h6': { - display: 'flex', - justifyContent: 'center', - textAlign: 'center', - marginTop: theme.spacing(2), - }, - }, - cardLink: { - fontSize: 15, - marginBottom: 2, - }, cardShadow: { boxShadow: '0px 1px 3px 1px rgba(0, 0, 0, 0.15) !important', }, @@ -93,9 +61,6 @@ export default (theme) => ({ display: 'block', }, }, - uniquelocations: { - flexGrow: '1 !important', - }, divTrans: { width: '50%', [theme.breakpoints.down('md')]: { From 542b0f027cb38f7740c0af7bbcebe741af79e392 Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Tue, 1 Aug 2023 15:23:55 -0600 Subject: [PATCH 14/75] feat(webapp): add EVM Dashboard --- webapp/src/components/SimpleDataCard/index.js | 2 +- .../components/TransactionsHistory/index.js | 1 + .../components/TransactionsLineChart/index.js | 20 +++++- webapp/src/config/evm.config.js | 21 ++++++ webapp/src/config/index.js | 3 +- webapp/src/gql/evm.gql.js | 14 ++++ webapp/src/gql/index.js | 1 + webapp/src/language/en.json | 16 ++++- webapp/src/language/es.json | 11 +++ webapp/src/routes/EVMDashboard/index.js | 68 +++++++++++++++++++ webapp/src/routes/EVMDashboard/styles.js | 11 +++ webapp/src/routes/EVMDashboard/useEVMstate.js | 45 ++++++++++++ webapp/src/routes/index.js | 11 +++ 13 files changed, 218 insertions(+), 6 deletions(-) create mode 100644 webapp/src/config/evm.config.js create mode 100644 webapp/src/gql/evm.gql.js create mode 100644 webapp/src/routes/EVMDashboard/index.js create mode 100644 webapp/src/routes/EVMDashboard/styles.js create mode 100644 webapp/src/routes/EVMDashboard/useEVMstate.js diff --git a/webapp/src/components/SimpleDataCard/index.js b/webapp/src/components/SimpleDataCard/index.js index 0fc16b1f..a6b74de9 100644 --- a/webapp/src/components/SimpleDataCard/index.js +++ b/webapp/src/components/SimpleDataCard/index.js @@ -48,7 +48,7 @@ SimpleDataCard.propTypes = { lowercase: PropTypes.bool, loading: PropTypes.bool, title: PropTypes.string, - value: PropTypes.string, + value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), children: PropTypes.node, } diff --git a/webapp/src/components/TransactionsHistory/index.js b/webapp/src/components/TransactionsHistory/index.js index f3806501..1c38174b 100644 --- a/webapp/src/components/TransactionsHistory/index.js +++ b/webapp/src/components/TransactionsHistory/index.js @@ -24,6 +24,7 @@ const BodyGraphValue = ({ loading, classes, links }) => { {links && links.map((href, index) => ( { +const TransactionsLineChart = ({ + data, + xAxisProps, + title, + yAxisProps, + zoomEnabled, +}) => { const options = { time: { timezoneOffset: new Date().getTimezoneOffset(), @@ -14,7 +20,7 @@ const TransactionsLineChart = ({ data, xAxisProps, title, yAxisProps, zoomEnable chart: { animation: false, type: 'spline', - zoomType: zoomEnabled ? 'x' : '' + zoomType: zoomEnabled ? 'x' : '', }, credits: { enabled: false, @@ -22,7 +28,15 @@ const TransactionsLineChart = ({ data, xAxisProps, title, yAxisProps, zoomEnable xAxis: xAxisProps, yAxis: yAxisProps, tooltip: { - pointFormat: '{series.name}: {point.y}
Net usage:{point.net} %
CPU usage:{point.cpu} %', + formatter() { + const { series, point } = this + const resourcesString = + point?.net && point?.cpu + ? `
Net usage:${point.net} %
CPU usage:${point.cpu} %` + : '' + + return `${series.name}: ${point.y}` + resourcesString + }, }, } diff --git a/webapp/src/config/evm.config.js b/webapp/src/config/evm.config.js new file mode 100644 index 00000000..3f8adb1f --- /dev/null +++ b/webapp/src/config/evm.config.js @@ -0,0 +1,21 @@ +import { eosConfig } from "config" + +let _avgBlockTime + +switch(eosConfig.networkName){ + case 'telos-testnet': + case 'telos': + _avgBlockTime = '0.5 s' + break + case 'jungle': + case 'eos': + _avgBlockTime = '1 s' + break + default: + _avgBlockTime = 'N/A' + break +} + + +export const gasPrice = '550 Gwei' +export const avgBlockTime = _avgBlockTime diff --git a/webapp/src/config/index.js b/webapp/src/config/index.js index bc65a418..826f9b68 100644 --- a/webapp/src/config/index.js +++ b/webapp/src/config/index.js @@ -1,7 +1,8 @@ import * as eosConfig from './eos.config' +import * as evmConfig from './evm.config' import * as generalConfig from './general' import { ualConfig } from './ual.config' import * as recaptchaConfig from './recaptcha.config' -export { eosConfig, generalConfig, ualConfig, recaptchaConfig } +export { eosConfig, evmConfig, generalConfig, ualConfig, recaptchaConfig } export * from './graphql.config' diff --git a/webapp/src/gql/evm.gql.js b/webapp/src/gql/evm.gql.js new file mode 100644 index 00000000..8583c84e --- /dev/null +++ b/webapp/src/gql/evm.gql.js @@ -0,0 +1,14 @@ +import gql from 'graphql-tag' + +export const EVM_STATS_SUBSCRIPTION = gql` + subscription { + evm_stats(limit: 1) { + block_gas_avg + daily_transaction_count + ath_transaction_sum + incoming_tlos_count + outgoing_tlos_count + avg_gas_used + } + } +` diff --git a/webapp/src/gql/index.js b/webapp/src/gql/index.js index 5cc41bf2..5a4709c8 100644 --- a/webapp/src/gql/index.js +++ b/webapp/src/gql/index.js @@ -2,3 +2,4 @@ export * from './producer.gql' export * from './setting.gql' export * from './transaction.gql' export * from './faucet.gql' +export * from './evm.gql' diff --git a/webapp/src/language/en.json b/webapp/src/language/en.json index 3de15202..f4f78574 100644 --- a/webapp/src/language/en.json +++ b/webapp/src/language/en.json @@ -89,9 +89,12 @@ "/missed-blocks>sidebar": "Missed Blocks", "/missed-blocks>title": "Missed Blocks - EOSIO + Antelope Network Dashboard", "/missed-blocks>heading": "Missed Blocks", - "/stress-test>title": "Stress Test Dashboard", + "/stress-test>title": "Stress Test Dashboard - EOSIO + Antelope Network Dashboard", "/stress-test>sidebar": "Stress Test", "/stress-test>heading": "Stress Test", + "/evm>title": "EVM Dashboard - EOSIO + Antelope Network Dashboard", + "/evm>sidebar": "EVM Dashboard", + "/evm>heading": "EVM Dashboard", "/endpoints>sidebar": "API Endpoints", "/endpoints>title": "API Endpoints - EOSIO + Antelope Network Dashboard", "/endpoints>heading": "API Endpoints", @@ -424,5 +427,16 @@ "charTitle": "Average Response Time from Costa Rica", "list": "List of endpoints", "timeInSecs": "Time in seconds" + }, + "evmDashboardRoute": { + "totalWallets": "Total wallets created", + "avgBlockTime": "Average block time", + "gasPrice": "Gas price", + "avgGasUsage": "Average gas usage", + "totalIncoming": "Total (TOKEN) incoming", + "totalOutgoing": "Total (TOKEN) outgoing", + "avgTX": "Average transaction per day", + "transactionsPerDay": "Transactions per Day", + "ATH": "All Time High" } } diff --git a/webapp/src/language/es.json b/webapp/src/language/es.json index 7e95062e..89407d1d 100644 --- a/webapp/src/language/es.json +++ b/webapp/src/language/es.json @@ -448,5 +448,16 @@ "charTitle": "Tiempo de respuesta promedio desde Costa Rica", "list": "Lista de puntos finales", "timeInSecs": "Tiempo en segundos" + }, + "evmDashboardRoute": { + "totalWallets": "Total de wallets creadas", + "avgBlockTime": "Tiempo promedio de bloque", + "gasPrice": "Precio de gas", + "avgGasUsage": "Uso promedio de gas", + "totalIncoming": "Total (TOKEN) entrantes", + "totalOutgoing": "Total (TOKEN) salientes", + "avgTX": "Promedio de transacciones por día", + "transactionsPerDay": "Transacciones por día", + "ATH": "Máximo histórico" } } diff --git a/webapp/src/routes/EVMDashboard/index.js b/webapp/src/routes/EVMDashboard/index.js new file mode 100644 index 00000000..25dd879e --- /dev/null +++ b/webapp/src/routes/EVMDashboard/index.js @@ -0,0 +1,68 @@ +import React from 'react' +import { makeStyles } from '@mui/styles' +import { useTranslation } from 'react-i18next' + +import SimpleDataCard from '../../components/SimpleDataCard' +import { eosConfig, evmConfig } from 'config' + +import styles from './styles' +import useEVMState from './useEVMstate' + +const useStyles = makeStyles(styles) + +const EVMDashboard = () => { + const classes = useStyles() + const { t } = useTranslation('evmDashboardRoute') + + const [{ EVMStats, loading }] = useEVMState() + + return ( + <> +
+ + + + + + + + +
+ + ) +} + +export default EVMDashboard diff --git a/webapp/src/routes/EVMDashboard/styles.js b/webapp/src/routes/EVMDashboard/styles.js new file mode 100644 index 00000000..ead309bf --- /dev/null +++ b/webapp/src/routes/EVMDashboard/styles.js @@ -0,0 +1,11 @@ +export default (theme) => ({ + container: { + display: 'flex', + marginBottom: theme.spacing(2), + gap: theme.spacing(2), + flexWrap: 'wrap', + }, + chartContainer: { + marginBottom: theme.spacing(2), + }, +}) diff --git a/webapp/src/routes/EVMDashboard/useEVMstate.js b/webapp/src/routes/EVMDashboard/useEVMstate.js new file mode 100644 index 00000000..001303d6 --- /dev/null +++ b/webapp/src/routes/EVMDashboard/useEVMstate.js @@ -0,0 +1,45 @@ +import { useState, useEffect } from 'react' +import { useSubscription } from '@apollo/client' + +import { EVM_STATS_SUBSCRIPTION } from '../../gql' +import eosApi from '../../utils/eosapi' + +const useEVMState = () => { + const [EVMStats, setEVMStats] = useState() + const { data, loading } = useSubscription(EVM_STATS_SUBSCRIPTION) + + const getWalletsCreated = async () => { + try { + const { rows } = await eosApi.getTableRows({ + code: 'eosio.evm', + scope: 'eosio.evm', + table: 'account', + reverse: true, + limit: 1, + json: true, + lower_bound: null, + }) + + return rows[0]?.index + 1 + } catch (error) {} + } + + useEffect(() => { + const getStats = async () => { + const amount = await getWalletsCreated() + const stats = { wallets_created_count: amount } + + if (!data) { + setEVMStats(stats) + } else { + setEVMStats({ ...stats, ...data.evm_stats[0] }) + } + } + + getStats() + }, [data]) + + return [{ EVMStats, loading }] +} + +export default useEVMState diff --git a/webapp/src/routes/index.js b/webapp/src/routes/index.js index f4c12d86..8912dbbc 100644 --- a/webapp/src/routes/index.js +++ b/webapp/src/routes/index.js @@ -14,6 +14,7 @@ import { BarChart as BarChartIcon, } from 'react-feather' import QueryStatsIcon from '@mui/icons-material/QueryStats' +import StackedLineChartIcon from '@mui/icons-material/StackedLineChart' import { eosConfig, generalConfig } from '../config' import { @@ -46,6 +47,7 @@ const BlockDistribution = lazy(() => import('./BlockDistribution')) const MissedBlocks = lazy(() => import('./MissedBlocks')) const EndpointsList = lazy(() => import('./EndpointsList')) const NonCompliantBPs = lazy(() => import('./NonCompliantBPs')) +const EVMDashboard = lazy(() => import('./EVMDashboard')) const LacchainNetwork = lazy(() => import('./Lacchain/LacchainNetwork')) const LacchainManagement = lazy(() => import('./Lacchain/LacchainManagement')) const LacchainNodeConfig = lazy(() => import('./Lacchain/LacchainNodeConfig')) @@ -143,6 +145,14 @@ const defaultRoutes = [ path: '/ricardian-contract', exact: true, }, + { + header: 'EVM', + name: 'evm', + icon: , + component: EVMDashboard, + path: '/evm', + exact: true, + }, { header: 'tools', name: 'accounts', @@ -159,6 +169,7 @@ const defaultRoutes = [ exact: true, }, ] + const lacchainRoutes = [ { header: 'networkInformation', From f9f77372071624f6977bb71412e59369c3e507d8 Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Thu, 3 Aug 2023 13:15:47 -0600 Subject: [PATCH 15/75] fix(webapp): fix evm stats subscription --- webapp/src/config/evm.config.js | 35 ++++++++++--------- webapp/src/gql/evm.gql.js | 3 +- webapp/src/routes/EVMDashboard/index.js | 2 +- webapp/src/routes/EVMDashboard/useEVMstate.js | 10 +++--- 4 files changed, 24 insertions(+), 26 deletions(-) diff --git a/webapp/src/config/evm.config.js b/webapp/src/config/evm.config.js index 3f8adb1f..aac04146 100644 --- a/webapp/src/config/evm.config.js +++ b/webapp/src/config/evm.config.js @@ -1,21 +1,22 @@ -import { eosConfig } from "config" +import { eosConfig } from 'config' -let _avgBlockTime +let _avgBlockTime = 'N/A' +let _gasPrice = 'N/A' -switch(eosConfig.networkName){ - case 'telos-testnet': - case 'telos': - _avgBlockTime = '0.5 s' - break - case 'jungle': - case 'eos': - _avgBlockTime = '1 s' - break - default: - _avgBlockTime = 'N/A' - break +switch (eosConfig.networkName) { + case 'telos-testnet': + case 'telos': + _avgBlockTime = '0.5 s' + _gasPrice = '550 Gwei' + break + case 'jungle': + case 'eos': + _avgBlockTime = '1 s' + _gasPrice = '150 Gwei' + break + default: + break } - -export const gasPrice = '550 Gwei' -export const avgBlockTime = _avgBlockTime +export const gasPrice = _gasPrice +export const avgBlockTime = _avgBlockTime diff --git a/webapp/src/gql/evm.gql.js b/webapp/src/gql/evm.gql.js index 8583c84e..b86f1ff3 100644 --- a/webapp/src/gql/evm.gql.js +++ b/webapp/src/gql/evm.gql.js @@ -3,12 +3,11 @@ import gql from 'graphql-tag' export const EVM_STATS_SUBSCRIPTION = gql` subscription { evm_stats(limit: 1) { - block_gas_avg + avg_gas_used: block_gas_avg daily_transaction_count ath_transaction_sum incoming_tlos_count outgoing_tlos_count - avg_gas_used } } ` diff --git a/webapp/src/routes/EVMDashboard/index.js b/webapp/src/routes/EVMDashboard/index.js index 25dd879e..fa9f53dc 100644 --- a/webapp/src/routes/EVMDashboard/index.js +++ b/webapp/src/routes/EVMDashboard/index.js @@ -47,7 +47,7 @@ const EVMDashboard = () => { /> { } useEffect(() => { + if (!data) return + const getStats = async () => { const amount = await getWalletsCreated() const stats = { wallets_created_count: amount } - if (!data) { - setEVMStats(stats) - } else { - setEVMStats({ ...stats, ...data.evm_stats[0] }) - } + setEVMStats({ ...stats, ...data.evm_stats[0] }) } getStats() - }, [data]) + }, [data, loading]) return [{ EVMStats, loading }] } From a670e7e00d0c35a88c4bb1cca39176429a93e9df Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Mon, 7 Aug 2023 09:31:43 -0600 Subject: [PATCH 16/75] feat(webapp): add transactions and token history charts --- .../components/TransactionsLineChart/index.js | 17 ++- webapp/src/gql/evm.gql.js | 20 +++ webapp/src/language/en.json | 4 +- webapp/src/language/es.json | 4 +- .../src/routes/EVMDashboard/ChartHistory.js | 105 +++++++++++++++ webapp/src/routes/EVMDashboard/index.js | 80 ++++++++--- webapp/src/routes/EVMDashboard/styles.js | 34 ++++- webapp/src/routes/EVMDashboard/useEVMstate.js | 124 +++++++++++++++++- webapp/src/routes/Home/TransactionInfo.js | 19 ++- webapp/src/theme/variants.js | 4 + 10 files changed, 371 insertions(+), 40 deletions(-) create mode 100644 webapp/src/routes/EVMDashboard/ChartHistory.js diff --git a/webapp/src/components/TransactionsLineChart/index.js b/webapp/src/components/TransactionsLineChart/index.js index e54bd6cd..26794701 100644 --- a/webapp/src/components/TransactionsLineChart/index.js +++ b/webapp/src/components/TransactionsLineChart/index.js @@ -9,6 +9,8 @@ const TransactionsLineChart = ({ title, yAxisProps, zoomEnabled, + shared, + customFormatter }) => { const options = { time: { @@ -28,15 +30,8 @@ const TransactionsLineChart = ({ xAxis: xAxisProps, yAxis: yAxisProps, tooltip: { - formatter() { - const { series, point } = this - const resourcesString = - point?.net && point?.cpu - ? `
Net usage:${point.net} %
CPU usage:${point.cpu} %` - : '' - - return `${series.name}: ${point.y}` + resourcesString - }, + shared, + ...(customFormatter && { formatter() { return customFormatter(this) } }) }, } @@ -59,6 +54,8 @@ TransactionsLineChart.propTypes = { yAxisProps: PropTypes.object, title: PropTypes.string, zoomEnabled: PropTypes.bool, + shared: PropTypes.bool, + customFormatter: PropTypes.func } TransactionsLineChart.defaultProps = { @@ -67,6 +64,8 @@ TransactionsLineChart.defaultProps = { yAxisProps: {}, title: '', zoomEnabled: false, + shared: false, + customFormatter: undefined } export default TransactionsLineChart diff --git a/webapp/src/gql/evm.gql.js b/webapp/src/gql/evm.gql.js index b86f1ff3..f90f01cc 100644 --- a/webapp/src/gql/evm.gql.js +++ b/webapp/src/gql/evm.gql.js @@ -11,3 +11,23 @@ export const EVM_STATS_SUBSCRIPTION = gql` } } ` + +export const EVM_TRANSACTION_QUERY = gql` + query ($range: String!) { + transactions: evm_transactions_history(range: $range) { + datetime + transactions_count + gas_used + } + } +` + +export const EVM_TOKEN_QUERY = gql` + query ($range: String!) { + evm_token_history(range: $range) { + datetime + incoming + outgoing + } + } +` \ No newline at end of file diff --git a/webapp/src/language/en.json b/webapp/src/language/en.json index f4f78574..e48143d2 100644 --- a/webapp/src/language/en.json +++ b/webapp/src/language/en.json @@ -435,8 +435,10 @@ "avgGasUsage": "Average gas usage", "totalIncoming": "Total (TOKEN) incoming", "totalOutgoing": "Total (TOKEN) outgoing", + "incoming": "Incoming", + "outgoing": "Outgoing", "avgTX": "Average transaction per day", "transactionsPerDay": "Transactions per Day", - "ATH": "All Time High" + "ATH": "TPS All Time High" } } diff --git a/webapp/src/language/es.json b/webapp/src/language/es.json index 89407d1d..afc48b82 100644 --- a/webapp/src/language/es.json +++ b/webapp/src/language/es.json @@ -456,8 +456,10 @@ "avgGasUsage": "Uso promedio de gas", "totalIncoming": "Total (TOKEN) entrantes", "totalOutgoing": "Total (TOKEN) salientes", + "incoming": "Entrantes", + "outgoing": "Salientes", "avgTX": "Promedio de transacciones por día", "transactionsPerDay": "Transacciones por día", - "ATH": "Máximo histórico" + "ATH": "TPS Máximo histórico" } } diff --git a/webapp/src/routes/EVMDashboard/ChartHistory.js b/webapp/src/routes/EVMDashboard/ChartHistory.js new file mode 100644 index 00000000..2384c491 --- /dev/null +++ b/webapp/src/routes/EVMDashboard/ChartHistory.js @@ -0,0 +1,105 @@ +import React from 'react' +import { makeStyles } from '@mui/styles' +import { useTranslation } from 'react-i18next' +import Card from '@mui/material/Card' +import CardContent from '@mui/material/CardContent' +import PropTypes from 'prop-types' +import Select from '@mui/material/Select' +import MenuItem from '@mui/material/MenuItem' +import FormControl from '@mui/material/FormControl' +import InputLabel from '@mui/material/InputLabel' +import Typography from '@mui/material/Typography' +import LinearProgress from '@mui/material/LinearProgress' + +import TransactionsLineChart from 'components/TransactionsLineChart' + +import styles from './styles' + +const useStyles = makeStyles(styles) + +const ChartHistory = ({ + title, + ariaLabel, + options, + value, + yAxisText, + onSelect, + shared, + loading, + data, +}) => { + const classes = useStyles() + const { t } = useTranslation() + + return ( + + +
+ + {title} + + + {t('timeFrame')} + + +
+ {loading && } + +
+
+ ) +} + +ChartHistory.propTypes = { + title: PropTypes.string, + ariaLabel: PropTypes.string, + options: PropTypes.array, + value: PropTypes.string, + yAxisText: PropTypes.string, + onSelect: PropTypes.func, + shared: PropTypes.bool, + loading: PropTypes.bool, + data: PropTypes.array, +} + +ChartHistory.defaultProps = { + title: '', + ariaLabel: 'select', + yAxisText: '', + shared: false, + loading: false, +} + +export default ChartHistory diff --git a/webapp/src/routes/EVMDashboard/index.js b/webapp/src/routes/EVMDashboard/index.js index fa9f53dc..0170e83f 100644 --- a/webapp/src/routes/EVMDashboard/index.js +++ b/webapp/src/routes/EVMDashboard/index.js @@ -1,63 +1,103 @@ import React from 'react' -import { makeStyles } from '@mui/styles' +import { useTheme } from '@mui/material/styles' import { useTranslation } from 'react-i18next' +import { makeStyles } from '@mui/styles' import SimpleDataCard from '../../components/SimpleDataCard' import { eosConfig, evmConfig } from 'config' import styles from './styles' import useEVMState from './useEVMstate' +import ChartHistory from './ChartHistory' const useStyles = makeStyles(styles) const EVMDashboard = () => { const classes = useStyles() + const theme = useTheme() const { t } = useTranslation('evmDashboardRoute') - const [{ EVMStats, loading }] = useEVMState() + const [ + { + EVMStats, + tokenHistoryData, + transactionsHistoryData, + options, + loading, + selected, + }, + { handleSelect }, + ] = useEVMState(theme, t) return ( <> -
+
+
+ handleSelect('txs', option)} + /> +
+
+ handleSelect('token', option)} + /> +
+
+
diff --git a/webapp/src/routes/EVMDashboard/styles.js b/webapp/src/routes/EVMDashboard/styles.js index ead309bf..06a7cb6e 100644 --- a/webapp/src/routes/EVMDashboard/styles.js +++ b/webapp/src/routes/EVMDashboard/styles.js @@ -2,10 +2,38 @@ export default (theme) => ({ container: { display: 'flex', marginBottom: theme.spacing(2), - gap: theme.spacing(2), + gap: '10px', + }, + column: { + width: '50%', + [theme.breakpoints.down('md')]: { + width: '100%', + } + }, + cardsContainer: { flexWrap: 'wrap', }, - chartContainer: { - marginBottom: theme.spacing(2), + chartsContainer: { + [theme.breakpoints.down('md')]: { + flexDirection: 'column', + } + }, + cardShadow: { + boxShadow: '0px 1px 3px 1px rgba(0, 0, 0, 0.15) !important', + }, + header: { + display: 'flex', + justifyContent: 'space-between', + alignItems: 'baseline', + padding: theme.spacing(1), + gap: theme.spacing(1), + flexWrap: 'wrap', + [theme.breakpoints.up('lg')]: { + alignItems: 'center', + }, + '& .MuiInputLabel-formControl': { + position: 'relative', + marginBottom: `-${theme.spacing(2)}`, + }, }, }) diff --git a/webapp/src/routes/EVMDashboard/useEVMstate.js b/webapp/src/routes/EVMDashboard/useEVMstate.js index 75760ecd..25e2176f 100644 --- a/webapp/src/routes/EVMDashboard/useEVMstate.js +++ b/webapp/src/routes/EVMDashboard/useEVMstate.js @@ -1,12 +1,118 @@ import { useState, useEffect } from 'react' -import { useSubscription } from '@apollo/client' +import { useSubscription, useLazyQuery } from '@apollo/client' +import moment from 'moment' -import { EVM_STATS_SUBSCRIPTION } from '../../gql' +import { + EVM_STATS_SUBSCRIPTION, + EVM_TRANSACTION_QUERY, + EVM_TOKEN_QUERY, +} from '../../gql' import eosApi from '../../utils/eosapi' +import { rangeOptions } from '../../utils' -const useEVMState = () => { +const useEVMState = (theme, t) => { const [EVMStats, setEVMStats] = useState() const { data, loading } = useSubscription(EVM_STATS_SUBSCRIPTION) + const [getTransactionHistory, { data: transactionsData }] = useLazyQuery( + EVM_TRANSACTION_QUERY, + { fetchPolicy: 'network-only' }, + ) + const [getTokenHistory, { data: tokenData }] = useLazyQuery(EVM_TOKEN_QUERY, { + fetchPolicy: 'network-only', + }) + const [selected, setSelected] = useState({ txs: '1 Month', token: '1 Month' }) + const [transactionsHistoryData, setTransactionsHistoryData] = useState() + const [tokenHistoryData, setTokenHistoryData] = useState() + + const handleSelect = (chart, option) => { + setSelected(prev => ({ ...prev, [chart]: option })) + if (chart === 'txs') { + getTransactionHistory({ + variables: { + range: option, + }, + }) + } else { + getTokenHistory({ + variables: { + range: option, + }, + }) + } + } + + useEffect(() => { + getTransactionHistory({ + variables: { + range: selected['txs'], + }, + }) + getTokenHistory({ + variables: { + range: selected['token'], + }, + }) + + // eslint-disable-next-line + }, []) + + useEffect(() => { + if (tokenData?.evm_token_history) { + const { incoming, outgoing } = tokenData?.evm_token_history.reduce( + (history, tokenHistory) => { + const name = moment(tokenHistory.datetime)?.format('ll') + const datetime = new Date(tokenHistory.datetime).getTime() + + history.incoming.push({ + name, + y: tokenHistory.incoming || 0, + x: datetime, + }) + + history.outgoing.push({ + name, + y: tokenHistory.outgoing || 0, + x: datetime, + }) + + return history + }, + { incoming: [], outgoing: [] }, + ) + + setTokenHistoryData([ + { + name: t('incoming'), + color: theme.palette.secondary.main, + data: incoming, + }, + { + name: t('outgoing'), + color: theme.palette.tertiary.main, + data: outgoing, + }, + ]) + } + }, [tokenData, t, theme]) + + useEffect(() => { + if (transactionsData?.transactions) { + const data = transactionsData?.transactions.map((transaction) => ({ + name: moment(transaction.datetime)?.format('ll'), + gas: transaction.gas_used || 0, + y: transaction.transactions_count || 0, + x: new Date(transaction.datetime).getTime(), + })) + + setTransactionsHistoryData([ + { + name: t('transactionsPerDay'), + color: theme.palette.secondary.main, + data, + }, + ]) + } + }, [transactionsData, t, theme]) const getWalletsCreated = async () => { try { @@ -37,7 +143,17 @@ const useEVMState = () => { getStats() }, [data, loading]) - return [{ EVMStats, loading }] + return [ + { + EVMStats, + options: rangeOptions, + selected, + transactionsHistoryData, + tokenHistoryData, + loading, + }, + { handleSelect }, + ] } export default useEVMState diff --git a/webapp/src/routes/Home/TransactionInfo.js b/webapp/src/routes/Home/TransactionInfo.js index c879c3b7..e4a59a75 100644 --- a/webapp/src/routes/Home/TransactionInfo.js +++ b/webapp/src/routes/Home/TransactionInfo.js @@ -14,6 +14,7 @@ import CardContent from '@mui/material/CardContent' import Typography from '@mui/material/Typography' import PlayArrowIcon from '@mui/icons-material/PlayArrow' import LinearProgress from '@mui/material/LinearProgress' +import moment from 'moment' import { TRANSACTION_QUERY } from '../../gql' import { formatWithThousandSeparator, rangeOptions } from '../../utils' @@ -83,7 +84,7 @@ const TransactionInfo = ({ t, startTrackingInfo, stopTrackingInfo }) => { }, { name: t('transactionsPerBlock'), - color: '#00C853', + color: theme.palette.tertiary.main, data: trxPerBlock, }, ]) @@ -119,6 +120,7 @@ const TransactionInfo = ({ t, startTrackingInfo, stopTrackingInfo }) => { const { trxPerBlock, trxPerSecond } = data.transactions.reduce( (history, transactionHistory) => { history.trxPerBlock.push({ + name: moment(transactionHistory.datetime)?.format('ll'), cpu: transactionHistory.cpu || 0, net: transactionHistory.net || 0, y: transactionHistory.transactions_count || 0, @@ -126,6 +128,7 @@ const TransactionInfo = ({ t, startTrackingInfo, stopTrackingInfo }) => { }) history.trxPerSecond.push({ + name: moment(transactionHistory.datetime)?.format('ll'), cpu: transactionHistory.cpu / 2 || 0, net: transactionHistory.net / 2 || 0, y: transactionHistory.transactions_count * 2 || 0, @@ -145,7 +148,7 @@ const TransactionInfo = ({ t, startTrackingInfo, stopTrackingInfo }) => { }, { name: t('transactionsPerBlock'), - color: '#00C853', + color: theme.palette.tertiary.main, data: trxPerBlock, }, ]) @@ -242,6 +245,18 @@ const TransactionInfo = ({ t, startTrackingInfo, stopTrackingInfo }) => { maxPadding: 0.05, }} data={graphicData} + customFormatter={ element => { + const series = element?.series + const point = element?.point + + const pointName = point?.name ? `${point.name}
` : '' + const resourcesDetail = + point?.net && point?.cpu + ? `
Net usage:${point.net} %
CPU usage:${point.cpu} %` + : '' + + return pointName + `${series?.name}: ${point?.y}` + resourcesDetail + }} /> diff --git a/webapp/src/theme/variants.js b/webapp/src/theme/variants.js index e663fcc0..609f07bf 100644 --- a/webapp/src/theme/variants.js +++ b/webapp/src/theme/variants.js @@ -10,6 +10,10 @@ const lightVariant = { secondary: { main: blue[600], contrastText: '#FFF' + }, + tertiary: { + main: '#00C853', + contrastText: '#FFF' } }, header: { From bbe5264db8e5063582c0647730c3d4eb2d3453e8 Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Mon, 7 Aug 2023 09:32:41 -0600 Subject: [PATCH 17/75] chore(webapp): add EVM Dashboard description --- webapp/src/language/en.jungle.json | 3 ++- webapp/src/language/en.mainnet.json | 3 ++- webapp/src/language/en.telos-testnet.json | 3 ++- webapp/src/language/en.telos.json | 3 ++- webapp/src/language/es.jungle.json | 3 ++- webapp/src/language/es.mainnet.json | 3 ++- webapp/src/language/es.telos-testnet.json | 3 ++- webapp/src/language/es.telos.json | 3 ++- 8 files changed, 16 insertions(+), 8 deletions(-) diff --git a/webapp/src/language/en.jungle.json b/webapp/src/language/en.jungle.json index e420fcc0..19755905 100644 --- a/webapp/src/language/en.jungle.json +++ b/webapp/src/language/en.jungle.json @@ -30,6 +30,7 @@ "/nodes-distribution>moreDescription": "A visualization of the geographic distribution of the nodes in this network.", "/accounts>moreDescription": "This tool helps find information about accounts and interact with contracts on the network. Enter an account name and obtain account information, smart contract actions, and table data.", "/block-distribution>moreDescription": "A visualization of the distribution of blocks produced by the nodes in the network.", - "/missed-blocks>moreDescription": "A list of scheduled, produced, and missed blocks by each account in the network." + "/missed-blocks>moreDescription": "A list of scheduled, produced, and missed blocks by each account in the network.", + "/evm>moreDescription": "Monitor EVM statistics, such as transaction amount history, gas price and total wallets created." } } diff --git a/webapp/src/language/en.mainnet.json b/webapp/src/language/en.mainnet.json index 38a32fb2..e978b1b8 100644 --- a/webapp/src/language/en.mainnet.json +++ b/webapp/src/language/en.mainnet.json @@ -29,6 +29,7 @@ "/nodes-distribution>moreDescription": "A visualization of the geographic distribution of the nodes in this network.", "/accounts>moreDescription": "This tool helps find information about accounts and interact with contracts on the network. Enter an account name and obtain account information, smart contract actions, and table data.", "/block-distribution>moreDescription": "A visualization of the distribution of blocks produced by the nodes in the network.", - "/missed-blocks>moreDescription": "A list of scheduled, produced, and missed blocks by each account in the network." + "/missed-blocks>moreDescription": "A list of scheduled, produced, and missed blocks by each account in the network.", + "/evm>moreDescription": "Monitor EVM statistics, such as transaction amount history, gas price and total wallets created." } } diff --git a/webapp/src/language/en.telos-testnet.json b/webapp/src/language/en.telos-testnet.json index 6f75f9cd..13f474b7 100644 --- a/webapp/src/language/en.telos-testnet.json +++ b/webapp/src/language/en.telos-testnet.json @@ -30,6 +30,7 @@ "/nodes-distribution>moreDescription": "A visualization of the geographic distribution of the nodes in this network.", "/accounts>moreDescription": "This tool helps find information about accounts and interact with contracts on the network. Enter an account name and obtain account information, smart contract actions, and table data.", "/block-distribution>moreDescription": "A visualization of the distribution of blocks produced by the nodes in the network.", - "/missed-blocks>moreDescription": "A list of scheduled, produced, and missed blocks by each account in the network." + "/missed-blocks>moreDescription": "A list of scheduled, produced, and missed blocks by each account in the network.", + "/evm>moreDescription": "Monitor EVM statistics, such as transaction amount history, gas price and total wallets created." } } diff --git a/webapp/src/language/en.telos.json b/webapp/src/language/en.telos.json index 5af2c6e5..a660afcd 100644 --- a/webapp/src/language/en.telos.json +++ b/webapp/src/language/en.telos.json @@ -30,6 +30,7 @@ "/nodes-distribution>moreDescription": "A visualization of the geographic distribution of the nodes in this network.", "/accounts>moreDescription": "This tool helps find information about accounts and interact with contracts on the network. Enter an account name and obtain account information, smart contract actions, and table data.", "/block-distribution>moreDescription": "A visualization of the distribution of blocks produced by the nodes in the network.", - "/missed-blocks>moreDescription": "A list of scheduled, produced, and missed blocks by each account in the network." + "/missed-blocks>moreDescription": "A list of scheduled, produced, and missed blocks by each account in the network.", + "/evm>moreDescription": "Monitor EVM statistics, such as transaction amount history, gas price and total wallets created." } } diff --git a/webapp/src/language/es.jungle.json b/webapp/src/language/es.jungle.json index e9c1caeb..8d4ce17b 100644 --- a/webapp/src/language/es.jungle.json +++ b/webapp/src/language/es.jungle.json @@ -28,6 +28,7 @@ "/nodes-distribution>moreDescription": "Una visualización de la distribución geográfica de los nodos de esta red.", "/accounts>moreDescription": "Esta herramienta le ayuda a buscar información sobre cuentas y contratos de la red. Escriba el nombre de un contrato o cuenta en el espacio provisto para comenzar a buscar. Obtendrá los datos de las acciones del contrato, tablas de contrato, alcance, límites superior e inferior y límites.", "/block-distribution>moreDescription": "Una visualización de la distribución de bloques producida por los nodos de la red.", - "/missed-blocks>moreDescription": "Una lista de bloques programados, producidos y perdidos por cada cuenta en la red." + "/missed-blocks>moreDescription": "Una lista de bloques programados, producidos y perdidos por cada cuenta en la red.", + "/evm>moreDescription": "Supervise las estadísticas del EVM, como el histórico de la cantidad de transacciones, el precio del gas y las wallets creadas totales." } } diff --git a/webapp/src/language/es.mainnet.json b/webapp/src/language/es.mainnet.json index 5f271322..e4e2f2c1 100644 --- a/webapp/src/language/es.mainnet.json +++ b/webapp/src/language/es.mainnet.json @@ -28,6 +28,7 @@ "/nodes-distribution>moreDescription": "Una visualización de la distribución geográfica de los nodos de esta red.", "/accounts>moreDescription": "Esta herramienta le ayuda a buscar información sobre cuentas y contratos de la red. Escriba el nombre de un contrato o cuenta en el espacio provisto para comenzar a buscar. Obtendrá los datos de las acciones del contrato, tablas de contrato, alcance, límites superior e inferior y límites.", "/block-distribution>moreDescription": "Una visualización de la distribución de bloques producida por los nodos de la red.", - "/missed-blocks>moreDescription": "Una lista de bloques programados, producidos y perdidos por cada cuenta en la red." + "/missed-blocks>moreDescription": "Una lista de bloques programados, producidos y perdidos por cada cuenta en la red.", + "/evm>moreDescription": "Supervise las estadísticas del EVM, como el histórico de la cantidad de transacciones, el precio del gas y las wallets creadas totales." } } diff --git a/webapp/src/language/es.telos-testnet.json b/webapp/src/language/es.telos-testnet.json index a0a1a5a9..c8bd1c74 100644 --- a/webapp/src/language/es.telos-testnet.json +++ b/webapp/src/language/es.telos-testnet.json @@ -28,6 +28,7 @@ "/nodes-distribution>moreDescription": "Una visualización de la distribución geográfica de los nodos de esta red.", "/accounts>moreDescription": "Esta herramienta le ayuda a buscar información sobre cuentas y contratos de la red. Escriba el nombre de un contrato o cuenta en el espacio provisto para comenzar a buscar. Obtendrá los datos de las acciones del contrato, tablas de contrato, alcance, límites superior e inferior y límites.", "/block-distribution>moreDescription": "Una visualización de la distribución de bloques producida por los nodos de la red.", - "/missed-blocks>moreDescription": "Una lista de bloques programados, producidos y perdidos por cada cuenta en la red." + "/missed-blocks>moreDescription": "Una lista de bloques programados, producidos y perdidos por cada cuenta en la red.", + "/evm>moreDescription": "Supervise las estadísticas del EVM, como el histórico de la cantidad de transacciones, el precio del gas y las wallets creadas totales." } } diff --git a/webapp/src/language/es.telos.json b/webapp/src/language/es.telos.json index 2f231596..4f40e0fc 100644 --- a/webapp/src/language/es.telos.json +++ b/webapp/src/language/es.telos.json @@ -28,6 +28,7 @@ "/nodes-distribution>moreDescription": "Una visualización de la distribución geográfica de los nodos de esta red.", "/accounts>moreDescription": "Esta herramienta le ayuda a buscar información sobre cuentas y contratos de la red. Escriba el nombre de un contrato o cuenta en el espacio provisto para comenzar a buscar. Obtendrá los datos de las acciones del contrato, tablas de contrato, alcance, límites superior e inferior y límites.", "/block-distribution>moreDescription": "Una visualización de la distribución de bloques producida por los nodos de la red.", - "/missed-blocks>moreDescription": "Una lista de bloques programados, producidos y perdidos por cada cuenta en la red." + "/missed-blocks>moreDescription": "Una lista de bloques programados, producidos y perdidos por cada cuenta en la red.", + "/evm>moreDescription": "Supervise las estadísticas del EVM, como el histórico de la cantidad de transacciones, el precio del gas y las wallets creadas totales." } } From 07dec4a66bd1bf45282e36364411df04436e7bfb Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Mon, 7 Aug 2023 09:40:55 -0600 Subject: [PATCH 18/75] fix(webapp): fix empty link --- webapp/src/components/Sidebar/SidebarCategory.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webapp/src/components/Sidebar/SidebarCategory.js b/webapp/src/components/Sidebar/SidebarCategory.js index a14a3607..923c72b3 100644 --- a/webapp/src/components/Sidebar/SidebarCategory.js +++ b/webapp/src/components/Sidebar/SidebarCategory.js @@ -39,7 +39,7 @@ const SidebarCategory = ({ showOnlyIcons, ...rest }) => { - if (showOnlyIcons) return {icon} + if (showOnlyIcons) return {icon} return ( From 7ac45b9bd7d8c7c175c53bb74523ad018d16288d Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Mon, 7 Aug 2023 16:13:02 -0600 Subject: [PATCH 19/75] feat(webapp): use rpc endpoint to get gas price and last block --- docker-compose.yaml | 1 + webapp/Dockerfile | 2 + webapp/src/config/evm.config.js | 6 +- webapp/src/gql/evm.gql.js | 12 +++- webapp/src/language/en.json | 5 +- webapp/src/language/es.json | 5 +- .../src/routes/EVMDashboard/ChartHistory.js | 4 ++ webapp/src/routes/EVMDashboard/index.js | 33 ++++++++- webapp/src/routes/EVMDashboard/useEVMstate.js | 71 +++++++++++++------ webapp/src/utils/ethapi.js | 28 ++++++++ 10 files changed, 132 insertions(+), 35 deletions(-) create mode 100644 webapp/src/utils/ethapi.js diff --git a/docker-compose.yaml b/docker-compose.yaml index 621bc166..d0056ff7 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -136,5 +136,6 @@ services: REACT_APP_GOOGLE_ANALITIC_PAGE_ID: '${REACT_APP_GOOGLE_ANALITIC_PAGE_ID}' REACT_APP_PUBLIC_RE_CAPTCHA_KEY: '${REACT_APP_PUBLIC_RE_CAPTCHA_KEY}' REACT_APP_SYNC_TOLERANCE_INTERVAL: '${REACT_APP_SYNC_TOLERANCE_INTERVAL}' + REACT_APP_EVM_ENDPOINT: '${REACT_APP_EVM_ENDPOINT}' volumes: postgres_data: diff --git a/webapp/Dockerfile b/webapp/Dockerfile index d9f910d9..0f5fbcb3 100644 --- a/webapp/Dockerfile +++ b/webapp/Dockerfile @@ -29,6 +29,7 @@ ARG react_app_state_history_enabled ARG react_app_google_analitic_page_id ARG react_app_public_re_captcha_key ARG react_app_sync_tolerance_interval +ARG react_app_evm_endpoint ENV WORK_DIR /usr/src/app ENV PATH $WORK_DIR/node_modules/.bin:$PATH @@ -62,6 +63,7 @@ ENV REACT_APP_STATE_HISTORY_ENABLED $react_app_state_history_enabled ENV REACT_APP_GOOGLE_ANALITIC_PAGE_ID $react_app_google_analitic_page_id ENV REACT_APP_PUBLIC_RE_CAPTCHA_KEY $react_app_public_re_captcha_key ENV REACT_APP_SYNC_TOLERANCE_INTERVAL $react_app_sync_tolerance_interval +ENV REACT_APP_EVM_ENDPOINT $react_app_evm_endpoint RUN mkdir -p $WORK_DIR WORKDIR $WORK_DIR diff --git a/webapp/src/config/evm.config.js b/webapp/src/config/evm.config.js index aac04146..9dfb0e69 100644 --- a/webapp/src/config/evm.config.js +++ b/webapp/src/config/evm.config.js @@ -1,22 +1,20 @@ import { eosConfig } from 'config' let _avgBlockTime = 'N/A' -let _gasPrice = 'N/A' switch (eosConfig.networkName) { case 'telos-testnet': case 'telos': _avgBlockTime = '0.5 s' - _gasPrice = '550 Gwei' break case 'jungle': case 'eos': _avgBlockTime = '1 s' - _gasPrice = '150 Gwei' break default: break } -export const gasPrice = _gasPrice export const avgBlockTime = _avgBlockTime +export const account = 'eosio.evm' +export const endpoint = process.env.REACT_APP_EVM_ENDPOINT \ No newline at end of file diff --git a/webapp/src/gql/evm.gql.js b/webapp/src/gql/evm.gql.js index f90f01cc..65097ebb 100644 --- a/webapp/src/gql/evm.gql.js +++ b/webapp/src/gql/evm.gql.js @@ -12,12 +12,22 @@ export const EVM_STATS_SUBSCRIPTION = gql` } ` +export const EVM_TOTAL_TRANSACTIONS_SUBSCRIPTION = gql` + subscription { + evm_transaction_aggregate { + aggregate{ + count + } + } + } +` + export const EVM_TRANSACTION_QUERY = gql` query ($range: String!) { transactions: evm_transactions_history(range: $range) { datetime transactions_count - gas_used + avg_gas_used } } ` diff --git a/webapp/src/language/en.json b/webapp/src/language/en.json index e48143d2..e21603b3 100644 --- a/webapp/src/language/en.json +++ b/webapp/src/language/en.json @@ -438,7 +438,8 @@ "incoming": "Incoming", "outgoing": "Outgoing", "avgTX": "Average transaction per day", - "transactionsPerDay": "Transactions per Day", - "ATH": "TPS All Time High" + "ATH": "TPS All Time High", + "lastBlock": "Last block", + "totalTxs": "Total transactions" } } diff --git a/webapp/src/language/es.json b/webapp/src/language/es.json index afc48b82..0f8bf182 100644 --- a/webapp/src/language/es.json +++ b/webapp/src/language/es.json @@ -459,7 +459,8 @@ "incoming": "Entrantes", "outgoing": "Salientes", "avgTX": "Promedio de transacciones por día", - "transactionsPerDay": "Transacciones por día", - "ATH": "TPS Máximo histórico" + "ATH": "TPS Máximo histórico", + "lastBlock": "Último bloque", + "totalTxs": "Total de transacciones" } } diff --git a/webapp/src/routes/EVMDashboard/ChartHistory.js b/webapp/src/routes/EVMDashboard/ChartHistory.js index 2384c491..0b0aad82 100644 --- a/webapp/src/routes/EVMDashboard/ChartHistory.js +++ b/webapp/src/routes/EVMDashboard/ChartHistory.js @@ -27,6 +27,7 @@ const ChartHistory = ({ shared, loading, data, + customFormatter }) => { const classes = useStyles() const { t } = useTranslation() @@ -75,6 +76,7 @@ const ChartHistory = ({ }} data={data} shared={shared} + customFormatter={customFormatter} zoomEnabled /> @@ -92,6 +94,7 @@ ChartHistory.propTypes = { shared: PropTypes.bool, loading: PropTypes.bool, data: PropTypes.array, + customFormatter: PropTypes.func } ChartHistory.defaultProps = { @@ -100,6 +103,7 @@ ChartHistory.defaultProps = { yAxisText: '', shared: false, loading: false, + customFormatter: undefined } export default ChartHistory diff --git a/webapp/src/routes/EVMDashboard/index.js b/webapp/src/routes/EVMDashboard/index.js index 0170e83f..37197dad 100644 --- a/webapp/src/routes/EVMDashboard/index.js +++ b/webapp/src/routes/EVMDashboard/index.js @@ -31,6 +31,18 @@ const EVMDashboard = () => { return ( <> +
+ + +
{ data={transactionsHistoryData} options={options} value={selected['txs']} - onSelect={(option) => handleSelect('txs', option)} + onSelect={option => handleSelect('txs', option)} + customFormatter={element => { + const series = element?.series + const point = element?.point + + const pointName = point?.name ? `${point.name}
` : '' + const resourcesDetail = point?.gas + ? `
Gas used:${point?.gas}` + : '' + + return ( + pointName + + `${series?.name}: ${point?.y}` + + resourcesDetail + ) + }} />
@@ -54,7 +81,7 @@ const EVMDashboard = () => { data={tokenHistoryData} options={options} value={selected['token']} - onSelect={(option) => handleSelect('token', option)} + onSelect={option => handleSelect('token', option)} />
@@ -92,7 +119,7 @@ const EVMDashboard = () => { /> { - const [EVMStats, setEVMStats] = useState() const { data, loading } = useSubscription(EVM_STATS_SUBSCRIPTION) + const { data: txsCountData } = useSubscription( + EVM_TOTAL_TRANSACTIONS_SUBSCRIPTION, + ) const [getTransactionHistory, { data: transactionsData }] = useLazyQuery( EVM_TRANSACTION_QUERY, { fetchPolicy: 'network-only' }, @@ -20,10 +25,13 @@ const useEVMState = (theme, t) => { const [getTokenHistory, { data: tokenData }] = useLazyQuery(EVM_TOKEN_QUERY, { fetchPolicy: 'network-only', }) - const [selected, setSelected] = useState({ txs: '1 Month', token: '1 Month' }) + + const [EVMStats, setEVMStats] = useState() const [transactionsHistoryData, setTransactionsHistoryData] = useState() const [tokenHistoryData, setTokenHistoryData] = useState() + const [selected, setSelected] = useState({ txs: '1 Month', token: '1 Month' }) + const handleSelect = (chart, option) => { setSelected(prev => ({ ...prev, [chart]: option })) if (chart === 'txs') { @@ -41,6 +49,22 @@ const useEVMState = (theme, t) => { } } + const getWalletsCreated = async () => { + try { + const { rows } = await eosApi.getTableRows({ + code: evmConfig.account, + scope: evmConfig.account, + table: 'account', + reverse: true, + limit: 1, + json: true, + lower_bound: null, + }) + + return rows[0]?.index + 1 + } catch (error) {} + } + useEffect(() => { getTransactionHistory({ variables: { @@ -52,7 +76,6 @@ const useEVMState = (theme, t) => { range: selected['token'], }, }) - // eslint-disable-next-line }, []) @@ -99,14 +122,14 @@ const useEVMState = (theme, t) => { if (transactionsData?.transactions) { const data = transactionsData?.transactions.map((transaction) => ({ name: moment(transaction.datetime)?.format('ll'), - gas: transaction.gas_used || 0, + gas: transaction.avg_gas_used || 0, y: transaction.transactions_count || 0, x: new Date(transaction.datetime).getTime(), })) setTransactionsHistoryData([ { - name: t('transactionsPerDay'), + name: t('transactions'), color: theme.palette.secondary.main, data, }, @@ -114,30 +137,32 @@ const useEVMState = (theme, t) => { } }, [transactionsData, t, theme]) - const getWalletsCreated = async () => { - try { - const { rows } = await eosApi.getTableRows({ - code: 'eosio.evm', - scope: 'eosio.evm', - table: 'account', - reverse: true, - limit: 1, - json: true, - lower_bound: null, - }) + useEffect(() => { + if (!txsCountData) return - return rows[0]?.index + 1 - } catch (error) {} - } + const count = txsCountData.evm_transaction_aggregate.aggregate.count + + setEVMStats(prev => ({ ...prev, transactions_count: count })) + }, [txsCountData]) useEffect(() => { if (!data) return + setEVMStats(prev => ({ ...prev, ...data.evm_stats[0] })) + }, [data, loading]) + + useEffect(() => { const getStats = async () => { const amount = await getWalletsCreated() - const stats = { wallets_created_count: amount } - - setEVMStats({ ...stats, ...data.evm_stats[0] }) + const gasPrice = await ethApi.getGasPrice() + const lastBlock = await ethApi.getLastBlock() + const stats = { + wallets_created_count: amount, + gas_price: formatWithThousandSeparator(gasPrice / 10 ** 9, 1) + ' Gwei', + last_block: lastBlock, + } + + setEVMStats(prev => ({ ...prev, ...stats })) } getStats() diff --git a/webapp/src/utils/ethapi.js b/webapp/src/utils/ethapi.js new file mode 100644 index 00000000..e5b11ba5 --- /dev/null +++ b/webapp/src/utils/ethapi.js @@ -0,0 +1,28 @@ +import axios from 'axios' + +import { evmConfig } from '../config' + +const queryEthApi = async method => { + try { + const { + data: { result }, + } = await axios.post(evmConfig.endpoint, { + method, + params: [], + id: 1, + jsonrpc: '2.0', + }) + + return parseInt(result) + } catch (error) {} +} + +const getGasPrice = async () => await queryEthApi('eth_gasPrice') +const getLastBlock = async () => await queryEthApi('eth_blockNumber') +const getChainId = async () => await queryEthApi('eth_chainId') + +export default { + getGasPrice, + getLastBlock, + getChainId, +} From 0ec41db1ba6746b146c478b36a0f6b04e6e9f659 Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Mon, 7 Aug 2023 16:13:42 -0600 Subject: [PATCH 20/75] chore(kubernetes): add REACT_APP_EVM_ENDPOINT variable --- kubernetes/configmap-dashboard.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/kubernetes/configmap-dashboard.yaml b/kubernetes/configmap-dashboard.yaml index e6149c69..89c4c83e 100644 --- a/kubernetes/configmap-dashboard.yaml +++ b/kubernetes/configmap-dashboard.yaml @@ -33,6 +33,7 @@ data: REACT_APP_STATE_HISTORY_ENABLED: '${REACT_APP_STATE_HISTORY_ENABLED}' REACT_APP_GOOGLE_ANALITIC_PAGE_ID: '${REACT_APP_GOOGLE_ANALITIC_PAGE_ID}' REACT_APP_PUBLIC_RE_CAPTCHA_KEY: '${REACT_APP_PUBLIC_RE_CAPTCHA_KEY}' + REACT_APP_EVM_ENDPOINT: '${REACT_APP_EVM_ENDPOINT}' --- apiVersion: v1 kind: ConfigMap From 56c7ec0026cb0e29aa0a944a37a7d60f8339c2e6 Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Mon, 7 Aug 2023 16:15:06 -0600 Subject: [PATCH 21/75] chore(workflows): add evm endpoints for telos and eos and disable the route in the rest of networks --- .github/workflows/deploy-jungle-testnet.yaml | 1 + .github/workflows/deploy-lacchain.yaml | 2 +- .github/workflows/deploy-libre-testnet.yaml | 2 +- .github/workflows/deploy-libre.yaml | 2 +- .github/workflows/deploy-mainnet.yaml | 1 + .github/workflows/deploy-proton-testnet.yaml | 2 +- .github/workflows/deploy-proton.yaml | 2 +- .github/workflows/deploy-telos-testnet.yaml | 1 + .github/workflows/deploy-telos.yaml | 1 + .github/workflows/deploy-ultra-testnet.yaml | 2 +- .github/workflows/deploy-wax-testnet.yaml | 2 +- .github/workflows/deploy-wax.yaml | 2 +- 12 files changed, 12 insertions(+), 8 deletions(-) diff --git a/.github/workflows/deploy-jungle-testnet.yaml b/.github/workflows/deploy-jungle-testnet.yaml index 24338047..1e0d47b2 100644 --- a/.github/workflows/deploy-jungle-testnet.yaml +++ b/.github/workflows/deploy-jungle-testnet.yaml @@ -57,6 +57,7 @@ jobs: REACT_APP_STATE_HISTORY_ENABLED: 'false' REACT_APP_GOOGLE_ANALITIC_PAGE_ID: 'G-E6Y0EC9FT8' REACT_APP_PUBLIC_RE_CAPTCHA_KEY: ${{ secrets.REACT_APP_PUBLIC_RE_CAPTCHA_KEY }} + REACT_APP_EVM_ENDPOINT: 'https://api.testnet.evm.eosnetwork.com' - name: Build kubernetes files id: build_kubernetes_files diff --git a/.github/workflows/deploy-lacchain.yaml b/.github/workflows/deploy-lacchain.yaml index d84ac43a..eccde74a 100644 --- a/.github/workflows/deploy-lacchain.yaml +++ b/.github/workflows/deploy-lacchain.yaml @@ -54,7 +54,7 @@ jobs: REACT_APP_SYNC_TOLERANCE_INTERVAL: 180000 REACT_APP_TOKEN_SYMBOL: '' REACT_APP_NETWORK_URL: '[{"label":"EOS","value":"https://eos.antelope.tools","mainnet":true,"pair":"eos","icon":"eos","order":5},{"label":"Proton","value":"https://proton.antelope.tools","mainnet":true,"pair":"proton","icon":"proton","order":3},{"label":"WAX","value":"https://wax.antelope.tools","mainnet":true,"pair":"wax","icon":"wax","order":4},{"label":"Telos","value":"https://telos.antelope.tools","mainnet":true,"pair":"telos","icon":"telos","order":1},{"label":"Libre","value":"https://libre.antelope.tools","mainnet":true,"pair":"libre","icon":"libre","order":2},{"label":"LACChain EOSIO","value":"https://lacchain.antelope.tools","mainnet":true,"pair":null,"icon":"lacchain","order":6},{"label":"Jungle4 Testnet","value":"https://jungle.antelope.tools","mainnet":false,"pair":"eos","icon":"jungle","order":5},{"label":"Proton Testnet","value":"https://proton-testnet.antelope.tools","mainnet":false,"pair":"proton","icon":"proton","order":3},{"label":"WAX Testnet","value":"https://wax-testnet.antelope.tools","mainnet":false,"pair":"wax","icon":"wax","order":4},{"label":"Telos Testnet","value":"https://telos-testnet.antelope.tools","mainnet":false,"pair":"telos","icon":"telos","order":1},{"label":"Libre Testnet","value":"https://libre-testnet.antelope.tools","mainnet":false,"pair":"libre","icon":"libre","order":2},{"label":"Ultra Testnet","value":"https://ultra-testnet.antelope.tools","mainnet":false,"pair":"ultra","icon":"ultra","order":6}]' - REACT_APP_DISABLED_MENU_ITEMS: '["/undiscoverable-bps","/stress-test"]' + REACT_APP_DISABLED_MENU_ITEMS: '["/undiscoverable-bps","/stress-test","/evm"]' REACT_APP_BLOCK_EXPLORER_URL: 'https://eosio-explorer.lacchain.net/transaction/(transaction)' REACT_APP_STATE_HISTORY_ENABLED: 'true' REACT_APP_GOOGLE_ANALITIC_PAGE_ID: 'G-E6Y0EC9FT8' diff --git a/.github/workflows/deploy-libre-testnet.yaml b/.github/workflows/deploy-libre-testnet.yaml index 4b28efa9..0daebd0a 100644 --- a/.github/workflows/deploy-libre-testnet.yaml +++ b/.github/workflows/deploy-libre-testnet.yaml @@ -56,7 +56,7 @@ jobs: REACT_APP_SYNC_TOLERANCE_INTERVAL: 180000 REACT_APP_TOKEN_SYMBOL: 'LIBRE' REACT_APP_NETWORK_URL: '[{"label":"EOS","value":"https://eos.antelope.tools","mainnet":true,"pair":"eos","icon":"eos","order":5},{"label":"Proton","value":"https://proton.antelope.tools","mainnet":true,"pair":"proton","icon":"proton","order":3},{"label":"WAX","value":"https://wax.antelope.tools","mainnet":true,"pair":"wax","icon":"wax","order":4},{"label":"Telos","value":"https://telos.antelope.tools","mainnet":true,"pair":"telos","icon":"telos","order":1},{"label":"Libre","value":"https://libre.antelope.tools","mainnet":true,"pair":"libre","icon":"libre","order":2},{"label":"LACChain EOSIO","value":"https://lacchain.antelope.tools","mainnet":true,"pair":null,"icon":"lacchain","order":6},{"label":"Jungle4 Testnet","value":"https://jungle.antelope.tools","mainnet":false,"pair":"eos","icon":"jungle","order":5},{"label":"Proton Testnet","value":"https://proton-testnet.antelope.tools","mainnet":false,"pair":"proton","icon":"proton","order":3},{"label":"WAX Testnet","value":"https://wax-testnet.antelope.tools","mainnet":false,"pair":"wax","icon":"wax","order":4},{"label":"Telos Testnet","value":"https://telos-testnet.antelope.tools","mainnet":false,"pair":"telos","icon":"telos","order":1},{"label":"Libre Testnet","value":"https://libre-testnet.antelope.tools","mainnet":false,"pair":"libre","icon":"libre","order":2},{"label":"Ultra Testnet","value":"https://ultra-testnet.antelope.tools","mainnet":false,"pair":"ultra","icon":"ultra","order":6}]' - REACT_APP_DISABLED_MENU_ITEMS: '[]' + REACT_APP_DISABLED_MENU_ITEMS: '["/evm"]' REACT_APP_BLOCK_EXPLORER_URL: 'https://testnet.libre.org/v2/explore/transaction/(transaction)' REACT_APP_STATE_HISTORY_ENABLED: 'true' REACT_APP_GOOGLE_ANALITIC_PAGE_ID: 'G-E6Y0EC9FT8' diff --git a/.github/workflows/deploy-libre.yaml b/.github/workflows/deploy-libre.yaml index 36ff0011..5192eb64 100644 --- a/.github/workflows/deploy-libre.yaml +++ b/.github/workflows/deploy-libre.yaml @@ -56,7 +56,7 @@ jobs: REACT_APP_SYNC_TOLERANCE_INTERVAL: 180000 REACT_APP_TOKEN_SYMBOL: 'LIBRE' REACT_APP_NETWORK_URL: '[{"label":"EOS","value":"https://eos.antelope.tools","mainnet":true,"pair":"eos","icon":"eos","order":5},{"label":"Proton","value":"https://proton.antelope.tools","mainnet":true,"pair":"proton","icon":"proton","order":3},{"label":"WAX","value":"https://wax.antelope.tools","mainnet":true,"pair":"wax","icon":"wax","order":4},{"label":"Telos","value":"https://telos.antelope.tools","mainnet":true,"pair":"telos","icon":"telos","order":1},{"label":"Libre","value":"https://libre.antelope.tools","mainnet":true,"pair":"libre","icon":"libre","order":2},{"label":"LACChain EOSIO","value":"https://lacchain.antelope.tools","mainnet":true,"pair":null,"icon":"lacchain","order":6},{"label":"Jungle4 Testnet","value":"https://jungle.antelope.tools","mainnet":false,"pair":"eos","icon":"jungle","order":5},{"label":"Proton Testnet","value":"https://proton-testnet.antelope.tools","mainnet":false,"pair":"proton","icon":"proton","order":3},{"label":"WAX Testnet","value":"https://wax-testnet.antelope.tools","mainnet":false,"pair":"wax","icon":"wax","order":4},{"label":"Telos Testnet","value":"https://telos-testnet.antelope.tools","mainnet":false,"pair":"telos","icon":"telos","order":1},{"label":"Libre Testnet","value":"https://libre-testnet.antelope.tools","mainnet":false,"pair":"libre","icon":"libre","order":2},{"label":"Ultra Testnet","value":"https://ultra-testnet.antelope.tools","mainnet":false,"pair":"ultra","icon":"ultra","order":6}]' - REACT_APP_DISABLED_MENU_ITEMS: '["/missed-blocks","/stress-test"]' + REACT_APP_DISABLED_MENU_ITEMS: '["/missed-blocks","/stress-test","/evm"]' REACT_APP_BLOCK_EXPLORER_URL: 'https://www.libreblocks.io/tx/(transaction)' REACT_APP_STATE_HISTORY_ENABLED: 'true' REACT_APP_GOOGLE_ANALITIC_PAGE_ID: 'G-E6Y0EC9FT8' diff --git a/.github/workflows/deploy-mainnet.yaml b/.github/workflows/deploy-mainnet.yaml index d612b9c1..843dcec1 100644 --- a/.github/workflows/deploy-mainnet.yaml +++ b/.github/workflows/deploy-mainnet.yaml @@ -58,6 +58,7 @@ jobs: REACT_APP_STATE_HISTORY_ENABLED: 'false' REACT_APP_GOOGLE_ANALITIC_PAGE_ID: 'G-E6Y0EC9FT8' REACT_APP_PUBLIC_RE_CAPTCHA_KEY: ${{ secrets.REACT_APP_PUBLIC_RE_CAPTCHA_KEY }} + REACT_APP_EVM_ENDPOINT: 'https://api.evm.eosnetwork.com' - name: Build and deploy kubernetes files id: build_kubernetes_files diff --git a/.github/workflows/deploy-proton-testnet.yaml b/.github/workflows/deploy-proton-testnet.yaml index 3996b2a4..6689c5ea 100644 --- a/.github/workflows/deploy-proton-testnet.yaml +++ b/.github/workflows/deploy-proton-testnet.yaml @@ -56,7 +56,7 @@ jobs: REACT_APP_SYNC_TOLERANCE_INTERVAL: 180000 REACT_APP_TOKEN_SYMBOL: 'XPR' REACT_APP_NETWORK_URL: '[{"label":"EOS","value":"https://eos.antelope.tools","mainnet":true,"pair":"eos","icon":"eos","order":5},{"label":"Proton","value":"https://proton.antelope.tools","mainnet":true,"pair":"proton","icon":"proton","order":3},{"label":"WAX","value":"https://wax.antelope.tools","mainnet":true,"pair":"wax","icon":"wax","order":4},{"label":"Telos","value":"https://telos.antelope.tools","mainnet":true,"pair":"telos","icon":"telos","order":1},{"label":"Libre","value":"https://libre.antelope.tools","mainnet":true,"pair":"libre","icon":"libre","order":2},{"label":"LACChain EOSIO","value":"https://lacchain.antelope.tools","mainnet":true,"pair":null,"icon":"lacchain","order":6},{"label":"Jungle4 Testnet","value":"https://jungle.antelope.tools","mainnet":false,"pair":"eos","icon":"jungle","order":5},{"label":"Proton Testnet","value":"https://proton-testnet.antelope.tools","mainnet":false,"pair":"proton","icon":"proton","order":3},{"label":"WAX Testnet","value":"https://wax-testnet.antelope.tools","mainnet":false,"pair":"wax","icon":"wax","order":4},{"label":"Telos Testnet","value":"https://telos-testnet.antelope.tools","mainnet":false,"pair":"telos","icon":"telos","order":1},{"label":"Libre Testnet","value":"https://libre-testnet.antelope.tools","mainnet":false,"pair":"libre","icon":"libre","order":2},{"label":"Ultra Testnet","value":"https://ultra-testnet.antelope.tools","mainnet":false,"pair":"ultra","icon":"ultra","order":6}]' - REACT_APP_DISABLED_MENU_ITEMS: '["/missed-blocks","/block-distribution","/cpu-benchmark","/stress-test"]' + REACT_APP_DISABLED_MENU_ITEMS: '["/missed-blocks","/block-distribution","/cpu-benchmark","/stress-test","/evm"]' REACT_APP_BLOCK_EXPLORER_URL: 'https://testnet.protonscan.io/transaction/(transaction)' REACT_APP_STATE_HISTORY_ENABLED: 'false' REACT_APP_GOOGLE_ANALITIC_PAGE_ID: 'G-E6Y0EC9FT8' diff --git a/.github/workflows/deploy-proton.yaml b/.github/workflows/deploy-proton.yaml index 72d62eab..00e099b6 100644 --- a/.github/workflows/deploy-proton.yaml +++ b/.github/workflows/deploy-proton.yaml @@ -56,7 +56,7 @@ jobs: REACT_APP_SYNC_TOLERANCE_INTERVAL: 180000 REACT_APP_TOKEN_SYMBOL: 'XPR' REACT_APP_NETWORK_URL: '[{"label":"EOS","value":"https://eos.antelope.tools","mainnet":true,"pair":"eos","icon":"eos","order":5},{"label":"Proton","value":"https://proton.antelope.tools","mainnet":true,"pair":"proton","icon":"proton","order":3},{"label":"WAX","value":"https://wax.antelope.tools","mainnet":true,"pair":"wax","icon":"wax","order":4},{"label":"Telos","value":"https://telos.antelope.tools","mainnet":true,"pair":"telos","icon":"telos","order":1},{"label":"Libre","value":"https://libre.antelope.tools","mainnet":true,"pair":"libre","icon":"libre","order":2},{"label":"LACChain EOSIO","value":"https://lacchain.antelope.tools","mainnet":true,"pair":null,"icon":"lacchain","order":6},{"label":"Jungle4 Testnet","value":"https://jungle.antelope.tools","mainnet":false,"pair":"eos","icon":"jungle","order":5},{"label":"Proton Testnet","value":"https://proton-testnet.antelope.tools","mainnet":false,"pair":"proton","icon":"proton","order":3},{"label":"WAX Testnet","value":"https://wax-testnet.antelope.tools","mainnet":false,"pair":"wax","icon":"wax","order":4},{"label":"Telos Testnet","value":"https://telos-testnet.antelope.tools","mainnet":false,"pair":"telos","icon":"telos","order":1},{"label":"Libre Testnet","value":"https://libre-testnet.antelope.tools","mainnet":false,"pair":"libre","icon":"libre","order":2},{"label":"Ultra Testnet","value":"https://ultra-testnet.antelope.tools","mainnet":false,"pair":"ultra","icon":"ultra","order":6}]' - REACT_APP_DISABLED_MENU_ITEMS: '["/missed-blocks","/block-distribution","/cpu-benchmark","/stress-test"]' + REACT_APP_DISABLED_MENU_ITEMS: '["/missed-blocks","/block-distribution","/cpu-benchmark","/stress-test","/evm"]' REACT_APP_BLOCK_EXPLORER_URL: 'https://www.protonscan.io/transaction/(transaction)' REACT_APP_STATE_HISTORY_ENABLED: 'false' REACT_APP_GOOGLE_ANALITIC_PAGE_ID: 'G-E6Y0EC9FT8' diff --git a/.github/workflows/deploy-telos-testnet.yaml b/.github/workflows/deploy-telos-testnet.yaml index c4d18507..d7e25c8e 100644 --- a/.github/workflows/deploy-telos-testnet.yaml +++ b/.github/workflows/deploy-telos-testnet.yaml @@ -61,6 +61,7 @@ jobs: REACT_APP_STATE_HISTORY_ENABLED=: 'false' REACT_APP_GOOGLE_ANALITIC_PAGE_ID: 'G-E6Y0EC9FT8' REACT_APP_PUBLIC_RE_CAPTCHA_KEY: ${{ secrets.REACT_APP_PUBLIC_RE_CAPTCHA_KEY }} + REACT_APP_EVM_ENDPOINT: 'https://testnet.telos.net/evm' - name: Build and deploy kubernetes files id: build_kubernetes_files diff --git a/.github/workflows/deploy-telos.yaml b/.github/workflows/deploy-telos.yaml index eaff756e..e3223f9f 100644 --- a/.github/workflows/deploy-telos.yaml +++ b/.github/workflows/deploy-telos.yaml @@ -61,6 +61,7 @@ jobs: REACT_APP_STATE_HISTORY_ENABLED=: 'false' REACT_APP_GOOGLE_ANALITIC_PAGE_ID: 'G-E6Y0EC9FT8' REACT_APP_PUBLIC_RE_CAPTCHA_KEY: ${{ secrets.REACT_APP_PUBLIC_RE_CAPTCHA_KEY }} + REACT_APP_EVM_ENDPOINT: 'https://mainnet.telos.net/evm' - name: Build and deploy kubernetes files id: build_kubernetes_files diff --git a/.github/workflows/deploy-ultra-testnet.yaml b/.github/workflows/deploy-ultra-testnet.yaml index 064324f4..ff8dc886 100644 --- a/.github/workflows/deploy-ultra-testnet.yaml +++ b/.github/workflows/deploy-ultra-testnet.yaml @@ -56,7 +56,7 @@ jobs: REACT_APP_SYNC_TOLERANCE_INTERVAL: 180000 REACT_APP_TOKEN_SYMBOL: 'UOS' REACT_APP_NETWORK_URL: '[{"label":"EOS","value":"https://eos.antelope.tools","mainnet":true,"pair":"eos","icon":"eos","order":5},{"label":"Proton","value":"https://proton.antelope.tools","mainnet":true,"pair":"proton","icon":"proton","order":3},{"label":"WAX","value":"https://wax.antelope.tools","mainnet":true,"pair":"wax","icon":"wax","order":4},{"label":"Telos","value":"https://telos.antelope.tools","mainnet":true,"pair":"telos","icon":"telos","order":1},{"label":"Libre","value":"https://libre.antelope.tools","mainnet":true,"pair":"libre","icon":"libre","order":2},{"label":"LACChain EOSIO","value":"https://lacchain.antelope.tools","mainnet":true,"pair":null,"icon":"lacchain","order":6},{"label":"Jungle4 Testnet","value":"https://jungle.antelope.tools","mainnet":false,"pair":"eos","icon":"jungle","order":5},{"label":"Proton Testnet","value":"https://proton-testnet.antelope.tools","mainnet":false,"pair":"proton","icon":"proton","order":3},{"label":"WAX Testnet","value":"https://wax-testnet.antelope.tools","mainnet":false,"pair":"wax","icon":"wax","order":4},{"label":"Telos Testnet","value":"https://telos-testnet.antelope.tools","mainnet":false,"pair":"telos","icon":"telos","order":1},{"label":"Libre Testnet","value":"https://libre-testnet.antelope.tools","mainnet":false,"pair":"libre","icon":"libre","order":2},{"label":"Ultra Testnet","value":"https://ultra-testnet.antelope.tools","mainnet":false,"pair":"ultra","icon":"ultra","order":6}]' - REACT_APP_DISABLED_MENU_ITEMS: '["/block-producers","/nodes","/missed-blocks","/endpoints","/bpjson","/ricardian-contract","/block-distribution","/nodes-distribution","/cpu-benchmark","/rewards-distribution","/undiscoverable-bps","/endpoints-stats","/stress-test"]' + REACT_APP_DISABLED_MENU_ITEMS: '["/block-producers","/nodes","/missed-blocks","/endpoints","/bpjson","/ricardian-contract","/block-distribution","/nodes-distribution","/cpu-benchmark","/rewards-distribution","/undiscoverable-bps","/endpoints-stats","/stress-test","/evm"]' REACT_APP_BLOCK_EXPLORER_URL: 'https://explorer.testnet.ultra.io/tx/(transaction)' REACT_APP_STATE_HISTORY_ENABLED: 'false' REACT_APP_GOOGLE_ANALITIC_PAGE_ID: 'G-E6Y0EC9FT8' diff --git a/.github/workflows/deploy-wax-testnet.yaml b/.github/workflows/deploy-wax-testnet.yaml index 44c346ad..3fac9653 100644 --- a/.github/workflows/deploy-wax-testnet.yaml +++ b/.github/workflows/deploy-wax-testnet.yaml @@ -56,7 +56,7 @@ jobs: REACT_APP_SYNC_TOLERANCE_INTERVAL: 180000 REACT_APP_TOKEN_SYMBOL: 'WAX' REACT_APP_NETWORK_URL: '[{"label":"EOS","value":"https://eos.antelope.tools","mainnet":true,"pair":"eos","icon":"eos","order":5},{"label":"Proton","value":"https://proton.antelope.tools","mainnet":true,"pair":"proton","icon":"proton","order":3},{"label":"WAX","value":"https://wax.antelope.tools","mainnet":true,"pair":"wax","icon":"wax","order":4},{"label":"Telos","value":"https://telos.antelope.tools","mainnet":true,"pair":"telos","icon":"telos","order":1},{"label":"Libre","value":"https://libre.antelope.tools","mainnet":true,"pair":"libre","icon":"libre","order":2},{"label":"LACChain EOSIO","value":"https://lacchain.antelope.tools","mainnet":true,"pair":null,"icon":"lacchain","order":6},{"label":"Jungle4 Testnet","value":"https://jungle.antelope.tools","mainnet":false,"pair":"eos","icon":"jungle","order":5},{"label":"Proton Testnet","value":"https://proton-testnet.antelope.tools","mainnet":false,"pair":"proton","icon":"proton","order":3},{"label":"WAX Testnet","value":"https://wax-testnet.antelope.tools","mainnet":false,"pair":"wax","icon":"wax","order":4},{"label":"Telos Testnet","value":"https://telos-testnet.antelope.tools","mainnet":false,"pair":"telos","icon":"telos","order":1},{"label":"Libre Testnet","value":"https://libre-testnet.antelope.tools","mainnet":false,"pair":"libre","icon":"libre","order":2},{"label":"Ultra Testnet","value":"https://ultra-testnet.antelope.tools","mainnet":false,"pair":"ultra","icon":"ultra","order":6}]' - REACT_APP_DISABLED_MENU_ITEMS: '["/missed-blocks", "/cpu-benchmark","/block-distribution","/stress-test"]' + REACT_APP_DISABLED_MENU_ITEMS: '["/missed-blocks", "/cpu-benchmark","/block-distribution","/stress-test",""/evm"]' REACT_APP_BLOCK_EXPLORER_URL: 'https://wax-test.bloks.io/transaction/(transaction)' REACT_APP_STATE_HISTORY_ENABLED=: 'false' REACT_APP_GOOGLE_ANALITIC_PAGE_ID: 'G-E6Y0EC9FT8' diff --git a/.github/workflows/deploy-wax.yaml b/.github/workflows/deploy-wax.yaml index 25b618d2..ef43fddf 100644 --- a/.github/workflows/deploy-wax.yaml +++ b/.github/workflows/deploy-wax.yaml @@ -56,7 +56,7 @@ jobs: REACT_APP_SYNC_TOLERANCE_INTERVAL: 180000 REACT_APP_TOKEN_SYMBOL: 'WAX' REACT_APP_NETWORK_URL: '[{"label":"EOS","value":"https://eos.antelope.tools","mainnet":true,"pair":"eos","icon":"eos","order":5},{"label":"Proton","value":"https://proton.antelope.tools","mainnet":true,"pair":"proton","icon":"proton","order":3},{"label":"WAX","value":"https://wax.antelope.tools","mainnet":true,"pair":"wax","icon":"wax","order":4},{"label":"Telos","value":"https://telos.antelope.tools","mainnet":true,"pair":"telos","icon":"telos","order":1},{"label":"Libre","value":"https://libre.antelope.tools","mainnet":true,"pair":"libre","icon":"libre","order":2},{"label":"LACChain EOSIO","value":"https://lacchain.antelope.tools","mainnet":true,"pair":null,"icon":"lacchain","order":6},{"label":"Jungle4 Testnet","value":"https://jungle.antelope.tools","mainnet":false,"pair":"eos","icon":"jungle","order":5},{"label":"Proton Testnet","value":"https://proton-testnet.antelope.tools","mainnet":false,"pair":"proton","icon":"proton","order":3},{"label":"WAX Testnet","value":"https://wax-testnet.antelope.tools","mainnet":false,"pair":"wax","icon":"wax","order":4},{"label":"Telos Testnet","value":"https://telos-testnet.antelope.tools","mainnet":false,"pair":"telos","icon":"telos","order":1},{"label":"Libre Testnet","value":"https://libre-testnet.antelope.tools","mainnet":false,"pair":"libre","icon":"libre","order":2},{"label":"Ultra Testnet","value":"https://ultra-testnet.antelope.tools","mainnet":false,"pair":"ultra","icon":"ultra","order":6}]' - REACT_APP_DISABLED_MENU_ITEMS: '["/missed-blocks", "/cpu-benchmark","/block-distribution","/stress-test"]' + REACT_APP_DISABLED_MENU_ITEMS: '["/missed-blocks", "/cpu-benchmark","/block-distribution","/stress-test","/evm"]' REACT_APP_BLOCK_EXPLORER_URL: 'https://wax.bloks.io/transaction/(transaction)' REACT_APP_STATE_HISTORY_ENABLED=: 'false' REACT_APP_GOOGLE_ANALITIC_PAGE_ID: 'G-E6Y0EC9FT8' From e8c8d2fc102d60d0de884b4228088569e614734f Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Mon, 7 Aug 2023 16:50:11 -0600 Subject: [PATCH 22/75] chore: format code --- .github/workflows/deploy-libre.yaml | 4 ++-- webapp/src/config/evm.config.js | 2 +- webapp/src/gql/evm.gql.js | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/deploy-libre.yaml b/.github/workflows/deploy-libre.yaml index 5192eb64..bbc1b706 100644 --- a/.github/workflows/deploy-libre.yaml +++ b/.github/workflows/deploy-libre.yaml @@ -56,7 +56,7 @@ jobs: REACT_APP_SYNC_TOLERANCE_INTERVAL: 180000 REACT_APP_TOKEN_SYMBOL: 'LIBRE' REACT_APP_NETWORK_URL: '[{"label":"EOS","value":"https://eos.antelope.tools","mainnet":true,"pair":"eos","icon":"eos","order":5},{"label":"Proton","value":"https://proton.antelope.tools","mainnet":true,"pair":"proton","icon":"proton","order":3},{"label":"WAX","value":"https://wax.antelope.tools","mainnet":true,"pair":"wax","icon":"wax","order":4},{"label":"Telos","value":"https://telos.antelope.tools","mainnet":true,"pair":"telos","icon":"telos","order":1},{"label":"Libre","value":"https://libre.antelope.tools","mainnet":true,"pair":"libre","icon":"libre","order":2},{"label":"LACChain EOSIO","value":"https://lacchain.antelope.tools","mainnet":true,"pair":null,"icon":"lacchain","order":6},{"label":"Jungle4 Testnet","value":"https://jungle.antelope.tools","mainnet":false,"pair":"eos","icon":"jungle","order":5},{"label":"Proton Testnet","value":"https://proton-testnet.antelope.tools","mainnet":false,"pair":"proton","icon":"proton","order":3},{"label":"WAX Testnet","value":"https://wax-testnet.antelope.tools","mainnet":false,"pair":"wax","icon":"wax","order":4},{"label":"Telos Testnet","value":"https://telos-testnet.antelope.tools","mainnet":false,"pair":"telos","icon":"telos","order":1},{"label":"Libre Testnet","value":"https://libre-testnet.antelope.tools","mainnet":false,"pair":"libre","icon":"libre","order":2},{"label":"Ultra Testnet","value":"https://ultra-testnet.antelope.tools","mainnet":false,"pair":"ultra","icon":"ultra","order":6}]' - REACT_APP_DISABLED_MENU_ITEMS: '["/missed-blocks","/stress-test","/evm"]' + REACT_APP_DISABLED_MENU_ITEMS: '["/stress-test","/evm"]' REACT_APP_BLOCK_EXPLORER_URL: 'https://www.libreblocks.io/tx/(transaction)' REACT_APP_STATE_HISTORY_ENABLED: 'true' REACT_APP_GOOGLE_ANALITIC_PAGE_ID: 'G-E6Y0EC9FT8' @@ -83,7 +83,7 @@ jobs: HAPI_EOS_API_NETWORK_NAME: libre HAPI_EOS_API_ENDPOINTS: '["https://libre.edenia.cloud","https://libre.eosusa.io","https://api.libre.cryptolions.io"]' HAPI_EOS_STATE_HISTORY_PLUGIN_ENDPOINT: 'ws://api-node.libre:8080' - HAPI_EOS_MISSED_BLOCKS_ENABLED: 'false' + HAPI_EOS_MISSED_BLOCKS_ENABLED: 'true' HAPI_EOS_BLOCK_HISTORY_DAYS: 90 HAPI_EOS_MAX_CPU_BLOCK: 100000 HAPI_EOS_MAX_NET_BLOCK: 1048576 diff --git a/webapp/src/config/evm.config.js b/webapp/src/config/evm.config.js index 9dfb0e69..adb73cdf 100644 --- a/webapp/src/config/evm.config.js +++ b/webapp/src/config/evm.config.js @@ -17,4 +17,4 @@ switch (eosConfig.networkName) { export const avgBlockTime = _avgBlockTime export const account = 'eosio.evm' -export const endpoint = process.env.REACT_APP_EVM_ENDPOINT \ No newline at end of file +export const endpoint = process.env.REACT_APP_EVM_ENDPOINT diff --git a/webapp/src/gql/evm.gql.js b/webapp/src/gql/evm.gql.js index 65097ebb..e1dbe4cd 100644 --- a/webapp/src/gql/evm.gql.js +++ b/webapp/src/gql/evm.gql.js @@ -15,7 +15,7 @@ export const EVM_STATS_SUBSCRIPTION = gql` export const EVM_TOTAL_TRANSACTIONS_SUBSCRIPTION = gql` subscription { evm_transaction_aggregate { - aggregate{ + aggregate { count } } @@ -40,4 +40,4 @@ export const EVM_TOKEN_QUERY = gql` outgoing } } -` \ No newline at end of file +` From 7eb95694fe87089480c499942a893c816b65997f Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Tue, 8 Aug 2023 11:34:51 -0600 Subject: [PATCH 23/75] chore(webapp): format labels --- webapp/src/components/SimpleDataCard/index.js | 3 +- webapp/src/routes/EVMDashboard/index.js | 30 ++++++++++++++----- webapp/src/routes/EVMDashboard/useEVMstate.js | 4 +-- webapp/src/utils/ethapi.js | 2 +- 4 files changed, 27 insertions(+), 12 deletions(-) diff --git a/webapp/src/components/SimpleDataCard/index.js b/webapp/src/components/SimpleDataCard/index.js index a6b74de9..2694af58 100644 --- a/webapp/src/components/SimpleDataCard/index.js +++ b/webapp/src/components/SimpleDataCard/index.js @@ -19,13 +19,14 @@ const SimpleDataCard = ({ children, }) => { const classes = useStyles() + const isNotLoading = !loading ?? !!value return (
{title && {title}} - {!loading ? ( + {isNotLoading ? ( {
@@ -93,17 +94,23 @@ const EVMDashboard = () => { /> { />
diff --git a/webapp/src/routes/EVMDashboard/useEVMstate.js b/webapp/src/routes/EVMDashboard/useEVMstate.js index 6593c5f1..fd7039f2 100644 --- a/webapp/src/routes/EVMDashboard/useEVMstate.js +++ b/webapp/src/routes/EVMDashboard/useEVMstate.js @@ -10,7 +10,7 @@ import { } from '../../gql' import eosApi from '../../utils/eosapi' import ethApi from '../../utils/ethapi' -import { formatWithThousandSeparator, rangeOptions } from '../../utils' +import { rangeOptions } from '../../utils' import { evmConfig } from 'config' const useEVMState = (theme, t) => { @@ -158,7 +158,7 @@ const useEVMState = (theme, t) => { const lastBlock = await ethApi.getLastBlock() const stats = { wallets_created_count: amount, - gas_price: formatWithThousandSeparator(gasPrice / 10 ** 9, 1) + ' Gwei', + gas_price: gasPrice / 10 ** 9, last_block: lastBlock, } diff --git a/webapp/src/utils/ethapi.js b/webapp/src/utils/ethapi.js index e5b11ba5..02b0a34f 100644 --- a/webapp/src/utils/ethapi.js +++ b/webapp/src/utils/ethapi.js @@ -13,7 +13,7 @@ const queryEthApi = async method => { jsonrpc: '2.0', }) - return parseInt(result) + return parseInt(result) || result } catch (error) {} } From 4f5a526b259ff0a4431407a3a775c4f823a1c5e4 Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Tue, 8 Aug 2023 11:35:00 -0600 Subject: [PATCH 24/75] chore(envs): add evm endpoints --- .env.jungle | 1 + .env.mainnet | 1 + .env.telos | 1 + .env.telostestnet | 3 ++- 4 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.env.jungle b/.env.jungle index 06d01497..51f2b382 100644 --- a/.env.jungle +++ b/.env.jungle @@ -88,3 +88,4 @@ REACT_APP_STATE_HISTORY_ENABLED=false REACT_APP_GOOGLE_ANALITIC_PAGE_ID=G-E6Y0EC9FT8 REACT_APP_PUBLIC_RE_CAPTCHA_KEY=key REACT_APP_EOS_INCLUDE_TRANSACTION= +REACT_APP_EVM_ENDPOINT=https://api.testnet.evm.eosnetwork.com diff --git a/.env.mainnet b/.env.mainnet index d55c9dc2..69c80ee4 100644 --- a/.env.mainnet +++ b/.env.mainnet @@ -88,3 +88,4 @@ REACT_APP_STATE_HISTORY_ENABLED=false REACT_APP_GOOGLE_ANALITIC_PAGE_ID=G-E6Y0EC9FT8 REACT_APP_PUBLIC_RE_CAPTCHA_KEY=key REACT_APP_EOS_INCLUDE_TRANSACTION= +REACT_APP_EVM_ENDPOINT='https://api.evm.eosnetwork.com' diff --git a/.env.telos b/.env.telos index 733d880c..6af5b1b5 100644 --- a/.env.telos +++ b/.env.telos @@ -87,3 +87,4 @@ REACT_APP_STATE_HISTORY_ENABLED=false REACT_APP_GOOGLE_ANALITIC_PAGE_ID=G-E6Y0EC9FT8 REACT_APP_PUBLIC_RE_CAPTCHA_KEY=key REACT_APP_EOS_INCLUDE_TRANSACTION= +REACT_APP_EVM_ENDPOINT='https://mainnet.telos.net/evm' diff --git a/.env.telostestnet b/.env.telostestnet index 61abd7d3..9cb52eb8 100644 --- a/.env.telostestnet +++ b/.env.telostestnet @@ -87,4 +87,5 @@ REACT_APP_BLOCK_EXPLORER_URL=https://explorer-test.telos.net/transaction/(transa REACT_APP_STATE_HISTORY_ENABLED=false REACT_APP_GOOGLE_ANALITIC_PAGE_ID=G-E6Y0EC9FT8 REACT_APP_PUBLIC_RE_CAPTCHA_KEY=key -REACT_APP_EOS_INCLUDE_TRANSACTION= \ No newline at end of file +REACT_APP_EOS_INCLUDE_TRANSACTION= +REACT_APP_EVM_ENDPOINT=https://testnet.telos.net/evm \ No newline at end of file From 8e88b516b08ae38e80775bcf552c235893d0e328 Mon Sep 17 00:00:00 2001 From: Leister Francisco Alvarez Campos Date: Wed, 9 Aug 2023 11:09:21 -0600 Subject: [PATCH 25/75] refactor(hapi-evm): apply code factor suggestion --- .../services/hyperion/updaters/eosio-evm-transfer.updater.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/hapi-evm/src/services/hyperion/updaters/eosio-evm-transfer.updater.ts b/hapi-evm/src/services/hyperion/updaters/eosio-evm-transfer.updater.ts index cfc009cd..2cfe96f2 100644 --- a/hapi-evm/src/services/hyperion/updaters/eosio-evm-transfer.updater.ts +++ b/hapi-evm/src/services/hyperion/updaters/eosio-evm-transfer.updater.ts @@ -1,5 +1,3 @@ -import { isAddress } from 'web3-validator' - import { transferModel } from '../../../models' // TODO: handle this as a network function, for example, base on the From b6ad93599e1e8120a038c3aaac162b921365d4a8 Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Wed, 9 Aug 2023 15:02:56 -0600 Subject: [PATCH 26/75] feat(webapp): add transactions per block live graphic - refactor: Split transaction chart component - fix: get block --- .../PauseButton}/EqualIcon.js | 0 webapp/src/components/PauseButton/index.js | 54 ++++++ webapp/src/components/PauseButton/styles.js | 14 ++ webapp/src/components/SimpleDataCard/index.js | 2 +- .../TransactionsChartContainer/index.js | 143 +++++++++++++++ .../TransactionsChartContainer/styles.js | 33 ++++ webapp/src/config/evm.config.js | 5 +- webapp/src/language/en.json | 8 +- webapp/src/language/es.json | 8 +- .../src/routes/EVMDashboard/ChartHistory.js | 109 ----------- webapp/src/routes/EVMDashboard/index.js | 79 ++++---- webapp/src/routes/EVMDashboard/styles.js | 18 -- webapp/src/routes/EVMDashboard/useEVMstate.js | 140 ++++++++++++--- webapp/src/routes/Home/TransactionInfo.js | 169 +++++------------- webapp/src/routes/Home/styles.js | 39 ---- webapp/src/utils/ethapi.js | 7 +- 16 files changed, 470 insertions(+), 358 deletions(-) rename webapp/src/{routes/Home => components/PauseButton}/EqualIcon.js (100%) create mode 100644 webapp/src/components/PauseButton/index.js create mode 100644 webapp/src/components/PauseButton/styles.js create mode 100644 webapp/src/components/TransactionsChartContainer/index.js create mode 100644 webapp/src/components/TransactionsChartContainer/styles.js delete mode 100644 webapp/src/routes/EVMDashboard/ChartHistory.js diff --git a/webapp/src/routes/Home/EqualIcon.js b/webapp/src/components/PauseButton/EqualIcon.js similarity index 100% rename from webapp/src/routes/Home/EqualIcon.js rename to webapp/src/components/PauseButton/EqualIcon.js diff --git a/webapp/src/components/PauseButton/index.js b/webapp/src/components/PauseButton/index.js new file mode 100644 index 00000000..c379b511 --- /dev/null +++ b/webapp/src/components/PauseButton/index.js @@ -0,0 +1,54 @@ +/* eslint camelcase: 0 */ +import React from 'react' +import { makeStyles } from '@mui/styles' +import { useTheme } from '@mui/material/styles' +import { useTranslation } from 'react-i18next' +import clsx from 'clsx' +import PropTypes from 'prop-types' +import Typography from '@mui/material/Typography' +import PlayArrowIcon from '@mui/icons-material/PlayArrow' + +import styles from './styles' +import EqualIcon from './EqualIcon' + +const useStyles = makeStyles(styles) + +const PauseButton = ({ isPaused, handlePause, isEnabled }) => { + const { t } = useTranslation('homeRoute') + const classes = useStyles() + const theme = useTheme() + + return ( + <> +
+ {isPaused ? ( + + ) : ( + + )} + {isPaused ? t('play') : t('pause')} +
+ + ) +} + +PauseButton.propTypes = { + isPaused: PropTypes.bool, + isEnabled: PropTypes.bool, + handlePause: PropTypes.func, +} + +export default PauseButton diff --git a/webapp/src/components/PauseButton/styles.js b/webapp/src/components/PauseButton/styles.js new file mode 100644 index 00000000..5753a893 --- /dev/null +++ b/webapp/src/components/PauseButton/styles.js @@ -0,0 +1,14 @@ +export default (theme) => ({ + pauseButton: { + display: 'flex', + width: 75, + height: 24, + '&:hover': { + cursor: 'pointer', + }, + }, + disableButton: { + color: theme.palette.action.disabled, + }, + }) + \ No newline at end of file diff --git a/webapp/src/components/SimpleDataCard/index.js b/webapp/src/components/SimpleDataCard/index.js index 2694af58..1207b73a 100644 --- a/webapp/src/components/SimpleDataCard/index.js +++ b/webapp/src/components/SimpleDataCard/index.js @@ -19,7 +19,7 @@ const SimpleDataCard = ({ children, }) => { const classes = useStyles() - const isNotLoading = !loading ?? !!value + const isNotLoading = !loading || !!value?.toString() return (
diff --git a/webapp/src/components/TransactionsChartContainer/index.js b/webapp/src/components/TransactionsChartContainer/index.js new file mode 100644 index 00000000..d17d8362 --- /dev/null +++ b/webapp/src/components/TransactionsChartContainer/index.js @@ -0,0 +1,143 @@ +import React from 'react' +import { makeStyles } from '@mui/styles' +import { useTranslation } from 'react-i18next' +import Card from '@mui/material/Card' +import CardContent from '@mui/material/CardContent' +import PropTypes from 'prop-types' +import Select from '@mui/material/Select' +import MenuItem from '@mui/material/MenuItem' +import FormControl from '@mui/material/FormControl' +import InputLabel from '@mui/material/InputLabel' +import Typography from '@mui/material/Typography' +import LinearProgress from '@mui/material/LinearProgress' + +import PauseButton from '../../components/PauseButton' +import TransactionsLineChart from '../../components/TransactionsLineChart' + +import styles from './styles' + +const useStyles = makeStyles(styles) + +const TransactionsChartContainer = ({ + title, + ariaLabel, + loading, + data, + isPaused, + handlePause, + chartLabelFormat, + historyState +}) => { + const classes = useStyles() + const { t } = useTranslation() + + return ( + + +
+ + {title} + +
+ + {historyState?.isHistoryEnabled && ( + <> + {t('timeFrame')} + + + )} + + {handlePause && ( + + )} +
+
+ {loading && } + +
+
+ ) +} + +TransactionsChartContainer.propTypes = { + ariaLabel: PropTypes.string, + title: PropTypes.string, + loading: PropTypes.bool, + isPaused: PropTypes.bool, + data: PropTypes.array, + handlePause: PropTypes.func, + chartLabelFormat: PropTypes.shape({ + yAxisText: PropTypes.string, + shared: PropTypes.bool, + blockTime: PropTypes.number, + customFormatter: PropTypes.func, + }), + historyState: PropTypes.shape({ + value: PropTypes.string, + options: PropTypes.array, + isLive: PropTypes.bool, + isHistoryEnabled: PropTypes.bool, + onSelect: PropTypes.func, + }) +} + +TransactionsChartContainer.defaultProps = { + title: '', + ariaLabel: '', + loading: false, + isPaused: false, + handlePause: undefined, +} + +export default TransactionsChartContainer diff --git a/webapp/src/components/TransactionsChartContainer/styles.js b/webapp/src/components/TransactionsChartContainer/styles.js new file mode 100644 index 00000000..88c3f6a2 --- /dev/null +++ b/webapp/src/components/TransactionsChartContainer/styles.js @@ -0,0 +1,33 @@ +export default (theme) => ({ + headerTransactionLine: { + display: 'flex', + justifyContent: 'space-between', + flexDirection: 'column', + alignItems: 'baseline', + padding: theme.spacing(1), + [theme.breakpoints.up('lg')]: { + justifyContent: 'space-between', + alignItems: 'center', + flexDirection: 'row', + }, + }, + formControl: { + display: 'flex', + justifyContent: 'space-between', + alignItems: 'center', + width: '100%', + '& .MuiFormControl-root': { + width: 200, + }, + '& .MuiInputLabel-formControl': { + position: 'relative', + marginBottom: `-${theme.spacing(2)}`, + }, + [theme.breakpoints.up('lg')]: { + width: 300, + }, + }, + cardShadow: { + boxShadow: '0px 1px 3px 1px rgba(0, 0, 0, 0.15) !important', + }, +}) diff --git a/webapp/src/config/evm.config.js b/webapp/src/config/evm.config.js index adb73cdf..c68cc048 100644 --- a/webapp/src/config/evm.config.js +++ b/webapp/src/config/evm.config.js @@ -5,16 +5,17 @@ let _avgBlockTime = 'N/A' switch (eosConfig.networkName) { case 'telos-testnet': case 'telos': - _avgBlockTime = '0.5 s' + _avgBlockTime = 0.5 break case 'jungle': case 'eos': - _avgBlockTime = '1 s' + _avgBlockTime = 1 break default: break } export const avgBlockTime = _avgBlockTime +export const maxTPSDataSize = 30 / _avgBlockTime export const account = 'eosio.evm' export const endpoint = process.env.REACT_APP_EVM_ENDPOINT diff --git a/webapp/src/language/en.json b/webapp/src/language/en.json index e21603b3..3e084a7a 100644 --- a/webapp/src/language/en.json +++ b/webapp/src/language/en.json @@ -47,7 +47,8 @@ "options": "Options", "noOptions": "No matches", "updatedAt": "Updated at", - "nextUpdateAt": "Next updated at" + "nextUpdateAt": "Next update at", + "secondsAgo": "Seconds Ago" }, "routes": { "/>sidebar": "Dashboard", @@ -138,7 +139,6 @@ "Last Week": "Last Week", "Last Year": "Last Year", "scheduleVersion": "Schedule Version", - "secondsAgo": "Seconds Ago", "tpsAllTimeHigh": "TPS All Time High", "cpuUtilization": "CPU Usage", "netUtilization": "NET Usage", @@ -440,6 +440,8 @@ "avgTX": "Average transaction per day", "ATH": "TPS All Time High", "lastBlock": "Last block", - "totalTxs": "Total transactions" + "totalTxs": "Total EVM transactions", + "transactions": "EVM transactions", + "gasUsed": "Gas Used" } } diff --git a/webapp/src/language/es.json b/webapp/src/language/es.json index 0f8bf182..beb5ae4b 100644 --- a/webapp/src/language/es.json +++ b/webapp/src/language/es.json @@ -58,7 +58,8 @@ "options": "Opciones", "noOptions": "Sin coincidencias", "updatedAt": "Última actualización", - "nextUpdateAt": "Próxima actualización" + "nextUpdateAt": "Próxima actualización", + "secondsAgo": "Hace Segundos" }, "routes": { "/>sidebar": "Panel", @@ -140,7 +141,6 @@ "Last Week": "Última Semana", "Last Year": "Último Año", "scheduleVersion": "Versión de Programa", - "secondsAgo": "Hace Segundos", "cpuUtilization": "Uso de CPU", "netUtilization": "Uso de NET", "cpuUtilizationAllTimeHigh": "Uso de CPU en TPS máximo histórico", @@ -461,6 +461,8 @@ "avgTX": "Promedio de transacciones por día", "ATH": "TPS Máximo histórico", "lastBlock": "Último bloque", - "totalTxs": "Total de transacciones" + "totalTxs": "Total de transacciones EVM", + "transactions": "Transacciones EVM", + "gasUsed": "Gas Usado" } } diff --git a/webapp/src/routes/EVMDashboard/ChartHistory.js b/webapp/src/routes/EVMDashboard/ChartHistory.js deleted file mode 100644 index 0b0aad82..00000000 --- a/webapp/src/routes/EVMDashboard/ChartHistory.js +++ /dev/null @@ -1,109 +0,0 @@ -import React from 'react' -import { makeStyles } from '@mui/styles' -import { useTranslation } from 'react-i18next' -import Card from '@mui/material/Card' -import CardContent from '@mui/material/CardContent' -import PropTypes from 'prop-types' -import Select from '@mui/material/Select' -import MenuItem from '@mui/material/MenuItem' -import FormControl from '@mui/material/FormControl' -import InputLabel from '@mui/material/InputLabel' -import Typography from '@mui/material/Typography' -import LinearProgress from '@mui/material/LinearProgress' - -import TransactionsLineChart from 'components/TransactionsLineChart' - -import styles from './styles' - -const useStyles = makeStyles(styles) - -const ChartHistory = ({ - title, - ariaLabel, - options, - value, - yAxisText, - onSelect, - shared, - loading, - data, - customFormatter -}) => { - const classes = useStyles() - const { t } = useTranslation() - - return ( - - -
- - {title} - - - {t('timeFrame')} - - -
- {loading && } - -
-
- ) -} - -ChartHistory.propTypes = { - title: PropTypes.string, - ariaLabel: PropTypes.string, - options: PropTypes.array, - value: PropTypes.string, - yAxisText: PropTypes.string, - onSelect: PropTypes.func, - shared: PropTypes.bool, - loading: PropTypes.bool, - data: PropTypes.array, - customFormatter: PropTypes.func -} - -ChartHistory.defaultProps = { - title: '', - ariaLabel: 'select', - yAxisText: '', - shared: false, - loading: false, - customFormatter: undefined -} - -export default ChartHistory diff --git a/webapp/src/routes/EVMDashboard/index.js b/webapp/src/routes/EVMDashboard/index.js index e925207a..28e538d5 100644 --- a/webapp/src/routes/EVMDashboard/index.js +++ b/webapp/src/routes/EVMDashboard/index.js @@ -4,12 +4,12 @@ import { useTranslation } from 'react-i18next' import { makeStyles } from '@mui/styles' import { formatWithThousandSeparator } from '../../utils' +import { eosConfig, evmConfig } from '../../config' import SimpleDataCard from '../../components/SimpleDataCard' -import { eosConfig, evmConfig } from 'config' +import TransactionsChartContainer from '../../components/TransactionsChartContainer' import styles from './styles' import useEVMState from './useEVMstate' -import ChartHistory from './ChartHistory' const useStyles = makeStyles(styles) @@ -26,8 +26,10 @@ const EVMDashboard = () => { options, loading, selected, + isPaused, + isLive }, - { handleSelect }, + { handleSelect, handlePause }, ] = useEVMState(theme, t) return ( @@ -43,46 +45,63 @@ const EVMDashboard = () => { value={formatWithThousandSeparator(EVMStats?.transactions_count) || 0} loading={loading} /> -
+
- handleSelect('txs', option), + isLive: isLive, + isHistoryEnabled: true, + }} data={transactionsHistoryData} - options={options} - value={selected['txs']} - onSelect={option => handleSelect('txs', option)} - customFormatter={element => { - const series = element?.series - const point = element?.point + chartLabelFormat={{ + yAxisText: t('transactions'), + blockTime: evmConfig.avgBlockTime, + customFormatter: (element) => { + const series = element?.series + const point = element?.point - const pointName = point?.name ? `${point.name}
` : '' - const resourcesDetail = point?.gas - ? `
Gas used:${point?.gas}` - : '' + const pointName = point?.name ? `${point.name}
` : '' + const resourcesDetail = point?.gas + ? `
${t('gasUsed')}: ${formatWithThousandSeparator( + point?.gas, + 3, + )} %` + : '' - return ( - pointName + - `${series?.name}: ${point?.y}` + - resourcesDetail - ) + return ( + pointName + + `${series?.name}: ${point?.y}` + + resourcesDetail + ) + }, }} />
- handleSelect('token', option), + isHistoryEnabled: true, + }} data={tokenHistoryData} - options={options} - value={selected['token']} - onSelect={option => handleSelect('token', option)} + chartLabelFormat={{ + yAxisText: eosConfig.tokenSymbol, + shared: true + }} />
@@ -116,7 +135,7 @@ const EVMDashboard = () => { ({ flexDirection: 'column', } }, - cardShadow: { - boxShadow: '0px 1px 3px 1px rgba(0, 0, 0, 0.15) !important', - }, - header: { - display: 'flex', - justifyContent: 'space-between', - alignItems: 'baseline', - padding: theme.spacing(1), - gap: theme.spacing(1), - flexWrap: 'wrap', - [theme.breakpoints.up('lg')]: { - alignItems: 'center', - }, - '& .MuiInputLabel-formControl': { - position: 'relative', - marginBottom: `-${theme.spacing(2)}`, - }, - }, }) diff --git a/webapp/src/routes/EVMDashboard/useEVMstate.js b/webapp/src/routes/EVMDashboard/useEVMstate.js index fd7039f2..e2965145 100644 --- a/webapp/src/routes/EVMDashboard/useEVMstate.js +++ b/webapp/src/routes/EVMDashboard/useEVMstate.js @@ -1,4 +1,4 @@ -import { useState, useEffect } from 'react' +import { useState, useEffect, useRef } from 'react' import { useSubscription, useLazyQuery } from '@apollo/client' import moment from 'moment' @@ -27,19 +27,36 @@ const useEVMState = (theme, t) => { }) const [EVMStats, setEVMStats] = useState() + const [blocksList, setBlockList] = useState( + new Array(evmConfig.maxTPSDataSize).fill({ y: 0 }), + ) const [transactionsHistoryData, setTransactionsHistoryData] = useState() const [tokenHistoryData, setTokenHistoryData] = useState() - const [selected, setSelected] = useState({ txs: '1 Month', token: '1 Month' }) + const [pause, setPause] = useState(false) + const [selected, setSelected] = useState({ + txs: 'Live (30s)', + token: '1 Month', + }) + + const pauseRef = useRef(pause) + const timeoutId = useRef(0) + + pauseRef.current = pause const handleSelect = (chart, option) => { setSelected(prev => ({ ...prev, [chart]: option })) if (chart === 'txs') { - getTransactionHistory({ - variables: { - range: option, - }, - }) + if (option !== 'Live (30s)') { + setPause(true) + getTransactionHistory({ + variables: { + range: option, + }, + }) + } else { + setPause(false) + } } else { getTokenHistory({ variables: { @@ -66,16 +83,47 @@ const useEVMState = (theme, t) => { } useEffect(() => { - getTransactionHistory({ - variables: { - range: selected['txs'], - }, - }) + if (!data) return + + setEVMStats(prev => ({ ...prev, ...data.evm_stats[0] })) + }, [data, loading]) + + useEffect(() => { + const updateStats = async () => { + const amount = await getWalletsCreated() + const lastBlock = await ethApi.getLastBlock() + const stats = { + wallets_created_count: amount, + last_block: lastBlock, + } + + setEVMStats(prev => ({ ...prev, ...stats })) + } + + updateStats() + }, [data, loading]) + + useEffect(() => { + const updateGasPrice = async () => { + const gasPrice = await ethApi.getGasPrice() + + setEVMStats(prev => ({ ...prev, gas_price: gasPrice / 10 ** 9 })) + } + + if (selected['txs'] !== 'Live (30s)') { + getTransactionHistory({ + variables: { + range: selected['txs'], + }, + }) + } getTokenHistory({ variables: { range: selected['token'], }, }) + + updateGasPrice() // eslint-disable-next-line }, []) @@ -146,38 +194,74 @@ const useEVMState = (theme, t) => { }, [txsCountData]) useEffect(() => { - if (!data) return + const updateTPB = async blockNum => { + if (!blockNum) { + blockNum = await ethApi.getLastBlock() + } - setEVMStats(prev => ({ ...prev, ...data.evm_stats[0] })) - }, [data, loading]) + if (!pauseRef.current) { + ethApi.getBlock(blockNum).then(block => { + setBlockList(prev => { + let data = JSON.parse(JSON.stringify(prev)) - useEffect(() => { - const getStats = async () => { - const amount = await getWalletsCreated() - const gasPrice = await ethApi.getGasPrice() - const lastBlock = await ethApi.getLastBlock() - const stats = { - wallets_created_count: amount, - gas_price: gasPrice / 10 ** 9, - last_block: lastBlock, + if (data.length >= evmConfig.maxTPSDataSize) { + data.pop() + } + + data = [ + { + name: `Block Height: ${blockNum}`, + gas: (block?.gasUsed / block?.gasLimit) * 100 || 0, + y: block?.transactions?.length || 0, + }, + ...data, + ] + + return data.map((point, index) => { + point.x = index + return point + }) + }) + }) } - setEVMStats(prev => ({ ...prev, ...stats })) + timeoutId.current = setTimeout(() => { + updateTPB(blockNum + 1) + }, evmConfig.avgBlockTime * 1000) } - getStats() - }, [data, loading]) + updateTPB() + + return () => { + clearTimeout(timeoutId.current) + } + }, []) + + useEffect(() => { + setTransactionsHistoryData([{ + name: t('transactions'), + color: theme.palette.secondary.main, + data: blocksList, + }]) + }, [blocksList, t, theme]) return [ { EVMStats, options: rangeOptions, selected, + isPaused: pause, + isLive: selected.txs === 'Live (30s)', transactionsHistoryData, tokenHistoryData, loading, }, - { handleSelect }, + { + handleSelect, + handlePause: () => { + setPause(prev => !prev) + }, + }, ] } diff --git a/webapp/src/routes/Home/TransactionInfo.js b/webapp/src/routes/Home/TransactionInfo.js index e4a59a75..e66f0688 100644 --- a/webapp/src/routes/Home/TransactionInfo.js +++ b/webapp/src/routes/Home/TransactionInfo.js @@ -1,36 +1,19 @@ /* eslint camelcase: 0 */ import React, { useEffect, useState } from 'react' import { useLazyQuery } from '@apollo/client' -import { makeStyles } from '@mui/styles' import { useTheme } from '@mui/material/styles' -import clsx from 'clsx' import PropTypes from 'prop-types' -import Select from '@mui/material/Select' -import Card from '@mui/material/Card' -import MenuItem from '@mui/material/MenuItem' -import FormControl from '@mui/material/FormControl' -import InputLabel from '@mui/material/InputLabel' -import CardContent from '@mui/material/CardContent' -import Typography from '@mui/material/Typography' -import PlayArrowIcon from '@mui/icons-material/PlayArrow' -import LinearProgress from '@mui/material/LinearProgress' import moment from 'moment' import { TRANSACTION_QUERY } from '../../gql' import { formatWithThousandSeparator, rangeOptions } from '../../utils' -import TransactionsLineChart from '../../components/TransactionsLineChart' import { useSharedState } from '../../context/state.context' import { generalConfig } from '../../config' - -import EqualIcon from './EqualIcon' -import styles from './styles' - -const useStyles = makeStyles(styles) +import TransactionsChartContainer from '../../components/TransactionsChartContainer' const options = ['Live (30s)', ...rangeOptions] const TransactionInfo = ({ t, startTrackingInfo, stopTrackingInfo }) => { - const classes = useStyles() const theme = useTheme() const [{ tps, tpb }] = useSharedState() const [graphicData, setGraphicData] = useState([ @@ -40,7 +23,7 @@ const TransactionInfo = ({ t, startTrackingInfo, stopTrackingInfo }) => { }, { name: t('transactionsPerBlock'), - color: '#00C853', + color: theme.palette.tertiary.main, }, ]) const [option, setOption] = useState(options[0]) @@ -156,110 +139,50 @@ const TransactionInfo = ({ t, startTrackingInfo, stopTrackingInfo }) => { }, [data, t]) return ( - - -
- - {t('transactions')} - -
- - {generalConfig.historyEnabled && ( - <> - {t('timeFrame')} - - - )} - -
{ - if (option === options[0]) { - setPause(!pause) - if (pause) { - startTrackingInfo() - } else { - stopTrackingInfo() - } - } - }} - className={clsx(classes.pauseButton, { - [classes.disableButton]: option !== options[0], - })} - > - {pause ? ( - - ) : ( - - )} - {pause ? t('play') : t('pause')} -
-
-
- {loading && } - { - const series = element?.series - const point = element?.point - - const pointName = point?.name ? `${point.name}
` : '' - const resourcesDetail = - point?.net && point?.cpu - ? `
Net usage:${point.net} %
CPU usage:${point.cpu} %` - : '' - - return pointName + `${series?.name}: ${point?.y}` + resourcesDetail - }} - /> -
-
+ { + if (option === options[0]) { + setPause(!pause) + if (pause) { + startTrackingInfo() + } else { + stopTrackingInfo() + } + } + }} + historyState={{ + value: option, + options: options, + isLive: option === options[0], + isHistoryEnabled: generalConfig.historyEnabled, + onSelect: setOption, + }} + data={graphicData} + chartLabelFormat={{ + ariaLabel: 'select time filter', + yAxisText: t('transactions'), + blockTime: 1, + customFormatter: element => { + const series = element?.series + const point = element?.point + + const pointName = point?.name ? `${point.name}
` : '' + const resourcesDetail = + point?.net && point?.cpu + ? `
${t('netUsage')}:${point.net} %
${t( + 'cpuUsage', + )}:${point.cpu} %` + : '' + + return ( + pointName + `${series?.name}: ${point?.y}` + resourcesDetail + ) + }, + }} + /> ) } diff --git a/webapp/src/routes/Home/styles.js b/webapp/src/routes/Home/styles.js index 128dc4ff..f37cc49a 100644 --- a/webapp/src/routes/Home/styles.js +++ b/webapp/src/routes/Home/styles.js @@ -10,45 +10,6 @@ export default (theme) => ({ display: 'block', }, }, - pauseButton: { - display: 'flex', - width: 75, - height: 24, - '&:hover': { - cursor: 'pointer', - }, - }, - disableButton: { - color: theme.palette.action.disabled, - }, - headerTransactionLine: { - display: 'flex', - justifyContent: 'space-between', - flexDirection: 'column', - alignItems: 'baseline', - padding: theme.spacing(1), - [theme.breakpoints.up('lg')]: { - justifyContent: 'space-between', - alignItems: 'center', - flexDirection: 'row', - }, - }, - formControl: { - display: 'flex', - justifyContent: 'space-between', - alignItems: 'center', - width: '100%', - '& .MuiFormControl-root': { - width: 200, - }, - '& .MuiInputLabel-formControl': { - position: 'relative', - marginBottom: `-${theme.spacing(2)}`, - }, - [theme.breakpoints.up('lg')]: { - width: 300, - }, - }, cardShadow: { boxShadow: '0px 1px 3px 1px rgba(0, 0, 0, 0.15) !important', }, diff --git a/webapp/src/utils/ethapi.js b/webapp/src/utils/ethapi.js index 02b0a34f..2fbed92c 100644 --- a/webapp/src/utils/ethapi.js +++ b/webapp/src/utils/ethapi.js @@ -2,13 +2,13 @@ import axios from 'axios' import { evmConfig } from '../config' -const queryEthApi = async method => { +const queryEthApi = async (method, params = []) => { try { const { data: { result }, } = await axios.post(evmConfig.endpoint, { method, - params: [], + params, id: 1, jsonrpc: '2.0', }) @@ -20,9 +20,12 @@ const queryEthApi = async method => { const getGasPrice = async () => await queryEthApi('eth_gasPrice') const getLastBlock = async () => await queryEthApi('eth_blockNumber') const getChainId = async () => await queryEthApi('eth_chainId') +const getBlock = async blockNum => + await queryEthApi('eth_getBlockByNumber', [blockNum.toString(), false]) export default { getGasPrice, getLastBlock, getChainId, + getBlock, } From 9a2a7bc1677d30468123df0bd843b5740aefa072 Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Wed, 9 Aug 2023 15:21:07 -0600 Subject: [PATCH 27/75] fix: format code --- .env.telostestnet | 2 +- .github/workflows/deploy-wax-testnet.yaml | 2 +- webapp/src/components/PauseButton/styles.js | 23 ++++++++++----------- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/.env.telostestnet b/.env.telostestnet index 9cb52eb8..0ad66e03 100644 --- a/.env.telostestnet +++ b/.env.telostestnet @@ -88,4 +88,4 @@ REACT_APP_STATE_HISTORY_ENABLED=false REACT_APP_GOOGLE_ANALITIC_PAGE_ID=G-E6Y0EC9FT8 REACT_APP_PUBLIC_RE_CAPTCHA_KEY=key REACT_APP_EOS_INCLUDE_TRANSACTION= -REACT_APP_EVM_ENDPOINT=https://testnet.telos.net/evm \ No newline at end of file +REACT_APP_EVM_ENDPOINT=https://testnet.telos.net/evm diff --git a/.github/workflows/deploy-wax-testnet.yaml b/.github/workflows/deploy-wax-testnet.yaml index 3fac9653..620f51fe 100644 --- a/.github/workflows/deploy-wax-testnet.yaml +++ b/.github/workflows/deploy-wax-testnet.yaml @@ -56,7 +56,7 @@ jobs: REACT_APP_SYNC_TOLERANCE_INTERVAL: 180000 REACT_APP_TOKEN_SYMBOL: 'WAX' REACT_APP_NETWORK_URL: '[{"label":"EOS","value":"https://eos.antelope.tools","mainnet":true,"pair":"eos","icon":"eos","order":5},{"label":"Proton","value":"https://proton.antelope.tools","mainnet":true,"pair":"proton","icon":"proton","order":3},{"label":"WAX","value":"https://wax.antelope.tools","mainnet":true,"pair":"wax","icon":"wax","order":4},{"label":"Telos","value":"https://telos.antelope.tools","mainnet":true,"pair":"telos","icon":"telos","order":1},{"label":"Libre","value":"https://libre.antelope.tools","mainnet":true,"pair":"libre","icon":"libre","order":2},{"label":"LACChain EOSIO","value":"https://lacchain.antelope.tools","mainnet":true,"pair":null,"icon":"lacchain","order":6},{"label":"Jungle4 Testnet","value":"https://jungle.antelope.tools","mainnet":false,"pair":"eos","icon":"jungle","order":5},{"label":"Proton Testnet","value":"https://proton-testnet.antelope.tools","mainnet":false,"pair":"proton","icon":"proton","order":3},{"label":"WAX Testnet","value":"https://wax-testnet.antelope.tools","mainnet":false,"pair":"wax","icon":"wax","order":4},{"label":"Telos Testnet","value":"https://telos-testnet.antelope.tools","mainnet":false,"pair":"telos","icon":"telos","order":1},{"label":"Libre Testnet","value":"https://libre-testnet.antelope.tools","mainnet":false,"pair":"libre","icon":"libre","order":2},{"label":"Ultra Testnet","value":"https://ultra-testnet.antelope.tools","mainnet":false,"pair":"ultra","icon":"ultra","order":6}]' - REACT_APP_DISABLED_MENU_ITEMS: '["/missed-blocks", "/cpu-benchmark","/block-distribution","/stress-test",""/evm"]' + REACT_APP_DISABLED_MENU_ITEMS: '["/missed-blocks", "/cpu-benchmark","/block-distribution","/stress-test","/evm"]' REACT_APP_BLOCK_EXPLORER_URL: 'https://wax-test.bloks.io/transaction/(transaction)' REACT_APP_STATE_HISTORY_ENABLED=: 'false' REACT_APP_GOOGLE_ANALITIC_PAGE_ID: 'G-E6Y0EC9FT8' diff --git a/webapp/src/components/PauseButton/styles.js b/webapp/src/components/PauseButton/styles.js index 5753a893..5738cf6d 100644 --- a/webapp/src/components/PauseButton/styles.js +++ b/webapp/src/components/PauseButton/styles.js @@ -1,14 +1,13 @@ export default (theme) => ({ - pauseButton: { - display: 'flex', - width: 75, - height: 24, - '&:hover': { - cursor: 'pointer', - }, + pauseButton: { + display: 'flex', + width: 75, + height: 24, + '&:hover': { + cursor: 'pointer', }, - disableButton: { - color: theme.palette.action.disabled, - }, - }) - \ No newline at end of file + }, + disableButton: { + color: theme.palette.action.disabled, + }, +}) From 97586aa2d36c6df9eed2e6e481b2286084e2ef78 Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Thu, 10 Aug 2023 16:29:19 -0600 Subject: [PATCH 28/75] feat(hapi-evm): add /evm-token-history and /evm-transactions-history routes --- hapi-evm/package.json | 2 + hapi-evm/src/config/hasura.config.ts | 3 +- hapi-evm/src/models/history-payload/index.ts | 1 + .../src/models/history-payload/interfaces.ts | 7 + hapi-evm/src/models/index.ts | 1 + hapi-evm/src/routes/index.ts | 4 + hapi-evm/src/routes/token-history.route.ts | 26 +++ hapi-evm/src/routes/transactions.route.ts | 26 +++ .../src/services/token-history.service.ts | 32 +++ hapi-evm/src/services/transactions.service.ts | 44 ++++ .../src/utils/get-granularity-from-range.ts | 33 +++ hapi-evm/src/utils/index.ts | 1 + hapi-evm/src/utils/sequelize.util.ts | 10 + hapi-evm/yarn.lock | 190 +++++++++++++++++- 14 files changed, 378 insertions(+), 2 deletions(-) create mode 100644 hapi-evm/src/models/history-payload/index.ts create mode 100644 hapi-evm/src/models/history-payload/interfaces.ts create mode 100644 hapi-evm/src/routes/token-history.route.ts create mode 100644 hapi-evm/src/routes/transactions.route.ts create mode 100644 hapi-evm/src/services/token-history.service.ts create mode 100644 hapi-evm/src/services/transactions.service.ts create mode 100644 hapi-evm/src/utils/get-granularity-from-range.ts create mode 100644 hapi-evm/src/utils/sequelize.util.ts diff --git a/hapi-evm/package.json b/hapi-evm/package.json index 44e95370..fa684fea 100644 --- a/hapi-evm/package.json +++ b/hapi-evm/package.json @@ -29,6 +29,8 @@ "joi": "^17.9.2", "moment": "^2.29.4", "node-fetch": "^3.3.1", + "pg": "^8.6.0", + "sequelize": "^6.6.2", "web3": "^4.0.3", "websocket": "^1.0.34" }, diff --git a/hapi-evm/src/config/hasura.config.ts b/hapi-evm/src/config/hasura.config.ts index e0067fe6..4dab1989 100644 --- a/hapi-evm/src/config/hasura.config.ts +++ b/hapi-evm/src/config/hasura.config.ts @@ -2,7 +2,8 @@ export const url = process.env.HAPI_HASURA_URL || 'http://hasura:8080/v1/graphql' export const adminSecret = process.env.HAPI_HASURA_ADMIN_SECRET || 'myadminsecretkey' +export const databaseURL = process.env.HAPI_DATABASE_URL -if (!url || !adminSecret) { +if (!url || !adminSecret || !databaseURL) { throw new Error('Missing required hasura env variables') } diff --git a/hapi-evm/src/models/history-payload/index.ts b/hapi-evm/src/models/history-payload/index.ts new file mode 100644 index 00000000..c48e15f3 --- /dev/null +++ b/hapi-evm/src/models/history-payload/index.ts @@ -0,0 +1 @@ +export * as interfaces from './interfaces' diff --git a/hapi-evm/src/models/history-payload/interfaces.ts b/hapi-evm/src/models/history-payload/interfaces.ts new file mode 100644 index 00000000..3244d913 --- /dev/null +++ b/hapi-evm/src/models/history-payload/interfaces.ts @@ -0,0 +1,7 @@ +export interface HistoryQuery { + payload: { + input: { + range: string + } + } +} diff --git a/hapi-evm/src/models/index.ts b/hapi-evm/src/models/index.ts index 6621f500..a6491da5 100644 --- a/hapi-evm/src/models/index.ts +++ b/hapi-evm/src/models/index.ts @@ -4,3 +4,4 @@ export * as transactionModel from './transaction' export * as hyperionStateModel from './hyperion-state' export * as transferModel from './transfer' export * as paramModel from './param' +export * as historyPayloadModel from './history-payload' diff --git a/hapi-evm/src/routes/index.ts b/hapi-evm/src/routes/index.ts index 4845e31e..ee065564 100644 --- a/hapi-evm/src/routes/index.ts +++ b/hapi-evm/src/routes/index.ts @@ -1,9 +1,13 @@ import { Server } from '@hapi/hapi' import * as serverRoute from './server.route' +import * as transactionsRoute from './transactions.route' +import * as tokenHistoryRoute from './token-history.route' const routes = (server: Server) => { serverRoute.routes(server) + transactionsRoute.routes(server) + tokenHistoryRoute.routes(server) } export default routes diff --git a/hapi-evm/src/routes/token-history.route.ts b/hapi-evm/src/routes/token-history.route.ts new file mode 100644 index 00000000..ad3c0a60 --- /dev/null +++ b/hapi-evm/src/routes/token-history.route.ts @@ -0,0 +1,26 @@ +import { Server } from '@hapi/hapi' +import Joi from 'joi' + +import { historyPayloadModel } from '../models' +import { getTokenHistory } from '../services/token-history.service' + +export const routes = (server: Server) => { + server.route({ + method: 'POST', + path: '/evm-token-history', + handler: ({ + payload: { input } + }: historyPayloadModel.interfaces.HistoryQuery) => + getTokenHistory(input?.range), + options: { + validate: { + payload: Joi.object({ + input: Joi.object({ + range: Joi.string().required() + }).required() + }).options({ stripUnknown: true }) + }, + auth: false + } + }) +} diff --git a/hapi-evm/src/routes/transactions.route.ts b/hapi-evm/src/routes/transactions.route.ts new file mode 100644 index 00000000..ebf0a6ad --- /dev/null +++ b/hapi-evm/src/routes/transactions.route.ts @@ -0,0 +1,26 @@ +import { Server } from '@hapi/hapi' +import Joi from 'joi' + +import { historyPayloadModel } from '../models' +import { getTransactions } from '../services/transactions.service' + +export const routes = (server: Server) => { + server.route({ + method: 'POST', + path: '/evm-transactions-history', + handler: ({ + payload: { input } + }: historyPayloadModel.interfaces.HistoryQuery) => + getTransactions(input?.range), + options: { + validate: { + payload: Joi.object({ + input: Joi.object({ + range: Joi.string().required() + }).required() + }).options({ stripUnknown: true }) + }, + auth: false + } + }) +} diff --git a/hapi-evm/src/services/token-history.service.ts b/hapi-evm/src/services/token-history.service.ts new file mode 100644 index 00000000..7c9ba67c --- /dev/null +++ b/hapi-evm/src/services/token-history.service.ts @@ -0,0 +1,32 @@ +import { sequelizeUtil } from '../utils' + +import { getGranularityFromRange } from '../utils/get-granularity-from-range' + +export const getTokenHistory = async (range: string) => { + const granularity = getGranularityFromRange(range) + const [rows] = await sequelizeUtil.sequelize.query(` + WITH interval AS ( + SELECT generate_series( + date_trunc('${granularity}', now()) - '${range}'::interval, + date_trunc('${granularity}', now()), + '1 ${granularity}'::interval + ) AS value + ) + + SELECT + interval.value as datetime, + sum(CASE WHEN transfer.type = 'incoming' THEN transfer.amount END)::numeric as incoming, + sum(CASE WHEN transfer.type = 'outgoing' THEN transfer.amount END)::numeric as outgoing + FROM + interval + LEFT JOIN + ( SELECT amount, timestamp, type FROM evm.transfer WHERE amount > 0 ) + AS transfer ON date_trunc('${granularity}', transfer.timestamp) = interval.value + GROUP BY + 1 + ORDER BY + 1 ASC + `) + + return rows +} diff --git a/hapi-evm/src/services/transactions.service.ts b/hapi-evm/src/services/transactions.service.ts new file mode 100644 index 00000000..110cb7a5 --- /dev/null +++ b/hapi-evm/src/services/transactions.service.ts @@ -0,0 +1,44 @@ +import Web3 from 'web3' + +import { sequelizeUtil } from '../utils' +import { networkConfig } from '../config' +import { getGranularityFromRange } from '../utils/get-granularity-from-range' + +export const getTransactions = async (range: string) => { + const granularity = getGranularityFromRange(range) + const httpProvider = new Web3.providers.HttpProvider( + networkConfig.evmEndpoint + ) + const web3 = new Web3(httpProvider) + const lastBlock = await web3.eth.getBlock('latest') + const gasLimit = Number(lastBlock?.gasLimit) || 1000000000 + + const [rows] = await sequelizeUtil.sequelize.query(` + WITH interval AS ( + SELECT generate_series( + date_trunc('${granularity}', now()) - '${range}'::interval, + date_trunc('${granularity}', now()), + '1 ${granularity}'::interval + ) AS value + ) + + SELECT + interval.value AS datetime, + sum(transactions_count) AS transactions_count, + avg(block.gas_used)::numeric(6,3) AS avg_gas_used + FROM + interval + LEFT JOIN + ( SELECT transactions_count, timestamp, gas_used / ${gasLimit} * 100 AS gas_used + FROM ( SELECT block_hash, count(1) AS transactions_count + FROM evm.transaction GROUP BY block_hash) + AS subquery INNER JOIN evm.block ON evm.block.hash = block_hash) + AS block ON date_trunc('${granularity}', block.timestamp) = interval.value + GROUP BY + 1 + ORDER BY + 1 ASC + `) + + return rows +} diff --git a/hapi-evm/src/utils/get-granularity-from-range.ts b/hapi-evm/src/utils/get-granularity-from-range.ts new file mode 100644 index 00000000..12529da0 --- /dev/null +++ b/hapi-evm/src/utils/get-granularity-from-range.ts @@ -0,0 +1,33 @@ +export const getGranularityFromRange = (range: string) => { + let granularity + + switch (range) { + case '3 Hours': + case '6 Hours': + case '12 Hours': + granularity = 'minute' + break + case '1 Day': + case '2 Days': + case '4 Days': + case '7 Days': + case '14 Days': + granularity = 'hour' + break + case '1 Month': + case '2 Months': + case '3 Months': + case '6 Months': + granularity = 'day' + break + case '1 Year': + case 'all': + granularity = 'month' + break + default: + granularity = 'minute' + break + } + + return granularity +} diff --git a/hapi-evm/src/utils/index.ts b/hapi-evm/src/utils/index.ts index e2c85405..c72b461d 100644 --- a/hapi-evm/src/utils/index.ts +++ b/hapi-evm/src/utils/index.ts @@ -1,2 +1,3 @@ export * as coreUtil from './core' export * as timeUtil from './time.util' +export * as sequelizeUtil from './sequelize.util' diff --git a/hapi-evm/src/utils/sequelize.util.ts b/hapi-evm/src/utils/sequelize.util.ts new file mode 100644 index 00000000..e641a5ea --- /dev/null +++ b/hapi-evm/src/utils/sequelize.util.ts @@ -0,0 +1,10 @@ +import { Sequelize } from 'sequelize' + +import { hasuraConfig } from '../config' + +export const sequelize = new Sequelize(hasuraConfig.databaseURL, { + dialectOptions: { + connectTimeout: 60000000 + }, + logging: false +}) diff --git a/hapi-evm/yarn.lock b/hapi-evm/yarn.lock index 1e9b13c9..cc3c6be7 100644 --- a/hapi-evm/yarn.lock +++ b/hapi-evm/yarn.lock @@ -641,11 +641,23 @@ resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9" integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== +"@types/debug@^4.1.8": + version "4.1.8" + resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.8.tgz#cef723a5d0a90990313faec2d1e22aee5eecb317" + integrity sha512-/vPO1EPOs306Cvhwv7KfVfYvOJqA/S/AXjaHQiJboCZzcNDb+TIJFN9/2C9DZ//ijSKWioNyUxD792QmDJ+HKQ== + dependencies: + "@types/ms" "*" + "@types/json-schema@^7.0.11": version "7.0.12" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.12.tgz#d70faba7039d5fca54c83c7dbab41051d2b6f6cb" integrity sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA== +"@types/ms@*": + version "0.7.31" + resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.31.tgz#31b7ca6407128a3d2bbc27fe2d21b345397f6197" + integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA== + "@types/node@*", "@types/node@^20.1.5": version "20.4.2" resolved "https://registry.yarnpkg.com/@types/node/-/node-20.4.2.tgz#129cc9ae69f93824f92fac653eebfb4812ab4af9" @@ -656,6 +668,11 @@ resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.0.tgz#591c1ce3a702c45ee15f47a42ade72c2fd78978a" integrity sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw== +"@types/validator@^13.7.17": + version "13.11.1" + resolved "https://registry.yarnpkg.com/@types/validator/-/validator-13.11.1.tgz#6560af76ed54490e68c42f717ab4e742ba7be74b" + integrity sha512-d/MUkJYdOeKycmm75Arql4M5+UuXmf4cHdHKsyw1GcvnNgL6s77UkgSgJ8TE/rI5PYsnwYq5jkcWBLuN/MpQ1A== + "@types/web3@^1.2.2": version "1.2.2" resolved "https://registry.yarnpkg.com/@types/web3/-/web3-1.2.2.tgz#d95a101547ce625c5ebd0470baa5dbd4b9f3c015" @@ -929,6 +946,11 @@ brorand@^1.1.0: resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== +buffer-writer@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/buffer-writer/-/buffer-writer-2.0.0.tgz#ce7eb81a38f7829db09c873f2fbb792c0c98ec04" + integrity sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw== + bufferutil@^4.0.1: version "4.0.7" resolved "https://registry.yarnpkg.com/bufferutil/-/bufferutil-4.0.7.tgz#60c0d19ba2c992dd8273d3f73772ffc894c153ad" @@ -1166,6 +1188,11 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" +dottie@^2.0.4: + version "2.0.6" + resolved "https://registry.yarnpkg.com/dottie/-/dottie-2.0.6.tgz#34564ebfc6ec5e5772272d466424ad5b696484d4" + integrity sha512-iGCHkfUc5kFekGiqhe8B/mdaurD+lakO9txNnTvKtA6PISrw86LgqHvRzWYPyoE2Ph5aMIrCw9/uko6XHTKCwA== + eastasianwidth@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" @@ -1741,6 +1768,11 @@ indent-string@^4.0.0: resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== +inflection@^1.13.4: + version "1.13.4" + resolved "https://registry.yarnpkg.com/inflection/-/inflection-1.13.4.tgz#65aa696c4e2da6225b148d7a154c449366633a32" + integrity sha512-6I/HUDeYFfuNCVS3td055BaXBwKYuzw7K3ExVMStBowKo9oOAMJIXIHvdyR3iboTCp1b+1i5DSkIZTcwIktuDw== + inflight@^1.0.4: version "1.0.6" resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" @@ -2003,6 +2035,11 @@ lodash.merge@^4.6.2: resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== +lodash@^4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + log-update@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/log-update/-/log-update-4.0.0.tgz#589ecd352471f2a1c0c570287543a64dfd20e0a1" @@ -2087,6 +2124,13 @@ minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: dependencies: brace-expansion "^1.1.7" +moment-timezone@^0.5.43: + version "0.5.43" + resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.43.tgz#3dd7f3d0c67f78c23cd1906b9b2137a09b3c4790" + integrity sha512-72j3aNyuIsDxdF1i7CEgV2FfxM1r6aaqJyLB2vwb33mXYyoyLly+F1zbWqhA3/bVIoJ4szlUoMbUnVdid32NUQ== + dependencies: + moment "^2.29.4" + moment@^2.29.4: version "2.29.4" resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108" @@ -2274,6 +2318,11 @@ p-map@^4.0.0: dependencies: aggregate-error "^3.0.0" +packet-reader@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/packet-reader/-/packet-reader-1.0.0.tgz#9238e5480dedabacfe1fe3f2771063f164157d74" + integrity sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ== + pako@2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/pako/-/pako-2.0.3.tgz#cdf475e31b678565251406de9e759196a0ea7a43" @@ -2311,6 +2360,64 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== +pg-cloudflare@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz#e6d5833015b170e23ae819e8c5d7eaedb472ca98" + integrity sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q== + +pg-connection-string@^2.6.0, pg-connection-string@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.6.2.tgz#713d82053de4e2bd166fab70cd4f26ad36aab475" + integrity sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA== + +pg-int8@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/pg-int8/-/pg-int8-1.0.1.tgz#943bd463bf5b71b4170115f80f8efc9a0c0eb78c" + integrity sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw== + +pg-pool@^3.6.1: + version "3.6.1" + resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-3.6.1.tgz#5a902eda79a8d7e3c928b77abf776b3cb7d351f7" + integrity sha512-jizsIzhkIitxCGfPRzJn1ZdcosIt3pz9Sh3V01fm1vZnbnCMgmGl5wvGGdNN2EL9Rmb0EcFoCkixH4Pu+sP9Og== + +pg-protocol@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/pg-protocol/-/pg-protocol-1.6.0.tgz#4c91613c0315349363af2084608db843502f8833" + integrity sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q== + +pg-types@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/pg-types/-/pg-types-2.2.0.tgz#2d0250d636454f7cfa3b6ae0382fdfa8063254a3" + integrity sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA== + dependencies: + pg-int8 "1.0.1" + postgres-array "~2.0.0" + postgres-bytea "~1.0.0" + postgres-date "~1.0.4" + postgres-interval "^1.1.0" + +pg@^8.6.0: + version "8.11.2" + resolved "https://registry.yarnpkg.com/pg/-/pg-8.11.2.tgz#1a23f6de7bfb65ba56e4dd15df96668d319900c4" + integrity sha512-l4rmVeV8qTIrrPrIR3kZQqBgSN93331s9i6wiUiLOSk0Q7PmUxZD/m1rQI622l3NfqBby9Ar5PABfS/SulfieQ== + dependencies: + buffer-writer "2.0.0" + packet-reader "1.0.0" + pg-connection-string "^2.6.2" + pg-pool "^3.6.1" + pg-protocol "^1.6.0" + pg-types "^2.1.0" + pgpass "1.x" + optionalDependencies: + pg-cloudflare "^1.1.1" + +pgpass@1.x: + version "1.0.5" + resolved "https://registry.yarnpkg.com/pgpass/-/pgpass-1.0.5.tgz#9b873e4a564bb10fa7a7dbd55312728d422a223d" + integrity sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug== + dependencies: + split2 "^4.1.0" + picocolors@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" @@ -2326,6 +2433,28 @@ pidtree@^0.6.0: resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.6.0.tgz#90ad7b6d42d5841e69e0a2419ef38f8883aa057c" integrity sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g== +postgres-array@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-2.0.0.tgz#48f8fce054fbc69671999329b8834b772652d82e" + integrity sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA== + +postgres-bytea@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/postgres-bytea/-/postgres-bytea-1.0.0.tgz#027b533c0aa890e26d172d47cf9ccecc521acd35" + integrity sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w== + +postgres-date@~1.0.4: + version "1.0.7" + resolved "https://registry.yarnpkg.com/postgres-date/-/postgres-date-1.0.7.tgz#51bc086006005e5061c591cee727f2531bf641a8" + integrity sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q== + +postgres-interval@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/postgres-interval/-/postgres-interval-1.2.0.tgz#b460c82cb1587507788819a06aa0fffdb3544695" + integrity sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ== + dependencies: + xtend "^4.0.0" + prelude-ls@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" @@ -2383,6 +2512,11 @@ restore-cursor@^3.1.0: onetime "^5.1.0" signal-exit "^3.0.2" +retry-as-promised@^7.0.4: + version "7.0.4" + resolved "https://registry.yarnpkg.com/retry-as-promised/-/retry-as-promised-7.0.4.tgz#9df73adaeea08cb2948b9d34990549dc13d800a2" + integrity sha512-XgmCoxKWkDofwH8WddD0w85ZfqYz+ZHlr5yo+3YUCfycWawU56T5ckWXsScsj5B8tqUcIG67DxXByo3VUgiAdA== + reusify@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" @@ -2426,13 +2560,40 @@ rxjs@^7.8.0: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -semver@^7.5.0, semver@^7.5.3: +semver@^7.5.0, semver@^7.5.1, semver@^7.5.3: version "7.5.4" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== dependencies: lru-cache "^6.0.0" +sequelize-pool@^7.1.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/sequelize-pool/-/sequelize-pool-7.1.0.tgz#210b391af4002762f823188fd6ecfc7413020768" + integrity sha512-G9c0qlIWQSK29pR/5U2JF5dDQeqqHRragoyahj/Nx4KOOQ3CPPfzxnfqFPCSB7x5UgjOgnZ61nSxz+fjDpRlJg== + +sequelize@^6.6.2: + version "6.32.1" + resolved "https://registry.yarnpkg.com/sequelize/-/sequelize-6.32.1.tgz#8e8669a8d6cf711d2d94b33cc721928fad7487f6" + integrity sha512-3Iv0jruv57Y0YvcxQW7BE56O7DC1BojcfIrqh6my+IQwde+9u/YnuYHzK+8kmZLhLvaziRT1eWu38nh9yVwn/g== + dependencies: + "@types/debug" "^4.1.8" + "@types/validator" "^13.7.17" + debug "^4.3.4" + dottie "^2.0.4" + inflection "^1.13.4" + lodash "^4.17.21" + moment "^2.29.4" + moment-timezone "^0.5.43" + pg-connection-string "^2.6.0" + retry-as-promised "^7.0.4" + semver "^7.5.1" + sequelize-pool "^7.1.0" + toposort-class "^1.0.1" + uuid "^8.3.2" + validator "^13.9.0" + wkx "^0.5.0" + setimmediate@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" @@ -2493,6 +2654,11 @@ slice-ansi@^5.0.0: ansi-styles "^6.0.0" is-fullwidth-code-point "^4.0.0" +split2@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/split2/-/split2-4.2.0.tgz#c9c5920904d148bab0b9f67145f245a86aadbfa4" + integrity sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg== + string-argv@^0.3.1: version "0.3.2" resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.2.tgz#2b6d0ef24b656274d957d54e0a4bbf6153dc02b6" @@ -2589,6 +2755,11 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" +toposort-class@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toposort-class/-/toposort-class-1.0.1.tgz#7ffd1f78c8be28c3ba45cd4e1a3f5ee193bd9988" + integrity sha512-OsLcGGbYF3rMjPUf8oKktyvCiUxSbqMMS39m33MAjLTC1DVIH6x3WSt63/M77ihI09+Sdfk1AXvfhCEeUmC7mg== + touch@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" @@ -2709,11 +2880,21 @@ util@^0.12.5: is-typed-array "^1.1.3" which-typed-array "^1.1.2" +uuid@^8.3.2: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + v8-compile-cache-lib@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== +validator@^13.9.0: + version "13.11.0" + resolved "https://registry.yarnpkg.com/validator/-/validator-13.11.0.tgz#23ab3fd59290c61248364eabf4067f04955fbb1b" + integrity sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ== + web-streams-polyfill@^3.0.3: version "3.2.1" resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz#71c2718c52b45fd49dbeee88634b3a60ceab42a6" @@ -2979,6 +3160,13 @@ which@^2.0.1: dependencies: isexe "^2.0.0" +wkx@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/wkx/-/wkx-0.5.0.tgz#c6c37019acf40e517cc6b94657a25a3d4aa33e8c" + integrity sha512-Xng/d4Ichh8uN4l0FToV/258EjMGU9MGcA0HV2d9B/ZpZB3lqQm7nkOdZdm5GhKtLLhAE7PiVQwN4eN+2YJJUg== + dependencies: + "@types/node" "*" + wrap-ansi@^6.2.0: version "6.2.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" From b823b720d2bc27386d94d00f5126a0eb1dc3d0be Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Thu, 10 Aug 2023 16:34:15 -0600 Subject: [PATCH 29/75] feat(kubernetes): add HASURA_GRAPHQL_ACTION_EVM_URL --- docker-compose.yaml | 1 + kubernetes/configmap-dashboard.yaml | 1 + 2 files changed, 2 insertions(+) diff --git a/docker-compose.yaml b/docker-compose.yaml index 01686599..a83161b1 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -107,6 +107,7 @@ services: HASURA_GRAPHQL_METADATA_DIR: /metadata HASURA_GRAPHQL_SEEDS_DIR: /seeds HASURA_GRAPHQL_ACTION_BASE_URL: '${HASURA_GRAPHQL_ACTION_BASE_URL}' + HASURA_GRAPHQL_ACTION_EVM_URL: '${HASURA_GRAPHQL_ACTION_EVM_URL}' HASURA_GRAPHQL_ENABLE_CONSOLE: 'true' # Local Development Configurations It is recommended to disable this in production HASURA_GRAPHQL_DEV_MODE: 'true' diff --git a/kubernetes/configmap-dashboard.yaml b/kubernetes/configmap-dashboard.yaml index e6149c69..c3785bb3 100644 --- a/kubernetes/configmap-dashboard.yaml +++ b/kubernetes/configmap-dashboard.yaml @@ -112,3 +112,4 @@ data: HASURA_GRAPHQL_ADMIN_SECRET: '${HASURA_GRAPHQL_ADMIN_SECRET}' HASURA_GRAPHQL_UNAUTHORIZED_ROLE: '${HASURA_GRAPHQL_UNAUTHORIZED_ROLE}' HASURA_GRAPHQL_ACTION_BASE_URL: '${HASURA_GRAPHQL_ACTION_BASE_URL}' + HASURA_GRAPHQL_ACTION_EVM_URL: '${HASURA_GRAPHQL_ACTION_EVM_URL}' From 710b7857f18aa54b5e7dbaf89e5c3ab8d14d7540 Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Thu, 10 Aug 2023 16:35:11 -0600 Subject: [PATCH 30/75] feat(hasura): add evm_transactions_history and evm_token_history actions --- hasura/metadata/actions.graphql | 24 ++++++++++++++++++++++++ hasura/metadata/actions.yaml | 10 ++++++++++ 2 files changed, 34 insertions(+) diff --git a/hasura/metadata/actions.graphql b/hasura/metadata/actions.graphql index 0b70dfb6..fa62826d 100644 --- a/hasura/metadata/actions.graphql +++ b/hasura/metadata/actions.graphql @@ -22,6 +22,18 @@ type Query { eosrate_stats: [EOSRateStats] } +type Query { + evm_token_history( + range: String! + ): [EVMTokenHistory] +} + +type Query { + evm_transactions_history( + range: String! + ): [EVMTransaction] +} + type Mutation { getProducersInfo( bpParams: GetProducersInfoInput! @@ -113,3 +125,15 @@ type EOSRateStats { trustiness: Float } +type EVMTransaction { + datetime: String + transactions_count: Int + avg_gas_used: Float +} + +type EVMTokenHistory { + datetime: String + incoming: Float + outgoing: Float +} + diff --git a/hasura/metadata/actions.yaml b/hasura/metadata/actions.yaml index a11591bd..a4fdf99e 100644 --- a/hasura/metadata/actions.yaml +++ b/hasura/metadata/actions.yaml @@ -26,6 +26,14 @@ actions: handler: '{{HASURA_GRAPHQL_ACTION_BASE_URL}}/get-eos-rate' permissions: - role: guest + - name: evm_token_history + definition: + kind: "" + handler: '{{HASURA_GRAPHQL_ACTION_EVM_URL}}/evm-token-history' + - name: evm_transactions_history + definition: + kind: "" + handler: '{{HASURA_GRAPHQL_ACTION_EVM_URL}}/evm-transactions-history' - name: getProducersInfo definition: kind: synchronous @@ -72,4 +80,6 @@ custom_types: - name: TransferFaucetTokensOutput - name: GetProducersInfoOutput - name: EOSRateStats + - name: EVMTransaction + - name: EVMTokenHistory scalars: [] From c0c9ac703c7380a35d348580ece001b1c4b14621 Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Fri, 11 Aug 2023 10:46:01 -0600 Subject: [PATCH 31/75] chore(hapi-evm): use Hasura env variables --- .env.telos | 3 +-- docker-compose.yaml | 5 +++-- hapi-evm/src/config/hasura.config.ts | 8 +++----- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/.env.telos b/.env.telos index e4055be3..dd5a455c 100644 --- a/.env.telos +++ b/.env.telos @@ -17,6 +17,7 @@ HASURA_GRAPHQL_DATABASE_URL=postgres://eoscr:password@postgres:5432/localdb HASURA_GRAPHQL_ADMIN_SECRET=myadminsecretkey HASURA_GRAPHQL_UNAUTHORIZED_ROLE=guest HASURA_GRAPHQL_ACTION_BASE_URL=http://hapi:9090 +HASURA_GRAPHQL_ACTION_EVM_URL=http://hapi-evm:9090 # hapi HAPI_EOS_API_NETWORK_NAME=telos @@ -62,8 +63,6 @@ HAPI_EVM_ENDPOINT=https://testnet.telos.net/evm HAPI_EVM_API_ENDPOINTS=["https://telos.greymass.com","https://telos.eosphere.io","telos.caleos.io","mainnet.telosusa.io"] HAPI_EVM_NETWORK_CHAIN_ID=4667b205c6838ef70ff7988f6e8257e8be0e1284a2f59699054a018f743b1d11 HAPI_EVM_EOS_EVM_ACCOUNT=eosio.evm -HAPI_EVM_HASURA_URL=http://hasura:8080/v1/graphql/evm -HAPI_EVM_HASURA_ADMIN_SECRET=myadminsecretkey HAPI_BLOCK_INTERVAL_SEC=0.3 #webapp diff --git a/docker-compose.yaml b/docker-compose.yaml index a83161b1..ac4ca2b3 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -90,8 +90,9 @@ services: HAPI_EVM_API_ENDPOINTS: '${HAPI_EVM_API_ENDPOINTS}' HAPI_EVM_NETWORK_CHAIN_ID: '${HAPI_EVM_NETWORK_CHAIN_ID}' HAPI_EVM_EOS_EVM_ACCOUNT: '${HAPI_EVM_EOS_EVM_ACCOUNT}' - HAPI_EVM_HASURA_URL: '${HAPI_EVM_HASURA_URL}' - HAPI_EVM_HASURA_ADMIN_SECRET: '${HAPI_EVM_HASURA_ADMIN_SECRET}' + HAPI_EVM_HASURA_URL: '${HAPI_HASURA_URL}' + HAPI_EVM_HASURA_ADMIN_SECRET: '${HAPI_HASURA_ADMIN_SECRET}' + HAPI_EVM_DATABASE_URL: '${HAPI_DATABASE_URL}' HAPI_BLOCK_INTERVAL_SEC: '${HAPI_BLOCK_INTERVAL_SEC}' hasura: container_name: '${STAGE}-${APP_NAME}-hasura' diff --git a/hapi-evm/src/config/hasura.config.ts b/hapi-evm/src/config/hasura.config.ts index 4dab1989..0bcdd0b1 100644 --- a/hapi-evm/src/config/hasura.config.ts +++ b/hapi-evm/src/config/hasura.config.ts @@ -1,8 +1,6 @@ -export const url = - process.env.HAPI_HASURA_URL || 'http://hasura:8080/v1/graphql' -export const adminSecret = - process.env.HAPI_HASURA_ADMIN_SECRET || 'myadminsecretkey' -export const databaseURL = process.env.HAPI_DATABASE_URL +export const url = process.env.HAPI_EVM_HASURA_URL || '' +export const adminSecret = process.env.HAPI_EVM_HASURA_ADMIN_SECRET || '' +export const databaseURL = process.env.HAPI_EVM_DATABASE_URL || '' if (!url || !adminSecret || !databaseURL) { throw new Error('Missing required hasura env variables') From 1a91854d3e334b55b308134e0d046c89ddeb16f5 Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Fri, 11 Aug 2023 14:00:05 -0600 Subject: [PATCH 32/75] chore(webapp): format the amount of tokens and refactor code --- webapp/src/language/en.json | 3 +- webapp/src/language/es.json | 3 +- webapp/src/routes/EVMDashboard/index.js | 29 ++++++++++++++--- webapp/src/routes/EVMDashboard/useEVMstate.js | 32 ++++++++++--------- webapp/src/routes/Home/TransactionInfo.js | 4 +-- 5 files changed, 48 insertions(+), 23 deletions(-) diff --git a/webapp/src/language/en.json b/webapp/src/language/en.json index 3e084a7a..2394a528 100644 --- a/webapp/src/language/en.json +++ b/webapp/src/language/en.json @@ -161,7 +161,8 @@ "chainNetLimit": "Chain Net Limit", "timeToFinality": "Time to Finality", "cpuUsage": "CPU Usage", - "netUsage": "NET Usage" + "netUsage": "NET Usage", + "average": "Average" }, "blockProducersRoute": {}, "rewardsDistributionRoute": { diff --git a/webapp/src/language/es.json b/webapp/src/language/es.json index beb5ae4b..fb38462e 100644 --- a/webapp/src/language/es.json +++ b/webapp/src/language/es.json @@ -164,7 +164,8 @@ "chainNetLimit": "Límite de Net en cadena", "timeToFinality": "Tiempo para finalidad", "cpuUsage": "Uso del CPU", - "netUsage": "Uso de NET" + "netUsage": "Uso de NET", + "average": "Promedio" }, "blockProducersRoute": {}, "rewardsDistributionRoute": { diff --git a/webapp/src/routes/EVMDashboard/index.js b/webapp/src/routes/EVMDashboard/index.js index 28e538d5..06b7a189 100644 --- a/webapp/src/routes/EVMDashboard/index.js +++ b/webapp/src/routes/EVMDashboard/index.js @@ -24,6 +24,7 @@ const EVMDashboard = () => { tokenHistoryData, transactionsHistoryData, options, + liveOption, loading, selected, isPaused, @@ -54,7 +55,7 @@ const EVMDashboard = () => { handlePause={handlePause} isPaused={isPaused} historyState={{ - options: ['Live (30s)', ...options], + options: [liveOption, ...options], value: selected['txs'], onSelect: option => handleSelect('txs', option), isLive: isLive, @@ -100,7 +101,27 @@ const EVMDashboard = () => { data={tokenHistoryData} chartLabelFormat={{ yAxisText: eosConfig.tokenSymbol, - shared: true + shared: true, + customFormatter: (element) => { + const points = element?.points + const pointName = points[0]?.point?.name || '' + + return ( + pointName + + points.reduce((tooltipText, point) => { + const series = point?.series + + return ( + tooltipText + + '
' + + `${series?.name}: ${formatWithThousandSeparator( + point?.y, + 2, + )}` + ) + }, '') + ) + }, }} />
@@ -121,14 +142,14 @@ const EVMDashboard = () => { diff --git a/webapp/src/routes/EVMDashboard/useEVMstate.js b/webapp/src/routes/EVMDashboard/useEVMstate.js index e2965145..3914e662 100644 --- a/webapp/src/routes/EVMDashboard/useEVMstate.js +++ b/webapp/src/routes/EVMDashboard/useEVMstate.js @@ -33,9 +33,10 @@ const useEVMState = (theme, t) => { const [transactionsHistoryData, setTransactionsHistoryData] = useState() const [tokenHistoryData, setTokenHistoryData] = useState() + const liveOption = 'Live (30s)' const [pause, setPause] = useState(false) const [selected, setSelected] = useState({ - txs: 'Live (30s)', + txs: liveOption, token: '1 Month', }) @@ -47,7 +48,7 @@ const useEVMState = (theme, t) => { const handleSelect = (chart, option) => { setSelected(prev => ({ ...prev, [chart]: option })) if (chart === 'txs') { - if (option !== 'Live (30s)') { + if (option !== liveOption) { setPause(true) getTransactionHistory({ variables: { @@ -89,28 +90,28 @@ const useEVMState = (theme, t) => { }, [data, loading]) useEffect(() => { - const updateStats = async () => { - const amount = await getWalletsCreated() + const updateLastBlock = async () => { const lastBlock = await ethApi.getLastBlock() - const stats = { - wallets_created_count: amount, - last_block: lastBlock, - } - setEVMStats(prev => ({ ...prev, ...stats })) + setEVMStats(prev => ({ ...prev, last_block: lastBlock })) } - updateStats() + updateLastBlock() }, [data, loading]) useEffect(() => { - const updateGasPrice = async () => { + const updateStats = async () => { const gasPrice = await ethApi.getGasPrice() + const amount = await getWalletsCreated() - setEVMStats(prev => ({ ...prev, gas_price: gasPrice / 10 ** 9 })) + setEVMStats(prev => ({ + ...prev, + gas_price: gasPrice / 10 ** 9, + wallets_created_count: amount, + })) } - if (selected['txs'] !== 'Live (30s)') { + if (selected['txs'] !== liveOption) { getTransactionHistory({ variables: { range: selected['txs'], @@ -123,7 +124,7 @@ const useEVMState = (theme, t) => { }, }) - updateGasPrice() + updateStats() // eslint-disable-next-line }, []) @@ -248,10 +249,11 @@ const useEVMState = (theme, t) => { return [ { EVMStats, + liveOption, options: rangeOptions, selected, isPaused: pause, - isLive: selected.txs === 'Live (30s)', + isLive: selected.txs === liveOption, transactionsHistoryData, tokenHistoryData, loading, diff --git a/webapp/src/routes/Home/TransactionInfo.js b/webapp/src/routes/Home/TransactionInfo.js index e66f0688..c7ea65cd 100644 --- a/webapp/src/routes/Home/TransactionInfo.js +++ b/webapp/src/routes/Home/TransactionInfo.js @@ -125,12 +125,12 @@ const TransactionInfo = ({ t, startTrackingInfo, stopTrackingInfo }) => { setGraphicData([ { - name: t('transactionsPerSecond'), + name: t('average') + ' ' + t('transactionsPerSecond'), color: theme.palette.secondary.main, data: trxPerSecond, }, { - name: t('transactionsPerBlock'), + name: t('average') + ' ' + t('transactionsPerBlock'), color: theme.palette.tertiary.main, data: trxPerBlock, }, From e5d4b0318c92001d5f726e9d079a1d808bdc9152 Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Fri, 11 Aug 2023 14:35:59 -0600 Subject: [PATCH 33/75] chore(hapi-evm): update sequelize --- hapi-evm/package.json | 2 +- hapi-evm/yarn.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/hapi-evm/package.json b/hapi-evm/package.json index fa684fea..6b8ee294 100644 --- a/hapi-evm/package.json +++ b/hapi-evm/package.json @@ -30,7 +30,7 @@ "moment": "^2.29.4", "node-fetch": "^3.3.1", "pg": "^8.6.0", - "sequelize": "^6.6.2", + "sequelize": "^6.32.1", "web3": "^4.0.3", "websocket": "^1.0.34" }, diff --git a/hapi-evm/yarn.lock b/hapi-evm/yarn.lock index cc3c6be7..b12f9a55 100644 --- a/hapi-evm/yarn.lock +++ b/hapi-evm/yarn.lock @@ -2572,7 +2572,7 @@ sequelize-pool@^7.1.0: resolved "https://registry.yarnpkg.com/sequelize-pool/-/sequelize-pool-7.1.0.tgz#210b391af4002762f823188fd6ecfc7413020768" integrity sha512-G9c0qlIWQSK29pR/5U2JF5dDQeqqHRragoyahj/Nx4KOOQ3CPPfzxnfqFPCSB7x5UgjOgnZ61nSxz+fjDpRlJg== -sequelize@^6.6.2: +sequelize@^6.32.1: version "6.32.1" resolved "https://registry.yarnpkg.com/sequelize/-/sequelize-6.32.1.tgz#8e8669a8d6cf711d2d94b33cc721928fad7487f6" integrity sha512-3Iv0jruv57Y0YvcxQW7BE56O7DC1BojcfIrqh6my+IQwde+9u/YnuYHzK+8kmZLhLvaziRT1eWu38nh9yVwn/g== From 9f238c6d499da3e01f49e71dfad1530660284fa6 Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Tue, 15 Aug 2023 09:44:27 -0600 Subject: [PATCH 34/75] chore(hasura): add guest permissions to stats view --- .../metadata/databases/default/tables/evm_stats.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/hasura/metadata/databases/default/tables/evm_stats.yaml b/hasura/metadata/databases/default/tables/evm_stats.yaml index b99a0f1b..0ab926b1 100644 --- a/hasura/metadata/databases/default/tables/evm_stats.yaml +++ b/hasura/metadata/databases/default/tables/evm_stats.yaml @@ -1,3 +1,13 @@ table: name: stats schema: evm +select_permissions: + - role: guest + permission: + columns: + - ath_transaction_sum + - daily_transaction_count + - incoming_tlos_count + - outgoing_tlos_count + - block_gas_avg + filter: {} From 66c17646917a1681b8451c2e29ff2c8667b3eaf4 Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Wed, 16 Aug 2023 10:45:55 -0600 Subject: [PATCH 35/75] feat(hasura): add table to persists historical stats --- .../default/tables/evm_historical_stats.yaml | 13 +++++++++++++ .../metadata/databases/default/tables/tables.yaml | 1 + .../down.sql | 5 +++++ .../up.sql | 5 +++++ .../down.sql | 1 + .../up.sql | 2 ++ 6 files changed, 27 insertions(+) create mode 100644 hasura/metadata/databases/default/tables/evm_historical_stats.yaml create mode 100644 hasura/migrations/default/1692117604338_set_fk_evm_transaction_block_hash_block_number/down.sql create mode 100644 hasura/migrations/default/1692117604338_set_fk_evm_transaction_block_hash_block_number/up.sql create mode 100644 hasura/migrations/default/1692132948056_create_table_evm_historical_stats/down.sql create mode 100644 hasura/migrations/default/1692132948056_create_table_evm_historical_stats/up.sql diff --git a/hasura/metadata/databases/default/tables/evm_historical_stats.yaml b/hasura/metadata/databases/default/tables/evm_historical_stats.yaml new file mode 100644 index 00000000..db99c245 --- /dev/null +++ b/hasura/metadata/databases/default/tables/evm_historical_stats.yaml @@ -0,0 +1,13 @@ +table: + name: historical_stats + schema: evm +select_permissions: + - role: guest + permission: + columns: + - id + - total_transactions + - tps_all_time_high + - total_incoming_token + - total_outgoing_token + filter: {} diff --git a/hasura/metadata/databases/default/tables/tables.yaml b/hasura/metadata/databases/default/tables/tables.yaml index c741a2a0..daa73701 100644 --- a/hasura/metadata/databases/default/tables/tables.yaml +++ b/hasura/metadata/databases/default/tables/tables.yaml @@ -1,4 +1,5 @@ - "!include evm_block.yaml" +- "!include evm_historical_stats.yaml" - "!include evm_hyperion_state.yaml" - "!include evm_param.yaml" - "!include evm_stats.yaml" diff --git a/hasura/migrations/default/1692117604338_set_fk_evm_transaction_block_hash_block_number/down.sql b/hasura/migrations/default/1692117604338_set_fk_evm_transaction_block_hash_block_number/down.sql new file mode 100644 index 00000000..922df2f9 --- /dev/null +++ b/hasura/migrations/default/1692117604338_set_fk_evm_transaction_block_hash_block_number/down.sql @@ -0,0 +1,5 @@ +alter table "evm"."transaction" drop constraint "transaction_block_hash_block_number_fkey", + add constraint "transaction_block_number_block_hash_fkey" + foreign key ("block_number", "block_hash") + references "evm"."block" + ("number", "hash") on update restrict on delete restrict; diff --git a/hasura/migrations/default/1692117604338_set_fk_evm_transaction_block_hash_block_number/up.sql b/hasura/migrations/default/1692117604338_set_fk_evm_transaction_block_hash_block_number/up.sql new file mode 100644 index 00000000..0266f6a7 --- /dev/null +++ b/hasura/migrations/default/1692117604338_set_fk_evm_transaction_block_hash_block_number/up.sql @@ -0,0 +1,5 @@ +alter table "evm"."transaction" drop constraint "transaction_block_number_block_hash_fkey", + add constraint "transaction_block_hash_block_number_fkey" + foreign key ("block_hash", "block_number") + references "evm"."block" + ("hash", "number") on update restrict on delete cascade; diff --git a/hasura/migrations/default/1692132948056_create_table_evm_historical_stats/down.sql b/hasura/migrations/default/1692132948056_create_table_evm_historical_stats/down.sql new file mode 100644 index 00000000..8ab1f4c2 --- /dev/null +++ b/hasura/migrations/default/1692132948056_create_table_evm_historical_stats/down.sql @@ -0,0 +1 @@ +DROP TABLE "evm"."historical_stats"; diff --git a/hasura/migrations/default/1692132948056_create_table_evm_historical_stats/up.sql b/hasura/migrations/default/1692132948056_create_table_evm_historical_stats/up.sql new file mode 100644 index 00000000..49bc7329 --- /dev/null +++ b/hasura/migrations/default/1692132948056_create_table_evm_historical_stats/up.sql @@ -0,0 +1,2 @@ +CREATE TABLE "evm"."historical_stats" ("id" uuid NOT NULL DEFAULT gen_random_uuid(), "total_transactions" integer NOT NULL DEFAULT 0, "tps_all_time_high" jsonb NOT NULL DEFAULT jsonb_build_object(), "total_incoming_token" numeric NOT NULL DEFAULT 0, "total_outgoing_token" numeric NOT NULL DEFAULT 0, PRIMARY KEY ("id") , UNIQUE ("id")); +CREATE EXTENSION IF NOT EXISTS pgcrypto; From 64b6573b07f7cebfa18aa9b76fb523469d877dfb Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Wed, 16 Aug 2023 16:26:54 -0600 Subject: [PATCH 36/75] feat(hapi-evm): add logic to save historical stats --- hapi-evm/src/models/block/queries.ts | 37 ++++- hapi-evm/src/models/historical-stats/index.ts | 2 + .../src/models/historical-stats/interfaces.ts | 17 +++ .../src/models/historical-stats/queries.ts | 138 ++++++++++++++++++ hapi-evm/src/models/index.ts | 2 + hapi-evm/src/models/stats/index.ts | 2 + hapi-evm/src/models/stats/interfaces.ts | 5 + hapi-evm/src/models/stats/queries.ts | 24 +++ hapi-evm/src/models/transfer/queries.ts | 31 ++++ hapi-evm/src/services/block.service.ts | 65 ++++++++- hapi-evm/src/services/hyperion/index.ts | 2 +- hapi-evm/src/services/transfer.service.ts | 15 ++ hapi-evm/src/services/worker/index.ts | 4 + 13 files changed, 334 insertions(+), 10 deletions(-) create mode 100644 hapi-evm/src/models/historical-stats/index.ts create mode 100644 hapi-evm/src/models/historical-stats/interfaces.ts create mode 100644 hapi-evm/src/models/historical-stats/queries.ts create mode 100644 hapi-evm/src/models/stats/index.ts create mode 100644 hapi-evm/src/models/stats/interfaces.ts create mode 100644 hapi-evm/src/models/stats/queries.ts create mode 100644 hapi-evm/src/services/transfer.service.ts diff --git a/hapi-evm/src/models/block/queries.ts b/hapi-evm/src/models/block/queries.ts index 883ece5d..8110a972 100644 --- a/hapi-evm/src/models/block/queries.ts +++ b/hapi-evm/src/models/block/queries.ts @@ -1,3 +1,4 @@ +import moment from 'moment' import { gql } from 'graphql-request' import { coreUtil } from '../../utils' @@ -22,6 +23,12 @@ interface BlockInsertOneResponse { } } +interface BlockDeleteResponse { + delete_evm_block: { + affected_rows: number + } +} + const internal_get = async ( type: OperationType = Operation.query, table: TableType, @@ -104,12 +111,32 @@ export const add_or_modify = async (block: CappedBlock) => { } } ` - const { insert_evm_block_one: data } = - await coreUtil.hasura.default.request(mutation, { - evm_block: block - }) - return data + try { + const { insert_evm_block_one: data } = + await coreUtil.hasura.default.request(mutation, { + evm_block: block + }) + + return data + } catch (error) { + //console.log('ERROR', block.number) + //throw error + } +} + +export const deleteOldBlocks = async () => { + const mutation = gql` + mutation ($date: timestamptz) { + delete_evm_block(where: { timestamp: { _lt: $date } }) { + affected_rows + } + } + ` + + await coreUtil.hasura.default.request(mutation, { + date: moment().subtract(1, 'years').format('YYYY-MM-DD') + }) } export default { diff --git a/hapi-evm/src/models/historical-stats/index.ts b/hapi-evm/src/models/historical-stats/index.ts new file mode 100644 index 00000000..5e08e0f1 --- /dev/null +++ b/hapi-evm/src/models/historical-stats/index.ts @@ -0,0 +1,2 @@ +export * as interfaces from './interfaces' +export * as queries from './queries' diff --git a/hapi-evm/src/models/historical-stats/interfaces.ts b/hapi-evm/src/models/historical-stats/interfaces.ts new file mode 100644 index 00000000..69998a62 --- /dev/null +++ b/hapi-evm/src/models/historical-stats/interfaces.ts @@ -0,0 +1,17 @@ +export interface HistoricalStats { + id?: string + total_transactions?: number + total_incoming_token?: number + total_outgoing_token?: number + tps_all_time_high?: { + blocks: string[] + transactions_count: number + gas_used: number + } +} + +export interface HistoricalStatsIncInput { + total_transactions?: number + total_incoming_token?: number + total_outgoing_token?: number +} diff --git a/hapi-evm/src/models/historical-stats/queries.ts b/hapi-evm/src/models/historical-stats/queries.ts new file mode 100644 index 00000000..875c0220 --- /dev/null +++ b/hapi-evm/src/models/historical-stats/queries.ts @@ -0,0 +1,138 @@ +import { gql } from 'graphql-request' + +import { coreUtil } from '../../utils' +import { HistoricalStats, HistoricalStatsIncInput } from './interfaces' + +interface HistoricalStatsResponse { + evm_historical_stats: HistoricalStats[] +} + +interface HistoricalStatsOneResponse { + insert_evm_historical_stats_one: { + id: string + } +} + +const defaultHistoricalStats = { + id: '00000000-0000-0000-0000-000000000000', + total_transactions: 0, + total_incoming_token: 0, + total_outgoing_token: 0, + tps_all_time_high: { + blocks: [], + transactions_count: 0, + gas_used: 0 + } +} + +const save = async (payload: HistoricalStats) => { + const mutation = gql` + mutation ($payload: evm_historical_stats_insert_input!) { + insert_evm_historical_stats_one(object: $payload) { + id + } + } + ` + + const data = + await coreUtil.hasura.default.request( + mutation, + { + payload + } + ) + + return data.insert_evm_historical_stats_one +} + +const update = async ( + id: string, + inc: HistoricalStatsIncInput, + payload: HistoricalStats +) => { + const mutation = gql` + mutation ( + $id: uuid! + $inc: evm_historical_stats_inc_input + $payload: evm_historical_stats_set_input + ) { + update_evm_historical_stats_by_pk( + _inc: $inc + pk_columns: { id: $id } + _set: $payload + ) { + id + } + } + ` + + await coreUtil.hasura.default.request(mutation, { + id, + inc, + payload + }) +} + +export const getState = async () => { + const query = gql` + query { + evm_historical_stats( + where: { id: { _neq: "00000000-0000-0000-0000-000000000000" } } + limit: 1 + ) { + id + total_transactions + total_incoming_token + total_outgoing_token + tps_all_time_high + } + } + ` + const data = await coreUtil.hasura.default.request( + query + ) + + if (!data.evm_historical_stats.length) { + return defaultHistoricalStats + } + + const state = data.evm_historical_stats[0] + + return { + id: state.id || defaultHistoricalStats.id, + total_transactions: + state.total_transactions || defaultHistoricalStats.total_transactions, + total_incoming_token: + state.total_incoming_token || defaultHistoricalStats.total_incoming_token, + total_outgoing_token: + state.total_outgoing_token || defaultHistoricalStats.total_outgoing_token, + tps_all_time_high: + state.tps_all_time_high || defaultHistoricalStats.tps_all_time_high + } +} + +export const saveOrUpdate = async (payload: HistoricalStats): Promise => { + const currentState = await getState() + + if (currentState === defaultHistoricalStats) { + await save(payload) + + return + } + + await update(currentState.id, {}, payload) +} + +export const saveOrIncrement = async ( + payload: HistoricalStatsIncInput +): Promise => { + const currentState = await getState() + + if (currentState === defaultHistoricalStats) { + await save(payload) + + return + } + + await update(currentState.id, payload, {}) +} diff --git a/hapi-evm/src/models/index.ts b/hapi-evm/src/models/index.ts index a6491da5..28294e7c 100644 --- a/hapi-evm/src/models/index.ts +++ b/hapi-evm/src/models/index.ts @@ -5,3 +5,5 @@ export * as hyperionStateModel from './hyperion-state' export * as transferModel from './transfer' export * as paramModel from './param' export * as historyPayloadModel from './history-payload' +export * as historicalStatsModel from './historical-stats' +export * as StatsModel from './stats' diff --git a/hapi-evm/src/models/stats/index.ts b/hapi-evm/src/models/stats/index.ts new file mode 100644 index 00000000..5e08e0f1 --- /dev/null +++ b/hapi-evm/src/models/stats/index.ts @@ -0,0 +1,2 @@ +export * as interfaces from './interfaces' +export * as queries from './queries' diff --git a/hapi-evm/src/models/stats/interfaces.ts b/hapi-evm/src/models/stats/interfaces.ts new file mode 100644 index 00000000..ab41d856 --- /dev/null +++ b/hapi-evm/src/models/stats/interfaces.ts @@ -0,0 +1,5 @@ +export interface Stats { + ath_blocks: string + ath_transactions_count: number + ath_gas_used: number +} diff --git a/hapi-evm/src/models/stats/queries.ts b/hapi-evm/src/models/stats/queries.ts new file mode 100644 index 00000000..18ca4935 --- /dev/null +++ b/hapi-evm/src/models/stats/queries.ts @@ -0,0 +1,24 @@ +import { gql } from 'graphql-request' + +import { coreUtil } from '../../utils' +import { Stats } from './interfaces' + +interface StatsResponse { + evm_stats: Stats[] +} + +export const getPartialATH = async () => { + const query = gql` + query { + evm_stats(limit: 1) { + ath_blocks + ath_transactions_count + ath_gas_used + } + } + ` + const data = await coreUtil.hasura.default.request(query) + const state = data.evm_stats[0] + + return state +} diff --git a/hapi-evm/src/models/transfer/queries.ts b/hapi-evm/src/models/transfer/queries.ts index aa2c9157..ace45bde 100644 --- a/hapi-evm/src/models/transfer/queries.ts +++ b/hapi-evm/src/models/transfer/queries.ts @@ -1,7 +1,9 @@ +import moment from 'moment' import { gql } from 'graphql-request' import { coreUtil } from '../../utils' import { Transfer } from './interfaces' +import { historicalStatsModel } from '..' // interface TransferResponse { // evm_transfer: Transfer[] @@ -13,6 +15,12 @@ interface TransferInsertOneResponse { } } +interface TransferDeleteResponse { + delete_evm_transfer: { + affected_rows: number + } +} + export const save = async (payload: Transfer) => { const mutation = gql` mutation ($payload: evm_transfer_insert_input!) { @@ -22,6 +30,15 @@ export const save = async (payload: Transfer) => { } ` + await historicalStatsModel.queries.saveOrIncrement({ + total_incoming_token: Number(payload.type === 'incoming'), + total_outgoing_token: Number(payload.type === 'outgoing') + }) + + if (moment(payload.timestamp).isBefore(moment().subtract(1, 'years'))) { + return + } + const data = await coreUtil.hasura.default.request( mutation, { @@ -31,3 +48,17 @@ export const save = async (payload: Transfer) => { return data.insert_evm_transfer_one } + +export const deleteOldTransfers = async () => { + const mutation = gql` + mutation ($date: timestamptz) { + delete_evm_transfer(where: { timestamp: { _lt: $date } }) { + affected_rows + } + } + ` + + await coreUtil.hasura.default.request(mutation, { + date: moment().subtract(1, 'years').format('YYYY-MM-DD') + }) +} diff --git a/hapi-evm/src/services/block.service.ts b/hapi-evm/src/services/block.service.ts index 7f8a2f61..1e18f946 100644 --- a/hapi-evm/src/services/block.service.ts +++ b/hapi-evm/src/services/block.service.ts @@ -5,9 +5,12 @@ import { defaultModel, blockModel, transactionModel, - paramModel + paramModel, + historicalStatsModel, + StatsModel } from '../models' import { networkConfig } from '../config' +import moment from 'moment' const httpProvider = new Web3.providers.HttpProvider(networkConfig.evmEndpoint) const web3 = new Web3(httpProvider) @@ -26,7 +29,6 @@ const web3 = new Web3(httpProvider) // test() // TODO: syncronize passed blocks - const syncFullBlock = async (blockNumber: number | bigint) => { const block: Block = await web3.eth.getBlock(blockNumber) @@ -38,12 +40,27 @@ const syncFullBlock = async (blockNumber: number | bigint) => { if (blockExist) return + const transactionsCount = block.transactions?.length + + if (transactionsCount) { + await historicalStatsModel.queries.saveOrIncrement({ + total_transactions: transactionsCount + }) + } + + const blockTimestamp = new Date(Number(block.timestamp) * 1000) + const isBefore = moment(blockTimestamp).isBefore( + moment().subtract(1, 'years') + ) + + if (isBefore) return + const cappedBlock = { hash: block.hash.toString(), gas_used: Number(block.gasUsed), transactions: (block.transactions || []) as TransactionHash[], number: Number(block.number), - timestamp: new Date(Number(block.timestamp) * 1000) + timestamp: blockTimestamp } await blockModel.queries.add_or_modify(cappedBlock) @@ -124,6 +141,28 @@ const blockWorker = async () => { getBlock() } +const cleanOldBlocks = async () => { + await blockModel.queries.deleteOldBlocks() +} + +const syncATH = async () => { + const currentState = await historicalStatsModel.queries.getState() + const partialATH = await StatsModel.queries.getPartialATH() + + if ( + currentState.tps_all_time_high.transactions_count || + 0 < partialATH.ath_transactions_count + ) { + await historicalStatsModel.queries.saveOrUpdate({ + tps_all_time_high: { + blocks: partialATH.ath_blocks.split(','), + transactions_count: partialATH.ath_transactions_count, + gas_used: partialATH.ath_gas_used + } + }) + } +} + const syncBlockWorker = (): defaultModel.Worker => { return { name: 'SYNC BLOCK WORKER', @@ -140,7 +179,25 @@ const syncOldBlockWorker = (): defaultModel.Worker => { } } +const syncATHWorker = (): defaultModel.Worker => { + return { + name: 'SYNC ATH WORKER', + intervalSec: 60, + action: syncATH + } +} + +const cleanOldBlocksWorker = (): defaultModel.Worker => { + return { + name: 'CLEAN UP OLD BLOCKS WORKER', + intervalSec: 86400, + action: cleanOldBlocks + } +} + export default { syncBlockWorker, - syncOldBlockWorker + syncOldBlockWorker, + cleanOldBlocksWorker, + syncATHWorker } diff --git a/hapi-evm/src/services/hyperion/index.ts b/hapi-evm/src/services/hyperion/index.ts index 59c18092..aa3d95a9 100644 --- a/hapi-evm/src/services/hyperion/index.ts +++ b/hapi-evm/src/services/hyperion/index.ts @@ -2,7 +2,7 @@ import moment, { DurationInputArg2 } from 'moment' import { hyperionConfig } from '../../config' import { coreUtil, timeUtil } from '../../utils' -import { hyperionStateModel } from '../../models' +import { historicalStatsModel, hyperionStateModel } from '../../models' import updaters from './updaters' diff --git a/hapi-evm/src/services/transfer.service.ts b/hapi-evm/src/services/transfer.service.ts new file mode 100644 index 00000000..ab8faa81 --- /dev/null +++ b/hapi-evm/src/services/transfer.service.ts @@ -0,0 +1,15 @@ +import { defaultModel, transferModel } from '../models' + +const cleanOldTransfersWorker = (): defaultModel.Worker => { + return { + name: 'CLEAN UP OLD TRANSFER WORKER', + intervalSec: 86400, + action: async () => { + await transferModel.queries.deleteOldTransfers() + } + } +} + +export default { + cleanOldTransfersWorker +} diff --git a/hapi-evm/src/services/worker/index.ts b/hapi-evm/src/services/worker/index.ts index 043e7955..8da10122 100644 --- a/hapi-evm/src/services/worker/index.ts +++ b/hapi-evm/src/services/worker/index.ts @@ -1,6 +1,7 @@ import { timeUtil, coreUtil } from '../../utils' import { defaultModel } from '../../models' import blockService from '../block.service' +import transferService from '../transfer.service' import hyperionService from '../hyperion' const run = async (worker: defaultModel.Worker) => { @@ -23,6 +24,9 @@ const init = async () => { run(blockService.syncBlockWorker()) run(blockService.syncOldBlockWorker()) + run(blockService.syncATHWorker()) + run(blockService.cleanOldBlocksWorker()) + run(transferService.cleanOldTransfersWorker()) run(hyperionService.syncWorker()) } From 445d7afd9ab4ed9056e9450d33e215fcd2de8e1a Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Thu, 17 Aug 2023 09:37:59 -0600 Subject: [PATCH 37/75] chore(hasura): remove unused fields from evm stats view and add partial ath calculation --- .../databases/default/tables/evm_stats.yaml | 5 +--- .../down.sql | 30 +++++++++++++++++++ .../up.sql | 28 +++++++++++++++++ 3 files changed, 59 insertions(+), 4 deletions(-) create mode 100644 hasura/migrations/default/1692286077976_create_evm_stats_view_v4/down.sql create mode 100644 hasura/migrations/default/1692286077976_create_evm_stats_view_v4/up.sql diff --git a/hasura/metadata/databases/default/tables/evm_stats.yaml b/hasura/metadata/databases/default/tables/evm_stats.yaml index 0ab926b1..ef1561bd 100644 --- a/hasura/metadata/databases/default/tables/evm_stats.yaml +++ b/hasura/metadata/databases/default/tables/evm_stats.yaml @@ -5,9 +5,6 @@ select_permissions: - role: guest permission: columns: - - ath_transaction_sum - - daily_transaction_count - - incoming_tlos_count - - outgoing_tlos_count - block_gas_avg + - daily_transaction_count filter: {} diff --git a/hasura/migrations/default/1692286077976_create_evm_stats_view_v4/down.sql b/hasura/migrations/default/1692286077976_create_evm_stats_view_v4/down.sql new file mode 100644 index 00000000..839dc42d --- /dev/null +++ b/hasura/migrations/default/1692286077976_create_evm_stats_view_v4/down.sql @@ -0,0 +1,30 @@ +-- Could not auto-generate a down migration. +-- Please write an appropriate down migration for the SQL below: +-- DROP VIEW IF EXISTS "evm"."stats"; +-- CREATE OR REPLACE VIEW "evm"."stats" AS +-- SELECT COALESCE(evm_block.avg_gas_used, (0)::numeric) AS block_gas_avg, +-- COALESCE(daily_transactions.total_transaction_count, (0)::bigint) AS daily_transaction_count, +-- COALESCE(max_transaction_sum, (0)::numeric) AS ath_transactions_count, +-- COALESCE(gas_used_sum, (0)::numeric) AS ath_gas_used, +-- blocks AS ath_blocks +-- FROM (((( SELECT avg(subquery_alias.gas_used) AS avg_gas_used +-- FROM ( SELECT block.gas_used, block."timestamp" +-- FROM evm.block +-- ORDER BY block."timestamp" DESC +-- LIMIT 100) subquery_alias) evm_block +-- CROSS JOIN LATERAL ( +-- SELECT sum(jsonb_array_length(block.transactions)) AS total_transaction_count +-- FROM evm.block +-- WHERE (block."timestamp" >= (now() - '24:00:00'::interval))) daily_transactions) +-- CROSS JOIN LATERAL ( +-- WITH subquery AS( +-- SELECT array_to_string(array_agg(evm.block.number), ',') AS blocks , +-- sum(jsonb_array_length(evm.block.transactions)) AS total_transaction_count, +-- sum(evm.block.gas_used) AS gas_used_sum +-- FROM evm.block +-- GROUP BY timestamp) +-- SELECT blocks, max_transaction_sum, gas_used_sum +-- FROM ( SELECT max(subquery.total_transaction_count) AS max_transaction_sum +-- FROM subquery) q1 +-- INNER JOIN subquery q2 ON q1.max_transaction_sum = q2.total_transaction_count +-- LIMIT 1) ath_last_year)); diff --git a/hasura/migrations/default/1692286077976_create_evm_stats_view_v4/up.sql b/hasura/migrations/default/1692286077976_create_evm_stats_view_v4/up.sql new file mode 100644 index 00000000..91993b63 --- /dev/null +++ b/hasura/migrations/default/1692286077976_create_evm_stats_view_v4/up.sql @@ -0,0 +1,28 @@ +DROP VIEW IF EXISTS "evm"."stats"; +CREATE OR REPLACE VIEW "evm"."stats" AS + SELECT COALESCE(evm_block.avg_gas_used, (0)::numeric) AS block_gas_avg, + COALESCE(daily_transactions.total_transaction_count, (0)::bigint) AS daily_transaction_count, + COALESCE(max_transaction_sum, (0)::numeric) AS ath_transactions_count, + COALESCE(gas_used_sum, (0)::numeric) AS ath_gas_used, + blocks AS ath_blocks + FROM (((( SELECT avg(subquery_alias.gas_used) AS avg_gas_used + FROM ( SELECT block.gas_used, block."timestamp" + FROM evm.block + ORDER BY block."timestamp" DESC + LIMIT 100) subquery_alias) evm_block + CROSS JOIN LATERAL ( + SELECT sum(jsonb_array_length(block.transactions)) AS total_transaction_count + FROM evm.block + WHERE (block."timestamp" >= (now() - '24:00:00'::interval))) daily_transactions) + CROSS JOIN LATERAL ( + WITH subquery AS( + SELECT array_to_string(array_agg(evm.block.number), ',') AS blocks , + sum(jsonb_array_length(evm.block.transactions)) AS total_transaction_count, + sum(evm.block.gas_used) AS gas_used_sum + FROM evm.block + GROUP BY timestamp) + SELECT blocks, max_transaction_sum, gas_used_sum + FROM ( SELECT max(subquery.total_transaction_count) AS max_transaction_sum + FROM subquery) q1 + INNER JOIN subquery q2 ON q1.max_transaction_sum = q2.total_transaction_count + LIMIT 1) ath_last_year)); From 3e84eda08306fef904e391fa72ee7177407919e0 Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Thu, 17 Aug 2023 09:45:13 -0600 Subject: [PATCH 38/75] chore(hapi-evm): remove unused code and add conditional when partialATH is undefined --- hapi-evm/src/models/block/queries.ts | 16 +++++----------- hapi-evm/src/services/block.service.ts | 2 ++ hapi-evm/src/services/hyperion/index.ts | 2 +- 3 files changed, 8 insertions(+), 12 deletions(-) diff --git a/hapi-evm/src/models/block/queries.ts b/hapi-evm/src/models/block/queries.ts index 8110a972..983a7c97 100644 --- a/hapi-evm/src/models/block/queries.ts +++ b/hapi-evm/src/models/block/queries.ts @@ -111,18 +111,12 @@ export const add_or_modify = async (block: CappedBlock) => { } } ` + const { insert_evm_block_one: data } = + await coreUtil.hasura.default.request(mutation, { + evm_block: block + }) - try { - const { insert_evm_block_one: data } = - await coreUtil.hasura.default.request(mutation, { - evm_block: block - }) - - return data - } catch (error) { - //console.log('ERROR', block.number) - //throw error - } + return data } export const deleteOldBlocks = async () => { diff --git a/hapi-evm/src/services/block.service.ts b/hapi-evm/src/services/block.service.ts index 1e18f946..3621c3ad 100644 --- a/hapi-evm/src/services/block.service.ts +++ b/hapi-evm/src/services/block.service.ts @@ -149,6 +149,8 @@ const syncATH = async () => { const currentState = await historicalStatsModel.queries.getState() const partialATH = await StatsModel.queries.getPartialATH() + if (!partialATH) return + if ( currentState.tps_all_time_high.transactions_count || 0 < partialATH.ath_transactions_count diff --git a/hapi-evm/src/services/hyperion/index.ts b/hapi-evm/src/services/hyperion/index.ts index aa3d95a9..59c18092 100644 --- a/hapi-evm/src/services/hyperion/index.ts +++ b/hapi-evm/src/services/hyperion/index.ts @@ -2,7 +2,7 @@ import moment, { DurationInputArg2 } from 'moment' import { hyperionConfig } from '../../config' import { coreUtil, timeUtil } from '../../utils' -import { historicalStatsModel, hyperionStateModel } from '../../models' +import { hyperionStateModel } from '../../models' import updaters from './updaters' From 36bcf545a295b8ab1d0a0352b01a042cc17f1cb6 Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Thu, 17 Aug 2023 14:23:22 -0600 Subject: [PATCH 39/75] fix(hapi-evm): use the DB to get the last block to avoid missing blocks --- hapi-evm/src/models/block/queries.ts | 20 +++++++++++++++----- hapi-evm/src/services/block.service.ts | 12 +++++++++++- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/hapi-evm/src/models/block/queries.ts b/hapi-evm/src/models/block/queries.ts index 983a7c97..0982b0a5 100644 --- a/hapi-evm/src/models/block/queries.ts +++ b/hapi-evm/src/models/block/queries.ts @@ -36,19 +36,23 @@ const internal_get = async ( // TODO: not only accept where but also additional content // such as limit, order, etc where: object, + order: object | null, attributes: string, operation?: string ): Promise => { const query = gql` ${type} (${parameters}) { - ${table}${operation ? `_${operation}` : ''}(where: $where) { + ${table}${ + operation ? `_${operation}` : '' + }(where: $where, order_by: $order) { ${attributes} } } ` return await coreUtil.hasura.default.request(query, { - where + where, + order }) } @@ -56,12 +60,13 @@ export const exist = async (hashOrNumber: string | number) => { const result = await internal_get( 'query', 'evm_block', - '$where: evm_block_bool_exp!', + '$where: evm_block_bool_exp!, $order: [evm_block_order_by!]', { [typeof hashOrNumber === 'string' ? 'hash' : 'number']: { _eq: hashOrNumber } }, + null, 'aggregate { count }', 'aggregate' ) @@ -69,12 +74,17 @@ export const exist = async (hashOrNumber: string | number) => { return result.evm_block_aggregate.aggregate.count > 0 } -const get = async (where: object, many = false) => { +const get = async ( + where: object, + order: object | null = null, + many = false +) => { const result = await internal_get( 'query', 'evm_block', - '$where: evm_block_bool_exp!', + '$where: evm_block_bool_exp!, $order: [evm_block_order_by!]', where, + order, 'hash, gas_used, transactions, number, timestamp' ) diff --git a/hapi-evm/src/services/block.service.ts b/hapi-evm/src/services/block.service.ts index 3621c3ad..458563ab 100644 --- a/hapi-evm/src/services/block.service.ts +++ b/hapi-evm/src/services/block.service.ts @@ -103,7 +103,17 @@ const syncFullBlock = async (blockNumber: number | bigint) => { } const getBlock = async () => { - const blockNumber = await web3.eth.getBlockNumber() + let blockNumber: bigint + const lastBlockInDB = (await blockModel.queries.default.get( + { timestamp: { _gt: moment().subtract(30, 'minutes') } }, + { number: 'desc' } + )) as blockModel.interfaces.CappedBlock + + if (!lastBlockInDB) { + blockNumber = await web3.eth.getBlockNumber() + } else { + blockNumber = BigInt(lastBlockInDB.number + 1) + } await syncFullBlock(blockNumber) } From 305531b9266af907fa6ee107b5d24661109455e0 Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Thu, 17 Aug 2023 14:33:19 -0600 Subject: [PATCH 40/75] refactor(hapi-evm): use Type to compare the type of transfers --- hapi-evm/src/models/transfer/queries.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hapi-evm/src/models/transfer/queries.ts b/hapi-evm/src/models/transfer/queries.ts index ace45bde..e763791e 100644 --- a/hapi-evm/src/models/transfer/queries.ts +++ b/hapi-evm/src/models/transfer/queries.ts @@ -2,7 +2,7 @@ import moment from 'moment' import { gql } from 'graphql-request' import { coreUtil } from '../../utils' -import { Transfer } from './interfaces' +import { Transfer, Type } from './interfaces' import { historicalStatsModel } from '..' // interface TransferResponse { @@ -31,8 +31,8 @@ export const save = async (payload: Transfer) => { ` await historicalStatsModel.queries.saveOrIncrement({ - total_incoming_token: Number(payload.type === 'incoming'), - total_outgoing_token: Number(payload.type === 'outgoing') + total_incoming_token: Number(payload.type === Type.incoming), + total_outgoing_token: Number(payload.type === Type.outgoing) }) if (moment(payload.timestamp).isBefore(moment().subtract(1, 'years'))) { From c5b2032cc4d082028e279ed7bee151c06b9ddc5f Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Fri, 18 Aug 2023 14:16:46 -0600 Subject: [PATCH 41/75] refactor(webapp): use historical evm table and refactor BodyGraphValue component --- .../SimpleDataCard/BodyGraphValue.js | 43 +++++++++++++++++ .../src/components/SimpleDataCard/styles.js | 4 ++ .../components/TransactionsHistory/index.js | 38 +-------------- .../components/TransactionsHistory/styles.js | 4 -- webapp/src/config/evm.config.js | 1 + webapp/src/gql/evm.gql.js | 14 +++--- webapp/src/language/en.json | 1 - webapp/src/language/es.json | 1 - webapp/src/routes/EVMDashboard/index.js | 21 ++++++--- webapp/src/routes/EVMDashboard/useEVMstate.js | 47 ++++++++----------- webapp/src/utils/get-evmblocknum-url.js | 11 +++++ webapp/src/utils/index.js | 1 + 12 files changed, 101 insertions(+), 85 deletions(-) create mode 100644 webapp/src/components/SimpleDataCard/BodyGraphValue.js create mode 100644 webapp/src/utils/get-evmblocknum-url.js diff --git a/webapp/src/components/SimpleDataCard/BodyGraphValue.js b/webapp/src/components/SimpleDataCard/BodyGraphValue.js new file mode 100644 index 00000000..be9ac9b2 --- /dev/null +++ b/webapp/src/components/SimpleDataCard/BodyGraphValue.js @@ -0,0 +1,43 @@ +import React from 'react' +import { makeStyles } from '@mui/styles' +import PropTypes from 'prop-types' +import LinearProgress from '@mui/material/LinearProgress' +import LaunchIcon from '@mui/icons-material/Launch' + +import styles from './styles' + +const useStyles = makeStyles(styles) + +const BodyGraphValue = ({ loading, links }) => { + const classes = useStyles() + + if (loading) return + + return ( + <> + {links && + links.map((href, index) => ( + + + + ))} + + ) +} + +BodyGraphValue.propTypes = { + loading: PropTypes.bool, + href: PropTypes.string, +} + +BodyGraphValue.defaultProps = { + loading: false, +} + +export default BodyGraphValue diff --git a/webapp/src/components/SimpleDataCard/styles.js b/webapp/src/components/SimpleDataCard/styles.js index e14c383e..bbef27af 100644 --- a/webapp/src/components/SimpleDataCard/styles.js +++ b/webapp/src/components/SimpleDataCard/styles.js @@ -36,4 +36,8 @@ export default (theme) => ({ lowercase: { textTransform: 'lowercase !important', }, + svgLink: { + fontSize: 18, + marginLeft: theme.spacing(2), + }, }) diff --git a/webapp/src/components/TransactionsHistory/index.js b/webapp/src/components/TransactionsHistory/index.js index 1c38174b..26a18976 100644 --- a/webapp/src/components/TransactionsHistory/index.js +++ b/webapp/src/components/TransactionsHistory/index.js @@ -2,8 +2,6 @@ import React, { memo } from 'react' import { makeStyles } from '@mui/styles' import PropTypes from 'prop-types' -import LinearProgress from '@mui/material/LinearProgress' -import LaunchIcon from '@mui/icons-material/Launch' import { useSubscription } from '@apollo/client' import { BLOCK_TRANSACTIONS_HISTORY } from '../../gql' @@ -11,43 +9,12 @@ import { useSharedState } from '../../context/state.context' import { formatWithThousandSeparator, getBlockNumUrl } from '../../utils' import { generalConfig } from '../../config' import SimpleDataCard from '../SimpleDataCard' +import BodyGraphValue from '../SimpleDataCard/BodyGraphValue' import styles from './styles' const useStyles = makeStyles(styles) -const BodyGraphValue = ({ loading, classes, links }) => { - if (loading) return - - return ( - <> - {links && - links.map((href, index) => ( - - - - ))} - - ) -} - -BodyGraphValue.propTypes = { - loading: PropTypes.bool, - classes: PropTypes.object, - href: PropTypes.string, -} - -BodyGraphValue.defaultProps = { - loading: false, - classes: {}, -} - const TransactionsHistory = ({ t, nodesChildren }) => { const classes = useStyles() const [{ info, tps }] = useSharedState() @@ -63,7 +30,6 @@ const TransactionsHistory = ({ t, nodesChildren }) => { loading={loading} > getBlockNumUrl(block), )} @@ -75,7 +41,6 @@ const TransactionsHistory = ({ t, nodesChildren }) => { loading={loading} > getBlockNumUrl(block), )} @@ -87,7 +52,6 @@ const TransactionsHistory = ({ t, nodesChildren }) => { loading={loading} > getBlockNumUrl(block), )} diff --git a/webapp/src/components/TransactionsHistory/styles.js b/webapp/src/components/TransactionsHistory/styles.js index 5c7c252f..67db383b 100644 --- a/webapp/src/components/TransactionsHistory/styles.js +++ b/webapp/src/components/TransactionsHistory/styles.js @@ -1,8 +1,4 @@ export default (theme) => ({ - svgLink: { - fontSize: 18, - marginLeft: theme.spacing(2), - }, wrapper: { display: 'flex', gap: '10px', diff --git a/webapp/src/config/evm.config.js b/webapp/src/config/evm.config.js index c68cc048..c5a0f94b 100644 --- a/webapp/src/config/evm.config.js +++ b/webapp/src/config/evm.config.js @@ -19,3 +19,4 @@ export const avgBlockTime = _avgBlockTime export const maxTPSDataSize = 30 / _avgBlockTime export const account = 'eosio.evm' export const endpoint = process.env.REACT_APP_EVM_ENDPOINT +export const blockExplorerUrl = process.env.REACT_APP_EVM_BLOCK_EXPLORER_URL \ No newline at end of file diff --git a/webapp/src/gql/evm.gql.js b/webapp/src/gql/evm.gql.js index e1dbe4cd..f2372c8b 100644 --- a/webapp/src/gql/evm.gql.js +++ b/webapp/src/gql/evm.gql.js @@ -5,19 +5,17 @@ export const EVM_STATS_SUBSCRIPTION = gql` evm_stats(limit: 1) { avg_gas_used: block_gas_avg daily_transaction_count - ath_transaction_sum - incoming_tlos_count - outgoing_tlos_count } } ` -export const EVM_TOTAL_TRANSACTIONS_SUBSCRIPTION = gql` +export const EVM_HISTORICAL_STATS_SUBSCRIPTION = gql` subscription { - evm_transaction_aggregate { - aggregate { - count - } + evm_historical_stats{ + total_incoming_token + total_outgoing_token + total_transactions + tps_all_time_high } } ` diff --git a/webapp/src/language/en.json b/webapp/src/language/en.json index 2394a528..95fa938b 100644 --- a/webapp/src/language/en.json +++ b/webapp/src/language/en.json @@ -438,7 +438,6 @@ "totalOutgoing": "Total (TOKEN) outgoing", "incoming": "Incoming", "outgoing": "Outgoing", - "avgTX": "Average transaction per day", "ATH": "TPS All Time High", "lastBlock": "Last block", "totalTxs": "Total EVM transactions", diff --git a/webapp/src/language/es.json b/webapp/src/language/es.json index fb38462e..64199f51 100644 --- a/webapp/src/language/es.json +++ b/webapp/src/language/es.json @@ -459,7 +459,6 @@ "totalOutgoing": "Total (TOKEN) salientes", "incoming": "Entrantes", "outgoing": "Salientes", - "avgTX": "Promedio de transacciones por día", "ATH": "TPS Máximo histórico", "lastBlock": "Último bloque", "totalTxs": "Total de transacciones EVM", diff --git a/webapp/src/routes/EVMDashboard/index.js b/webapp/src/routes/EVMDashboard/index.js index 06b7a189..e3503c71 100644 --- a/webapp/src/routes/EVMDashboard/index.js +++ b/webapp/src/routes/EVMDashboard/index.js @@ -3,9 +3,10 @@ import { useTheme } from '@mui/material/styles' import { useTranslation } from 'react-i18next' import { makeStyles } from '@mui/styles' -import { formatWithThousandSeparator } from '../../utils' +import { formatWithThousandSeparator, getEVMBlockNumUrl } from '../../utils' import { eosConfig, evmConfig } from '../../config' import SimpleDataCard from '../../components/SimpleDataCard' +import BodyGraphValue from '../../components/SimpleDataCard/BodyGraphValue' import TransactionsChartContainer from '../../components/TransactionsChartContainer' import styles from './styles' @@ -43,7 +44,7 @@ const EVMDashboard = () => { />
@@ -129,11 +130,17 @@ const EVMDashboard = () => {
+ > + + getEVMBlockNumUrl(block), + )} + /> + { diff --git a/webapp/src/routes/EVMDashboard/useEVMstate.js b/webapp/src/routes/EVMDashboard/useEVMstate.js index 3914e662..1b853cad 100644 --- a/webapp/src/routes/EVMDashboard/useEVMstate.js +++ b/webapp/src/routes/EVMDashboard/useEVMstate.js @@ -4,7 +4,7 @@ import moment from 'moment' import { EVM_STATS_SUBSCRIPTION, - EVM_TOTAL_TRANSACTIONS_SUBSCRIPTION, + EVM_HISTORICAL_STATS_SUBSCRIPTION, EVM_TRANSACTION_QUERY, EVM_TOKEN_QUERY, } from '../../gql' @@ -14,9 +14,9 @@ import { rangeOptions } from '../../utils' import { evmConfig } from 'config' const useEVMState = (theme, t) => { - const { data, loading } = useSubscription(EVM_STATS_SUBSCRIPTION) - const { data: txsCountData } = useSubscription( - EVM_TOTAL_TRANSACTIONS_SUBSCRIPTION, + const { data: stats, loading } = useSubscription(EVM_STATS_SUBSCRIPTION) + const { data: historicalStats, loading: historicalLoading } = useSubscription( + EVM_HISTORICAL_STATS_SUBSCRIPTION, ) const [getTransactionHistory, { data: transactionsData }] = useLazyQuery( EVM_TRANSACTION_QUERY, @@ -84,20 +84,19 @@ const useEVMState = (theme, t) => { } useEffect(() => { - if (!data) return - - setEVMStats(prev => ({ ...prev, ...data.evm_stats[0] })) - }, [data, loading]) - - useEffect(() => { - const updateLastBlock = async () => { + const updateStats = async () => { const lastBlock = await ethApi.getLastBlock() - setEVMStats(prev => ({ ...prev, last_block: lastBlock })) + setEVMStats(prev => ({ + ...prev, + last_block: lastBlock, + ...(historicalStats && historicalStats.evm_historical_stats[0]), + ...(stats && stats.evm_stats[0]), + })) } - updateLastBlock() - }, [data, loading]) + updateStats() + }, [stats, loading, historicalStats, historicalLoading]) useEffect(() => { const updateStats = async () => { @@ -186,14 +185,6 @@ const useEVMState = (theme, t) => { } }, [transactionsData, t, theme]) - useEffect(() => { - if (!txsCountData) return - - const count = txsCountData.evm_transaction_aggregate.aggregate.count - - setEVMStats(prev => ({ ...prev, transactions_count: count })) - }, [txsCountData]) - useEffect(() => { const updateTPB = async blockNum => { if (!blockNum) { @@ -239,11 +230,13 @@ const useEVMState = (theme, t) => { }, []) useEffect(() => { - setTransactionsHistoryData([{ - name: t('transactions'), - color: theme.palette.secondary.main, - data: blocksList, - }]) + setTransactionsHistoryData([ + { + name: t('transactions'), + color: theme.palette.secondary.main, + data: blocksList, + }, + ]) }, [blocksList, t, theme]) return [ diff --git a/webapp/src/utils/get-evmblocknum-url.js b/webapp/src/utils/get-evmblocknum-url.js new file mode 100644 index 00000000..282e0bbe --- /dev/null +++ b/webapp/src/utils/get-evmblocknum-url.js @@ -0,0 +1,11 @@ +import { evmConfig } from '../config' + +export const getEVMBlockNumUrl = blockNum => { + if (!blockNum || !evmConfig.blockExplorerUrl) { + return + } + + return evmConfig.blockExplorerUrl.replace('(block)', blockNum) +} + +export default getEVMBlockNumUrl diff --git a/webapp/src/utils/index.js b/webapp/src/utils/index.js index f60d12e8..62309742 100644 --- a/webapp/src/utils/index.js +++ b/webapp/src/utils/index.js @@ -7,3 +7,4 @@ export * from './get-range-options' export * from './get-transaction-url' export * from './validate-image' export * from './validate-url' +export * from './get-evmblocknum-url' From eb6be38f6bb387187db882b2d6b8c3c1374b5df7 Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Fri, 18 Aug 2023 14:18:19 -0600 Subject: [PATCH 42/75] chore(workflows): add evm block explorer url --- .github/workflows/deploy-jungle-testnet.yaml | 2 +- .github/workflows/deploy-mainnet.yaml | 2 +- .github/workflows/deploy-telos-testnet.yaml | 1 + .github/workflows/deploy-telos.yaml | 1 + kubernetes/configmap-dashboard.yaml | 1 + 5 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/deploy-jungle-testnet.yaml b/.github/workflows/deploy-jungle-testnet.yaml index 1e0d47b2..795c18ba 100644 --- a/.github/workflows/deploy-jungle-testnet.yaml +++ b/.github/workflows/deploy-jungle-testnet.yaml @@ -52,7 +52,7 @@ jobs: REACT_APP_SYNC_TOLERANCE_INTERVAL: 180000 REACT_APP_TOKEN_SYMBOL: 'EOS' REACT_APP_NETWORK_URL: '[{"label":"EOS","value":"https://eos.antelope.tools","mainnet":true,"pair":"eos","icon":"eos","order":5},{"label":"Proton","value":"https://proton.antelope.tools","mainnet":true,"pair":"proton","icon":"proton","order":3},{"label":"WAX","value":"https://wax.antelope.tools","mainnet":true,"pair":"wax","icon":"wax","order":4},{"label":"Telos","value":"https://telos.antelope.tools","mainnet":true,"pair":"telos","icon":"telos","order":1},{"label":"Libre","value":"https://libre.antelope.tools","mainnet":true,"pair":"libre","icon":"libre","order":2},{"label":"LACChain EOSIO","value":"https://lacchain.antelope.tools","mainnet":true,"pair":null,"icon":"lacchain","order":6},{"label":"Jungle4 Testnet","value":"https://jungle.antelope.tools","mainnet":false,"pair":"eos","icon":"jungle","order":5},{"label":"Proton Testnet","value":"https://proton-testnet.antelope.tools","mainnet":false,"pair":"proton","icon":"proton","order":3},{"label":"WAX Testnet","value":"https://wax-testnet.antelope.tools","mainnet":false,"pair":"wax","icon":"wax","order":4},{"label":"Telos Testnet","value":"https://telos-testnet.antelope.tools","mainnet":false,"pair":"telos","icon":"telos","order":1},{"label":"Libre Testnet","value":"https://libre-testnet.antelope.tools","mainnet":false,"pair":"libre","icon":"libre","order":2},{"label":"Ultra Testnet","value":"https://ultra-testnet.antelope.tools","mainnet":false,"pair":"ultra","icon":"ultra","order":6}]' - REACT_APP_DISABLED_MENU_ITEMS: '["/missed-blocks","/block-distribution","/cpu-benchmark","/stress-test"]' + REACT_APP_DISABLED_MENU_ITEMS: '["/missed-blocks","/block-distribution","/cpu-benchmark","/stress-test","/evm"]' REACT_APP_BLOCK_EXPLORER_URL: 'https://jungle4.eosq.eosnation.io/tx/(transaction)' REACT_APP_STATE_HISTORY_ENABLED: 'false' REACT_APP_GOOGLE_ANALITIC_PAGE_ID: 'G-E6Y0EC9FT8' diff --git a/.github/workflows/deploy-mainnet.yaml b/.github/workflows/deploy-mainnet.yaml index 843dcec1..b322eb56 100644 --- a/.github/workflows/deploy-mainnet.yaml +++ b/.github/workflows/deploy-mainnet.yaml @@ -53,7 +53,7 @@ jobs: REACT_APP_EOS_API_NETWORK_LOGO: 'https://antelope.tools/images/eos.png' REACT_APP_TOKEN_SYMBOL: 'EOS' REACT_APP_NETWORK_URL: '[{"label":"EOS","value":"https://eos.antelope.tools","mainnet":true,"pair":"eos","icon":"eos","order":5},{"label":"Proton","value":"https://proton.antelope.tools","mainnet":true,"pair":"proton","icon":"proton","order":3},{"label":"WAX","value":"https://wax.antelope.tools","mainnet":true,"pair":"wax","icon":"wax","order":4},{"label":"Telos","value":"https://telos.antelope.tools","mainnet":true,"pair":"telos","icon":"telos","order":1},{"label":"Libre","value":"https://libre.antelope.tools","mainnet":true,"pair":"libre","icon":"libre","order":2},{"label":"LACChain EOSIO","value":"https://lacchain.antelope.tools","mainnet":true,"pair":null,"icon":"lacchain","order":6},{"label":"Jungle4 Testnet","value":"https://jungle.antelope.tools","mainnet":false,"pair":"eos","icon":"jungle","order":5},{"label":"Proton Testnet","value":"https://proton-testnet.antelope.tools","mainnet":false,"pair":"proton","icon":"proton","order":3},{"label":"WAX Testnet","value":"https://wax-testnet.antelope.tools","mainnet":false,"pair":"wax","icon":"wax","order":4},{"label":"Telos Testnet","value":"https://telos-testnet.antelope.tools","mainnet":false,"pair":"telos","icon":"telos","order":1},{"label":"Libre Testnet","value":"https://libre-testnet.antelope.tools","mainnet":false,"pair":"libre","icon":"libre","order":2},{"label":"Ultra Testnet","value":"https://ultra-testnet.antelope.tools","mainnet":false,"pair":"ultra","icon":"ultra","order":6}]' - REACT_APP_DISABLED_MENU_ITEMS: '["/missed-blocks", "/cpu-benchmark","/block-distribution","/stress-test"]' + REACT_APP_DISABLED_MENU_ITEMS: '["/missed-blocks", "/cpu-benchmark","/block-distribution","/stress-test","/evm"]' REACT_APP_BLOCK_EXPLORER_URL: 'https://bloks.io/transaction/(transaction)' REACT_APP_STATE_HISTORY_ENABLED: 'false' REACT_APP_GOOGLE_ANALITIC_PAGE_ID: 'G-E6Y0EC9FT8' diff --git a/.github/workflows/deploy-telos-testnet.yaml b/.github/workflows/deploy-telos-testnet.yaml index d7e25c8e..bff88432 100644 --- a/.github/workflows/deploy-telos-testnet.yaml +++ b/.github/workflows/deploy-telos-testnet.yaml @@ -62,6 +62,7 @@ jobs: REACT_APP_GOOGLE_ANALITIC_PAGE_ID: 'G-E6Y0EC9FT8' REACT_APP_PUBLIC_RE_CAPTCHA_KEY: ${{ secrets.REACT_APP_PUBLIC_RE_CAPTCHA_KEY }} REACT_APP_EVM_ENDPOINT: 'https://testnet.telos.net/evm' + REACT_APP_EVM_BLOCK_EXPLORER_URL: 'https://testnet.teloscan.io/block/(block)' - name: Build and deploy kubernetes files id: build_kubernetes_files diff --git a/.github/workflows/deploy-telos.yaml b/.github/workflows/deploy-telos.yaml index e3223f9f..e6509af3 100644 --- a/.github/workflows/deploy-telos.yaml +++ b/.github/workflows/deploy-telos.yaml @@ -62,6 +62,7 @@ jobs: REACT_APP_GOOGLE_ANALITIC_PAGE_ID: 'G-E6Y0EC9FT8' REACT_APP_PUBLIC_RE_CAPTCHA_KEY: ${{ secrets.REACT_APP_PUBLIC_RE_CAPTCHA_KEY }} REACT_APP_EVM_ENDPOINT: 'https://mainnet.telos.net/evm' + REACT_APP_EVM_BLOCK_EXPLORER_URL: https://www.teloscan.io/block/(block) - name: Build and deploy kubernetes files id: build_kubernetes_files diff --git a/kubernetes/configmap-dashboard.yaml b/kubernetes/configmap-dashboard.yaml index 89c4c83e..37fd6e10 100644 --- a/kubernetes/configmap-dashboard.yaml +++ b/kubernetes/configmap-dashboard.yaml @@ -34,6 +34,7 @@ data: REACT_APP_GOOGLE_ANALITIC_PAGE_ID: '${REACT_APP_GOOGLE_ANALITIC_PAGE_ID}' REACT_APP_PUBLIC_RE_CAPTCHA_KEY: '${REACT_APP_PUBLIC_RE_CAPTCHA_KEY}' REACT_APP_EVM_ENDPOINT: '${REACT_APP_EVM_ENDPOINT}' + REACT_APP_EVM_BLOCK_EXPLORER_URL: '${REACT_APP_EVM_BLOCK_EXPLORER_URL}' --- apiVersion: v1 kind: ConfigMap From f3843a218bd2d8789e3557b92ba45a21b7090683 Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Fri, 18 Aug 2023 14:18:45 -0600 Subject: [PATCH 43/75] chore: add evm block explorer url --- .env.telos | 1 + .env.telostestnet | 1 + docker-compose.yaml | 1 + webapp/Dockerfile | 2 ++ 4 files changed, 5 insertions(+) diff --git a/.env.telos b/.env.telos index 6af5b1b5..5a642510 100644 --- a/.env.telos +++ b/.env.telos @@ -88,3 +88,4 @@ REACT_APP_GOOGLE_ANALITIC_PAGE_ID=G-E6Y0EC9FT8 REACT_APP_PUBLIC_RE_CAPTCHA_KEY=key REACT_APP_EOS_INCLUDE_TRANSACTION= REACT_APP_EVM_ENDPOINT='https://mainnet.telos.net/evm' +REACT_APP_EVM_BLOCK_EXPLORER_URL=https://www.teloscan.io/block/(block) \ No newline at end of file diff --git a/.env.telostestnet b/.env.telostestnet index 0ad66e03..c2018553 100644 --- a/.env.telostestnet +++ b/.env.telostestnet @@ -89,3 +89,4 @@ REACT_APP_GOOGLE_ANALITIC_PAGE_ID=G-E6Y0EC9FT8 REACT_APP_PUBLIC_RE_CAPTCHA_KEY=key REACT_APP_EOS_INCLUDE_TRANSACTION= REACT_APP_EVM_ENDPOINT=https://testnet.telos.net/evm +REACT_APP_EVM_BLOCK_EXPLORER_URL=https://testnet.teloscan.io/block/(block) diff --git a/docker-compose.yaml b/docker-compose.yaml index d0056ff7..a143acb5 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -137,5 +137,6 @@ services: REACT_APP_PUBLIC_RE_CAPTCHA_KEY: '${REACT_APP_PUBLIC_RE_CAPTCHA_KEY}' REACT_APP_SYNC_TOLERANCE_INTERVAL: '${REACT_APP_SYNC_TOLERANCE_INTERVAL}' REACT_APP_EVM_ENDPOINT: '${REACT_APP_EVM_ENDPOINT}' + REACT_APP_EVM_BLOCK_EXPLORER_URL: '${REACT_APP_EVM_BLOCK_EXPLORER_URL}' volumes: postgres_data: diff --git a/webapp/Dockerfile b/webapp/Dockerfile index 0f5fbcb3..f548cc41 100644 --- a/webapp/Dockerfile +++ b/webapp/Dockerfile @@ -30,6 +30,7 @@ ARG react_app_google_analitic_page_id ARG react_app_public_re_captcha_key ARG react_app_sync_tolerance_interval ARG react_app_evm_endpoint +ARG react_app_evm_block_explorer_url ENV WORK_DIR /usr/src/app ENV PATH $WORK_DIR/node_modules/.bin:$PATH @@ -64,6 +65,7 @@ ENV REACT_APP_GOOGLE_ANALITIC_PAGE_ID $react_app_google_analitic_page_id ENV REACT_APP_PUBLIC_RE_CAPTCHA_KEY $react_app_public_re_captcha_key ENV REACT_APP_SYNC_TOLERANCE_INTERVAL $react_app_sync_tolerance_interval ENV REACT_APP_EVM_ENDPOINT $react_app_evm_endpoint +ENV REACT_APP_EVM_BLOCK_EXPLORER_URL $react_app_evm_block_explorer_url RUN mkdir -p $WORK_DIR WORKDIR $WORK_DIR From 3786fe7983bb7e993d989f584c3c12004d43c97d Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Mon, 21 Aug 2023 10:56:13 -0600 Subject: [PATCH 44/75] feat(webapp): add EVM endpoints page and refactor health check components --- webapp/src/components/EndpointsTable/index.js | 29 +---- .../src/components/HealthCheck/LightIcon.js | 9 +- webapp/src/components/HealthCheck/styles.js | 4 +- .../src/components/NodeCard/EndpointsChips.js | 12 +- .../src/components/NonCompliantCard/index.js | 7 +- webapp/src/config/evm.config.js | 3 +- webapp/src/config/general.js | 6 + webapp/src/language/en.json | 10 ++ webapp/src/language/en.telos-testnet.json | 4 +- webapp/src/language/en.telos.json | 4 +- webapp/src/language/es.json | 10 +- webapp/src/language/es.telos-testnet.json | 3 +- webapp/src/language/es.telos.json | 3 +- webapp/src/routes/EVMEndpointsList/index.js | 88 ++++++++++++++ webapp/src/routes/EVMEndpointsList/styles.js | 36 ++++++ .../EVMEndpointsList/useRPCEndpointsState.js | 108 ++++++++++++++++++ webapp/src/routes/index.js | 11 +- .../src/utils/get-endpoint-health-status.js | 28 +++++ webapp/src/utils/index.js | 1 + 19 files changed, 328 insertions(+), 48 deletions(-) create mode 100644 webapp/src/routes/EVMEndpointsList/index.js create mode 100644 webapp/src/routes/EVMEndpointsList/styles.js create mode 100644 webapp/src/routes/EVMEndpointsList/useRPCEndpointsState.js create mode 100644 webapp/src/utils/get-endpoint-health-status.js diff --git a/webapp/src/components/EndpointsTable/index.js b/webapp/src/components/EndpointsTable/index.js index 073db483..1fa71123 100644 --- a/webapp/src/components/EndpointsTable/index.js +++ b/webapp/src/components/EndpointsTable/index.js @@ -18,7 +18,7 @@ import QueryStatsIcon from '@mui/icons-material/QueryStats' import HealthCheck from '../HealthCheck' import HealthCheckInfo from 'components/HealthCheck/HealthCheckInfo' -import { eosConfig } from '../../config' +import { getStatus } from 'utils' import styles from './styles' import Tooltip from '../Tooltip' @@ -41,33 +41,6 @@ const EndpointsTable = ({ producers }) => { setAnchorEl(null) } - const syncToleranceInterval = eosConfig.syncToleranceInterval - - const isSynchronized = endpoint => { - const diffBlockTimems = - new Date(endpoint.updated_at) - new Date(endpoint.head_block_time) - - return diffBlockTimems <= syncToleranceInterval - } - - const getStatus = endpoint => { - if (endpoint.response.status === undefined) return - - if (endpoint.response?.isWorking) { - return !endpoint.head_block_time || isSynchronized(endpoint) - ? 'greenLight' - : 'timerOff' - } - - switch (Math.floor(endpoint.response?.status / 100)) { - case 4: - case 5: - return 'yellowLight' - default: - return 'redLight' - } - } - const CellList = ({ producer, endpointType }) => { return ( diff --git a/webapp/src/components/HealthCheck/LightIcon.js b/webapp/src/components/HealthCheck/LightIcon.js index b3c6f014..ea7996d7 100644 --- a/webapp/src/components/HealthCheck/LightIcon.js +++ b/webapp/src/components/HealthCheck/LightIcon.js @@ -5,19 +5,22 @@ import DoneOutlinedIcon from '@mui/icons-material/DoneOutlined' import TimerOffOutlinedIcon from '@mui/icons-material/TimerOffOutlined' import ReportProblemOutlinedIcon from '@mui/icons-material/ReportProblemOutlined' +import { generalConfig } from '../../config' + import styles from './styles' const useStyles = makeStyles(styles) const LightIcon = ({ status }) => { const classes = useStyles() + const { healthLights } = generalConfig switch (status) { - case 'greenLight': + case healthLights.greenLight: return - case 'timerOff': + case healthLights.timerOff: return - case 'yellowLight': + case healthLights.yellowLight: return default: return diff --git a/webapp/src/components/HealthCheck/styles.js b/webapp/src/components/HealthCheck/styles.js index 1b0b2af9..d4ca30e8 100644 --- a/webapp/src/components/HealthCheck/styles.js +++ b/webapp/src/components/HealthCheck/styles.js @@ -24,8 +24,8 @@ export default (theme) => ({ marginBlock: '2px', }, helpIcon: { - width: '15px !important', - height: '15px !important', + width: '18px !important', + height: '18px !important', cursor: 'pointer', }, greenLight: { diff --git a/webapp/src/components/NodeCard/EndpointsChips.js b/webapp/src/components/NodeCard/EndpointsChips.js index 0cf7ff39..8c8e1cfd 100644 --- a/webapp/src/components/NodeCard/EndpointsChips.js +++ b/webapp/src/components/NodeCard/EndpointsChips.js @@ -6,6 +6,7 @@ import moment from 'moment' import ChipList from '../ChipList' import HealthCheck from '../HealthCheck' +import { generalConfig } from '../../config' import styles from './styles' @@ -14,25 +15,26 @@ const useStyles = makeStyles(styles) const EndpointsChips = ({ node }) => { const classes = useStyles() const { t } = useTranslation('nodeCardComponent') + const { healthLights } = generalConfig if (!node?.endpoints?.length) return <> const getHealthStatus = (totalEndpoints, workingEndpoints) => { switch (workingEndpoints) { case totalEndpoints: - return 'greenLight' + return healthLights.greenLight case 0: - return 'redLight' + return healthLights.redLight default: - return 'yellowLight' + return healthLights.yellowLight } } const getStatusMessage = (healthStatus, failingEndpoints) => { switch (healthStatus) { - case 'greenLight': + case healthLights.greenLight: return t('allWorking') - case 'redLight': + case healthLights.redLight: return t('noneWorking') default: const beginning = diff --git a/webapp/src/components/NonCompliantCard/index.js b/webapp/src/components/NonCompliantCard/index.js index 87b99665..5eabd27e 100644 --- a/webapp/src/components/NonCompliantCard/index.js +++ b/webapp/src/components/NonCompliantCard/index.js @@ -7,7 +7,7 @@ import Link from '@mui/material/Link' import Typography from '@mui/material/Typography' import moment from 'moment' -import { eosConfig } from '../../config' +import { eosConfig, generalConfig } from '../../config' import { formatWithThousandSeparator } from '../../utils' import HealthCheck from '../HealthCheck' import HealthCheckInfo from 'components/HealthCheck/HealthCheckInfo' @@ -21,9 +21,10 @@ const useStyles = makeStyles(styles) const NonCompliantCard = ({ producer, stats }) => { const classes = useStyles() const { t } = useTranslation('producerCardComponent') + const { healthLights } = generalConfig - const getHealthStatus = (healthCheck) => { - return healthCheck.valid ? 'greenLight' : 'redLight' + const getHealthStatus = healthCheck => { + return healthCheck.valid ? healthLights.greenLight : healthLights.redLight } const RowInfo = ({ title, value }) => { diff --git a/webapp/src/config/evm.config.js b/webapp/src/config/evm.config.js index c5a0f94b..71e78e05 100644 --- a/webapp/src/config/evm.config.js +++ b/webapp/src/config/evm.config.js @@ -19,4 +19,5 @@ export const avgBlockTime = _avgBlockTime export const maxTPSDataSize = 30 / _avgBlockTime export const account = 'eosio.evm' export const endpoint = process.env.REACT_APP_EVM_ENDPOINT -export const blockExplorerUrl = process.env.REACT_APP_EVM_BLOCK_EXPLORER_URL \ No newline at end of file +export const blockExplorerUrl = process.env.REACT_APP_EVM_BLOCK_EXPLORER_URL +export const endpoints = JSON.parse(process.env.REACT_APP_EVM_ENDPOINTS || '[]') || [] diff --git a/webapp/src/config/general.js b/webapp/src/config/general.js index fbaba1e2..294cfe5b 100644 --- a/webapp/src/config/general.js +++ b/webapp/src/config/general.js @@ -22,3 +22,9 @@ export const historyEnabled = export const googleAnaliticPageId = process.env.REACT_APP_GOOGLE_ANALITIC_PAGE_ID export const highchartsMapURL = 'https://code.highcharts.com/mapdata/countries/' +export const healthLights = Object.freeze({ + greenLight: 'greenLight', + timerOff: 'timerOff', + yellowLight: 'yellowLight', + redLight: 'redLight', +}) diff --git a/webapp/src/language/en.json b/webapp/src/language/en.json index 95fa938b..d23bbfe3 100644 --- a/webapp/src/language/en.json +++ b/webapp/src/language/en.json @@ -96,6 +96,9 @@ "/evm>title": "EVM Dashboard - EOSIO + Antelope Network Dashboard", "/evm>sidebar": "EVM Dashboard", "/evm>heading": "EVM Dashboard", + "/evm-rpc-endpoints>title": "EVM RPC Endpoints - EOSIO + Antelope Network Dashboard", + "/evm-rpc-endpoints>sidebar": "EVM RPC Endpoints", + "/evm-rpc-endpoints>heading": "EVM RPC Endpoints", "/endpoints>sidebar": "API Endpoints", "/endpoints>title": "API Endpoints - EOSIO + Antelope Network Dashboard", "/endpoints>heading": "API Endpoints", @@ -443,5 +446,12 @@ "totalTxs": "Total EVM transactions", "transactions": "EVM transactions", "gasUsed": "Gas Used" + }, + "evmEndpointsRoute": { + "title": "EVM RPC endpoints list", + "rpcEndpoint": "RPC Endpoint", + "latency": "Latency", + "lastBlock": "Last block", + "rerun": "Re-run health checks" } } diff --git a/webapp/src/language/en.telos-testnet.json b/webapp/src/language/en.telos-testnet.json index 13f474b7..1b6b15ba 100644 --- a/webapp/src/language/en.telos-testnet.json +++ b/webapp/src/language/en.telos-testnet.json @@ -31,6 +31,8 @@ "/accounts>moreDescription": "This tool helps find information about accounts and interact with contracts on the network. Enter an account name and obtain account information, smart contract actions, and table data.", "/block-distribution>moreDescription": "A visualization of the distribution of blocks produced by the nodes in the network.", "/missed-blocks>moreDescription": "A list of scheduled, produced, and missed blocks by each account in the network.", - "/evm>moreDescription": "Monitor EVM statistics, such as transaction amount history, gas price and total wallets created." + "/evm>heading": "Telos EVM Dashboard", + "/evm>moreDescription": "Monitor Telos EVM statistics, such as transaction amount history, gas price and total wallets created.", + "/evm-rpc-endpoints>moreDescription": "A list of Telos EVM endpoints, with their health status and latency in milliseconds." } } diff --git a/webapp/src/language/en.telos.json b/webapp/src/language/en.telos.json index a660afcd..f4bddb41 100644 --- a/webapp/src/language/en.telos.json +++ b/webapp/src/language/en.telos.json @@ -31,6 +31,8 @@ "/accounts>moreDescription": "This tool helps find information about accounts and interact with contracts on the network. Enter an account name and obtain account information, smart contract actions, and table data.", "/block-distribution>moreDescription": "A visualization of the distribution of blocks produced by the nodes in the network.", "/missed-blocks>moreDescription": "A list of scheduled, produced, and missed blocks by each account in the network.", - "/evm>moreDescription": "Monitor EVM statistics, such as transaction amount history, gas price and total wallets created." + "/evm>heading": "Telos EVM Dashboard", + "/evm>moreDescription": "Monitor Telos EVM statistics, such as transaction amount history, gas price and total wallets created.", + "/evm-rpc-endpoints>moreDescription": "A list of Telos EVM endpoints, with their health status and latency in milliseconds." } } diff --git a/webapp/src/language/es.json b/webapp/src/language/es.json index 64199f51..7bc36aa1 100644 --- a/webapp/src/language/es.json +++ b/webapp/src/language/es.json @@ -412,7 +412,8 @@ "Connection error": "Error de conexión", "Connection established": "Conexión establecida", "Success": "Éxitosa", - "Failed": "Fallida" + "Failed": "Fallida", + "Network Error": "Error de red" }, "nodeSearchComponent": { "title": "Buscar Nodo", @@ -464,5 +465,12 @@ "totalTxs": "Total de transacciones EVM", "transactions": "Transacciones EVM", "gasUsed": "Gas Usado" + }, + "evmEndpointsRoute": { + "title": "Lista de puntos finales RPC de EVM", + "rpcEndpoint": "Punto final RPC", + "latency": "Latencia", + "lastBlock": "Último bloque", + "rerun": "Reejecutar las pruebas" } } diff --git a/webapp/src/language/es.telos-testnet.json b/webapp/src/language/es.telos-testnet.json index c8bd1c74..8e707870 100644 --- a/webapp/src/language/es.telos-testnet.json +++ b/webapp/src/language/es.telos-testnet.json @@ -29,6 +29,7 @@ "/accounts>moreDescription": "Esta herramienta le ayuda a buscar información sobre cuentas y contratos de la red. Escriba el nombre de un contrato o cuenta en el espacio provisto para comenzar a buscar. Obtendrá los datos de las acciones del contrato, tablas de contrato, alcance, límites superior e inferior y límites.", "/block-distribution>moreDescription": "Una visualización de la distribución de bloques producida por los nodos de la red.", "/missed-blocks>moreDescription": "Una lista de bloques programados, producidos y perdidos por cada cuenta en la red.", - "/evm>moreDescription": "Supervise las estadísticas del EVM, como el histórico de la cantidad de transacciones, el precio del gas y las wallets creadas totales." + "/evm>moreDescription": "Supervise las estadísticas del Telos EVM, como el histórico de la cantidad de transacciones, el precio del gas y las wallets creadas totales.", + "/evm-rpc-endpoints>moreDescription": "Una lista de puntos finales de Telos EVM, con sus estado de salud y latencia en milisegundos." } } diff --git a/webapp/src/language/es.telos.json b/webapp/src/language/es.telos.json index 4f40e0fc..fb302043 100644 --- a/webapp/src/language/es.telos.json +++ b/webapp/src/language/es.telos.json @@ -29,6 +29,7 @@ "/accounts>moreDescription": "Esta herramienta le ayuda a buscar información sobre cuentas y contratos de la red. Escriba el nombre de un contrato o cuenta en el espacio provisto para comenzar a buscar. Obtendrá los datos de las acciones del contrato, tablas de contrato, alcance, límites superior e inferior y límites.", "/block-distribution>moreDescription": "Una visualización de la distribución de bloques producida por los nodos de la red.", "/missed-blocks>moreDescription": "Una lista de bloques programados, producidos y perdidos por cada cuenta en la red.", - "/evm>moreDescription": "Supervise las estadísticas del EVM, como el histórico de la cantidad de transacciones, el precio del gas y las wallets creadas totales." + "/evm>moreDescription": "Supervise las estadísticas del Telos EVM, como el histórico de la cantidad de transacciones, el precio del gas y las wallets creadas totales.", + "/evm-rpc-endpoints>moreDescription": "Una lista de puntos finales de Telos EVM, con sus estado de salud y latencia en milisegundos." } } diff --git a/webapp/src/routes/EVMEndpointsList/index.js b/webapp/src/routes/EVMEndpointsList/index.js new file mode 100644 index 00000000..4a75775d --- /dev/null +++ b/webapp/src/routes/EVMEndpointsList/index.js @@ -0,0 +1,88 @@ +import React from 'react' +import { useTranslation } from 'react-i18next' +import { makeStyles } from '@mui/styles' +import Button from '@mui/material/Button' +import Card from '@mui/material/Card' +import CardContent from '@mui/material/CardContent' +import Table from '@mui/material/Table' +import TableBody from '@mui/material/TableBody' +import TableCell from '@mui/material/TableCell' +import TableContainer from '@mui/material/TableContainer' +import TableHead from '@mui/material/TableHead' +import TableRow from '@mui/material/TableRow' +import Typography from '@mui/material/Typography' +import AutorenewOutlinedIcon from '@mui/icons-material/AutorenewOutlined' + +import HealthCheck from 'components/HealthCheck' +import HealthCheckInfo from 'components/HealthCheck/HealthCheckInfo' +import HealthInfoModal from '../../components/HealthCheck/InfoModal' + +import styles from './styles' +import useRPCEndpointsState from './useRPCEndpointsState' +import { getStatus } from 'utils' + +const useStyles = makeStyles(styles) + +const EVMEndpointsList = () => { + const classes = useStyles() + const { t } = useTranslation('evmEndpointsRoute') + + const [{ endpoints }, { runHealthCheck }] = useRPCEndpointsState() + + return ( + + +
+ + {t('title')} + + +
+
+ +
+
+ + + + + {t('rpcEndpoint')} + {t('lastBlock')} + {t('latency')} + + + + {endpoints?.map((endpoint, index) => ( + + +
+ {endpoint.url} + + + +
+
+ {endpoint.height || 'N/A'} + + {endpoint.latency ? `${endpoint.latency} ms` : 'N/A'} + +
+ ))} +
+
+
+
+
+
+ ) +} + +export default EVMEndpointsList diff --git a/webapp/src/routes/EVMEndpointsList/styles.js b/webapp/src/routes/EVMEndpointsList/styles.js new file mode 100644 index 00000000..aa5b25f6 --- /dev/null +++ b/webapp/src/routes/EVMEndpointsList/styles.js @@ -0,0 +1,36 @@ +export default (theme) => ({ + cardShadow: { + boxShadow: '0px 1px 5px rgba(0, 0, 0, 0.15) !important', + }, + healthContainer: { + display: 'flex', + maxWidth: '300px', + justifyContent: 'space-between', + }, + titleContainer: { + display: 'flex', + gap: theme.spacing(4), + alignItems: 'center', + }, + buttonContainer: { + padding: '0 0 0 25%', + marginTop: theme.spacing(4), + [theme.breakpoints.down('md')]: { + padding: 0, + }, + }, + tableContainer: { + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + '& .MuiTableContainer-root': { + width: '80%', + [theme.breakpoints.down('md')]: { + width: '100%', + }, + [theme.breakpoints.up('lg')]: { + width: '50%', + } + }, + }, +}) diff --git a/webapp/src/routes/EVMEndpointsList/useRPCEndpointsState.js b/webapp/src/routes/EVMEndpointsList/useRPCEndpointsState.js new file mode 100644 index 00000000..84e01001 --- /dev/null +++ b/webapp/src/routes/EVMEndpointsList/useRPCEndpointsState.js @@ -0,0 +1,108 @@ +import { useCallback, useEffect, useState } from 'react' +import axios from 'axios' + +import { evmConfig } from '../../config' + +const useRPCEndpointsState = () => { + const [endpoints, setEndpoints] = useState(evmConfig.endpoints.map(url => ({url, response: {}}))) + + const customAxios = axios.create() + + customAxios.interceptors.request.use( + config => { + config.startTime = new Date() + + return config + }, + error => Promise.reject(error), + ) + + customAxios.interceptors.response.use( + response => { + response.latency = new Date() - response.config?.startTime + + return response + }, + error => Promise.reject(error), + ) + + const getEndpointHealthCheck = async endpointUrl => { + try { + const { + data: { result: height }, + } = await customAxios.post(endpointUrl, { + method: 'eth_blockNumber', + params: [], + id: 1, + jsonrpc: '2.0', + }) + + const { data, latency, status, statusText } = await customAxios.post( + endpointUrl, + { + method: 'eth_getBlockByNumber', + params: [height.toString(), false], + id: 1, + jsonrpc: '2.0', + }, + ) + + return { + url: endpointUrl, + latency, + height: parseInt(height), + updated_at: new Date(), + head_block_time: new Date(parseInt(data?.result?.timestamp) * 1000), + response: { status, statusText, isWorking: status === 200 }, + } + } catch (error) { + return { + url: endpointUrl, + updated_at: new Date(), + response: { + statusText: error?.message, + status: null, + isWorking: false, + }, + } + } + } + + const runHealthCheck = useCallback(() => { + setEndpoints(prev => prev.map(endpoint => ({ url: endpoint.url, response: {} }))) + + const rpcList = JSON.parse(JSON.stringify(endpoints)) + + rpcList.forEach(async ({ url }, index) => { + const endpoint = await getEndpointHealthCheck(url) + + setEndpoints(prev => { + const newEndpoints = [ + ...prev.slice(0, index), + endpoint, + ...prev.slice(index + 1), + ] + + if (newEndpoints.every(endpoint => !!endpoint.response.statusText)) { + newEndpoints.sort((e1, e2) => + e1?.height === e2?.height + ? e1?.latency - e2?.latency + : e2?.height - e1?.height, + ) + } + + return newEndpoints + }) + }) + // eslint-disable-next-line + }, [endpoints]) + + useEffect(() => { + runHealthCheck() + // eslint-disable-next-line + }, []) + + return [{ endpoints }, { runHealthCheck }] +} + +export default useRPCEndpointsState diff --git a/webapp/src/routes/index.js b/webapp/src/routes/index.js index 8912dbbc..9349814a 100644 --- a/webapp/src/routes/index.js +++ b/webapp/src/routes/index.js @@ -15,6 +15,7 @@ import { } from 'react-feather' import QueryStatsIcon from '@mui/icons-material/QueryStats' import StackedLineChartIcon from '@mui/icons-material/StackedLineChart' +import ListAltOutlined from '@mui/icons-material/ListAltOutlined'; import { eosConfig, generalConfig } from '../config' import { @@ -27,7 +28,6 @@ import { TopologySvg, RewardsSvg, } from '../components/Icons' -import StressTestDashboard from './StressTestDashboard' const Home = lazy(() => import('./Home')) const CPUBenchmark = lazy(() => import('./CPUBenchmark')) @@ -47,7 +47,9 @@ const BlockDistribution = lazy(() => import('./BlockDistribution')) const MissedBlocks = lazy(() => import('./MissedBlocks')) const EndpointsList = lazy(() => import('./EndpointsList')) const NonCompliantBPs = lazy(() => import('./NonCompliantBPs')) +const StressTestDashboard = lazy(() => import('./StressTestDashboard')) const EVMDashboard = lazy(() => import('./EVMDashboard')) +const EVMEndpointsList = lazy(() => import('./EVMEndpointsList')) const LacchainNetwork = lazy(() => import('./Lacchain/LacchainNetwork')) const LacchainManagement = lazy(() => import('./Lacchain/LacchainManagement')) const LacchainNodeConfig = lazy(() => import('./Lacchain/LacchainNodeConfig')) @@ -153,6 +155,13 @@ const defaultRoutes = [ path: '/evm', exact: true, }, + { + name: 'evm-rpc-endpoints', + icon: , + component: EVMEndpointsList, + path: '/evm-rpc-endpoints', + exact: true, + }, { header: 'tools', name: 'accounts', diff --git a/webapp/src/utils/get-endpoint-health-status.js b/webapp/src/utils/get-endpoint-health-status.js new file mode 100644 index 00000000..7c6571c3 --- /dev/null +++ b/webapp/src/utils/get-endpoint-health-status.js @@ -0,0 +1,28 @@ +import { eosConfig, generalConfig } from '../config' + +const { healthLights } = generalConfig + +const isSynchronized = endpoint => { + const diffBlockTimems = + new Date(endpoint.updated_at) - new Date(endpoint.head_block_time) + + return diffBlockTimems <= eosConfig.syncToleranceInterval +} + +export const getStatus = endpoint => { + if (endpoint.response.status === undefined) return + + if (endpoint.response?.isWorking) { + return !endpoint.head_block_time || isSynchronized(endpoint) + ? healthLights.greenLight + : healthLights.timerOff + } + + switch (Math.floor(endpoint.response?.status / 100)) { + case 4: + case 5: + return healthLights.yellowLight + default: + return healthLights.redLight + } +} diff --git a/webapp/src/utils/index.js b/webapp/src/utils/index.js index 62309742..2041205c 100644 --- a/webapp/src/utils/index.js +++ b/webapp/src/utils/index.js @@ -8,3 +8,4 @@ export * from './get-transaction-url' export * from './validate-image' export * from './validate-url' export * from './get-evmblocknum-url' +export * from './get-endpoint-health-status' From 2fc515fd2ed4f65cbda31a2b0b5ca6fc2817d436 Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Mon, 21 Aug 2023 10:57:58 -0600 Subject: [PATCH 45/75] chore(webapp): add env variable with the EVM endpoints --- .env.telos | 5 +++-- .env.telostestnet | 3 ++- docker-compose.yaml | 1 + webapp/Dockerfile | 2 ++ 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/.env.telos b/.env.telos index 5a642510..96abbf9e 100644 --- a/.env.telos +++ b/.env.telos @@ -81,11 +81,12 @@ REACT_APP_EOS_BP_JSON_ON_CHAIN_SCOPE=producerjson REACT_APP_SYNC_TOLERANCE_INTERVAL=180000 REACT_APP_TOKEN_SYMBOL=TLOS REACT_APP_NETWORK_URL=[{"label":"EOS","value":"https://eos.antelope.tools","mainnet":true,"pair":"eos","icon":"eos","order":5},{"label":"Proton","value":"https://proton.antelope.tools","mainnet":true,"pair":"proton","icon":"proton","order":3},{"label":"WAX","value":"https://wax.antelope.tools","mainnet":true,"pair":"wax","icon":"wax","order":4},{"label":"Telos","value":"https://telos.antelope.tools","mainnet":true,"pair":"telos","icon":"telos","order":1},{"label":"Libre","value":"https://libre.antelope.tools","mainnet":true,"pair":"libre","icon":"libre","order":2},{"label":"LACChain EOSIO","value":"https://lacchain.antelope.tools","mainnet":true,"pair":null,"icon":"lacchain","order":6},{"label":"Jungle4 Testnet","value":"https://jungle.antelope.tools","mainnet":false,"pair":"eos","icon":"jungle","order":5},{"label":"Proton Testnet","value":"https://proton-testnet.antelope.tools","mainnet":false,"pair":"proton","icon":"proton","order":3},{"label":"WAX Testnet","value":"https://wax-testnet.antelope.tools","mainnet":false,"pair":"wax","icon":"wax","order":4},{"label":"Telos Testnet","value":"https://telos-testnet.antelope.tools","mainnet":false,"pair":"telos","icon":"telos","order":1},{"label":"Libre Testnet","value":"https://libre-testnet.antelope.tools","mainnet":false,"pair":"libre","icon":"libre","order":2},{"label":"Ultra Testnet","value":"https://ultra-testnet.antelope.tools","mainnet":false,"pair":"ultra","icon":"ultra","order":6}] -REACT_APP_DISABLED_MENU_ITEMS=["/missed-blocks", "/cpu-benchmark","/block-distribution"] +REACT_APP_DISABLED_MENU_ITEMS=["/missed-blocks", "/cpu-benchmark","/block-distribution","stress-test"] REACT_APP_BLOCK_EXPLORER_URL=https://explorer.telos.net/transaction/(transaction) REACT_APP_STATE_HISTORY_ENABLED=false REACT_APP_GOOGLE_ANALITIC_PAGE_ID=G-E6Y0EC9FT8 REACT_APP_PUBLIC_RE_CAPTCHA_KEY=key REACT_APP_EOS_INCLUDE_TRANSACTION= REACT_APP_EVM_ENDPOINT='https://mainnet.telos.net/evm' -REACT_APP_EVM_BLOCK_EXPLORER_URL=https://www.teloscan.io/block/(block) \ No newline at end of file +REACT_APP_EVM_BLOCK_EXPLORER_URL=https://www.teloscan.io/block/(block) +REACT_APP_EVM_ENDPOINTS=["https://mainnet.telos.net/evm","https://rpc1.eu.telos.net/evm","https://rpc1.us.telos.net/evm","https://rpc2.us.telos.net/evm","https://api.kainosbp.com/evm","https://rpc2.eu.telos.net/evm","https://evm.teloskorea.com/evm","https://rpc2.teloskorea.com/evm","https://rpc01.us.telosunlimited.io/evm"] diff --git a/.env.telostestnet b/.env.telostestnet index c2018553..1cf6d3f1 100644 --- a/.env.telostestnet +++ b/.env.telostestnet @@ -82,7 +82,7 @@ REACT_APP_EOS_BP_JSON_ON_CHAIN_SCOPE=producerjson REACT_APP_SYNC_TOLERANCE_INTERVAL=180000 REACT_APP_TOKEN_SYMBOL=TLOS REACT_APP_NETWORK_URL=[{"label":"EOS","value":"https://eos.antelope.tools","mainnet":true,"pair":"eos","icon":"eos","order":5},{"label":"Proton","value":"https://proton.antelope.tools","mainnet":true,"pair":"proton","icon":"proton","order":3},{"label":"WAX","value":"https://wax.antelope.tools","mainnet":true,"pair":"wax","icon":"wax","order":4},{"label":"Telos","value":"https://telos.antelope.tools","mainnet":true,"pair":"telos","icon":"telos","order":1},{"label":"Libre","value":"https://libre.antelope.tools","mainnet":true,"pair":"libre","icon":"libre","order":2},{"label":"LACChain EOSIO","value":"https://lacchain.antelope.tools","mainnet":true,"pair":null,"icon":"lacchain","order":6},{"label":"Jungle4 Testnet","value":"https://jungle.antelope.tools","mainnet":false,"pair":"eos","icon":"jungle","order":5},{"label":"Proton Testnet","value":"https://proton-testnet.antelope.tools","mainnet":false,"pair":"proton","icon":"proton","order":3},{"label":"WAX Testnet","value":"https://wax-testnet.antelope.tools","mainnet":false,"pair":"wax","icon":"wax","order":4},{"label":"Telos Testnet","value":"https://telos-testnet.antelope.tools","mainnet":false,"pair":"telos","icon":"telos","order":1},{"label":"Libre Testnet","value":"https://libre-testnet.antelope.tools","mainnet":false,"pair":"libre","icon":"libre","order":2},{"label":"Ultra Testnet","value":"https://ultra-testnet.antelope.tools","mainnet":false,"pair":"ultra","icon":"ultra","order":6}] -REACT_APP_DISABLED_MENU_ITEMS=["/missed-blocks", "/cpu-benchmark","/block-distribution"] +REACT_APP_DISABLED_MENU_ITEMS=["/missed-blocks", "/cpu-benchmark","/block-distribution","/stress-test"] REACT_APP_BLOCK_EXPLORER_URL=https://explorer-test.telos.net/transaction/(transaction) REACT_APP_STATE_HISTORY_ENABLED=false REACT_APP_GOOGLE_ANALITIC_PAGE_ID=G-E6Y0EC9FT8 @@ -90,3 +90,4 @@ REACT_APP_PUBLIC_RE_CAPTCHA_KEY=key REACT_APP_EOS_INCLUDE_TRANSACTION= REACT_APP_EVM_ENDPOINT=https://testnet.telos.net/evm REACT_APP_EVM_BLOCK_EXPLORER_URL=https://testnet.teloscan.io/block/(block) +REACT_APP_EVM_ENDPOINTS=["https://testnet.telos.net/evm"] \ No newline at end of file diff --git a/docker-compose.yaml b/docker-compose.yaml index a143acb5..a373ea82 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -138,5 +138,6 @@ services: REACT_APP_SYNC_TOLERANCE_INTERVAL: '${REACT_APP_SYNC_TOLERANCE_INTERVAL}' REACT_APP_EVM_ENDPOINT: '${REACT_APP_EVM_ENDPOINT}' REACT_APP_EVM_BLOCK_EXPLORER_URL: '${REACT_APP_EVM_BLOCK_EXPLORER_URL}' + REACT_APP_EVM_ENDPOINTS: '${REACT_APP_EVM_ENDPOINTS}' volumes: postgres_data: diff --git a/webapp/Dockerfile b/webapp/Dockerfile index f548cc41..2cd29ede 100644 --- a/webapp/Dockerfile +++ b/webapp/Dockerfile @@ -31,6 +31,7 @@ ARG react_app_public_re_captcha_key ARG react_app_sync_tolerance_interval ARG react_app_evm_endpoint ARG react_app_evm_block_explorer_url +ARG react_app_evm_endpoints ENV WORK_DIR /usr/src/app ENV PATH $WORK_DIR/node_modules/.bin:$PATH @@ -66,6 +67,7 @@ ENV REACT_APP_PUBLIC_RE_CAPTCHA_KEY $react_app_public_re_captcha_key ENV REACT_APP_SYNC_TOLERANCE_INTERVAL $react_app_sync_tolerance_interval ENV REACT_APP_EVM_ENDPOINT $react_app_evm_endpoint ENV REACT_APP_EVM_BLOCK_EXPLORER_URL $react_app_evm_block_explorer_url +ENV REACT_APP_EVM_ENDPOINTS $react_app_evm_endpoints RUN mkdir -p $WORK_DIR WORKDIR $WORK_DIR From 767c80eec910b47ef62ac552c1286c075313ef13 Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Mon, 21 Aug 2023 10:58:50 -0600 Subject: [PATCH 46/75] chore(workflows): disable rpc endpoints page and add EVM endpoints --- .github/workflows/deploy-jungle-testnet.yaml | 2 +- .github/workflows/deploy-lacchain.yaml | 2 +- .github/workflows/deploy-libre-testnet.yaml | 2 +- .github/workflows/deploy-libre.yaml | 2 +- .github/workflows/deploy-mainnet.yaml | 2 +- .github/workflows/deploy-proton-testnet.yaml | 2 +- .github/workflows/deploy-proton.yaml | 2 +- .github/workflows/deploy-telos-testnet.yaml | 1 + .github/workflows/deploy-telos.yaml | 1 + .github/workflows/deploy-ultra-testnet.yaml | 2 +- .github/workflows/deploy-wax-testnet.yaml | 2 +- .github/workflows/deploy-wax.yaml | 2 +- kubernetes/configmap-dashboard.yaml | 1 + 13 files changed, 13 insertions(+), 10 deletions(-) diff --git a/.github/workflows/deploy-jungle-testnet.yaml b/.github/workflows/deploy-jungle-testnet.yaml index 795c18ba..12217ce8 100644 --- a/.github/workflows/deploy-jungle-testnet.yaml +++ b/.github/workflows/deploy-jungle-testnet.yaml @@ -52,7 +52,7 @@ jobs: REACT_APP_SYNC_TOLERANCE_INTERVAL: 180000 REACT_APP_TOKEN_SYMBOL: 'EOS' REACT_APP_NETWORK_URL: '[{"label":"EOS","value":"https://eos.antelope.tools","mainnet":true,"pair":"eos","icon":"eos","order":5},{"label":"Proton","value":"https://proton.antelope.tools","mainnet":true,"pair":"proton","icon":"proton","order":3},{"label":"WAX","value":"https://wax.antelope.tools","mainnet":true,"pair":"wax","icon":"wax","order":4},{"label":"Telos","value":"https://telos.antelope.tools","mainnet":true,"pair":"telos","icon":"telos","order":1},{"label":"Libre","value":"https://libre.antelope.tools","mainnet":true,"pair":"libre","icon":"libre","order":2},{"label":"LACChain EOSIO","value":"https://lacchain.antelope.tools","mainnet":true,"pair":null,"icon":"lacchain","order":6},{"label":"Jungle4 Testnet","value":"https://jungle.antelope.tools","mainnet":false,"pair":"eos","icon":"jungle","order":5},{"label":"Proton Testnet","value":"https://proton-testnet.antelope.tools","mainnet":false,"pair":"proton","icon":"proton","order":3},{"label":"WAX Testnet","value":"https://wax-testnet.antelope.tools","mainnet":false,"pair":"wax","icon":"wax","order":4},{"label":"Telos Testnet","value":"https://telos-testnet.antelope.tools","mainnet":false,"pair":"telos","icon":"telos","order":1},{"label":"Libre Testnet","value":"https://libre-testnet.antelope.tools","mainnet":false,"pair":"libre","icon":"libre","order":2},{"label":"Ultra Testnet","value":"https://ultra-testnet.antelope.tools","mainnet":false,"pair":"ultra","icon":"ultra","order":6}]' - REACT_APP_DISABLED_MENU_ITEMS: '["/missed-blocks","/block-distribution","/cpu-benchmark","/stress-test","/evm"]' + REACT_APP_DISABLED_MENU_ITEMS: '["/missed-blocks","/block-distribution","/cpu-benchmark","/stress-test","/evm","/evm-rpc-endpoints"]' REACT_APP_BLOCK_EXPLORER_URL: 'https://jungle4.eosq.eosnation.io/tx/(transaction)' REACT_APP_STATE_HISTORY_ENABLED: 'false' REACT_APP_GOOGLE_ANALITIC_PAGE_ID: 'G-E6Y0EC9FT8' diff --git a/.github/workflows/deploy-lacchain.yaml b/.github/workflows/deploy-lacchain.yaml index eccde74a..f11576d4 100644 --- a/.github/workflows/deploy-lacchain.yaml +++ b/.github/workflows/deploy-lacchain.yaml @@ -54,7 +54,7 @@ jobs: REACT_APP_SYNC_TOLERANCE_INTERVAL: 180000 REACT_APP_TOKEN_SYMBOL: '' REACT_APP_NETWORK_URL: '[{"label":"EOS","value":"https://eos.antelope.tools","mainnet":true,"pair":"eos","icon":"eos","order":5},{"label":"Proton","value":"https://proton.antelope.tools","mainnet":true,"pair":"proton","icon":"proton","order":3},{"label":"WAX","value":"https://wax.antelope.tools","mainnet":true,"pair":"wax","icon":"wax","order":4},{"label":"Telos","value":"https://telos.antelope.tools","mainnet":true,"pair":"telos","icon":"telos","order":1},{"label":"Libre","value":"https://libre.antelope.tools","mainnet":true,"pair":"libre","icon":"libre","order":2},{"label":"LACChain EOSIO","value":"https://lacchain.antelope.tools","mainnet":true,"pair":null,"icon":"lacchain","order":6},{"label":"Jungle4 Testnet","value":"https://jungle.antelope.tools","mainnet":false,"pair":"eos","icon":"jungle","order":5},{"label":"Proton Testnet","value":"https://proton-testnet.antelope.tools","mainnet":false,"pair":"proton","icon":"proton","order":3},{"label":"WAX Testnet","value":"https://wax-testnet.antelope.tools","mainnet":false,"pair":"wax","icon":"wax","order":4},{"label":"Telos Testnet","value":"https://telos-testnet.antelope.tools","mainnet":false,"pair":"telos","icon":"telos","order":1},{"label":"Libre Testnet","value":"https://libre-testnet.antelope.tools","mainnet":false,"pair":"libre","icon":"libre","order":2},{"label":"Ultra Testnet","value":"https://ultra-testnet.antelope.tools","mainnet":false,"pair":"ultra","icon":"ultra","order":6}]' - REACT_APP_DISABLED_MENU_ITEMS: '["/undiscoverable-bps","/stress-test","/evm"]' + REACT_APP_DISABLED_MENU_ITEMS: '["/undiscoverable-bps","/stress-test","/evm","/evm-rpc-endpoints"]' REACT_APP_BLOCK_EXPLORER_URL: 'https://eosio-explorer.lacchain.net/transaction/(transaction)' REACT_APP_STATE_HISTORY_ENABLED: 'true' REACT_APP_GOOGLE_ANALITIC_PAGE_ID: 'G-E6Y0EC9FT8' diff --git a/.github/workflows/deploy-libre-testnet.yaml b/.github/workflows/deploy-libre-testnet.yaml index 0daebd0a..b125167b 100644 --- a/.github/workflows/deploy-libre-testnet.yaml +++ b/.github/workflows/deploy-libre-testnet.yaml @@ -56,7 +56,7 @@ jobs: REACT_APP_SYNC_TOLERANCE_INTERVAL: 180000 REACT_APP_TOKEN_SYMBOL: 'LIBRE' REACT_APP_NETWORK_URL: '[{"label":"EOS","value":"https://eos.antelope.tools","mainnet":true,"pair":"eos","icon":"eos","order":5},{"label":"Proton","value":"https://proton.antelope.tools","mainnet":true,"pair":"proton","icon":"proton","order":3},{"label":"WAX","value":"https://wax.antelope.tools","mainnet":true,"pair":"wax","icon":"wax","order":4},{"label":"Telos","value":"https://telos.antelope.tools","mainnet":true,"pair":"telos","icon":"telos","order":1},{"label":"Libre","value":"https://libre.antelope.tools","mainnet":true,"pair":"libre","icon":"libre","order":2},{"label":"LACChain EOSIO","value":"https://lacchain.antelope.tools","mainnet":true,"pair":null,"icon":"lacchain","order":6},{"label":"Jungle4 Testnet","value":"https://jungle.antelope.tools","mainnet":false,"pair":"eos","icon":"jungle","order":5},{"label":"Proton Testnet","value":"https://proton-testnet.antelope.tools","mainnet":false,"pair":"proton","icon":"proton","order":3},{"label":"WAX Testnet","value":"https://wax-testnet.antelope.tools","mainnet":false,"pair":"wax","icon":"wax","order":4},{"label":"Telos Testnet","value":"https://telos-testnet.antelope.tools","mainnet":false,"pair":"telos","icon":"telos","order":1},{"label":"Libre Testnet","value":"https://libre-testnet.antelope.tools","mainnet":false,"pair":"libre","icon":"libre","order":2},{"label":"Ultra Testnet","value":"https://ultra-testnet.antelope.tools","mainnet":false,"pair":"ultra","icon":"ultra","order":6}]' - REACT_APP_DISABLED_MENU_ITEMS: '["/evm"]' + REACT_APP_DISABLED_MENU_ITEMS: '["/evm","/evm-rpc-endpoints"]' REACT_APP_BLOCK_EXPLORER_URL: 'https://testnet.libre.org/v2/explore/transaction/(transaction)' REACT_APP_STATE_HISTORY_ENABLED: 'true' REACT_APP_GOOGLE_ANALITIC_PAGE_ID: 'G-E6Y0EC9FT8' diff --git a/.github/workflows/deploy-libre.yaml b/.github/workflows/deploy-libre.yaml index bbc1b706..06e2207b 100644 --- a/.github/workflows/deploy-libre.yaml +++ b/.github/workflows/deploy-libre.yaml @@ -56,7 +56,7 @@ jobs: REACT_APP_SYNC_TOLERANCE_INTERVAL: 180000 REACT_APP_TOKEN_SYMBOL: 'LIBRE' REACT_APP_NETWORK_URL: '[{"label":"EOS","value":"https://eos.antelope.tools","mainnet":true,"pair":"eos","icon":"eos","order":5},{"label":"Proton","value":"https://proton.antelope.tools","mainnet":true,"pair":"proton","icon":"proton","order":3},{"label":"WAX","value":"https://wax.antelope.tools","mainnet":true,"pair":"wax","icon":"wax","order":4},{"label":"Telos","value":"https://telos.antelope.tools","mainnet":true,"pair":"telos","icon":"telos","order":1},{"label":"Libre","value":"https://libre.antelope.tools","mainnet":true,"pair":"libre","icon":"libre","order":2},{"label":"LACChain EOSIO","value":"https://lacchain.antelope.tools","mainnet":true,"pair":null,"icon":"lacchain","order":6},{"label":"Jungle4 Testnet","value":"https://jungle.antelope.tools","mainnet":false,"pair":"eos","icon":"jungle","order":5},{"label":"Proton Testnet","value":"https://proton-testnet.antelope.tools","mainnet":false,"pair":"proton","icon":"proton","order":3},{"label":"WAX Testnet","value":"https://wax-testnet.antelope.tools","mainnet":false,"pair":"wax","icon":"wax","order":4},{"label":"Telos Testnet","value":"https://telos-testnet.antelope.tools","mainnet":false,"pair":"telos","icon":"telos","order":1},{"label":"Libre Testnet","value":"https://libre-testnet.antelope.tools","mainnet":false,"pair":"libre","icon":"libre","order":2},{"label":"Ultra Testnet","value":"https://ultra-testnet.antelope.tools","mainnet":false,"pair":"ultra","icon":"ultra","order":6}]' - REACT_APP_DISABLED_MENU_ITEMS: '["/stress-test","/evm"]' + REACT_APP_DISABLED_MENU_ITEMS: '["/stress-test","/evm","/evm-rpc-endpoints"]' REACT_APP_BLOCK_EXPLORER_URL: 'https://www.libreblocks.io/tx/(transaction)' REACT_APP_STATE_HISTORY_ENABLED: 'true' REACT_APP_GOOGLE_ANALITIC_PAGE_ID: 'G-E6Y0EC9FT8' diff --git a/.github/workflows/deploy-mainnet.yaml b/.github/workflows/deploy-mainnet.yaml index b322eb56..093ac736 100644 --- a/.github/workflows/deploy-mainnet.yaml +++ b/.github/workflows/deploy-mainnet.yaml @@ -53,7 +53,7 @@ jobs: REACT_APP_EOS_API_NETWORK_LOGO: 'https://antelope.tools/images/eos.png' REACT_APP_TOKEN_SYMBOL: 'EOS' REACT_APP_NETWORK_URL: '[{"label":"EOS","value":"https://eos.antelope.tools","mainnet":true,"pair":"eos","icon":"eos","order":5},{"label":"Proton","value":"https://proton.antelope.tools","mainnet":true,"pair":"proton","icon":"proton","order":3},{"label":"WAX","value":"https://wax.antelope.tools","mainnet":true,"pair":"wax","icon":"wax","order":4},{"label":"Telos","value":"https://telos.antelope.tools","mainnet":true,"pair":"telos","icon":"telos","order":1},{"label":"Libre","value":"https://libre.antelope.tools","mainnet":true,"pair":"libre","icon":"libre","order":2},{"label":"LACChain EOSIO","value":"https://lacchain.antelope.tools","mainnet":true,"pair":null,"icon":"lacchain","order":6},{"label":"Jungle4 Testnet","value":"https://jungle.antelope.tools","mainnet":false,"pair":"eos","icon":"jungle","order":5},{"label":"Proton Testnet","value":"https://proton-testnet.antelope.tools","mainnet":false,"pair":"proton","icon":"proton","order":3},{"label":"WAX Testnet","value":"https://wax-testnet.antelope.tools","mainnet":false,"pair":"wax","icon":"wax","order":4},{"label":"Telos Testnet","value":"https://telos-testnet.antelope.tools","mainnet":false,"pair":"telos","icon":"telos","order":1},{"label":"Libre Testnet","value":"https://libre-testnet.antelope.tools","mainnet":false,"pair":"libre","icon":"libre","order":2},{"label":"Ultra Testnet","value":"https://ultra-testnet.antelope.tools","mainnet":false,"pair":"ultra","icon":"ultra","order":6}]' - REACT_APP_DISABLED_MENU_ITEMS: '["/missed-blocks", "/cpu-benchmark","/block-distribution","/stress-test","/evm"]' + REACT_APP_DISABLED_MENU_ITEMS: '["/missed-blocks", "/cpu-benchmark","/block-distribution","/stress-test","/evm","/evm-rpc-endpoints"]' REACT_APP_BLOCK_EXPLORER_URL: 'https://bloks.io/transaction/(transaction)' REACT_APP_STATE_HISTORY_ENABLED: 'false' REACT_APP_GOOGLE_ANALITIC_PAGE_ID: 'G-E6Y0EC9FT8' diff --git a/.github/workflows/deploy-proton-testnet.yaml b/.github/workflows/deploy-proton-testnet.yaml index 6689c5ea..d7b85d06 100644 --- a/.github/workflows/deploy-proton-testnet.yaml +++ b/.github/workflows/deploy-proton-testnet.yaml @@ -56,7 +56,7 @@ jobs: REACT_APP_SYNC_TOLERANCE_INTERVAL: 180000 REACT_APP_TOKEN_SYMBOL: 'XPR' REACT_APP_NETWORK_URL: '[{"label":"EOS","value":"https://eos.antelope.tools","mainnet":true,"pair":"eos","icon":"eos","order":5},{"label":"Proton","value":"https://proton.antelope.tools","mainnet":true,"pair":"proton","icon":"proton","order":3},{"label":"WAX","value":"https://wax.antelope.tools","mainnet":true,"pair":"wax","icon":"wax","order":4},{"label":"Telos","value":"https://telos.antelope.tools","mainnet":true,"pair":"telos","icon":"telos","order":1},{"label":"Libre","value":"https://libre.antelope.tools","mainnet":true,"pair":"libre","icon":"libre","order":2},{"label":"LACChain EOSIO","value":"https://lacchain.antelope.tools","mainnet":true,"pair":null,"icon":"lacchain","order":6},{"label":"Jungle4 Testnet","value":"https://jungle.antelope.tools","mainnet":false,"pair":"eos","icon":"jungle","order":5},{"label":"Proton Testnet","value":"https://proton-testnet.antelope.tools","mainnet":false,"pair":"proton","icon":"proton","order":3},{"label":"WAX Testnet","value":"https://wax-testnet.antelope.tools","mainnet":false,"pair":"wax","icon":"wax","order":4},{"label":"Telos Testnet","value":"https://telos-testnet.antelope.tools","mainnet":false,"pair":"telos","icon":"telos","order":1},{"label":"Libre Testnet","value":"https://libre-testnet.antelope.tools","mainnet":false,"pair":"libre","icon":"libre","order":2},{"label":"Ultra Testnet","value":"https://ultra-testnet.antelope.tools","mainnet":false,"pair":"ultra","icon":"ultra","order":6}]' - REACT_APP_DISABLED_MENU_ITEMS: '["/missed-blocks","/block-distribution","/cpu-benchmark","/stress-test","/evm"]' + REACT_APP_DISABLED_MENU_ITEMS: '["/missed-blocks","/block-distribution","/cpu-benchmark","/stress-test","/evm","/evm-rpc-endpoints"]' REACT_APP_BLOCK_EXPLORER_URL: 'https://testnet.protonscan.io/transaction/(transaction)' REACT_APP_STATE_HISTORY_ENABLED: 'false' REACT_APP_GOOGLE_ANALITIC_PAGE_ID: 'G-E6Y0EC9FT8' diff --git a/.github/workflows/deploy-proton.yaml b/.github/workflows/deploy-proton.yaml index 00e099b6..4ed7fe13 100644 --- a/.github/workflows/deploy-proton.yaml +++ b/.github/workflows/deploy-proton.yaml @@ -56,7 +56,7 @@ jobs: REACT_APP_SYNC_TOLERANCE_INTERVAL: 180000 REACT_APP_TOKEN_SYMBOL: 'XPR' REACT_APP_NETWORK_URL: '[{"label":"EOS","value":"https://eos.antelope.tools","mainnet":true,"pair":"eos","icon":"eos","order":5},{"label":"Proton","value":"https://proton.antelope.tools","mainnet":true,"pair":"proton","icon":"proton","order":3},{"label":"WAX","value":"https://wax.antelope.tools","mainnet":true,"pair":"wax","icon":"wax","order":4},{"label":"Telos","value":"https://telos.antelope.tools","mainnet":true,"pair":"telos","icon":"telos","order":1},{"label":"Libre","value":"https://libre.antelope.tools","mainnet":true,"pair":"libre","icon":"libre","order":2},{"label":"LACChain EOSIO","value":"https://lacchain.antelope.tools","mainnet":true,"pair":null,"icon":"lacchain","order":6},{"label":"Jungle4 Testnet","value":"https://jungle.antelope.tools","mainnet":false,"pair":"eos","icon":"jungle","order":5},{"label":"Proton Testnet","value":"https://proton-testnet.antelope.tools","mainnet":false,"pair":"proton","icon":"proton","order":3},{"label":"WAX Testnet","value":"https://wax-testnet.antelope.tools","mainnet":false,"pair":"wax","icon":"wax","order":4},{"label":"Telos Testnet","value":"https://telos-testnet.antelope.tools","mainnet":false,"pair":"telos","icon":"telos","order":1},{"label":"Libre Testnet","value":"https://libre-testnet.antelope.tools","mainnet":false,"pair":"libre","icon":"libre","order":2},{"label":"Ultra Testnet","value":"https://ultra-testnet.antelope.tools","mainnet":false,"pair":"ultra","icon":"ultra","order":6}]' - REACT_APP_DISABLED_MENU_ITEMS: '["/missed-blocks","/block-distribution","/cpu-benchmark","/stress-test","/evm"]' + REACT_APP_DISABLED_MENU_ITEMS: '["/missed-blocks","/block-distribution","/cpu-benchmark","/stress-test","/evm","/evm-rpc-endpoints"]' REACT_APP_BLOCK_EXPLORER_URL: 'https://www.protonscan.io/transaction/(transaction)' REACT_APP_STATE_HISTORY_ENABLED: 'false' REACT_APP_GOOGLE_ANALITIC_PAGE_ID: 'G-E6Y0EC9FT8' diff --git a/.github/workflows/deploy-telos-testnet.yaml b/.github/workflows/deploy-telos-testnet.yaml index bff88432..ad6dad9e 100644 --- a/.github/workflows/deploy-telos-testnet.yaml +++ b/.github/workflows/deploy-telos-testnet.yaml @@ -63,6 +63,7 @@ jobs: REACT_APP_PUBLIC_RE_CAPTCHA_KEY: ${{ secrets.REACT_APP_PUBLIC_RE_CAPTCHA_KEY }} REACT_APP_EVM_ENDPOINT: 'https://testnet.telos.net/evm' REACT_APP_EVM_BLOCK_EXPLORER_URL: 'https://testnet.teloscan.io/block/(block)' + REACT_APP_EVM_ENDPOINTS: '[\"https://testnet.telos.net/evm\"]' - name: Build and deploy kubernetes files id: build_kubernetes_files diff --git a/.github/workflows/deploy-telos.yaml b/.github/workflows/deploy-telos.yaml index e6509af3..2e88d795 100644 --- a/.github/workflows/deploy-telos.yaml +++ b/.github/workflows/deploy-telos.yaml @@ -63,6 +63,7 @@ jobs: REACT_APP_PUBLIC_RE_CAPTCHA_KEY: ${{ secrets.REACT_APP_PUBLIC_RE_CAPTCHA_KEY }} REACT_APP_EVM_ENDPOINT: 'https://mainnet.telos.net/evm' REACT_APP_EVM_BLOCK_EXPLORER_URL: https://www.teloscan.io/block/(block) + REACT_APP_EVM_ENDPOINTS: '[\"https://mainnet.telos.net/evm\",\"https://rpc1.eu.telos.net/evm\",\"https://rpc1.us.telos.net/evm\",\"https://rpc2.us.telos.net/evm\",\"https://api.kainosbp.com/evm\",\"https://rpc2.eu.telos.net/evm\",\"https://evm.teloskorea.com/evm\",\"https://rpc2.teloskorea.com/evm\",\"https://rpc01.us.telosunlimited.io/evm\"]' - name: Build and deploy kubernetes files id: build_kubernetes_files diff --git a/.github/workflows/deploy-ultra-testnet.yaml b/.github/workflows/deploy-ultra-testnet.yaml index ff8dc886..f50f3d34 100644 --- a/.github/workflows/deploy-ultra-testnet.yaml +++ b/.github/workflows/deploy-ultra-testnet.yaml @@ -56,7 +56,7 @@ jobs: REACT_APP_SYNC_TOLERANCE_INTERVAL: 180000 REACT_APP_TOKEN_SYMBOL: 'UOS' REACT_APP_NETWORK_URL: '[{"label":"EOS","value":"https://eos.antelope.tools","mainnet":true,"pair":"eos","icon":"eos","order":5},{"label":"Proton","value":"https://proton.antelope.tools","mainnet":true,"pair":"proton","icon":"proton","order":3},{"label":"WAX","value":"https://wax.antelope.tools","mainnet":true,"pair":"wax","icon":"wax","order":4},{"label":"Telos","value":"https://telos.antelope.tools","mainnet":true,"pair":"telos","icon":"telos","order":1},{"label":"Libre","value":"https://libre.antelope.tools","mainnet":true,"pair":"libre","icon":"libre","order":2},{"label":"LACChain EOSIO","value":"https://lacchain.antelope.tools","mainnet":true,"pair":null,"icon":"lacchain","order":6},{"label":"Jungle4 Testnet","value":"https://jungle.antelope.tools","mainnet":false,"pair":"eos","icon":"jungle","order":5},{"label":"Proton Testnet","value":"https://proton-testnet.antelope.tools","mainnet":false,"pair":"proton","icon":"proton","order":3},{"label":"WAX Testnet","value":"https://wax-testnet.antelope.tools","mainnet":false,"pair":"wax","icon":"wax","order":4},{"label":"Telos Testnet","value":"https://telos-testnet.antelope.tools","mainnet":false,"pair":"telos","icon":"telos","order":1},{"label":"Libre Testnet","value":"https://libre-testnet.antelope.tools","mainnet":false,"pair":"libre","icon":"libre","order":2},{"label":"Ultra Testnet","value":"https://ultra-testnet.antelope.tools","mainnet":false,"pair":"ultra","icon":"ultra","order":6}]' - REACT_APP_DISABLED_MENU_ITEMS: '["/block-producers","/nodes","/missed-blocks","/endpoints","/bpjson","/ricardian-contract","/block-distribution","/nodes-distribution","/cpu-benchmark","/rewards-distribution","/undiscoverable-bps","/endpoints-stats","/stress-test","/evm"]' + REACT_APP_DISABLED_MENU_ITEMS: '["/block-producers","/nodes","/missed-blocks","/endpoints","/bpjson","/ricardian-contract","/block-distribution","/nodes-distribution","/cpu-benchmark","/rewards-distribution","/undiscoverable-bps","/endpoints-stats","/stress-test","/evm","/evm-rpc-endpoints"]' REACT_APP_BLOCK_EXPLORER_URL: 'https://explorer.testnet.ultra.io/tx/(transaction)' REACT_APP_STATE_HISTORY_ENABLED: 'false' REACT_APP_GOOGLE_ANALITIC_PAGE_ID: 'G-E6Y0EC9FT8' diff --git a/.github/workflows/deploy-wax-testnet.yaml b/.github/workflows/deploy-wax-testnet.yaml index 620f51fe..46b05413 100644 --- a/.github/workflows/deploy-wax-testnet.yaml +++ b/.github/workflows/deploy-wax-testnet.yaml @@ -56,7 +56,7 @@ jobs: REACT_APP_SYNC_TOLERANCE_INTERVAL: 180000 REACT_APP_TOKEN_SYMBOL: 'WAX' REACT_APP_NETWORK_URL: '[{"label":"EOS","value":"https://eos.antelope.tools","mainnet":true,"pair":"eos","icon":"eos","order":5},{"label":"Proton","value":"https://proton.antelope.tools","mainnet":true,"pair":"proton","icon":"proton","order":3},{"label":"WAX","value":"https://wax.antelope.tools","mainnet":true,"pair":"wax","icon":"wax","order":4},{"label":"Telos","value":"https://telos.antelope.tools","mainnet":true,"pair":"telos","icon":"telos","order":1},{"label":"Libre","value":"https://libre.antelope.tools","mainnet":true,"pair":"libre","icon":"libre","order":2},{"label":"LACChain EOSIO","value":"https://lacchain.antelope.tools","mainnet":true,"pair":null,"icon":"lacchain","order":6},{"label":"Jungle4 Testnet","value":"https://jungle.antelope.tools","mainnet":false,"pair":"eos","icon":"jungle","order":5},{"label":"Proton Testnet","value":"https://proton-testnet.antelope.tools","mainnet":false,"pair":"proton","icon":"proton","order":3},{"label":"WAX Testnet","value":"https://wax-testnet.antelope.tools","mainnet":false,"pair":"wax","icon":"wax","order":4},{"label":"Telos Testnet","value":"https://telos-testnet.antelope.tools","mainnet":false,"pair":"telos","icon":"telos","order":1},{"label":"Libre Testnet","value":"https://libre-testnet.antelope.tools","mainnet":false,"pair":"libre","icon":"libre","order":2},{"label":"Ultra Testnet","value":"https://ultra-testnet.antelope.tools","mainnet":false,"pair":"ultra","icon":"ultra","order":6}]' - REACT_APP_DISABLED_MENU_ITEMS: '["/missed-blocks", "/cpu-benchmark","/block-distribution","/stress-test","/evm"]' + REACT_APP_DISABLED_MENU_ITEMS: '["/missed-blocks", "/cpu-benchmark","/block-distribution","/stress-test","/evm","/evm-rpc-endpoints"]' REACT_APP_BLOCK_EXPLORER_URL: 'https://wax-test.bloks.io/transaction/(transaction)' REACT_APP_STATE_HISTORY_ENABLED=: 'false' REACT_APP_GOOGLE_ANALITIC_PAGE_ID: 'G-E6Y0EC9FT8' diff --git a/.github/workflows/deploy-wax.yaml b/.github/workflows/deploy-wax.yaml index ef43fddf..f968f730 100644 --- a/.github/workflows/deploy-wax.yaml +++ b/.github/workflows/deploy-wax.yaml @@ -56,7 +56,7 @@ jobs: REACT_APP_SYNC_TOLERANCE_INTERVAL: 180000 REACT_APP_TOKEN_SYMBOL: 'WAX' REACT_APP_NETWORK_URL: '[{"label":"EOS","value":"https://eos.antelope.tools","mainnet":true,"pair":"eos","icon":"eos","order":5},{"label":"Proton","value":"https://proton.antelope.tools","mainnet":true,"pair":"proton","icon":"proton","order":3},{"label":"WAX","value":"https://wax.antelope.tools","mainnet":true,"pair":"wax","icon":"wax","order":4},{"label":"Telos","value":"https://telos.antelope.tools","mainnet":true,"pair":"telos","icon":"telos","order":1},{"label":"Libre","value":"https://libre.antelope.tools","mainnet":true,"pair":"libre","icon":"libre","order":2},{"label":"LACChain EOSIO","value":"https://lacchain.antelope.tools","mainnet":true,"pair":null,"icon":"lacchain","order":6},{"label":"Jungle4 Testnet","value":"https://jungle.antelope.tools","mainnet":false,"pair":"eos","icon":"jungle","order":5},{"label":"Proton Testnet","value":"https://proton-testnet.antelope.tools","mainnet":false,"pair":"proton","icon":"proton","order":3},{"label":"WAX Testnet","value":"https://wax-testnet.antelope.tools","mainnet":false,"pair":"wax","icon":"wax","order":4},{"label":"Telos Testnet","value":"https://telos-testnet.antelope.tools","mainnet":false,"pair":"telos","icon":"telos","order":1},{"label":"Libre Testnet","value":"https://libre-testnet.antelope.tools","mainnet":false,"pair":"libre","icon":"libre","order":2},{"label":"Ultra Testnet","value":"https://ultra-testnet.antelope.tools","mainnet":false,"pair":"ultra","icon":"ultra","order":6}]' - REACT_APP_DISABLED_MENU_ITEMS: '["/missed-blocks", "/cpu-benchmark","/block-distribution","/stress-test","/evm"]' + REACT_APP_DISABLED_MENU_ITEMS: '["/missed-blocks", "/cpu-benchmark","/block-distribution","/stress-test","/evm","/evm-rpc-endpoints"]' REACT_APP_BLOCK_EXPLORER_URL: 'https://wax.bloks.io/transaction/(transaction)' REACT_APP_STATE_HISTORY_ENABLED=: 'false' REACT_APP_GOOGLE_ANALITIC_PAGE_ID: 'G-E6Y0EC9FT8' diff --git a/kubernetes/configmap-dashboard.yaml b/kubernetes/configmap-dashboard.yaml index 37fd6e10..ffd6d5a9 100644 --- a/kubernetes/configmap-dashboard.yaml +++ b/kubernetes/configmap-dashboard.yaml @@ -35,6 +35,7 @@ data: REACT_APP_PUBLIC_RE_CAPTCHA_KEY: '${REACT_APP_PUBLIC_RE_CAPTCHA_KEY}' REACT_APP_EVM_ENDPOINT: '${REACT_APP_EVM_ENDPOINT}' REACT_APP_EVM_BLOCK_EXPLORER_URL: '${REACT_APP_EVM_BLOCK_EXPLORER_URL}' + REACT_APP_EVM_ENDPOINTS: '${REACT_APP_EVM_ENDPOINTS}' --- apiVersion: v1 kind: ConfigMap From b66f47575ff6e155ca2f4ad1d6a84e39b1891ad1 Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Mon, 21 Aug 2023 13:54:00 -0600 Subject: [PATCH 47/75] chore(webapp): format EVM endpoints data --- webapp/src/components/HealthCheck/InfoModal.js | 1 + webapp/src/language/en.json | 3 ++- webapp/src/language/es.json | 3 ++- webapp/src/routes/EVMEndpointsList/index.js | 10 +++++++--- .../routes/EVMEndpointsList/useRPCEndpointsState.js | 4 ++-- 5 files changed, 14 insertions(+), 7 deletions(-) diff --git a/webapp/src/components/HealthCheck/InfoModal.js b/webapp/src/components/HealthCheck/InfoModal.js index a5edd184..d9aecc88 100644 --- a/webapp/src/components/HealthCheck/InfoModal.js +++ b/webapp/src/components/HealthCheck/InfoModal.js @@ -34,6 +34,7 @@ const InfoModal = ({ lights = defaultLights }) => { return (

{t('help')}

+ {t('helpText')} {lights && Object.keys(lights).map((light, index) => (
diff --git a/webapp/src/language/en.json b/webapp/src/language/en.json index d23bbfe3..b7eb5530 100644 --- a/webapp/src/language/en.json +++ b/webapp/src/language/en.json @@ -408,7 +408,8 @@ "updated": "The endpoint is working", "outdated": "The endpoint works but is outdated with the last block", "error": "Error in the endpoint request", - "not working": "The endpoint is not responding" + "not working": "The endpoint is not responding", + "helpText": "Hover or click the icons to display the endpoint health status data" }, "copyToClipboardComponent": { "copy": "Click to copy", diff --git a/webapp/src/language/es.json b/webapp/src/language/es.json index 7bc36aa1..7e3c9340 100644 --- a/webapp/src/language/es.json +++ b/webapp/src/language/es.json @@ -427,7 +427,8 @@ "updated": "El punto final funciona", "outdated": "El punto final funciona, pero no está actualizado con el último bloque", "error": "Error en la consulta del punto final", - "not working": "El punto final no responde" + "not working": "El punto final no responde", + "helpText": "Pase el cursor o haga clic en los iconos para ver el estado de salud de un endpoint" }, "copyToClipboardComponent": { "copy": "Copiar", diff --git a/webapp/src/routes/EVMEndpointsList/index.js b/webapp/src/routes/EVMEndpointsList/index.js index 4a75775d..a004a80b 100644 --- a/webapp/src/routes/EVMEndpointsList/index.js +++ b/webapp/src/routes/EVMEndpointsList/index.js @@ -19,7 +19,7 @@ import HealthInfoModal from '../../components/HealthCheck/InfoModal' import styles from './styles' import useRPCEndpointsState from './useRPCEndpointsState' -import { getStatus } from 'utils' +import { getStatus, formatWithThousandSeparator } from 'utils' const useStyles = makeStyles(styles) @@ -70,9 +70,13 @@ const EVMEndpointsList = () => {
- {endpoint.height || 'N/A'} - {endpoint.latency ? `${endpoint.latency} ms` : 'N/A'} + {formatWithThousandSeparator(endpoint.height) || 'N/A'} + + + {endpoint.latency + ? `${formatWithThousandSeparator(endpoint.latency)} ms` + : 'N/A'} ))} diff --git a/webapp/src/routes/EVMEndpointsList/useRPCEndpointsState.js b/webapp/src/routes/EVMEndpointsList/useRPCEndpointsState.js index 84e01001..baafb246 100644 --- a/webapp/src/routes/EVMEndpointsList/useRPCEndpointsState.js +++ b/webapp/src/routes/EVMEndpointsList/useRPCEndpointsState.js @@ -30,7 +30,7 @@ const useRPCEndpointsState = () => { try { const { data: { result: height }, - } = await customAxios.post(endpointUrl, { + } = await axios.post(endpointUrl, { method: 'eth_blockNumber', params: [], id: 1, @@ -42,7 +42,7 @@ const useRPCEndpointsState = () => { { method: 'eth_getBlockByNumber', params: [height.toString(), false], - id: 1, + id: 2, jsonrpc: '2.0', }, ) From 82a78ac732373edf086483b76ad20b4783d4cdb5 Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Mon, 21 Aug 2023 14:07:48 -0600 Subject: [PATCH 48/75] chore(workflows): add EVM RPC endpoints --- .github/workflows/deploy-telos.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy-telos.yaml b/.github/workflows/deploy-telos.yaml index 2e88d795..d44a0596 100644 --- a/.github/workflows/deploy-telos.yaml +++ b/.github/workflows/deploy-telos.yaml @@ -63,7 +63,7 @@ jobs: REACT_APP_PUBLIC_RE_CAPTCHA_KEY: ${{ secrets.REACT_APP_PUBLIC_RE_CAPTCHA_KEY }} REACT_APP_EVM_ENDPOINT: 'https://mainnet.telos.net/evm' REACT_APP_EVM_BLOCK_EXPLORER_URL: https://www.teloscan.io/block/(block) - REACT_APP_EVM_ENDPOINTS: '[\"https://mainnet.telos.net/evm\",\"https://rpc1.eu.telos.net/evm\",\"https://rpc1.us.telos.net/evm\",\"https://rpc2.us.telos.net/evm\",\"https://api.kainosbp.com/evm\",\"https://rpc2.eu.telos.net/evm\",\"https://evm.teloskorea.com/evm\",\"https://rpc2.teloskorea.com/evm\",\"https://rpc01.us.telosunlimited.io/evm\"]' + REACT_APP_EVM_ENDPOINTS: '[\"https://rpc1.eu.telos.net/evm\",\"https://api.kainosbp.com/evm\",\"https://mainnet.telos.net/evm\",\"https://rpc1.us.telos.net/evm\",\"https://rpc2.eu.telos.net/evm\",\"https://rpc2.us.telos.net/evm\",\"https://evm.teloskorea.com/evm\",\"https://rpc2.teloskorea.com/evm\",\"https://rpc01.us.telosunlimited.io/evm\"]' - name: Build and deploy kubernetes files id: build_kubernetes_files From 47435a5e7c2c23b4122745dbba92721180b90339 Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Mon, 21 Aug 2023 14:26:58 -0600 Subject: [PATCH 49/75] chore(webapp): align table cell to the right --- webapp/src/routes/EVMEndpointsList/index.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/webapp/src/routes/EVMEndpointsList/index.js b/webapp/src/routes/EVMEndpointsList/index.js index a004a80b..51b02158 100644 --- a/webapp/src/routes/EVMEndpointsList/index.js +++ b/webapp/src/routes/EVMEndpointsList/index.js @@ -55,8 +55,8 @@ const EVMEndpointsList = () => { {t('rpcEndpoint')} - {t('lastBlock')} - {t('latency')} + {t('lastBlock')} + {t('latency')} @@ -70,10 +70,10 @@ const EVMEndpointsList = () => {
- + {formatWithThousandSeparator(endpoint.height) || 'N/A'} - + {endpoint.latency ? `${formatWithThousandSeparator(endpoint.latency)} ms` : 'N/A'} From d43959af12e53f4e39520b618141bdbb4b1c77db Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Mon, 21 Aug 2023 15:07:51 -0600 Subject: [PATCH 50/75] chore(webapp): format EVM transactions tooltip chart --- webapp/src/routes/EVMDashboard/index.js | 11 +++++++++-- webapp/src/routes/EVMDashboard/useEVMstate.js | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/webapp/src/routes/EVMDashboard/index.js b/webapp/src/routes/EVMDashboard/index.js index e3503c71..4ceaf690 100644 --- a/webapp/src/routes/EVMDashboard/index.js +++ b/webapp/src/routes/EVMDashboard/index.js @@ -70,7 +70,14 @@ const EVMDashboard = () => { const series = element?.series const point = element?.point - const pointName = point?.name ? `${point.name}
` : '' + let pointName = '' + + if (point?.name) { + pointName = !isLive + ? `${point.name}` + : `Block Height: ${formatWithThousandSeparator(point.name)}` + } + const resourcesDetail = point?.gas ? `
${t('gasUsed')}: ${formatWithThousandSeparator( point?.gas, @@ -79,7 +86,7 @@ const EVMDashboard = () => { : '' return ( - pointName + + pointName + '
' + `${series?.name}: ${point?.y}` + resourcesDetail ) diff --git a/webapp/src/routes/EVMDashboard/useEVMstate.js b/webapp/src/routes/EVMDashboard/useEVMstate.js index 1b853cad..cafde46f 100644 --- a/webapp/src/routes/EVMDashboard/useEVMstate.js +++ b/webapp/src/routes/EVMDashboard/useEVMstate.js @@ -202,7 +202,7 @@ const useEVMState = (theme, t) => { data = [ { - name: `Block Height: ${blockNum}`, + name: blockNum, gas: (block?.gasUsed / block?.gasLimit) * 100 || 0, y: block?.transactions?.length || 0, }, From 73d31ea35606a760b953b152501386127688f771 Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Tue, 22 Aug 2023 09:48:47 -0600 Subject: [PATCH 51/75] feat(webapp): improve faucet UI --- webapp/src/language/en.json | 8 ++++++-- webapp/src/language/es.json | 8 ++++++-- webapp/src/routes/Faucet/index.js | 31 +++++++++++++++++++----------- webapp/src/routes/Faucet/styles.js | 15 ++++++++++++--- 4 files changed, 44 insertions(+), 18 deletions(-) diff --git a/webapp/src/language/en.json b/webapp/src/language/en.json index 3de15202..fc430ca8 100644 --- a/webapp/src/language/en.json +++ b/webapp/src/language/en.json @@ -197,11 +197,15 @@ "createAccount": "Create Faucet Account", "newCreatedAccount": "Your new account is", "transferTokensTransaction": "Tokens transferred correctly. Check it on explorer here", - "createButton": "Create", + "createButton": "Create Account", "issueTokens": "Issue Tokens", "getTokens": "Get Tokens", "publicKey": "Public Key (Active/Owner)", - "accountName": "Account Name" + "accountName": "Account Name", + "invalidAccount": "Please enter a valid account name", + "emptyFields": "Fill out the fields to create an account", + "accountFormat": "Must be 12 or less characters and can contain from 'a' to 'z' in lower case and numbers from 1 to 5", + "keyFormat": "Please enter a valid key. Generate it with cleos or a compatible wallet" }, "ricardianContractRoute": { "title": "Block Producer Agreement" diff --git a/webapp/src/language/es.json b/webapp/src/language/es.json index 7e95062e..0ddf13ed 100644 --- a/webapp/src/language/es.json +++ b/webapp/src/language/es.json @@ -203,11 +203,15 @@ "createAccount": "Crear Cuenta Faucet", "newCreatedAccount": "Su nueva cuenta es", "transferTokensTransaction": "Tokens transferidos correctamente. Puede revisar la transacción aquí", - "createButton": "Crear", + "createButton": "Crear Cuenta", "issueTokens": "Emitir Tokens", "getTokens": "Obtener Tokens", "publicKey": "Llave pública (Active/Owner)", - "accountName": "Nombre de la cuenta" + "accountName": "Nombre de la cuenta", + "invalidAccount": "Ingrese un nombre de cuenta válido", + "emptyFields": "Rellene todos los campos para crear la cuenta", + "accountFormat": "Debe tener 12 caracteres o menos y puede contener desde la a 'a' la 'z' en minúsculas y números del 1 al 5", + "keyFormat": "Ingrese una llave válida. Puede generarla con cleos o cualquier wallet compatible" }, "ricardianContractRoute": { "title": "Acuerdo de Productor de Bloques" diff --git a/webapp/src/routes/Faucet/index.js b/webapp/src/routes/Faucet/index.js index 1c6a8fb7..8276b86d 100644 --- a/webapp/src/routes/Faucet/index.js +++ b/webapp/src/routes/Faucet/index.js @@ -25,12 +25,13 @@ const useStyles = makeStyles(styles) const Faucet = () => { const classes = useStyles() const { t } = useTranslation('faucetRoute') + const isUltraTestnet = eosConfig.networkName === 'ultra-testnet' const [, { showMessage }] = useSnackbarMessageState() const [account, setAccount] = useState('') const [createAccountValues, setCreateAccountValues] = useState({}) const [transferTokensTransaction, setTransferTokensTransaction] = useState('') const [createFaucetAccount, { loading: loadingCreateAccount }] = useMutation( - CREATE_ACCOUNT_MUTATION(eosConfig.networkName !== 'ultra-testnet'), + CREATE_ACCOUNT_MUTATION(!isUltraTestnet), ) const [transferFaucetTokens, { loading: loadingTransferFaucetTokens }] = useMutation(TRANFER_FAUCET_TOKENS_MUTATION) @@ -42,23 +43,23 @@ const Faucet = () => { if ( !reCaptchaToken || !createAccountValues.publicKey || - (eosConfig.networkName !== 'ultra-testnet' && + (!isUltraTestnet && !createAccountValues.accountName) ) { showMessage({ type: 'error', - content: 'Fill out the fields to create an account', + content: t('emptyFields'), }) return } if ( - eosConfig.networkName !== 'ultra-testnet' && + !isUltraTestnet && !isValidAccountName(createAccountValues.accountName) ) { showMessage({ type: 'error', - content: 'Please enter a valid account name', + content: t('invalidAccount'), }) return } @@ -107,7 +108,7 @@ const Faucet = () => { if (!isValidAccountName(account)) { showMessage({ type: 'error', - content: 'Please enter a valid account name', + content: t('invalidAccount'), }) return } @@ -150,13 +151,18 @@ const Faucet = () => { } const isValidAccountName = name => { - const regex = /^[.12345abcdefghijklmnopqrstuvwxyz]+$/i + const regex = /^[.12345abcdefghijklmnopqrstuvwxyz]+$/ return name?.length < 13 && regex.test(name) } return ( -
+
@@ -175,10 +181,11 @@ const Faucet = () => { }) } error={!createAccountValues.publicKey} + helperText={t('keyFormat')} required />
- {eosConfig.networkName !== 'ultra-testnet' && ( + {!isUltraTestnet && (
{ }) } error={!isValidAccountName(createAccountValues.accountName)} + helperText={t('accountFormat')} required />
@@ -221,16 +229,17 @@ const Faucet = () => {
- {t('issueTokens')} + {`${t('issueTokens')} (500 ${eosConfig.tokenSymbol})`}
setAccount(e.target.value)} error={!isValidAccountName(account)} + helperText={t('accountFormat')} required />
diff --git a/webapp/src/routes/Faucet/styles.js b/webapp/src/routes/Faucet/styles.js index b775ee3d..8011f37b 100644 --- a/webapp/src/routes/Faucet/styles.js +++ b/webapp/src/routes/Faucet/styles.js @@ -1,21 +1,30 @@ export default (theme) => ({ formControl: { - margin: theme.spacing(2), + margin: theme.spacing(4), display: 'flex', flexDirection: 'column', gap: theme.spacing(4), + minHeight: '150px', + justifyContent: 'center', + '& .MuiFormControl-root': { + width: '300px', + }, }, test: { display: 'flex', + justifyContent: 'center', [theme.breakpoints.down('md')]: { - display: 'block', + flexWrap: 'wrap', + height: '100% !important', }, + marginBottom: theme.spacing(4), }, card: { padding: '10px', height: '100%', '& .MuiPaper-root': { + height: '100%', boxShadow: '0px 1px 5px rgba(0, 0, 0, 0.15) !important', - } + }, }, }) From 78ed7bf2fb6dbbe721cb52ed4e75d1422a5f8cc4 Mon Sep 17 00:00:00 2001 From: Leister Francisco Alvarado Campos Date: Tue, 22 Aug 2023 10:18:54 -0600 Subject: [PATCH 52/75] feat(cicd): update workflow for specific networks with evm --- .env.telos | 7 ++++- .env.telostestnet | 14 ++++++++++ .github/workflows/deploy-telos-testnet.yaml | 3 ++- .github/workflows/deploy-telos.yaml | 3 ++- docker-compose.yaml | 10 ++++--- hapi-evm/src/config/hyperion.config.ts | 4 +-- hapi-evm/src/config/network.config.ts | 4 +-- kubernetes-evm/hapi-evm-deployment.yaml | 29 +++++++++++++++++++++ kubernetes-evm/hapi-evm-service.yaml | 13 +++++++++ kubernetes/configmap-dashboard.yaml | 19 ++++++++++++++ makefile | 10 +++++++ utils/meta.mk | 3 ++- 12 files changed, 107 insertions(+), 12 deletions(-) create mode 100644 kubernetes-evm/hapi-evm-deployment.yaml create mode 100644 kubernetes-evm/hapi-evm-service.yaml diff --git a/.env.telos b/.env.telos index dd5a455c..cdf1fc94 100644 --- a/.env.telos +++ b/.env.telos @@ -59,11 +59,16 @@ HAPI_CREATE_ACCOUNT_ACTION_NAME= # hapi-evm HAPI_EVM_SERVER_PORT=9090 HAPI_EVM_SERVER_ADDRESS=hapi-evm +HAPI_EVM_HASURA_URL=http://hasura:8080/v1/graphql +HAPI_EVM_HASURA_ADMIN_SECRET=myadminsecretkey +HAPI_EVM_DATABASE_URL=postgres://eoscr:password@postgres:5432/localdb HAPI_EVM_ENDPOINT=https://testnet.telos.net/evm HAPI_EVM_API_ENDPOINTS=["https://telos.greymass.com","https://telos.eosphere.io","telos.caleos.io","mainnet.telosusa.io"] HAPI_EVM_NETWORK_CHAIN_ID=4667b205c6838ef70ff7988f6e8257e8be0e1284a2f59699054a018f743b1d11 HAPI_EVM_EOS_EVM_ACCOUNT=eosio.evm -HAPI_BLOCK_INTERVAL_SEC=0.3 +HAPI_EVM_BLOCK_INTERVAL_SEC=0.3 +HAPI_EVM_HYPERION_API=https://telos.eosusa.io +HAPI_EVM_HYPERION_START_AT=2021-06-02T00:00:00.000+00:00 #webapp PORT=3000 diff --git a/.env.telostestnet b/.env.telostestnet index 61abd7d3..9c22efdd 100644 --- a/.env.telostestnet +++ b/.env.telostestnet @@ -56,6 +56,20 @@ HAPI_RE_CAPTCHA_PROJECT_ID= HAPI_PUBLIC_RE_CAPTCHA_KEY= HAPI_CREATE_ACCOUNT_ACTION_NAME= +# hapi-evm +HAPI_EVM_SERVER_PORT=9090 +HAPI_EVM_SERVER_ADDRESS=hapi-evm +HAPI_EVM_HASURA_URL=http://hasura:8080/v1/graphql +HAPI_EVM_HASURA_ADMIN_SECRET=myadminsecretkey +HAPI_EVM_DATABASE_URL=postgres://eoscr:password@postgres:5432/localdb +HAPI_EVM_ENDPOINT=https://testnet.telos.net/evm +HAPI_EVM_API_ENDPOINTS=["https://telos-testnet.edenia.cloud","https://telos-testnet.cryptolions.io","https://testnet.telos.eosrio.io","https://test.telos.eosusa.io"] +HAPI_EVM_NETWORK_CHAIN_ID=1eaa0824707c8c16bd25145493bf062aecddfeb56c736f6ba6397f3195f33c9f +HAPI_EVM_EOS_EVM_ACCOUNT=eosio.evm +HAPI_EVM_BLOCK_INTERVAL_SEC=0.3 +HAPI_EVM_HYPERION_API=https://test.telos.eosusa.io +HAPI_EVM_HYPERION_START_AT=2021-06-02T00:00:00.000+00:00 + #webapp PORT=3000 REACT_APP_VERSION=dev diff --git a/.github/workflows/deploy-telos-testnet.yaml b/.github/workflows/deploy-telos-testnet.yaml index c4d18507..c8b52c7a 100644 --- a/.github/workflows/deploy-telos-testnet.yaml +++ b/.github/workflows/deploy-telos-testnet.yaml @@ -66,7 +66,8 @@ jobs: id: build_kubernetes_files run: | make \ - build-kubernetes + build-kubernetes \ + build-kubernetes-evm env: # general NAMESPACE: telos-testnet-dashboard diff --git a/.github/workflows/deploy-telos.yaml b/.github/workflows/deploy-telos.yaml index eaff756e..a07d6c06 100644 --- a/.github/workflows/deploy-telos.yaml +++ b/.github/workflows/deploy-telos.yaml @@ -66,7 +66,8 @@ jobs: id: build_kubernetes_files run: | make \ - build-kubernetes + build-kubernetes \ + build-kubernetes-evm env: # general NAMESPACE: telos-dashboard diff --git a/docker-compose.yaml b/docker-compose.yaml index ac4ca2b3..c9ef0526 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -86,14 +86,16 @@ services: environment: HAPI_EVM_SERVER_PORT: '${HAPI_EVM_SERVER_PORT}' HAPI_EVM_SERVER_ADDRESS: '${HAPI_EVM_SERVER_ADDRESS}' + HAPI_EVM_HASURA_URL: '${HAPI_EVM_HASURA_URL}' + HAPI_EVM_HASURA_ADMIN_SECRET: '${HAPI_EVM_HASURA_ADMIN_SECRET}' + HAPI_EVM_DATABASE_URL: '${HAPI_EVM_DATABASE_URL}' HAPI_EVM_ENDPOINT: '${HAPI_EVM_ENDPOINT}' HAPI_EVM_API_ENDPOINTS: '${HAPI_EVM_API_ENDPOINTS}' HAPI_EVM_NETWORK_CHAIN_ID: '${HAPI_EVM_NETWORK_CHAIN_ID}' HAPI_EVM_EOS_EVM_ACCOUNT: '${HAPI_EVM_EOS_EVM_ACCOUNT}' - HAPI_EVM_HASURA_URL: '${HAPI_HASURA_URL}' - HAPI_EVM_HASURA_ADMIN_SECRET: '${HAPI_HASURA_ADMIN_SECRET}' - HAPI_EVM_DATABASE_URL: '${HAPI_DATABASE_URL}' - HAPI_BLOCK_INTERVAL_SEC: '${HAPI_BLOCK_INTERVAL_SEC}' + HAPI_EVM_BLOCK_INTERVAL_SEC: '${HAPI_EVM_BLOCK_INTERVAL_SEC}' + HAPI_EVM_HYPERION_API: '${HAPI_EVM_HYPERION_API}' + HAPI_EVM_HYPERION_START_AT: '${HAPI_EVM_HYPERION_START_AT}' hasura: container_name: '${STAGE}-${APP_NAME}-hasura' image: hasura/graphql-engine:v2.16.0.cli-migrations-v3 diff --git a/hapi-evm/src/config/hyperion.config.ts b/hapi-evm/src/config/hyperion.config.ts index aa4f6e2d..5852e926 100644 --- a/hapi-evm/src/config/hyperion.config.ts +++ b/hapi-evm/src/config/hyperion.config.ts @@ -1,4 +1,4 @@ export const api = - process.env.HAPI_HYPERION_API || 'https://test.telos.eosusa.io' + process.env.HAPI_EVM_HYPERION_API || 'https://test.telos.eosusa.io' export const startAt = - process.env.HAPI_HYPERION_START_AT || '2021-06-02T00:00:00.000+00:00' + process.env.HAPI_EVM_HYPERION_START_AT || '2021-06-02T00:00:00.000+00:00' diff --git a/hapi-evm/src/config/network.config.ts b/hapi-evm/src/config/network.config.ts index f056ae73..8c1449c4 100644 --- a/hapi-evm/src/config/network.config.ts +++ b/hapi-evm/src/config/network.config.ts @@ -1,9 +1,9 @@ export const evmEndpoint = process.env.HAPI_EVM_ENDPOINT || 'http://localhost/evm' -export const chainId = process.env.HAPI_NETWORK_CHAIN_ID || 'chainid1' +export const chainId = process.env.HAPI_EVM_NETWORK_CHAIN_ID || 'chainid1' export const evmAccount = process.env.HAPI_EVM_EOS_EVM_ACCOUNT || 'eosio.evm' export const eosEndpoints = process.env.HAPI_EVM_EOS_EVM_ACCOUNT?.split(',') || [] export const blockIntervalSec = parseFloat( - process.env.HAPI_BLOCK_INTERVAL_SEC || '0.5' + process.env.HAPI_EVM_BLOCK_INTERVAL_SEC || '0.5' ) diff --git a/kubernetes-evm/hapi-evm-deployment.yaml b/kubernetes-evm/hapi-evm-deployment.yaml new file mode 100644 index 00000000..d5af5007 --- /dev/null +++ b/kubernetes-evm/hapi-evm-deployment.yaml @@ -0,0 +1,29 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: dashboard-hapi-evm + name: dashboard-hapi-evm +spec: + replicas: 1 + selector: + matchLabels: + app: dashboard-hapi-evm + strategy: + type: Recreate + template: + metadata: + labels: + app: dashboard-hapi-evm + spec: + imagePullSecrets: + - name: regcred + containers: + - image: ${DOCKER_REGISTRY}/${IMAGE_NAME_HAPI_EVM}:${VERSION} + imagePullPolicy: "Always" + name: "dashboard-hapi-evm" + envFrom: + - configMapRef: + name: dashboard-hapi-evm-config + ports: + - containerPort: 9090 diff --git a/kubernetes-evm/hapi-evm-service.yaml b/kubernetes-evm/hapi-evm-service.yaml new file mode 100644 index 00000000..88c28f79 --- /dev/null +++ b/kubernetes-evm/hapi-evm-service.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app: dashboard-hapi-evm + name: dashboard-hapi-evm +spec: + ports: + - name: hapi + port: 9091 + targetPort: 9090 + selector: + app: dashboard-hapi-evm diff --git a/kubernetes/configmap-dashboard.yaml b/kubernetes/configmap-dashboard.yaml index c3785bb3..962d5adc 100644 --- a/kubernetes/configmap-dashboard.yaml +++ b/kubernetes/configmap-dashboard.yaml @@ -103,6 +103,25 @@ data: --- apiVersion: v1 kind: ConfigMap +metadata: + name: dashboard-hapi-evm-config +data: + # hapi-evm + HAPI_EVM_SERVER_PORT: '${HAPI_EVM_SERVER_PORT}' + HAPI_EVM_SERVER_ADDRESS: '${HAPI_EVM_SERVER_ADDRESS}' + HAPI_EVM_HASURA_URL: '${HAPI_EVM_HASURA_URL}' + HAPI_EVM_HASURA_ADMIN_SECRET: '${HAPI_EVM_HASURA_ADMIN_SECRET}' + HAPI_EVM_DATABASE_URL: '${HAPI_EVM_DATABASE_URL}' + HAPI_EVM_ENDPOINT: '${HAPI_EVM_ENDPOINT}' + HAPI_EVM_API_ENDPOINTS: '${HAPI_EVM_API_ENDPOINTS}' + HAPI_EVM_NETWORK_CHAIN_ID: '${HAPI_EVM_NETWORK_CHAIN_ID}' + HAPI_EVM_EOS_EVM_ACCOUNT: '${HAPI_EVM_EOS_EVM_ACCOUNT}' + HAPI_EVM_BLOCK_INTERVAL_SEC: '${HAPI_EVM_BLOCK_INTERVAL_SEC}' + HAPI_EVM_HYPERION_API: '${HAPI_EVM_HYPERION_API}' + HAPI_EVM_HYPERION_START_AT: '${HAPI_EVM_HYPERION_START_AT}' +--- +apiVersion: v1 +kind: ConfigMap metadata: name: dashboard-hasura-config data: diff --git a/makefile b/makefile index 8e1f0810..eea8370d 100644 --- a/makefile +++ b/makefile @@ -10,6 +10,7 @@ RESET := $(shell tput -Txterm sgr0) K8S_BUILD_DIR ?= ./build_k8s K8S_FILES := $(shell find ./kubernetes -name '*.yaml' | sed 's:./kubernetes/::g') +K8S_FILES_EVM := $(shell find ./kubernetes-evm -name '*.yaml' | sed 's:./kubernetes-evm/::g') run: @echo "$(BLUE)running action $(filter-out $@,$(MAKECMDGOALS))$(RESET)" @@ -165,6 +166,15 @@ build-kubernetes: ./kubernetes $(SHELL_EXPORT) envsubst <./kubernetes/$$file >$(K8S_BUILD_DIR)/$$file; \ done +build-kubernetes-evm: ##@devops Generate proper k8s files based on the templates for evm +build-kubernetes-evm: ./kubernetes-evm + @echo "Build kubernetes files for evm..." + @mkdir -p $(K8S_BUILD_DIR) + @for file in $(K8S_FILES_EVM); do \ + mkdir -p `dirname "$(K8S_BUILD_DIR)/$$file"`; \ + $(SHELL_EXPORT) envsubst <./kubernetes-evm/$$file >$(K8S_BUILD_DIR)/$$file; \ + done + deploy-kubernetes: ##@devops Publish the build k8s files deploy-kubernetes: $(K8S_BUILD_DIR) @kubectl create ns $(NAMESPACE) || echo "Namespace '$(NAMESPACE)' already exists."; diff --git a/utils/meta.mk b/utils/meta.mk index 9f9f4e92..64912889 100644 --- a/utils/meta.mk +++ b/utils/meta.mk @@ -4,13 +4,14 @@ VERSION ?= $(shell git rev-parse --short HEAD) IMAGE_NAME_WEBAPP=dashboard-webapp IMAGE_NAME_HAPI=dashboard-hapi +IMAGE_NAME_HAPI_EVM=dashboard-hapi-evm IMAGE_NAME_HASURA=dashboard-hasura IMAGE_NAME_WALLET=dashboard-wallet DOCKER_REGISTRY=ghcr.io/edenia SUBDIRS = webapp hapi hasura wallet -MAKE_ENV += DOCKER_REGISTRY VERSION IMAGE_NAME_WEBAPP IMAGE_NAME_HAPI IMAGE_NAME_WALLET IMAGE_NAME_HASURA +MAKE_ENV += DOCKER_REGISTRY VERSION IMAGE_NAME_WEBAPP IMAGE_NAME_HAPI IMAGE_NAME_HAPI_EVM IMAGE_NAME_WALLET IMAGE_NAME_HASURA SHELL_EXPORT := $(foreach v,$(MAKE_ENV),$(v)='$($(v))') From aec5d5a7aad9a0673c22620bb4fb623bba12e596 Mon Sep 17 00:00:00 2001 From: Leister Francisco Alvarado Campos Date: Tue, 22 Aug 2023 13:47:22 -0600 Subject: [PATCH 53/75] feat(cicd): add env values for hapi-evm deployment --- .github/workflows/deploy-telos-testnet.yaml | 13 +++++++++++++ .github/workflows/deploy-telos.yaml | 13 +++++++++++++ 2 files changed, 26 insertions(+) diff --git a/.github/workflows/deploy-telos-testnet.yaml b/.github/workflows/deploy-telos-testnet.yaml index c8b52c7a..2f835f55 100644 --- a/.github/workflows/deploy-telos-testnet.yaml +++ b/.github/workflows/deploy-telos-testnet.yaml @@ -105,6 +105,19 @@ jobs: HAPI_EOS_EXCHANGE_RATE_API: 'https://api.coingecko.com/api/v3/simple/price?ids=telos&vs_currencies=usd' HAPI_COINGECKO_API_TOKEN_ID: telos HAPI_REWARDS_TOKEN: TLOS + # hapi-evm + HAPI_EVM_SERVER_PORT: '9090' + HAPI_EVM_SERVER_ADDRESS: '0.0.0.0' + HAPI_EVM_HASURA_URL: 'http://dashboard-hasura:8080/v1/graphql' + HAPI_EVM_HASURA_ADMIN_SECRET: ${{ secrets.HAPI_EVM_HASURA_ADMIN_SECRET }} + HAPI_EVM_DATABASE_URL: ${{ secrets.HAPI_EVM_DATABASE_URL }} + HAPI_EVM_ENDPOINT: 'https://testnet.telos.net/evm' + HAPI_EVM_API_ENDPOINTS: '["https://telos-testnet.edenia.cloud","https://telos-testnet.cryptolions.io","https://testnet.telos.eosrio.io","https://test.telos.eosusa.io"]' + HAPI_EVM_NETWORK_CHAIN_ID: 1eaa0824707c8c16bd25145493bf062aecddfeb56c736f6ba6397f3195f33c9f + HAPI_EVM_EOS_EVM_ACCOUNT: ${{ secrets.HAPI_EVM_EOS_EVM_ACCOUNT }} + HAPI_EVM_BLOCK_INTERVAL_SEC: ${{ secrets.HAPI_EVM_BLOCK_INTERVAL_SEC }} + HAPI_EVM_HYPERION_API: ${{ secrets.HAPI_EVM_HYPERION_API }} + HAPI_EVM_HYPERION_START_AT: ${{ secrets.HAPI_EVM_HYPERION_START_AT }} # hasura HASURA_GRAPHQL_ENABLE_CONSOLE: 'true' HASURA_GRAPHQL_DATABASE_URL: ${{ secrets.HASURA_GRAPHQL_DATABASE_URL }} diff --git a/.github/workflows/deploy-telos.yaml b/.github/workflows/deploy-telos.yaml index a07d6c06..dab719b0 100644 --- a/.github/workflows/deploy-telos.yaml +++ b/.github/workflows/deploy-telos.yaml @@ -105,6 +105,19 @@ jobs: HAPI_EOS_EXCHANGE_RATE_API: 'https://api.coingecko.com/api/v3/simple/price?ids=telos&vs_currencies=usd' HAPI_COINGECKO_API_TOKEN_ID: telos HAPI_REWARDS_TOKEN: TLOS + # hapi-evm + HAPI_EVM_SERVER_PORT: '9090' + HAPI_EVM_SERVER_ADDRESS: '0.0.0.0' + HAPI_EVM_HASURA_URL: 'http://dashboard-hasura:8080/v1/graphql' + HAPI_EVM_HASURA_ADMIN_SECRET: ${{ secrets.HAPI_EVM_HASURA_ADMIN_SECRET }} + HAPI_EVM_DATABASE_URL: ${{ secrets.HAPI_EVM_DATABASE_URL }} + HAPI_EVM_ENDPOINT: 'https://telos.net/evm' + HAPI_EVM_API_ENDPOINTS: '["https://telos.greymass.com","https://telos.eosphere.io","telos.caleos.io","mainnet.telosusa.io"]' + HAPI_EVM_NETWORK_CHAIN_ID: 4667b205c6838ef70ff7988f6e8257e8be0e1284a2f59699054a018f743b1d11 + HAPI_EVM_EOS_EVM_ACCOUNT: ${{ secrets.HAPI_EVM_EOS_EVM_ACCOUNT }} + HAPI_EVM_BLOCK_INTERVAL_SEC: ${{ secrets.HAPI_EVM_BLOCK_INTERVAL_SEC }} + HAPI_EVM_HYPERION_API: ${{ secrets.HAPI_EVM_HYPERION_API }} + HAPI_EVM_HYPERION_START_AT: ${{ secrets.HAPI_EVM_HYPERION_START_AT }} # hasura HASURA_GRAPHQL_ENABLE_CONSOLE: 'true' HASURA_GRAPHQL_DATABASE_URL: ${{ secrets.HASURA_GRAPHQL_DATABASE_URL }} From 5a1f787a0231bd9cd796c36cda1d6826f217e3b3 Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Tue, 22 Aug 2023 13:53:39 -0600 Subject: [PATCH 54/75] fix(hapi-evm): fix token history query --- hapi-evm/src/services/token-history.service.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hapi-evm/src/services/token-history.service.ts b/hapi-evm/src/services/token-history.service.ts index 7c9ba67c..b22ea549 100644 --- a/hapi-evm/src/services/token-history.service.ts +++ b/hapi-evm/src/services/token-history.service.ts @@ -15,8 +15,8 @@ export const getTokenHistory = async (range: string) => { SELECT interval.value as datetime, - sum(CASE WHEN transfer.type = 'incoming' THEN transfer.amount END)::numeric as incoming, - sum(CASE WHEN transfer.type = 'outgoing' THEN transfer.amount END)::numeric as outgoing + COUNT(CASE WHEN transfer.type = 'incoming' THEN 1 END) as incoming, + COUNT(CASE WHEN transfer.type = 'outgoing' THEN 1 END) as outgoing FROM interval LEFT JOIN From 1454d7829f2523b150e545693a71a469562f192d Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Tue, 22 Aug 2023 14:01:28 -0600 Subject: [PATCH 55/75] chore(webapp): format incoming and outgoing data as integers --- webapp/src/routes/EVMDashboard/index.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/webapp/src/routes/EVMDashboard/index.js b/webapp/src/routes/EVMDashboard/index.js index 4ceaf690..c4259703 100644 --- a/webapp/src/routes/EVMDashboard/index.js +++ b/webapp/src/routes/EVMDashboard/index.js @@ -124,7 +124,6 @@ const EVMDashboard = () => { '
' + `${series?.name}: ${formatWithThousandSeparator( point?.y, - 2, )}` ) }, '') @@ -156,14 +155,14 @@ const EVMDashboard = () => { From d7f1cab5e0e4da1a7253e600a6870a4698af795f Mon Sep 17 00:00:00 2001 From: Leister Francisco Alvarado Campos Date: Tue, 22 Aug 2023 14:40:36 -0600 Subject: [PATCH 56/75] cicd(workflow): add missing variables --- .github/workflows/deploy-telos-testnet.yaml | 1 + .github/workflows/deploy-telos.yaml | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/deploy-telos-testnet.yaml b/.github/workflows/deploy-telos-testnet.yaml index 2f835f55..077a2b83 100644 --- a/.github/workflows/deploy-telos-testnet.yaml +++ b/.github/workflows/deploy-telos-testnet.yaml @@ -124,6 +124,7 @@ jobs: HASURA_GRAPHQL_ADMIN_SECRET: ${{ secrets.HASURA_GRAPHQL_ADMIN_SECRET }} HASURA_GRAPHQL_UNAUTHORIZED_ROLE: guest HASURA_GRAPHQL_ACTION_BASE_URL: http://dashboard-hapi:9090 + HASURA_GRAPHQL_ACTION_EVM_URL: http://dashboard-hapi-evm:9090 - name: Setup and deploy kubernetes environment uses: steebchen/kubectl@v1.1.0 diff --git a/.github/workflows/deploy-telos.yaml b/.github/workflows/deploy-telos.yaml index dab719b0..a73daf01 100644 --- a/.github/workflows/deploy-telos.yaml +++ b/.github/workflows/deploy-telos.yaml @@ -111,7 +111,7 @@ jobs: HAPI_EVM_HASURA_URL: 'http://dashboard-hasura:8080/v1/graphql' HAPI_EVM_HASURA_ADMIN_SECRET: ${{ secrets.HAPI_EVM_HASURA_ADMIN_SECRET }} HAPI_EVM_DATABASE_URL: ${{ secrets.HAPI_EVM_DATABASE_URL }} - HAPI_EVM_ENDPOINT: 'https://telos.net/evm' + HAPI_EVM_ENDPOINT: 'https://mainnet.telos.net/evm' HAPI_EVM_API_ENDPOINTS: '["https://telos.greymass.com","https://telos.eosphere.io","telos.caleos.io","mainnet.telosusa.io"]' HAPI_EVM_NETWORK_CHAIN_ID: 4667b205c6838ef70ff7988f6e8257e8be0e1284a2f59699054a018f743b1d11 HAPI_EVM_EOS_EVM_ACCOUNT: ${{ secrets.HAPI_EVM_EOS_EVM_ACCOUNT }} @@ -124,6 +124,7 @@ jobs: HASURA_GRAPHQL_ADMIN_SECRET: ${{ secrets.HASURA_GRAPHQL_ADMIN_SECRET }} HASURA_GRAPHQL_UNAUTHORIZED_ROLE: guest HASURA_GRAPHQL_ACTION_BASE_URL: http://dashboard-hapi:9090 + HASURA_GRAPHQL_ACTION_EVM_URL: http://dashboard-hapi-evm:9090 - name: Setup and deploy kubernetes environment uses: steebchen/kubectl@v1.1.0 From 0c2de2ad66504e515a4ecd1287535dcf9ace343b Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Tue, 22 Aug 2023 14:56:49 -0600 Subject: [PATCH 57/75] fix(webapp): fix tps and tpb chart using the next block instead of the latest --- webapp/src/context/state.context.js | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/webapp/src/context/state.context.js b/webapp/src/context/state.context.js index 256aac63..226e4268 100644 --- a/webapp/src/context/state.context.js +++ b/webapp/src/context/state.context.js @@ -1,4 +1,4 @@ -import React, { useEffect, useCallback } from 'react' +import React, { useEffect, useCallback, useRef } from 'react' import useLightUAL from '../hooks/useUAL' import { ualConfig } from '../config' @@ -155,9 +155,11 @@ export const useSharedState = () => { throw new Error(`useSharedState must be used within a SharedStateContext`) } + const lastBlock = useRef() + const infoInterval = useRef(null) + const [state, dispatch] = context const waitTrackingInterval = 30000 - let infoInterval let scheduleInterval let global @@ -268,7 +270,7 @@ export const useSharedState = () => { } const startTrackingInfo = async ({ interval = 1 } = {}) => { - if (infoInterval) return + if (infoInterval.current) return const handle = async () => { try { @@ -279,24 +281,31 @@ export const useSharedState = () => { payload: { ...info }, }) - await getBlock(info.head_block_num) + if (!lastBlock.current) { + lastBlock.current = info.head_block_num + } else { + lastBlock.current += 1 + } + + await getBlock(lastBlock.current) } catch (error) { console.error(error?.message || error) if (error?.message === ENDPOINTS_ERROR) { - clearInterval(infoInterval) + clearInterval(infoInterval.current) } } } - infoInterval = setInterval(handle, interval * 1000) + infoInterval.current = setInterval(handle, interval * 1000) } const stopTrackingInfo = () => { - if (!infoInterval) return + if (!infoInterval.current) return - clearInterval(infoInterval) - infoInterval = null + clearInterval(infoInterval.current) + infoInterval.current = null + lastBlock.current = null } const stopTrackingProducerSchedule = () => { From b11f379c7c12e3bcd5d86a465f4f20c7142cfbf7 Mon Sep 17 00:00:00 2001 From: codefactor-io Date: Tue, 22 Aug 2023 21:36:12 +0000 Subject: [PATCH 58/75] [CodeFactor] Apply fixes --- webapp/src/routes/EVMDashboard/useEVMstate.js | 6 +++--- webapp/src/routes/EVMEndpointsList/useRPCEndpointsState.js | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/webapp/src/routes/EVMDashboard/useEVMstate.js b/webapp/src/routes/EVMDashboard/useEVMstate.js index cafde46f..5ad9e3ec 100644 --- a/webapp/src/routes/EVMDashboard/useEVMstate.js +++ b/webapp/src/routes/EVMDashboard/useEVMstate.js @@ -110,16 +110,16 @@ const useEVMState = (theme, t) => { })) } - if (selected['txs'] !== liveOption) { + if (selected.txs !== liveOption) { getTransactionHistory({ variables: { - range: selected['txs'], + range: selected.txs, }, }) } getTokenHistory({ variables: { - range: selected['token'], + range: selected.token, }, }) diff --git a/webapp/src/routes/EVMEndpointsList/useRPCEndpointsState.js b/webapp/src/routes/EVMEndpointsList/useRPCEndpointsState.js index baafb246..2df17ed7 100644 --- a/webapp/src/routes/EVMEndpointsList/useRPCEndpointsState.js +++ b/webapp/src/routes/EVMEndpointsList/useRPCEndpointsState.js @@ -4,7 +4,7 @@ import axios from 'axios' import { evmConfig } from '../../config' const useRPCEndpointsState = () => { - const [endpoints, setEndpoints] = useState(evmConfig.endpoints.map(url => ({url, response: {}}))) + const [endpoints, setEndpoints] = useState(evmConfig.endpoints.map(url => ({ url, response: {} }))) const customAxios = axios.create() @@ -70,7 +70,7 @@ const useRPCEndpointsState = () => { const runHealthCheck = useCallback(() => { setEndpoints(prev => prev.map(endpoint => ({ url: endpoint.url, response: {} }))) - + const rpcList = JSON.parse(JSON.stringify(endpoints)) rpcList.forEach(async ({ url }, index) => { From 779ad1735b777bf25e00ec6c2fcab189ab49c8d4 Mon Sep 17 00:00:00 2001 From: Leister Francisco Alvarado Campos Date: Wed, 23 Aug 2023 14:04:28 -0600 Subject: [PATCH 59/75] cicd(meta): add missinng subdir --- utils/meta.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/utils/meta.mk b/utils/meta.mk index 64912889..ca022414 100644 --- a/utils/meta.mk +++ b/utils/meta.mk @@ -9,7 +9,7 @@ IMAGE_NAME_HASURA=dashboard-hasura IMAGE_NAME_WALLET=dashboard-wallet DOCKER_REGISTRY=ghcr.io/edenia -SUBDIRS = webapp hapi hasura wallet +SUBDIRS = webapp hapi hasura wallet hapi-evm MAKE_ENV += DOCKER_REGISTRY VERSION IMAGE_NAME_WEBAPP IMAGE_NAME_HAPI IMAGE_NAME_HAPI_EVM IMAGE_NAME_WALLET IMAGE_NAME_HASURA From 4ef7fbbcaceb4182babdbe1ff023e0554cf8a70f Mon Sep 17 00:00:00 2001 From: Leister Francisco Alvarado Campos Date: Wed, 23 Aug 2023 14:51:54 -0600 Subject: [PATCH 60/75] fix(makefile): update container variable reference --- hapi-evm/makefile | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/hapi-evm/makefile b/hapi-evm/makefile index c6d78f46..f5c9a0e0 100644 --- a/hapi-evm/makefile +++ b/hapi-evm/makefile @@ -17,26 +17,26 @@ run: node_modules build-docker: ##@devops Build the docker image build-docker: ./Dockerfile - @docker pull $(DOCKER_REGISTRY)/$(IMAGE_NAME_HAPI):$(VERSION) || true + @docker pull $(DOCKER_REGISTRY)/$(IMAGE_NAME_HAPI_EVM):$(VERSION) || true @docker build \ --target release \ - -t $(DOCKER_REGISTRY)/$(IMAGE_NAME_HAPI):$(VERSION) \ - -t $(DOCKER_REGISTRY)/$(IMAGE_NAME_HAPI):$(LATEST_TAG) \ + -t $(DOCKER_REGISTRY)/$(IMAGE_NAME_HAPI_EVM):$(VERSION) \ + -t $(DOCKER_REGISTRY)/$(IMAGE_NAME_HAPI_EVM):$(LATEST_TAG) \ . pull-image: ##@devops Pull the latest image from registry for caching pull-image: - @docker pull $(DOCKER_REGISTRY)/$(IMAGE_NAME_HAPI):$(LATEST_TAG) || true + @docker pull $(DOCKER_REGISTRY)/$(IMAGE_NAME_HAPI_EVM):$(LATEST_TAG) || true build-docker-cached: ##@devops Build the docker image using cached layers build-docker-cached: ./Dockerfile @docker build \ --target prod-stage \ - --cache-from $(DOCKER_REGISTRY)/$(IMAGE_NAME_HAPI):$(LATEST_TAG) \ - -t $(DOCKER_REGISTRY)/$(IMAGE_NAME_HAPI):$(VERSION) \ - -t $(DOCKER_REGISTRY)/$(IMAGE_NAME_HAPI):$(LATEST_TAG) \ + --cache-from $(DOCKER_REGISTRY)/$(IMAGE_NAME_HAPI_EVM):$(LATEST_TAG) \ + -t $(DOCKER_REGISTRY)/$(IMAGE_NAME_HAPI_EVM):$(VERSION) \ + -t $(DOCKER_REGISTRY)/$(IMAGE_NAME_HAPI_EVM):$(LATEST_TAG) \ . push-image: ##@devops Push the freshly built image and tag with release or latest tag push-image: - @docker push $(DOCKER_REGISTRY)/$(IMAGE_NAME_HAPI):$(VERSION) + @docker push $(DOCKER_REGISTRY)/$(IMAGE_NAME_HAPI_EVM):$(VERSION) From 7bd7688fac9f1c014b3663ba30316141dc18f4c6 Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Thu, 24 Aug 2023 10:19:39 -0600 Subject: [PATCH 61/75] fix(webapp): use UTC to check if endpoint is outdated --- webapp/src/utils/eosapi.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/webapp/src/utils/eosapi.js b/webapp/src/utils/eosapi.js index 3ffffe29..e772228b 100644 --- a/webapp/src/utils/eosapi.js +++ b/webapp/src/utils/eosapi.js @@ -30,7 +30,11 @@ const callEosApi = async method => { const headBlockTime = response.head_block_time if (headBlockTime) { - const diffBlockTimems = new Date() - new Date(headBlockTime) + const nowUTC = new Date() + + nowUTC.setMinutes(nowUTC.getMinutes() + nowUTC.getTimezoneOffset()) + + const diffBlockTimems = nowUTC - new Date(headBlockTime) if (diffBlockTimems > eosConfig.syncToleranceInterval) { throw new Error(`The endpoint ${eosApi.endpoint} is outdated`) From b1a2a240200c5255159a3245f877a029eeffbd51 Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Thu, 24 Aug 2023 10:35:06 -0600 Subject: [PATCH 62/75] fix(webapp): add missing env variables to makefile --- webapp/makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/webapp/makefile b/webapp/makefile index 64d0aded..57fa6142 100644 --- a/webapp/makefile +++ b/webapp/makefile @@ -51,6 +51,9 @@ build-docker: ./Dockerfile --build-arg react_app_google_analitic_page_id='$(REACT_APP_GOOGLE_ANALITIC_PAGE_ID)' \ --build-arg react_app_public_re_captcha_key='$(REACT_APP_PUBLIC_RE_CAPTCHA_KEY)' \ --build-arg react_app_sync_tolerance_interval='$(REACT_APP_SYNC_TOLERANCE_INTERVAL)' \ + --build-arg react_app_evm_endpoint='$(REACT_APP_EVM_ENDPOINT)' \ + --build-arg react_app_evm_block_explorer_url='$(REACT_APP_EVM_BLOCK_EXPLORER_URL)' \ + --build-arg react_app_evm_endpoints='$(REACT_APP_EVM_ENDPOINTS)' \ . pull-image: ##@devops Pull the latest image from registry for caching From cbd5f0bcf655da7687a6b351b91c38205b60ad95 Mon Sep 17 00:00:00 2001 From: Leister Francisco Alvarado Campos Date: Thu, 24 Aug 2023 15:45:11 -0600 Subject: [PATCH 63/75] fix(dockerfile): copy dist instead of src directory --- hapi-evm/Dockerfile | 2 +- hapi-evm/src/utils/eos.util.ts | 232 ------------------------------ hapi-evm/src/utils/eosjs-api.d.ts | 1 - 3 files changed, 1 insertion(+), 234 deletions(-) delete mode 100644 hapi-evm/src/utils/eos.util.ts delete mode 100644 hapi-evm/src/utils/eosjs-api.d.ts diff --git a/hapi-evm/Dockerfile b/hapi-evm/Dockerfile index bddff6bb..c74126ba 100644 --- a/hapi-evm/Dockerfile +++ b/hapi-evm/Dockerfile @@ -6,7 +6,7 @@ WORKDIR /app FROM base AS builder COPY package.json yarn.lock ./ RUN yarn --ignore-optional -COPY ./src ./src +COPY ./dist ./src # ---------- Release ---------- FROM base AS release diff --git a/hapi-evm/src/utils/eos.util.ts b/hapi-evm/src/utils/eos.util.ts deleted file mode 100644 index 2c33cf85..00000000 --- a/hapi-evm/src/utils/eos.util.ts +++ /dev/null @@ -1,232 +0,0 @@ -import { Api, JsonRpc } from 'eosjs' -import { JsSignatureProvider } from 'eosjs/dist/eosjs-jssig' -import fetch from 'node-fetch' -import EosApi from 'eosjs-api' - -import { eosConfig } from '../config' - -import walletUtil from './wallet.util' - -const rpc = new JsonRpc(eosConfig.endpoint, { fetch }) -const eosApi = EosApi({ - httpEndpoint: eosConfig.endpoint, - verbose: false, - fetchConfiguration: {} -}) - -const newAccount = async (accountName: string) => { - const password = await walletUtil.create(accountName) - const key = await walletUtil.createKey(accountName) - - try { - await walletUtil.unlock( - eosConfig.baseAccount, - eosConfig.baseAccountPassword - ) - } catch (error) { - console.log('Wallet already unlocked') - } - - const keys = await walletUtil.listKeys( - eosConfig.baseAccount, - eosConfig.baseAccountPassword - ) - const api = new Api({ - rpc, - chainId: eosConfig.chainId, - signatureProvider: new JsSignatureProvider(keys) - }) - const authorization = [ - { - actor: eosConfig.baseAccount, - permission: 'active' - } - ] - - const transaction = await api.transact( - { - actions: [ - { - authorization, - account: 'eosio', - name: 'newaccount', - data: { - creator: eosConfig.baseAccount, - name: accountName, - owner: { - threshold: 1, - keys: [ - { - key, - weight: 1 - } - ], - accounts: [], - waits: [] - }, - active: { - threshold: 1, - keys: [ - { - key, - weight: 1 - } - ], - accounts: [], - waits: [] - } - } - }, - { - authorization, - account: 'eosio', - name: 'buyrambytes', - data: { - payer: eosConfig.baseAccount, - receiver: accountName, - bytes: 4096 - } - }, - { - authorization, - account: 'eosio', - name: 'delegatebw', - data: { - from: eosConfig.baseAccount, - receiver: accountName, - stake_net_quantity: '1.0000 EOS', - stake_cpu_quantity: '1.0000 EOS', - transfer: false - } - } - ] - }, - { - blocksBehind: 3, - expireSeconds: 30 - } - ) - await walletUtil.lock(eosConfig.baseAccount) - - return { - password, - transaction - } -} - -const generateRandomAccountName = async (prefix = ''): Promise => { - const length = 12 - - if (prefix.length === 12) return prefix - - const characters = 'abcdefghijklmnopqrstuvwxyz12345' - let accountName = prefix - - while (accountName.length < length) { - accountName = `${accountName}${characters.charAt( - Math.floor(Math.random() * characters.length) - )}` - } - - try { - const account = await getAccount(accountName) - - return account ? generateRandomAccountName(prefix) : accountName - } catch (error) { - return accountName - } -} - -const getAbi = (account: string) => eosApi.getAbi(account) - -const getAccount = async (account: string) => { - try { - const accountInfo = await eosApi.getAccount(account) - - return accountInfo - } catch (error) { - return null - } -} - -const getBlock = async (blockNumber: number) => { - try { - const block = await eosApi.getBlock(blockNumber) - - return block - } catch (error) { - return null - } -} - -const getCodeHash = (account: string) => eosApi.getCodeHash(account) - -const getCurrencyBalance = (code: string, account: string, symbol: string) => - eosApi.getCurrencyBalance(code, account, symbol) - -const getTableRows = (options: any) => - eosApi.getTableRows({ json: true, ...options }) - -const transact = async (actions: any, auths: any) => { - try { - const keys = [] - - for (let index = 0; index < auths.length; index++) { - const auth = auths[index] - try { - await walletUtil.unlock(auth.account, auth.password) - } catch (error) { - console.log('Wallet already unlocked') - } - - try { - keys.push(...(await walletUtil.listKeys(auth.account, auth.password))) - } catch (error) { - console.log('Key already exists') - } - } - - const api = new Api({ - rpc, - chainId: eosConfig.chainId, - signatureProvider: new JsSignatureProvider(keys) - }) - - const transaction = await api.transact( - { - actions - }, - { - blocksBehind: 3, - expireSeconds: 30 - } - ) - - for (let index = 0; index < auths.length; index++) { - try { - const auth = auths[index] - await walletUtil.lock(auth.account) - } catch (error) { - console.log('Wallet already locked') - } - } - - return transaction - } catch (error: any) { - throw new Error( - error.message.replace(/assertion failure with message: /gi, '') - ) - } -} - -export default { - newAccount, - generateRandomAccountName, - getAccount, - getBlock, - getAbi, - getCodeHash, - getCurrencyBalance, - getTableRows, - transact -} diff --git a/hapi-evm/src/utils/eosjs-api.d.ts b/hapi-evm/src/utils/eosjs-api.d.ts deleted file mode 100644 index 610f2697..00000000 --- a/hapi-evm/src/utils/eosjs-api.d.ts +++ /dev/null @@ -1 +0,0 @@ -declare module 'eosjs-api' From ae48e6c2d6b2f16e565361bb016850efdea7b5ee Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Thu, 24 Aug 2023 16:15:03 -0600 Subject: [PATCH 64/75] chore(webapp): UI/UX adjustment in faucet page --- webapp/src/language/en.json | 4 ++-- webapp/src/language/es.json | 4 ++-- webapp/src/routes/Faucet/index.js | 11 +++++------ webapp/src/routes/Faucet/styles.js | 2 +- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/webapp/src/language/en.json b/webapp/src/language/en.json index fc430ca8..425749e6 100644 --- a/webapp/src/language/en.json +++ b/webapp/src/language/en.json @@ -204,8 +204,8 @@ "accountName": "Account Name", "invalidAccount": "Please enter a valid account name", "emptyFields": "Fill out the fields to create an account", - "accountFormat": "Must be 12 or less characters and can contain from 'a' to 'z' in lower case and numbers from 1 to 5", - "keyFormat": "Please enter a valid key. Generate it with cleos or a compatible wallet" + "accountFormat": "Must be 12 or less characters and can contain from 'a' to 'z' in lowercase and numbers from 1 to 5", + "keyFormat": "Please enter a ECC valid key. Generate it with cleos or a compatible wallet" }, "ricardianContractRoute": { "title": "Block Producer Agreement" diff --git a/webapp/src/language/es.json b/webapp/src/language/es.json index 0ddf13ed..972c918d 100644 --- a/webapp/src/language/es.json +++ b/webapp/src/language/es.json @@ -210,8 +210,8 @@ "accountName": "Nombre de la cuenta", "invalidAccount": "Ingrese un nombre de cuenta válido", "emptyFields": "Rellene todos los campos para crear la cuenta", - "accountFormat": "Debe tener 12 caracteres o menos y puede contener desde la a 'a' la 'z' en minúsculas y números del 1 al 5", - "keyFormat": "Ingrese una llave válida. Puede generarla con cleos o cualquier wallet compatible" + "accountFormat": "Debe tener 12 caracteres o menos y puede contener desde la letra 'a' a la 'z' en minúsculas y números del 1 al 5", + "keyFormat": "Ingrese una llave ECC válida. Puede generarla con cleos o cualquier wallet compatible" }, "ricardianContractRoute": { "title": "Acuerdo de Productor de Bloques" diff --git a/webapp/src/routes/Faucet/index.js b/webapp/src/routes/Faucet/index.js index 8276b86d..6a18f6be 100644 --- a/webapp/src/routes/Faucet/index.js +++ b/webapp/src/routes/Faucet/index.js @@ -103,9 +103,9 @@ const Faucet = () => { const reCaptchaToken = await executeRecaptcha?.('submit') - if (!reCaptchaToken || !account) return + if (!reCaptchaToken) return - if (!isValidAccountName(account)) { + if (!account || !isValidAccountName(account)) { showMessage({ type: 'error', content: t('invalidAccount'), @@ -160,7 +160,7 @@ const Faucet = () => {
@@ -180,7 +180,6 @@ const Faucet = () => { ...{ publicKey: e.target.value }, }) } - error={!createAccountValues.publicKey} helperText={t('keyFormat')} required /> @@ -198,7 +197,7 @@ const Faucet = () => { ...{ accountName: e.target.value }, }) } - error={!isValidAccountName(createAccountValues.accountName)} + error={!!createAccountValues.accountName && !isValidAccountName(createAccountValues.accountName)} helperText={t('accountFormat')} required /> @@ -238,7 +237,7 @@ const Faucet = () => { variant="outlined" value={account} onChange={(e) => setAccount(e.target.value)} - error={!isValidAccountName(account)} + error={!!account && !isValidAccountName(account)} helperText={t('accountFormat')} required /> diff --git a/webapp/src/routes/Faucet/styles.js b/webapp/src/routes/Faucet/styles.js index 8011f37b..03c5538b 100644 --- a/webapp/src/routes/Faucet/styles.js +++ b/webapp/src/routes/Faucet/styles.js @@ -1,6 +1,6 @@ export default (theme) => ({ formControl: { - margin: theme.spacing(4), + margin: theme.spacing(6, 4, 4), display: 'flex', flexDirection: 'column', gap: theme.spacing(4), From e99efa6127f210260282928bf4e8ada8382d432b Mon Sep 17 00:00:00 2001 From: Leister Francisco Alvarado Campos Date: Thu, 24 Aug 2023 16:30:35 -0600 Subject: [PATCH 65/75] fix(dockerfile): copy dist instead of src directory --- hapi-evm/Dockerfile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/hapi-evm/Dockerfile b/hapi-evm/Dockerfile index c74126ba..76e473de 100644 --- a/hapi-evm/Dockerfile +++ b/hapi-evm/Dockerfile @@ -6,11 +6,12 @@ WORKDIR /app FROM base AS builder COPY package.json yarn.lock ./ RUN yarn --ignore-optional -COPY ./dist ./src +COPY ./ ./ +RUN yarn build # ---------- Release ---------- FROM base AS release COPY --from=builder /app/node_modules ./node_modules -COPY --from=builder /app/src ./src +COPY --from=builder /app/dist ./src USER node CMD ["node", "./src/index.js"] From e1ae1347ddebfba17ec8ca99a3d61e3776d594a6 Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Thu, 24 Aug 2023 17:45:36 -0600 Subject: [PATCH 66/75] fix(webapp): avoid invalid array length error --- webapp/src/config/evm.config.js | 4 ++-- webapp/src/routes/EVMDashboard/index.js | 9 +++++---- webapp/src/routes/EVMDashboard/useEVMstate.js | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/webapp/src/config/evm.config.js b/webapp/src/config/evm.config.js index 71e78e05..972b2fde 100644 --- a/webapp/src/config/evm.config.js +++ b/webapp/src/config/evm.config.js @@ -8,7 +8,7 @@ switch (eosConfig.networkName) { _avgBlockTime = 0.5 break case 'jungle': - case 'eos': + case 'mainnet': _avgBlockTime = 1 break default: @@ -16,7 +16,7 @@ switch (eosConfig.networkName) { } export const avgBlockTime = _avgBlockTime -export const maxTPSDataSize = 30 / _avgBlockTime +export const maxTPSDataSize = 30 / _avgBlockTime || 0 export const account = 'eosio.evm' export const endpoint = process.env.REACT_APP_EVM_ENDPOINT export const blockExplorerUrl = process.env.REACT_APP_EVM_BLOCK_EXPLORER_URL diff --git a/webapp/src/routes/EVMDashboard/index.js b/webapp/src/routes/EVMDashboard/index.js index c4259703..1d68689d 100644 --- a/webapp/src/routes/EVMDashboard/index.js +++ b/webapp/src/routes/EVMDashboard/index.js @@ -29,7 +29,7 @@ const EVMDashboard = () => { loading, selected, isPaused, - isLive + isLive, }, { handleSelect, handlePause }, ] = useEVMState(theme, t) @@ -47,7 +47,7 @@ const EVMDashboard = () => { value={formatWithThousandSeparator(EVMStats?.total_transactions) || 0} loading={loading} /> -
+
{ : '' return ( - pointName + '
' + + pointName + + '
' + `${series?.name}: ${point?.y}` + resourcesDetail ) @@ -96,7 +97,7 @@ const EVMDashboard = () => {
{ const { data: stats, loading } = useSubscription(EVM_STATS_SUBSCRIPTION) From 5e301f40f30a5f7a2741aae582ebf99ab83bf942 Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Thu, 24 Aug 2023 17:51:17 -0600 Subject: [PATCH 67/75] chore(workflows): format code --- .github/workflows/deploy-telos.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy-telos.yaml b/.github/workflows/deploy-telos.yaml index d44a0596..a50d9c64 100644 --- a/.github/workflows/deploy-telos.yaml +++ b/.github/workflows/deploy-telos.yaml @@ -62,7 +62,7 @@ jobs: REACT_APP_GOOGLE_ANALITIC_PAGE_ID: 'G-E6Y0EC9FT8' REACT_APP_PUBLIC_RE_CAPTCHA_KEY: ${{ secrets.REACT_APP_PUBLIC_RE_CAPTCHA_KEY }} REACT_APP_EVM_ENDPOINT: 'https://mainnet.telos.net/evm' - REACT_APP_EVM_BLOCK_EXPLORER_URL: https://www.teloscan.io/block/(block) + REACT_APP_EVM_BLOCK_EXPLORER_URL: 'https://www.teloscan.io/block/(block)' REACT_APP_EVM_ENDPOINTS: '[\"https://rpc1.eu.telos.net/evm\",\"https://api.kainosbp.com/evm\",\"https://mainnet.telos.net/evm\",\"https://rpc1.us.telos.net/evm\",\"https://rpc2.eu.telos.net/evm\",\"https://rpc2.us.telos.net/evm\",\"https://evm.teloskorea.com/evm\",\"https://rpc2.teloskorea.com/evm\",\"https://rpc01.us.telosunlimited.io/evm\"]' - name: Build and deploy kubernetes files From 05a07adec7c0f388afe4d4a7cbf1e285cc4d4814 Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Thu, 24 Aug 2023 19:06:27 -0600 Subject: [PATCH 68/75] fix(webapp): fix highcharts error --- webapp/src/routes/EVMDashboard/index.js | 1 + webapp/src/routes/EVMDashboard/useEVMstate.js | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/webapp/src/routes/EVMDashboard/index.js b/webapp/src/routes/EVMDashboard/index.js index 1d68689d..296a4f55 100644 --- a/webapp/src/routes/EVMDashboard/index.js +++ b/webapp/src/routes/EVMDashboard/index.js @@ -106,6 +106,7 @@ const EVMDashboard = () => { options: options, onSelect: option => handleSelect('token', option), isHistoryEnabled: true, + isLive: false, }} data={tokenHistoryData} chartLabelFormat={{ diff --git a/webapp/src/routes/EVMDashboard/useEVMstate.js b/webapp/src/routes/EVMDashboard/useEVMstate.js index 9d555153..04bd1526 100644 --- a/webapp/src/routes/EVMDashboard/useEVMstate.js +++ b/webapp/src/routes/EVMDashboard/useEVMstate.js @@ -136,13 +136,13 @@ const useEVMState = (theme, t) => { history.incoming.push({ name, - y: tokenHistory.incoming || 0, + y: parseInt(tokenHistory.incoming) || 0, x: datetime, }) history.outgoing.push({ name, - y: tokenHistory.outgoing || 0, + y: parseInt(tokenHistory.outgoing) || 0, x: datetime, }) @@ -171,7 +171,7 @@ const useEVMState = (theme, t) => { const data = transactionsData?.transactions.map((transaction) => ({ name: moment(transaction.datetime)?.format('ll'), gas: transaction.avg_gas_used || 0, - y: transaction.transactions_count || 0, + y: parseInt(transaction.transactions_count) || 0, x: new Date(transaction.datetime).getTime(), })) From dac4581be89f164c5f2acc80ae5d379bef17c20c Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Fri, 25 Aug 2023 13:59:33 -0600 Subject: [PATCH 69/75] chore(hapi-evm): use env variables to config the intervals --- hapi-evm/src/config/network.config.ts | 15 +++++++++++++++ hapi-evm/src/models/block/queries.ts | 5 ++++- hapi-evm/src/models/transfer/queries.ts | 5 ++++- hapi-evm/src/services/block.service.ts | 8 ++++---- hapi-evm/src/services/transfer.service.ts | 3 ++- 5 files changed, 29 insertions(+), 7 deletions(-) diff --git a/hapi-evm/src/config/network.config.ts b/hapi-evm/src/config/network.config.ts index 8c1449c4..6e5ed10f 100644 --- a/hapi-evm/src/config/network.config.ts +++ b/hapi-evm/src/config/network.config.ts @@ -7,3 +7,18 @@ export const eosEndpoints = export const blockIntervalSec = parseFloat( process.env.HAPI_EVM_BLOCK_INTERVAL_SEC || '0.5' ) +export const oldBlockIntervalSec = parseFloat( + process.env.HAPI_EVM_OLD_BLOCK_INTERVAL_SEC || '0.1' +) +export const ATHIntervalSec = parseFloat( + process.env.HAPI_EVM_ATH_INTERVAL_SEC || '60' +) +export const cleanOldBlockIntervalSec = parseFloat( + process.env.HAPI_EVM_CLEAN_OLD_BLOCK_INTERVAL_SEC || '86400' +) +export const cleanOldTransferIntervalSec = parseFloat( + process.env.HAPI_EVM_CLEAN_OLD_TRANSFER_INTERVAL_SEC || '86400' +) +export const keepHistoryForYears = parseFloat( + process.env.HAPI_EVM_KEEP_HISTORY_FOR_YEARS || '1' +) diff --git a/hapi-evm/src/models/block/queries.ts b/hapi-evm/src/models/block/queries.ts index 0982b0a5..5fbfcbfb 100644 --- a/hapi-evm/src/models/block/queries.ts +++ b/hapi-evm/src/models/block/queries.ts @@ -1,6 +1,7 @@ import moment from 'moment' import { gql } from 'graphql-request' +import { networkConfig } from '../../config' import { coreUtil } from '../../utils' import { OperationType, TableType, Operation } from '../default.model' import { CappedBlock } from './interfaces' @@ -139,7 +140,9 @@ export const deleteOldBlocks = async () => { ` await coreUtil.hasura.default.request(mutation, { - date: moment().subtract(1, 'years').format('YYYY-MM-DD') + date: moment() + .subtract(networkConfig.keepHistoryForYears, 'years') + .format('YYYY-MM-DD') }) } diff --git a/hapi-evm/src/models/transfer/queries.ts b/hapi-evm/src/models/transfer/queries.ts index e763791e..7d6b454c 100644 --- a/hapi-evm/src/models/transfer/queries.ts +++ b/hapi-evm/src/models/transfer/queries.ts @@ -1,6 +1,7 @@ import moment from 'moment' import { gql } from 'graphql-request' +import { networkConfig } from '../../config' import { coreUtil } from '../../utils' import { Transfer, Type } from './interfaces' import { historicalStatsModel } from '..' @@ -59,6 +60,8 @@ export const deleteOldTransfers = async () => { ` await coreUtil.hasura.default.request(mutation, { - date: moment().subtract(1, 'years').format('YYYY-MM-DD') + date: moment() + .subtract(networkConfig.keepHistoryForYears, 'years') + .format('YYYY-MM-DD') }) } diff --git a/hapi-evm/src/services/block.service.ts b/hapi-evm/src/services/block.service.ts index 458563ab..55feedcb 100644 --- a/hapi-evm/src/services/block.service.ts +++ b/hapi-evm/src/services/block.service.ts @@ -50,7 +50,7 @@ const syncFullBlock = async (blockNumber: number | bigint) => { const blockTimestamp = new Date(Number(block.timestamp) * 1000) const isBefore = moment(blockTimestamp).isBefore( - moment().subtract(1, 'years') + moment().subtract(networkConfig.keepHistoryForYears, 'years') ) if (isBefore) return @@ -186,7 +186,7 @@ const syncBlockWorker = (): defaultModel.Worker => { const syncOldBlockWorker = (): defaultModel.Worker => { return { name: 'SYNC OLD BLOCK WORKER', - intervalSec: 0.1, + intervalSec: networkConfig.oldBlockIntervalSec, action: syncOldBlocks } } @@ -194,7 +194,7 @@ const syncOldBlockWorker = (): defaultModel.Worker => { const syncATHWorker = (): defaultModel.Worker => { return { name: 'SYNC ATH WORKER', - intervalSec: 60, + intervalSec: networkConfig.ATHIntervalSec, action: syncATH } } @@ -202,7 +202,7 @@ const syncATHWorker = (): defaultModel.Worker => { const cleanOldBlocksWorker = (): defaultModel.Worker => { return { name: 'CLEAN UP OLD BLOCKS WORKER', - intervalSec: 86400, + intervalSec: networkConfig.cleanOldBlockIntervalSec, action: cleanOldBlocks } } diff --git a/hapi-evm/src/services/transfer.service.ts b/hapi-evm/src/services/transfer.service.ts index ab8faa81..a8013094 100644 --- a/hapi-evm/src/services/transfer.service.ts +++ b/hapi-evm/src/services/transfer.service.ts @@ -1,9 +1,10 @@ import { defaultModel, transferModel } from '../models' +import { networkConfig } from '../config' const cleanOldTransfersWorker = (): defaultModel.Worker => { return { name: 'CLEAN UP OLD TRANSFER WORKER', - intervalSec: 86400, + intervalSec: networkConfig.cleanOldTransferIntervalSec, action: async () => { await transferModel.queries.deleteOldTransfers() } From 84bd5608f29407fffe820fdad610c63becc0addb Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Fri, 25 Aug 2023 14:05:12 -0600 Subject: [PATCH 70/75] chore(kubernetes): add env variables for evm services config --- docker-compose.yaml | 5 +++++ kubernetes/configmap-dashboard.yaml | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/docker-compose.yaml b/docker-compose.yaml index 1197418e..805e5ffd 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -96,6 +96,11 @@ services: HAPI_EVM_BLOCK_INTERVAL_SEC: '${HAPI_EVM_BLOCK_INTERVAL_SEC}' HAPI_EVM_HYPERION_API: '${HAPI_EVM_HYPERION_API}' HAPI_EVM_HYPERION_START_AT: '${HAPI_EVM_HYPERION_START_AT}' + HAPI_EVM_OLD_BLOCK_INTERVAL_SEC: '${HAPI_EVM_OLD_BLOCK_INTERVAL_SEC}' + HAPI_EVM_ATH_INTERVAL_SEC: '${HAPI_EVM_ATH_INTERVAL_SEC}' + HAPI_EVM_CLEAN_OLD_BLOCK_INTERVAL_SEC: '${HAPI_EVM_CLEAN_OLD_BLOCK_INTERVAL_SEC}' + HAPI_EVM_CLEAN_OLD_TRANSFER_INTERVAL_SEC: '${HAPI_EVM_CLEAN_OLD_TRANSFER_INTERVAL_SEC}' + HAPI_EVM_KEEP_HISTORY_FOR_YEARS: '${HAPI_EVM_KEEP_HISTORY_FOR_YEARS}' hasura: container_name: '${STAGE}-${APP_NAME}-hasura' image: hasura/graphql-engine:v2.16.0.cli-migrations-v3 diff --git a/kubernetes/configmap-dashboard.yaml b/kubernetes/configmap-dashboard.yaml index 486e8492..639c4e07 100644 --- a/kubernetes/configmap-dashboard.yaml +++ b/kubernetes/configmap-dashboard.yaml @@ -120,6 +120,11 @@ data: HAPI_EVM_NETWORK_CHAIN_ID: '${HAPI_EVM_NETWORK_CHAIN_ID}' HAPI_EVM_EOS_EVM_ACCOUNT: '${HAPI_EVM_EOS_EVM_ACCOUNT}' HAPI_EVM_BLOCK_INTERVAL_SEC: '${HAPI_EVM_BLOCK_INTERVAL_SEC}' + HAPI_EVM_OLD_BLOCK_INTERVAL_SEC: '${HAPI_EVM_OLD_BLOCK_INTERVAL_SEC}' + HAPI_EVM_ATH_INTERVAL_SEC: '${HAPI_EVM_ATH_INTERVAL_SEC}' + HAPI_EVM_CLEAN_OLD_BLOCK_INTERVAL_SEC: '${HAPI_EVM_CLEAN_OLD_BLOCK_INTERVAL_SEC}' + HAPI_EVM_CLEAN_OLD_TRANSFER_INTERVAL_SEC: '${HAPI_EVM_CLEAN_OLD_TRANSFER_INTERVAL_SEC}' + HAPI_EVM_KEEP_HISTORY_FOR_YEARS: '${HAPI_EVM_KEEP_HISTORY_FOR_YEARS}' HAPI_EVM_HYPERION_API: '${HAPI_EVM_HYPERION_API}' HAPI_EVM_HYPERION_START_AT: '${HAPI_EVM_HYPERION_START_AT}' --- From 097149f0877132bbd0e2706a56df6f5d80b408e0 Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Fri, 25 Aug 2023 14:14:14 -0600 Subject: [PATCH 71/75] chore(workflows): add env variables for evm services config --- .github/workflows/deploy-telos-testnet.yaml | 5 +++++ .github/workflows/deploy-telos.yaml | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/.github/workflows/deploy-telos-testnet.yaml b/.github/workflows/deploy-telos-testnet.yaml index 7235e839..3cbd1e9a 100644 --- a/.github/workflows/deploy-telos-testnet.yaml +++ b/.github/workflows/deploy-telos-testnet.yaml @@ -119,6 +119,11 @@ jobs: HAPI_EVM_NETWORK_CHAIN_ID: 1eaa0824707c8c16bd25145493bf062aecddfeb56c736f6ba6397f3195f33c9f HAPI_EVM_EOS_EVM_ACCOUNT: ${{ secrets.HAPI_EVM_EOS_EVM_ACCOUNT }} HAPI_EVM_BLOCK_INTERVAL_SEC: ${{ secrets.HAPI_EVM_BLOCK_INTERVAL_SEC }} + HAPI_EVM_OLD_BLOCK_INTERVAL_SEC: ${{ secrets.HAPI_EVM_OLD_BLOCK_INTERVAL_SEC }} + HAPI_EVM_ATH_INTERVAL_SEC: ${{ secrets.HAPI_EVM_ATH_INTERVAL_SEC }} + HAPI_EVM_CLEAN_OLD_BLOCK_INTERVAL_SEC: ${{ secrets.HAPI_EVM_CLEAN_OLD_BLOCK_INTERVAL_SEC }} + HAPI_EVM_CLEAN_OLD_TRANSFER_INTERVAL_SEC: ${{ secrets.HAPI_EVM_CLEAN_OLD_TRANSFER_INTERVAL_SEC }} + HAPI_EVM_KEEP_HISTORY_FOR_YEARS: ${{ secrets.HAPI_EVM_KEEP_HISTORY_FOR_YEARS }} HAPI_EVM_HYPERION_API: ${{ secrets.HAPI_EVM_HYPERION_API }} HAPI_EVM_HYPERION_START_AT: ${{ secrets.HAPI_EVM_HYPERION_START_AT }} # hasura diff --git a/.github/workflows/deploy-telos.yaml b/.github/workflows/deploy-telos.yaml index fa9748e1..3cf0807e 100644 --- a/.github/workflows/deploy-telos.yaml +++ b/.github/workflows/deploy-telos.yaml @@ -119,6 +119,11 @@ jobs: HAPI_EVM_NETWORK_CHAIN_ID: 4667b205c6838ef70ff7988f6e8257e8be0e1284a2f59699054a018f743b1d11 HAPI_EVM_EOS_EVM_ACCOUNT: ${{ secrets.HAPI_EVM_EOS_EVM_ACCOUNT }} HAPI_EVM_BLOCK_INTERVAL_SEC: ${{ secrets.HAPI_EVM_BLOCK_INTERVAL_SEC }} + HAPI_EVM_OLD_BLOCK_INTERVAL_SEC: ${{ secrets.HAPI_EVM_OLD_BLOCK_INTERVAL_SEC }} + HAPI_EVM_ATH_INTERVAL_SEC: ${{ secrets.HAPI_EVM_ATH_INTERVAL_SEC }} + HAPI_EVM_CLEAN_OLD_BLOCK_INTERVAL_SEC: ${{ secrets.HAPI_EVM_CLEAN_OLD_BLOCK_INTERVAL_SEC }} + HAPI_EVM_CLEAN_OLD_TRANSFER_INTERVAL_SEC: ${{ secrets.HAPI_EVM_CLEAN_OLD_TRANSFER_INTERVAL_SEC }} + HAPI_EVM_KEEP_HISTORY_FOR_YEARS: ${{ secrets.HAPI_EVM_KEEP_HISTORY_FOR_YEARS }} HAPI_EVM_HYPERION_API: ${{ secrets.HAPI_EVM_HYPERION_API }} HAPI_EVM_HYPERION_START_AT: ${{ secrets.HAPI_EVM_HYPERION_START_AT }} # hasura From c3325fea47dac909053c52ee046f3e2ac90a0b39 Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Fri, 25 Aug 2023 15:03:29 -0600 Subject: [PATCH 72/75] chore(envs): add env variables for evm services config --- .env.telos | 11 ++++++++--- .env.telostestnet | 8 +++++++- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/.env.telos b/.env.telos index 2bcd0802..8f9200cd 100644 --- a/.env.telos +++ b/.env.telos @@ -62,11 +62,16 @@ HAPI_EVM_SERVER_ADDRESS=hapi-evm HAPI_EVM_HASURA_URL=http://hasura:8080/v1/graphql HAPI_EVM_HASURA_ADMIN_SECRET=myadminsecretkey HAPI_EVM_DATABASE_URL=postgres://eoscr:password@postgres:5432/localdb -HAPI_EVM_ENDPOINT=https://testnet.telos.net/evm +HAPI_EVM_ENDPOINT=https://mainnet.telos.net/evm HAPI_EVM_API_ENDPOINTS=["https://telos.greymass.com","https://telos.eosphere.io","telos.caleos.io","mainnet.telosusa.io"] HAPI_EVM_NETWORK_CHAIN_ID=4667b205c6838ef70ff7988f6e8257e8be0e1284a2f59699054a018f743b1d11 HAPI_EVM_EOS_EVM_ACCOUNT=eosio.evm -HAPI_EVM_BLOCK_INTERVAL_SEC=0.3 +HAPI_EVM_BLOCK_INTERVAL_SEC=0.5 +HAPI_EVM_OLD_BLOCK_INTERVAL_SEC=0.1 +HAPI_EVM_ATH_INTERVAL_SEC=60 +HAPI_EVM_CLEAN_OLD_BLOCK_INTERVAL_SEC=86400 +HAPI_EVM_CLEAN_OLD_TRANSFER_INTERVAL_SEC=86400 +HAPI_EVM_KEEP_HISTORY_FOR_YEARS=1 HAPI_EVM_HYPERION_API=https://telos.eosusa.io HAPI_EVM_HYPERION_START_AT=2021-06-02T00:00:00.000+00:00 @@ -102,6 +107,6 @@ REACT_APP_STATE_HISTORY_ENABLED=false REACT_APP_GOOGLE_ANALITIC_PAGE_ID=G-E6Y0EC9FT8 REACT_APP_PUBLIC_RE_CAPTCHA_KEY=key REACT_APP_EOS_INCLUDE_TRANSACTION= -REACT_APP_EVM_ENDPOINT='https://mainnet.telos.net/evm' +REACT_APP_EVM_ENDPOINT=https://mainnet.telos.net/evm REACT_APP_EVM_BLOCK_EXPLORER_URL=https://www.teloscan.io/block/(block) REACT_APP_EVM_ENDPOINTS=["https://mainnet.telos.net/evm","https://rpc1.eu.telos.net/evm","https://rpc1.us.telos.net/evm","https://rpc2.us.telos.net/evm","https://api.kainosbp.com/evm","https://rpc2.eu.telos.net/evm","https://evm.teloskorea.com/evm","https://rpc2.teloskorea.com/evm","https://rpc01.us.telosunlimited.io/evm"] diff --git a/.env.telostestnet b/.env.telostestnet index 02d84d84..335da79c 100644 --- a/.env.telostestnet +++ b/.env.telostestnet @@ -17,6 +17,7 @@ HASURA_GRAPHQL_DATABASE_URL=postgres://eoscr:password@postgres:5432/localdb HASURA_GRAPHQL_ADMIN_SECRET=myadminsecretkey HASURA_GRAPHQL_UNAUTHORIZED_ROLE=guest HASURA_GRAPHQL_ACTION_BASE_URL=http://hapi:9090 +HASURA_GRAPHQL_ACTION_EVM_URL=http://hapi-evm:9090 # hapi HAPI_EOS_API_NETWORK_NAME=telos @@ -66,7 +67,12 @@ HAPI_EVM_ENDPOINT=https://testnet.telos.net/evm HAPI_EVM_API_ENDPOINTS=["https://telos-testnet.edenia.cloud","https://telos-testnet.cryptolions.io","https://testnet.telos.eosrio.io","https://test.telos.eosusa.io"] HAPI_EVM_NETWORK_CHAIN_ID=1eaa0824707c8c16bd25145493bf062aecddfeb56c736f6ba6397f3195f33c9f HAPI_EVM_EOS_EVM_ACCOUNT=eosio.evm -HAPI_EVM_BLOCK_INTERVAL_SEC=0.3 +HAPI_EVM_BLOCK_INTERVAL_SEC=0.5 +HAPI_EVM_OLD_BLOCK_INTERVAL_SEC=0.1 +HAPI_EVM_ATH_INTERVAL_SEC=60 +HAPI_EVM_CLEAN_OLD_BLOCK_INTERVAL_SEC=86400 +HAPI_EVM_CLEAN_OLD_TRANSFER_INTERVAL_SEC=86400 +HAPI_EVM_KEEP_HISTORY_FOR_YEARS=1 HAPI_EVM_HYPERION_API=https://test.telos.eosusa.io HAPI_EVM_HYPERION_START_AT=2021-06-02T00:00:00.000+00:00 From e09058170347f1e365ad4adf65cf5b0560b78543 Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Fri, 25 Aug 2023 16:24:32 -0600 Subject: [PATCH 73/75] chore(webapp): small text adjustments --- webapp/src/language/en.json | 6 +++--- webapp/src/language/es.json | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/webapp/src/language/en.json b/webapp/src/language/en.json index 425749e6..a0d0fff9 100644 --- a/webapp/src/language/en.json +++ b/webapp/src/language/en.json @@ -194,7 +194,7 @@ "bpjsonInconsistency": "The bp.json on chain and of chain does not match, review it and make the necessary changes" }, "faucetRoute": { - "createAccount": "Create Faucet Account", + "createAccount": "Create a New Account", "newCreatedAccount": "Your new account is", "transferTokensTransaction": "Tokens transferred correctly. Check it on explorer here", "createButton": "Create Account", @@ -204,8 +204,8 @@ "accountName": "Account Name", "invalidAccount": "Please enter a valid account name", "emptyFields": "Fill out the fields to create an account", - "accountFormat": "Must be 12 or less characters and can contain from 'a' to 'z' in lowercase and numbers from 1 to 5", - "keyFormat": "Please enter a ECC valid key. Generate it with cleos or a compatible wallet" + "accountFormat": "Must be 12 characters or less and can contain from 'a' to 'z' in lowercase and numbers from 1 to 5", + "keyFormat": "Please enter a valid ECC key. Generate it with cleos or a compatible wallet" }, "ricardianContractRoute": { "title": "Block Producer Agreement" diff --git a/webapp/src/language/es.json b/webapp/src/language/es.json index 972c918d..696161dc 100644 --- a/webapp/src/language/es.json +++ b/webapp/src/language/es.json @@ -200,7 +200,7 @@ "bpjsonInconsistency": "El bp.json on chain y en of chain no coincide revisalo y realiza los cambios necesarios" }, "faucetRoute": { - "createAccount": "Crear Cuenta Faucet", + "createAccount": "Crear una Nueva Cuenta", "newCreatedAccount": "Su nueva cuenta es", "transferTokensTransaction": "Tokens transferidos correctamente. Puede revisar la transacción aquí", "createButton": "Crear Cuenta", From 500f7ffa4a62d6e5bcbe7af4d693273dc5c143fa Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Fri, 25 Aug 2023 16:44:44 -0600 Subject: [PATCH 74/75] chore(hapi-evm): parse history limit as integer --- hapi-evm/src/config/network.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hapi-evm/src/config/network.config.ts b/hapi-evm/src/config/network.config.ts index 6e5ed10f..e97f6b72 100644 --- a/hapi-evm/src/config/network.config.ts +++ b/hapi-evm/src/config/network.config.ts @@ -19,6 +19,6 @@ export const cleanOldBlockIntervalSec = parseFloat( export const cleanOldTransferIntervalSec = parseFloat( process.env.HAPI_EVM_CLEAN_OLD_TRANSFER_INTERVAL_SEC || '86400' ) -export const keepHistoryForYears = parseFloat( +export const keepHistoryForYears = parseInt( process.env.HAPI_EVM_KEEP_HISTORY_FOR_YEARS || '1' ) From 92e5b36ef8367dd6b9c61c262983a1153d7a77b4 Mon Sep 17 00:00:00 2001 From: Torresmorah Date: Mon, 28 Aug 2023 10:00:18 -0600 Subject: [PATCH 75/75] chore(webapp): apply texts adjustments --- webapp/src/language/en.json | 24 ++++++++++++------------ webapp/src/language/es.json | 26 +++++++++++++------------- webapp/src/routes/Faucet/index.js | 6 +++++- 3 files changed, 30 insertions(+), 26 deletions(-) diff --git a/webapp/src/language/en.json b/webapp/src/language/en.json index a0d0fff9..a1aa60e9 100644 --- a/webapp/src/language/en.json +++ b/webapp/src/language/en.json @@ -194,18 +194,18 @@ "bpjsonInconsistency": "The bp.json on chain and of chain does not match, review it and make the necessary changes" }, "faucetRoute": { - "createAccount": "Create a New Account", - "newCreatedAccount": "Your new account is", - "transferTokensTransaction": "Tokens transferred correctly. Check it on explorer here", - "createButton": "Create Account", - "issueTokens": "Issue Tokens", - "getTokens": "Get Tokens", - "publicKey": "Public Key (Active/Owner)", - "accountName": "Account Name", - "invalidAccount": "Please enter a valid account name", - "emptyFields": "Fill out the fields to create an account", - "accountFormat": "Must be 12 characters or less and can contain from 'a' to 'z' in lowercase and numbers from 1 to 5", - "keyFormat": "Please enter a valid ECC key. Generate it with cleos or a compatible wallet" + "createAccount": "Create Your Account", + "newCreatedAccount": "Congratulations! Your new account has been created:", + "transferTokensTransaction": "Tokens have been successfully transferred. View the transaction on the explorer:", + "createButton": "Create Your Account", + "issueTokens": "Distribute Tokens", + "getTokens": "Receive Tokens", + "publicKey": "Enter Public Key (Active/Owner)", + "accountName": "Choose an Account Name", + "invalidAccount": "Enter a valid account name, please.", + "emptyFields": "Complete all fields to proceed with account creation.", + "accountFormat": "Account name should be 12 characters or fewer. Use lowercase letters (a-z) and numbers (1-5) only.", + "keyFormat": "Enter a valid ECC key. You can generate one using cleos or any compatible wallet." }, "ricardianContractRoute": { "title": "Block Producer Agreement" diff --git a/webapp/src/language/es.json b/webapp/src/language/es.json index 696161dc..65c56abb 100644 --- a/webapp/src/language/es.json +++ b/webapp/src/language/es.json @@ -140,7 +140,7 @@ "Last Week": "Última Semana", "Last Year": "Último Año", "scheduleVersion": "Versión de Programa", - "secondsAgo": "Hace Segundos", + "secondsAgo": "Hace Segundos", "cpuUtilization": "Uso de CPU", "netUtilization": "Uso de NET", "cpuUtilizationAllTimeHigh": "Uso de CPU en TPS máximo histórico", @@ -200,18 +200,18 @@ "bpjsonInconsistency": "El bp.json on chain y en of chain no coincide revisalo y realiza los cambios necesarios" }, "faucetRoute": { - "createAccount": "Crear una Nueva Cuenta", - "newCreatedAccount": "Su nueva cuenta es", - "transferTokensTransaction": "Tokens transferidos correctamente. Puede revisar la transacción aquí", - "createButton": "Crear Cuenta", - "issueTokens": "Emitir Tokens", - "getTokens": "Obtener Tokens", - "publicKey": "Llave pública (Active/Owner)", - "accountName": "Nombre de la cuenta", - "invalidAccount": "Ingrese un nombre de cuenta válido", - "emptyFields": "Rellene todos los campos para crear la cuenta", - "accountFormat": "Debe tener 12 caracteres o menos y puede contener desde la letra 'a' a la 'z' en minúsculas y números del 1 al 5", - "keyFormat": "Ingrese una llave ECC válida. Puede generarla con cleos o cualquier wallet compatible" + "createAccount": "Cree su Cuenta", + "newCreatedAccount": "¡Felicidades! Su nueva cuenta ha sido creada:", + "transferTokensTransaction": "Los tokens han sido transferidos exitosamente. Vea la transacción en el explorador:", + "createButton": "Cree su Cuenta", + "issueTokens": "Distribuya Tokens", + "getTokens": "Reciba Tokens", + "publicKey": "Introduzca la Clave Pública (Activa/Propietario)", + "accountName": "Elija un Nombre de Cuenta", + "invalidAccount": "Por favor, introduzca un nombre de cuenta válido.", + "emptyFields": "Complete todos los campos para continuar con la creación de la cuenta.", + "accountFormat": "El nombre de la cuenta debe tener 12 caracteres o menos. Utilice solo letras minúsculas (a-z) y números (1-5).", + "keyFormat": "Introduzca una clave ECC válida. Puede generar una usando cleos o cualquier billetera compatible." }, "ricardianContractRoute": { "title": "Acuerdo de Productor de Bloques" diff --git a/webapp/src/routes/Faucet/index.js b/webapp/src/routes/Faucet/index.js index 6a18f6be..dd7172eb 100644 --- a/webapp/src/routes/Faucet/index.js +++ b/webapp/src/routes/Faucet/index.js @@ -130,7 +130,11 @@ const Faucet = () => { showMessage({ type: 'success', content: ( - + {`${t('transferTokensTransaction')} ${tx.slice(0, 7)}`} ),