diff --git a/.env.local b/.env.local index 5d07ee75..6326eecc 100644 --- a/.env.local +++ b/.env.local @@ -64,7 +64,7 @@ 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://api.evm.eosnetwork.com -HAPI_EVM_API_ENDPOINTS=["https://eos.edenia.cloud","https://api.main.alohaeos.com","https://eos.api.eosnation.io","https://eos.greymass.com","https://eos.eosphere.io","https://api.eosrio.io"] +HAPI_EVM_API_ENDPOINTS=["https://eos.eosusa.io","https://api.main.alohaeos.com","https://eos.api.eosnation.io","https://eos.greymass.com","https://eos.eosphere.io","https://api.eosrio.io"] HAPI_EVM_NETWORK=EOSIO# EOSIO, TELOS HAPI_EVM_NETWORK_CHAIN_ID=aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906 HAPI_EVM_EOS_EVM_ACCOUNT=eosio.evm diff --git a/.env.telostestnet b/.env.telostestnet index c9156553..7f96f6b5 100644 --- a/.env.telostestnet +++ b/.env.telostestnet @@ -64,7 +64,7 @@ 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_API_ENDPOINTS=["https://test.telos.eosusa.io","https://telos-testnet.cryptolions.io","https://testnet.telos.eosrio.io"] HAPI_EVM_NETWORK_CHAIN_ID=1eaa0824707c8c16bd25145493bf062aecddfeb56c736f6ba6397f3195f33c9f HAPI_EVM_NETWORK=TELOS HAPI_EVM_EOS_EVM_ACCOUNT=eosio.evm diff --git a/.github/workflows/deploy-jungle-testnet.yaml b/.github/workflows/deploy-jungle-testnet.yaml index 854d4293..eca0696c 100644 --- a/.github/workflows/deploy-jungle-testnet.yaml +++ b/.github/workflows/deploy-jungle-testnet.yaml @@ -41,7 +41,7 @@ jobs: REACT_APP_EOS_API_NETWORK_NAME: jungle REACT_APP_EOS_API_NETWORK_LABEL: Jungle4 Testnet REACT_APP_EOS_API_NETWORK_LOGO: https://antelope.tools/images/jungle.jpg - REACT_APP_EOS_API_HOSTS: '[\"jungle.edenia.cloud\",\"jungle4.eosphere.io\",\"jungle4.api.eosnation.io\",\"jungle4.eossweden.org\"]' + REACT_APP_EOS_API_HOSTS: '[\"jungle.eosusa.io\",\"jungle4.eosphere.io\",\"jungle4.api.eosnation.io\",\"jungle4.eossweden.org\"]' REACT_APP_EOS_API_PORT: 443 REACT_APP_EOS_API_PROTOCOL: https REACT_APP_EOS_CHAIN_ID: 73e4385a2708e6d7048834fbc1079f2fabb17b3c125b146af438971e90716c4d @@ -80,7 +80,7 @@ jobs: POSTGRES_DB: ${{ secrets.POSTGRES_DB }} POSTGRES_DATA: ${{ secrets.POSTGRES_DATA }} # hapi - HAPI_EOS_API_ENDPOINTS: '["https://jungle.edenia.cloud","https://jungle4.eosphere.io","https://jungle4.api.eosnation.io","https://jungle4.eossweden.org"]' + HAPI_EOS_API_ENDPOINTS: '["https://jungle.eosusa.io","https://jungle4.eosphere.io","https://jungle4.api.eosnation.io","https://jungle4.eossweden.org"]' HAPI_EOS_API_CHAIN_ID: 73e4385a2708e6d7048834fbc1079f2fabb17b3c125b146af438971e90716c4d GOOGLE_CREDENTIALS_JSON: ${{ secrets.GOOGLE_CREDENTIALS_JSON }} HAPI_EOS_BASE_ACCOUNT: ${{ secrets.HAPI_EOS_BASE_ACCOUNT }} @@ -116,7 +116,7 @@ jobs: HAPI_EVM_HASURA_ADMIN_SECRET: ${{ secrets.HAPI_EVM_HASURA_ADMIN_SECRET }} HAPI_EVM_DATABASE_URL: ${{ secrets.HAPI_EVM_DATABASE_URL }} HAPI_EVM_ENDPOINT: 'https://api.testnet.evm.eosnetwork.com' - HAPI_EVM_API_ENDPOINTS: '["https://jungle.edenia.cloud","https://jungle4.eosphere.io","https://jungle4.api.eosnation.io","https://jungle4.eossweden.org"]' + HAPI_EVM_API_ENDPOINTS: '["https://jungle.eosusa.io","https://jungle4.eosphere.io","https://jungle4.api.eosnation.io","https://jungle4.eossweden.org"]' HAPI_EVM_NETWORK: EOSIO HAPI_EVM_NETWORK_CHAIN_ID: 73e4385a2708e6d7048834fbc1079f2fabb17b3c125b146af438971e90716c4d HAPI_EVM_EOS_EVM_ACCOUNT: eosio.evm diff --git a/.github/workflows/deploy-mainnet.yaml b/.github/workflows/deploy-mainnet.yaml index 21a965d7..3dcbc805 100644 --- a/.github/workflows/deploy-mainnet.yaml +++ b/.github/workflows/deploy-mainnet.yaml @@ -39,7 +39,7 @@ jobs: REACT_APP_USE_REWARDS: 'true' REACT_APP_USE_VOTES: 'true' REACT_APP_HASURA_URL: 'https://graphql-eos.antelope.tools/v1/graphql' - REACT_APP_EOS_API_HOSTS: '[\"api.main.alohaeos.com\",\"eos.edenia.cloud\",\"eos.api.eosnation.io\",\"eos.greymass.com\",\"eos.eosphere.io\",\"api.eosrio.io\"]' + REACT_APP_EOS_API_HOSTS: '[\"api.main.alohaeos.com\",\"eos.eosusa.io\",\"eos.api.eosnation.io\",\"eos.greymass.com\",\"eos.eosphere.io\",\"api.eosrio.io\"]' REACT_APP_EOS_API_PORT: '443' REACT_APP_EOS_API_PROTOCOL: 'https' REACT_APP_EOS_CHAIN_ID: 'aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906' @@ -81,7 +81,7 @@ jobs: POSTGRES_DB: ${{ secrets.POSTGRES_DB }} POSTGRES_DATA: ${{ secrets.POSTGRES_DATA }} # hapi - HAPI_EOS_API_ENDPOINTS: '["https://eos.edenia.cloud","https://api.main.alohaeos.com","https://eos.api.eosnation.io","https://eos.greymass.com","https://eos.eosphere.io","https://api.eosrio.io"]' + HAPI_EOS_API_ENDPOINTS: '["https://eos.eosusa.io","https://api.main.alohaeos.com","https://eos.api.eosnation.io","https://eos.greymass.com","https://eos.eosphere.io","https://api.eosrio.io"]' HAPI_EOS_API_CHAIN_ID: 'aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906' HAPI_EOS_BASE_ACCOUNT: ${{ secrets.HAPI_EOS_BASE_ACCOUNT }} HAPI_EOS_BASE_ACCOUNT_PASSWORD: ${{ secrets.HAPI_EOS_BASE_ACCOUNT_PASSWORD }} @@ -114,7 +114,7 @@ jobs: HAPI_EVM_HASURA_ADMIN_SECRET: ${{ secrets.HAPI_EVM_HASURA_ADMIN_SECRET }} HAPI_EVM_DATABASE_URL: ${{ secrets.HAPI_EVM_DATABASE_URL }} HAPI_EVM_ENDPOINT: 'https://api.evm.eosnetwork.com' - HAPI_EVM_API_ENDPOINTS: '["https://eos.edenia.cloud","https://api.main.alohaeos.com","https://eos.api.eosnation.io","https://eos.greymass.com","https://eos.eosphere.io","https://api.eosrio.io"]' + HAPI_EVM_API_ENDPOINTS: '["https://eos.eosusa.io","https://api.main.alohaeos.com","https://eos.api.eosnation.io","https://eos.greymass.com","https://eos.eosphere.io","https://api.eosrio.io"]' HAPI_EVM_NETWORK: EOSIO HAPI_EVM_NETWORK_CHAIN_ID: aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906 HAPI_EVM_EOS_EVM_ACCOUNT: eosio.evm diff --git a/.github/workflows/deploy-telos-testnet.yaml b/.github/workflows/deploy-telos-testnet.yaml index d446f367..63198230 100644 --- a/.github/workflows/deploy-telos-testnet.yaml +++ b/.github/workflows/deploy-telos-testnet.yaml @@ -115,7 +115,7 @@ jobs: 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_API_ENDPOINTS: '["https://test.telos.eosusa.io","https://telos-testnet.cryptolions.io","https://testnet.telos.eosrio.io"]' HAPI_EVM_NETWORK: TELOS HAPI_EVM_NETWORK_CHAIN_ID: 1eaa0824707c8c16bd25145493bf062aecddfeb56c736f6ba6397f3195f33c9f HAPI_EVM_EOS_EVM_ACCOUNT: eosio.evm diff --git a/.github/workflows/deploy-wax.yaml b/.github/workflows/deploy-wax.yaml index 837537a4..bee50634 100644 --- a/.github/workflows/deploy-wax.yaml +++ b/.github/workflows/deploy-wax.yaml @@ -45,7 +45,7 @@ jobs: REACT_APP_EOS_API_NETWORK_NAME: 'wax' REACT_APP_EOS_API_NETWORK_LABEL: 'WAX Mainnet' REACT_APP_EOS_API_NETWORK_LOGO: 'https://antelope.tools/images/wax.jpg' - REACT_APP_EOS_API_HOSTS: '[\"wax.api.eosnation.io\",\"wax.edenia.cloud\",\"wax.api.eosnation.io\",\"wax.greymass.com\"]' + REACT_APP_EOS_API_HOSTS: '[\"wax.api.eosnation.io\",\"wax.eosusa.io\",\"wax.api.eosnation.io\",\"wax.greymass.com\"]' REACT_APP_EOS_API_PORT: '443' REACT_APP_EOS_API_PROTOCOL: 'https' REACT_APP_EOS_CHAIN_ID: '1064487b3cd1a897ce03ae5b6a865651747e2e152090f99c1d19d44e01aea5a4' @@ -81,7 +81,7 @@ jobs: POSTGRES_DATA: ${{ secrets.POSTGRES_DATA }} # hapi HAPI_EOS_API_NETWORK_NAME: wax - HAPI_EOS_API_ENDPOINTS: '["https://wax.api.eosnation.io","https://wax.edenia.cloud","https://wax.api.eosnation.io","https://wax.greymass.com"]' + HAPI_EOS_API_ENDPOINTS: '["https://wax.api.eosnation.io","https://wax.eosusa.io","https://wax.api.eosnation.io","https://wax.greymass.com"]' HAPI_EOS_API_CHAIN_ID: 1064487b3cd1a897ce03ae5b6a865651747e2e152090f99c1d19d44e01aea5a4 HAPI_EOS_BASE_ACCOUNT: ${{ secrets.HAPI_EOS_BASE_ACCOUNT }} HAPI_EOS_BASE_ACCOUNT_PASSWORD: ${{ secrets.HAPI_EOS_BASE_ACCOUNT_PASSWORD }} diff --git a/README.md b/README.md index 521a3072..fc4b36dc 100644 --- a/README.md +++ b/README.md @@ -166,7 +166,7 @@ HASURA_GRAPHQL_ADMIN_SECRET=myadminsecretkey HASURA_GRAPHQL_UNAUTHORIZED_ROLE=guest # hapi -HAPI_EOS_API_ENDPOINTS=["https://jungle.edenia.cloud"] +HAPI_EOS_API_ENDPOINTS=["https://jungle.eosusa.io"] HAPI_EOS_API_CHAIN_ID=73e4385a2708e6d7048834fbc1079f2fabb17b3c125b146af438971e90716c4d HAPI_EOS_BASE_ACCOUNT=baseaccount HAPI_EOS_BASE_ACCOUNT_PASSWORD=PW... @@ -192,7 +192,7 @@ REACT_APP_USE_REWARDS=true REACT_APP_USE_VOTES=true REACT_APP_USE_CPU_BENCHMARK=true REACT_APP_HASURA_URL=http://localhost:8080/v1/graphql -REACT_APP_EOS_API_HOSTS=["jungle.edenia.cloud"] +REACT_APP_EOS_API_HOSTS=["jungle.eosusa.io"] REACT_APP_EOS_API_PORT=443 REACT_APP_EOS_API_PROTOCOL=https REACT_APP_EOS_CHAIN_ID=73e4385a2708e6d7048834fbc1079f2fabb17b3c125b146af438971e90716c4d diff --git a/docs/producers-API-documentation.md b/docs/producers-API-documentation.md index e05e3348..e1038412 100644 --- a/docs/producers-API-documentation.md +++ b/docs/producers-API-documentation.md @@ -112,13 +112,13 @@ curl -X 'POST' \ "owner": "costaricaeos", "endpoints": [ { - "link": "eos.edenia.cloud:9876", + "link": "eos.eosusa.io:9876", "response": {}, "updated_at": "2022-11-14T17:23:00.174097+00:00", "type": "p2p" }, { - "link": "https://eos.edenia.cloud", + "link": "https://eos.eosusa.io", "response": { "status": 200, "statusText": "OK" @@ -239,7 +239,7 @@ curl -X 'POST' \ "owner": "costaricaeos", "endpoints": [ { - "link": "eos.edenia.cloud:9876", + "link": "eos.eosusa.io:9876", "response": {}, "updated_at": "2022-11-14T17:23:00.174097+00:00", "type": "p2p" diff --git a/docs/wallet-config.md b/docs/wallet-config.md index 5057cb16..aed5cedc 100644 --- a/docs/wallet-config.md +++ b/docs/wallet-config.md @@ -30,18 +30,18 @@ HAPI_EOS_MECHANICS_PASSWORD=PW... Let's make sure that the wallet was created correctly: ```bash -cleos -u https://jungle.edenia.cloud --wallet-url http://localhost:8888 wallet list +cleos -u https://jungle.eosusa.io --wallet-url http://localhost:8888 wallet list ``` If the wallet is present but locked, then execute the following command: ```bash -cleos -u https://jungle.edenia.cloud --wallet-url http://localhost:8888 wallet unlock -n eosmechanics +cleos -u https://jungle.eosusa.io --wallet-url http://localhost:8888 wallet unlock -n eosmechanics ``` Finally, we will import an EOSIO key for reading information about statistics of the block producers called eosmechanics (Ask the admins about the key): ```bash -cleos -u https://jungle.edenia.cloud --wallet-url http://localhost:8888 wallet import -n eosmechanics +cleos -u https://jungle.eosusa.io --wallet-url http://localhost:8888 wallet import -n eosmechanics ``` diff --git a/hapi/package.json b/hapi/package.json index 0775b353..18aaccb0 100644 --- a/hapi/package.json +++ b/hapi/package.json @@ -1,5 +1,5 @@ { - "name": "eosiodashboard", + "name": "antelopetools", "version": "1.0.0", "description": "Antelope Tools BackEnd", "repository": "https://github.com/edenia/antelope-tools.git", diff --git a/hapi/src/config/eos.config.js b/hapi/src/config/eos.config.js index 53d2a5ad..3e941363 100644 --- a/hapi/src/config/eos.config.js +++ b/hapi/src/config/eos.config.js @@ -46,6 +46,7 @@ module.exports = { nodeTable: process.env.HAPI_EOS_BP_JSON_ON_CHAIN_TABLE2 || 'node' }, knownNetworks: { + fio: 'fio', lacchain: 'lacchain', libre: 'libre', telos: 'telos', diff --git a/hapi/src/services/cpu.service.js b/hapi/src/services/cpu.service.js index a3f22c23..8f935274 100644 --- a/hapi/src/services/cpu.service.js +++ b/hapi/src/services/cpu.service.js @@ -6,7 +6,7 @@ const { } = require('../utils') const { eosConfig } = require('../config') -const saveBenchmark = async payload => { +const saveBenchmark = async (payload) => { const mutation = ` mutation ($account: String!, $usage: Int!) { insert_cpu_one (object: {account: $account, usage: $usage}) { @@ -39,7 +39,11 @@ const cleanOldBenchmarks = async () => { } const worker = async () => { - if (!eosConfig.eosmechanics.account || !eosConfig.eosmechanics.password) { + if ( + eosConfig.eosmechanics.account === ' ' || + !eosConfig.eosmechanics.account || + !eosConfig.eosmechanics.password + ) { return } @@ -49,7 +53,7 @@ const worker = async () => { await saveBenchmark({ account: block.producer, usage: block?.transactions.find( - trx => trx?.trx?.id === transaction.processed.id + (trx) => trx?.trx?.id === transaction.processed.id ).cpu_usage_us }) } catch (error) { diff --git a/hapi/src/services/fio.service.js b/hapi/src/services/fio.service.js new file mode 100644 index 00000000..6a0e16cd --- /dev/null +++ b/hapi/src/services/fio.service.js @@ -0,0 +1,256 @@ +const { StatusCodes } = require('http-status-codes') + +const { axiosUtil, eosUtil, sequelizeUtil, producerUtil } = require('../utils') +const { eosConfig } = require('../config') + +const getProducers = async () => { + let producers = [] + let totalVoteWeight + let hasMore = true + let nextKey + + try { + while (hasMore) { + const { + rows, + more + } = await eosUtil.getTableRows({ + code: 'eosio', + table: 'producers', + scope: 'eosio', + limit: 100, + json: true, + lower_bound: nextKey + }) + + hasMore = !!more + nextKey = more + producers.push(...rows) + } + + const { + rows, + } = await eosUtil.getTableRows({ + code: 'eosio', + table: 'global', + scope: 'eosio', + limit: 1, + json: true, + lower_bound: nextKey + }) + + totalVoteWeight = parseFloat(rows?.at(0)?.total_producer_vote_weight) + } catch (error) { + console.error('PRODUCER SYNC ERROR', error) + producers = await getProducersFromDB() + + return await getBPJsons(producers) + } + producers = producers + .filter(producer => !!producer.is_active) + .sort((a, b) => { + if (parseInt(a.total_votes) > parseInt(b.total_votes)) { + return -1 + } + + if (parseInt(a.total_votes) < parseInt(b.total_votes)) { + return 1 + } + + return 0 + }) + + const rewards = await producerUtil.getExpectedRewards( + producers, + totalVoteWeight + ) + const nonPaidStandby = { vote_rewards: 0, block_rewards: 0, total_rewards: 0 } + + producers = producers.map((producer, index) => { + return { + owner: producer.owner, + ...(rewards[producer.owner] || nonPaidStandby), + total_votes: producer.total_votes, + total_votes_percent: producer.total_votes / totalVoteWeight, + total_votes_eos: producerUtil.getVotes(producer.total_votes), + rank: index + 1, + producer_key: producer.producer_public_key, + url: producer.url, + unpaid_blocks: producer.unpaid_blocks, + last_claim_time: producer.last_claim_time, + location: producer.location, + producer_authority: producer.producer_authority, + is_active: !!producer.is_active, + fio_address: producer.fio_address, + addresshash: producer.addresshash, + last_bpclaim: producer.last_bpclaim?.toString() || '0' + } + }) + producers = await getBPJsons(producers) + + return producers +} + +const getBPJsons = async (producers = []) => { + const isEosNetwork = eosConfig.chainId === eosConfig.eosChainId + let topProducers = producers.slice(0, eosConfig.eosTopLimit) + + topProducers = await Promise.all( + topProducers.map(async producer => { + let bpJson = {} + let bpJsonUrl = '' + let healthStatus = [] + + if (producer.url && producer.url.length > 3) { + const producerUrl = getProducerUrl(producer) + const chains = await getChains(producerUrl) + const chainUrl = chains[eosConfig.chainId] + bpJsonUrl = getBPJsonUrl(producerUrl, chainUrl || '/bp.json') + + try { + bpJson = await getBPJson(bpJsonUrl) + } catch (error) { + if (error.code === 'ECONNABORTED') { + return { + ...producer, + bp_json_url: bpJsonUrl, + health_status: healthStatus, + bp_json: bpJson + } + } + } + + if (bpJson && !chainUrl && !isEosNetwork) { + const { org, producer_account_name: name } = bpJson + + bpJson = { + ...(org && { org }), + ...(name && { producer_account_name: name }) + } + } + + healthStatus = await getProducerHealthStatus({ + ...producer, + producerUrl, + bpJson, + }) + } + + return { + ...producer, + bp_json_url: bpJsonUrl, + health_status: healthStatus, + bp_json: bpJson + } + }) + ) + + return topProducers.concat(producers.slice(eosConfig.eosTopLimit)) +} + +const getBPJsonUrl = (producerUrl, chainUrl) => { + return `${producerUrl}/${chainUrl}`.replace(/(?<=:\/\/.*)((\/\/))/, '/') +} + +const getBPJson = async bpJsonUrl => { + const { data: _bpJson } = await axiosUtil.instance.get(bpJsonUrl) + const bpJson = !!_bpJson && typeof _bpJson === 'object' ? _bpJson : {} + + return bpJson +} + +const getProducerUrl = producer => { + let producerUrl = producer?.url?.replace(/(“|'|”|")/g, '') || '' + + if (!producerUrl.startsWith('http')) { + producerUrl = `http://${producerUrl}` + } + + return producerUrl +} + +const getChains = async producerUrl => { + const chainsUrl = `${producerUrl}/chains.json`.replace( + /(?<=:\/\/.*)((\/\/))/, + '/' + ) + + try { + const { + data: { chains } + } = await axiosUtil.instance.get(chainsUrl) + + return chains ?? {} + } catch (error) { + return {} + } +} + +const isNonCompliant = producer => { + return !Object.keys(producer.bpJson).length && producer.total_rewards >= 100 +} + +const getProducerHealthStatus = async producer => { + const healthStatus = [] + const {bpJson, producerUrl} = producer + + if (isNonCompliant(producer)) { + const response = await producerUtil.getUrlStatus(producerUrl) + + healthStatus.push({ name: 'bpJson', valid: false }) + healthStatus.push({ + name: 'website', + valid: response?.status === StatusCodes.OK, + response: { + status: response?.status, + statusText: response?.statusText || 'No response' + } + }) + + return healthStatus + } + + if (!bpJson || !Object.keys(bpJson).length) return [] + + healthStatus.push({ + name: 'bpJson', + valid: true + }) + healthStatus.push({ + name: 'organization_name', + valid: !!bpJson.org?.candidate_name + }) + healthStatus.push({ + name: 'email', + valid: !!bpJson.org?.email + }) + healthStatus.push({ + name: 'website', + valid: !!bpJson.org?.website + }) + healthStatus.push({ + name: 'logo_256', + valid: !!bpJson?.org?.branding?.logo_256 + }) + healthStatus.push({ + name: 'country', + valid: !!bpJson?.org?.location?.country + }) + + return healthStatus +} + +const getProducersFromDB = async () => { + const [producers] = await sequelizeUtil.query(` + SELECT * + FROM producer + ORDER BY rank ASC + ; + `) + + return producers +} + +module.exports = { + getProducers +} diff --git a/hapi/src/services/fioProducers.js b/hapi/src/services/fioProducers.js deleted file mode 100644 index 00605fba..00000000 --- a/hapi/src/services/fioProducers.js +++ /dev/null @@ -1,84 +0,0 @@ -const axios = require('axios'); - -// FIO API endpoint (replace with the correct endpoint if needed) -const FIO_API_URL = 'https://testnet.fioprotocol.io/v1/chain/get_table_rows'; - -const getProducers = async () => { - let producers = []; - let totalVoteWeight; - let hasMore = true; - let nextKey; - - try { - while (hasMore) { - const response = await axios.post(FIO_API_URL, { - code: 'fio.system', // Contract name - table: 'producers', // Table name - scope: 'fio', // Scope - limit: 100, - json: true, - lower_bound: nextKey - }); - - if (response.status !== 200) { - throw new Error(`Request failed with status code ${response.status}`); - } - - const { - rows, - more, - total_producer_vote_weight: _totalVoteWeight - } = response.data; - - if (!rows) { - throw new Error('Response data does not contain rows'); - } - - hasMore = !!more; - nextKey = more; - totalVoteWeight = parseFloat(_totalVoteWeight); - producers.push(...rows); - } - } catch (error) { - console.error('PRODUCER SYNC ERROR', error.message); - return; - } - - producers = producers - .filter(producer => !!producer.is_active) - .sort((a, b) => { - if (parseFloat(a.total_votes) > parseFloat(b.total_votes)) { - return -1; - } - - if (parseFloat(a.total_votes) < parseFloat(b.total_votes)) { - return 1; - } - - return 0; - }); - - producers = producers.map((producer, index) => { - return { - id: producer.id, - owner: producer.owner, - fio_address: producer.fio_address, - total_votes: producer.total_votes, - total_votes_percent: producer.total_votes / totalVoteWeight, - total_votes_eos: producer.total_votes, - rank: index + 1, - producer_public_key: producer.producer_public_key, - url: producer.url, - unpaid_blocks: producer.unpaid_blocks, - last_claim_time: producer.last_claim_time, - location: producer.location, - is_active: !!producer.is_active - }; - }); - - console.log(producers); - return producers; -} - -// Call the function to test it -getProducers(); diff --git a/hapi/src/services/producer.service.js b/hapi/src/services/producer.service.js index 530b28ce..ec0244ad 100644 --- a/hapi/src/services/producer.service.js +++ b/hapi/src/services/producer.service.js @@ -4,6 +4,7 @@ const { hasuraUtil, sequelizeUtil, producerUtil } = require('../utils') const { eosConfig, workersConfig } = require('../config') const lacchainService = require('./lacchain.service') +const fioService = require('./fio.service') const eosioService = require('./eosio.service') const nodeService = require('./node.service') const statsService = require('./stats.service') @@ -24,7 +25,7 @@ const updateBPJSONs = async (producers = []) => { const updateProducers = async (producers = []) => { const upsertMutation = ` mutation ($producers: [producer_insert_input!]!) { - insert_producer(objects: $producers, on_conflict: {constraint: producer_owner_key, update_columns: [ producer_key, unpaid_blocks,last_claim_time, url, location, producer_authority, is_active, total_votes, total_votes_percent, total_votes_eos, vote_rewards,block_rewards, total_rewards, endpoints, rank, bp_json_url]}) { + insert_producer(objects: $producers, on_conflict: {constraint: producer_owner_key, update_columns: [ producer_key, unpaid_blocks,last_claim_time, url, location, producer_authority, is_active, total_votes, total_votes_percent, total_votes_eos, vote_rewards,block_rewards, total_rewards, endpoints, rank, bp_json_url, fio_address, addresshash, last_bpclaim]}) { affected_rows, returning { id, @@ -84,6 +85,9 @@ const syncProducers = async () => { case eosConfig.knownNetworks.lacchain: producers = await lacchainService.getProducers() break + case eosConfig.knownNetworks.fio: + producers = await fioService.getProducers() + break default: producers = await eosioService.getProducers() break diff --git a/hapi/src/utils/eos.util.js b/hapi/src/utils/eos.util.js index 0fc0d5f8..51b12f84 100644 --- a/hapi/src/utils/eos.util.js +++ b/hapi/src/utils/eos.util.js @@ -218,7 +218,7 @@ const getCurrencyBalance = (code, account, symbol) => eosApi.getCurrencyBalance(code, account, symbol) const getTableRows = options => - eosApi.getTableRows({ json: true, ...options }) + callEosApi('getTableRows', async eosApi => eosApi.getTableRows({ json: true, ...options })) const getProducerSchedule = () => eosApi.getProducerSchedule({}) diff --git a/hapi/src/utils/producer.util.js b/hapi/src/utils/producer.util.js index b0a10b23..eb9a393d 100644 --- a/hapi/src/utils/producer.util.js +++ b/hapi/src/utils/producer.util.js @@ -126,6 +126,9 @@ const getExpectedRewards = async (producers, totalVotes) => { case eosConfig.knownNetworks.telos: rewards = await getTelosRewards(producers) break + case eosConfig.knownNetworks.fio: + rewards = await getFioRewards(producers) + break default: rewards = await getEOSIORewards(producers, totalVotes) break @@ -278,6 +281,12 @@ const getEOSIORewards = async (producers, totalVotes) => { return producersRewards } +const getFioRewards = async (producers) => { + const producersRewards = [] + // ToDo : Calculate producer Rewards Based on FIO System Contracts + return producersRewards +} + const getVotes = (votes) => { switch (eosConfig.networkName) { case eosConfig.knownNetworks.telos: diff --git a/hasura/migrations/default/1719953232361_alter_table_public_producer_add_column_fio_address/down.sql b/hasura/migrations/default/1719953232361_alter_table_public_producer_add_column_fio_address/down.sql new file mode 100644 index 00000000..f780b3ee --- /dev/null +++ b/hasura/migrations/default/1719953232361_alter_table_public_producer_add_column_fio_address/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 "public"."producer" add column "fio_address" varchar +-- null unique; diff --git a/hasura/migrations/default/1719953232361_alter_table_public_producer_add_column_fio_address/up.sql b/hasura/migrations/default/1719953232361_alter_table_public_producer_add_column_fio_address/up.sql new file mode 100644 index 00000000..411304c3 --- /dev/null +++ b/hasura/migrations/default/1719953232361_alter_table_public_producer_add_column_fio_address/up.sql @@ -0,0 +1,2 @@ +alter table "public"."producer" add column "fio_address" varchar + null unique; diff --git a/hasura/migrations/default/1719953258027_alter_table_public_producer_add_column_addresshash/down.sql b/hasura/migrations/default/1719953258027_alter_table_public_producer_add_column_addresshash/down.sql new file mode 100644 index 00000000..099a3d2c --- /dev/null +++ b/hasura/migrations/default/1719953258027_alter_table_public_producer_add_column_addresshash/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 "public"."producer" add column "addresshash" varchar +-- null; diff --git a/hasura/migrations/default/1719953258027_alter_table_public_producer_add_column_addresshash/up.sql b/hasura/migrations/default/1719953258027_alter_table_public_producer_add_column_addresshash/up.sql new file mode 100644 index 00000000..7b6e801f --- /dev/null +++ b/hasura/migrations/default/1719953258027_alter_table_public_producer_add_column_addresshash/up.sql @@ -0,0 +1,2 @@ +alter table "public"."producer" add column "addresshash" varchar + null; diff --git a/hasura/migrations/default/1719953328741_alter_table_public_producer_add_column_last_bpclaim/down.sql b/hasura/migrations/default/1719953328741_alter_table_public_producer_add_column_last_bpclaim/down.sql new file mode 100644 index 00000000..588d8388 --- /dev/null +++ b/hasura/migrations/default/1719953328741_alter_table_public_producer_add_column_last_bpclaim/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 "public"."producer" add column "last_bpclaim" varchar +-- null; diff --git a/hasura/migrations/default/1719953328741_alter_table_public_producer_add_column_last_bpclaim/up.sql b/hasura/migrations/default/1719953328741_alter_table_public_producer_add_column_last_bpclaim/up.sql new file mode 100644 index 00000000..b4d7099c --- /dev/null +++ b/hasura/migrations/default/1719953328741_alter_table_public_producer_add_column_last_bpclaim/up.sql @@ -0,0 +1,2 @@ +alter table "public"."producer" add column "last_bpclaim" varchar + null; diff --git a/makefile b/makefile index dac1d2bb..11c7c659 100644 --- a/makefile +++ b/makefile @@ -90,7 +90,7 @@ stop: start: make start-postgres - make start-wallet +# make start-wallet make start-hapi # make start-hapi-evm make start-hasura diff --git a/webapp/package.json b/webapp/package.json index f7dbf8a9..99783e4b 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -1,5 +1,5 @@ { - "name": "eosiodashboard", + "name": "antelopetools", "version": "v0.1.11", "description": "Antelope Tools WebApp", "repository": "https://github.com/edenia/antelope-tools.git", diff --git a/webapp/src/components/ProducersChart/index.js b/webapp/src/components/ProducersChart/index.js index 0c61d5d6..eeff10f6 100644 --- a/webapp/src/components/ProducersChart/index.js +++ b/webapp/src/components/ProducersChart/index.js @@ -183,7 +183,7 @@ const CustomTooltip = memo(({ active, payload }) => { {t('name')}:{' '} {' '} - {payload[0].payload.owner} + {payload[0].payload.name || payload[0].payload.owner} {generalConfig.useRewards && ( diff --git a/webapp/src/config/general.js b/webapp/src/config/general.js index ad7168a2..d81b876f 100644 --- a/webapp/src/config/general.js +++ b/webapp/src/config/general.js @@ -15,7 +15,7 @@ export const disabledMenuItems = JSON.parse( ) export const appVersion = process.env.REACT_APP_VERSION.split('/').pop() || 'v1.0' -export const appName = process.env.REACT_APP_NAME || 'eosiodashboard' +export const appName = process.env.REACT_APP_NAME || 'antelopetools' export const networkLinks = process.env.REACT_APP_NETWORK_URL ? JSON.parse(process.env.REACT_APP_NETWORK_URL) : [] diff --git a/webapp/src/config/ual.config.js b/webapp/src/config/ual.config.js index f9814f9d..b2dedabb 100644 --- a/webapp/src/config/ual.config.js +++ b/webapp/src/config/ual.config.js @@ -1,6 +1,6 @@ import { Anchor } from 'ual-anchor' -const appName = process.env.REACT_APP_EOS_APP_NAME || 'eosiodashboard' +const appName = process.env.REACT_APP_EOS_APP_NAME || 'antelopetools' const network = { chainId: process.env.REACT_APP_EOS_CHAIN_ID || @@ -11,7 +11,7 @@ const network = { protocol: process.env.REACT_APP_EOS_API_PROTOCOL || 'https', host: JSON.parse(process.env.REACT_APP_EOS_API_HOSTS)[0] || - 'jungle.edenia.cloud', + 'jungle.eosusa.io', port: parseInt(process.env.REACT_APP_EOS_API_PORT || '443'), }, ], diff --git a/webapp/src/gql/producer.gql.js b/webapp/src/gql/producer.gql.js index cd0344a1..8e94134d 100644 --- a/webapp/src/gql/producer.gql.js +++ b/webapp/src/gql/producer.gql.js @@ -35,6 +35,7 @@ export const PRODUCERS_QUERY = gql` type value } + fio_address } } ` diff --git a/webapp/src/routes/Home/BlockProducerInfo.js b/webapp/src/routes/Home/BlockProducerInfo.js index 7510fdbc..bae28dfe 100644 --- a/webapp/src/routes/Home/BlockProducerInfo.js +++ b/webapp/src/routes/Home/BlockProducerInfo.js @@ -48,7 +48,8 @@ const BlockProducerInfo = ({ t, classes }) => { return { logo: data?.bp_json?.org?.branding?.logo_256, url: data?.url, - owner: item.producer_name || data.owner, + name: data?.fio_address || data?.bp_json?.producer_account_name, + owner: item.producer_name || data.owner, rewards: data.total_rewards || 0, total_votes_percent: data.total_votes_percent * 100 || 0, value: 20, @@ -88,7 +89,7 @@ const BlockProducerInfo = ({ t, classes }) => { header lowercase title={t('currentProducer')} - value={info.head_block_producer} + value={schedule.producers?.find(p => p.owner === info.head_block_producer)?.name || info.head_block_producer} />