diff --git a/chains/chain.js b/chains/chain.js index b057c85..1db8a44 100644 --- a/chains/chain.js +++ b/chains/chain.js @@ -12,7 +12,7 @@ function Chain(client, data, paramsData, opts) { ...opts } const { path, chain, assetlist } = data; - const { params, services, prices } = paramsData + const { params, versions, services, prices } = paramsData chain.name = chain.chain_name const coingecko = prices?.coingecko || {} @@ -30,10 +30,6 @@ function Chain(client, data, paramsData, opts) { const health = await apiHealth(type) return ChainApis(health) } - - function apiUrls(type){ - return (chain.apis || {})[type] - } async function apiHealth(type) { const healthPath = {} @@ -46,6 +42,18 @@ function Chain(client, data, paramsData, opts) { return type ? {[type]: health[0]} : health } + function apiUrls(type){ + switch (type) { + case 'service': + return serviceApis() || [] + case 'private-rpc': + case 'private-rest': + return privateApis(type.replace('private-', '')) || [] + default: + return (chain.apis || {})[type] || [] + } + } + function serviceApis(){ return (config.serviceApis || []).map(url => { return { ...url, service: true } @@ -79,6 +87,7 @@ function Chain(client, data, paramsData, opts) { ...data, config, params, + versions, services, prices, apis, diff --git a/chains/chainApis.js b/chains/chainApis.js index 5f53cea..04d79bb 100644 --- a/chains/chainApis.js +++ b/chains/chainApis.js @@ -7,11 +7,11 @@ const IGNORE_ERROR_DIFF = 60 * 60 function ChainApis(health) { function bestAddress(type) { - let urls = Object.values(health[type] || {}) + let urls = availableUrls(type) if(['rpc', 'rest'].includes(type)){ - urls = urls.concat(Object.values(health[`private-${type}`] || {})) + urls = urls.concat(availableUrls(`private-${type}`)) } - const best = _.sample(prepareUrls(urls.filter(el => el.available))) + const best = _.sample(prepareUrls(filterUrls(urls))) return best && best.address } @@ -23,26 +23,29 @@ function ChainApis(health) { } function bestHeight(type) { - let urls + return Math.max(...availableUrls(type).map(el => el.blockHeight).filter(Number.isFinite)) + } + + function bestUrls(type) { + return prepareUrls(filterUrls(availableUrls(type))) + } + + function availableUrls(type) { + return getUrls(type).filter(el => el.available) + } + + function getUrls(type) { if(type){ - urls = [] - urls = urls.concat(Object.values(health[type] || {})) + return Object.values(health[type] || {}) }else{ - urls = Object.values(health).reduce((sum, urls) => { + return Object.values(health).reduce((sum, urls) => { return sum.concat(Object.values(urls)) }, []) } - return Math.max(...urls.filter(el => el.available).map(el => el.blockHeight).filter(Number.isFinite)) - } - - function bestUrls(type) { - let urls - urls = Object.values(health[type] || {}).filter(el => el.available) - return prepareUrls(urls) } function prepareUrls(urls){ - return filterUrls(urls).map(el => { + return urls.map(el => { const url = { ...el.url } url.address = el.finalAddress || url.address return url @@ -79,8 +82,10 @@ function ChainApis(health) { return { bestAddress, bestServiceAddress, - bestUrls, bestHeight, + bestUrls, + availableUrls, + getUrls, health } } diff --git a/chains/chainMonitor.js b/chains/chainMonitor.js index b109992..761aa94 100644 --- a/chains/chainMonitor.js +++ b/chains/chainMonitor.js @@ -1,6 +1,7 @@ import PQueue from 'p-queue'; import got from 'got'; import _ from 'lodash' +import { compareVersions, validate } from 'compare-versions'; import { bignumber, multiply, divide } from 'mathjs' import { createAgent, debugLog, timeStamp, formatNumber } from '../utils.js'; @@ -24,12 +25,14 @@ function ChainMonitor() { const current = await client.json.get('chains:' + chain.path, '$') || {} let chainParams = await getChainParams(restUrl, chain, current.params || {}); + let versionParams = await getVersionParams(chain, apis, current.versions || {}) await client.json.set('chains:' + chain.path, '$', { ...current, chainId: chain.chainId, lastUpdated: Date.now(), - params: chainParams || current.params + params: chainParams || current.params, + versions: versionParams || current.versions }); debugLog(chain.path, 'Chain update complete') }; @@ -38,6 +41,40 @@ function ChainMonitor() { debugLog('Chain update complete') } + async function getVersionParams(chain, apis, current){ + try { + const versions = { + application_version: [], + cosmos_sdk_version: [], + tendermint_version: [] + } + await Promise.all(['rest', 'private-rest'].map(async (type) => { + const urls = apis.availableUrls(type) + await Promise.all(urls.map(async (url) => { + try { + const response = await got.get(url.finalAddress + '/cosmos/base/tendermint/v1beta1/node_info', gotOpts) + const data = JSON.parse(response.body) + const { version, cosmos_sdk_version } = data.application_version + const tendermint_version = data.default_node_info?.version || data.node_info?.version + if(validate(version)) versions.application_version.push(version) + if(validate(cosmos_sdk_version)) versions.cosmos_sdk_version.push(cosmos_sdk_version) + if(validate(tendermint_version)) versions.tendermint_version.push(tendermint_version) + } catch (error) { + debugLog(chain.path, url.finalAddress, 'Node update failed:', error.message) + } + })) + })); + // use the lowest available version + return { + application_version: versions.application_version.sort(compareVersions)[0] || current.application_version, + cosmos_sdk_version: versions.cosmos_sdk_version.sort(compareVersions)[0] || current.cosmos_sdk_version, + tendermint_version: versions.tendermint_version.sort(compareVersions)[0] || current.tendermint_version + } + } catch (error) { + timeStamp(chain.path, 'Version update failed', error.message) + } + } + async function getChainParams(restUrl, chain, current) { const { denom } = chain try { @@ -74,7 +111,7 @@ function ChainMonitor() { annualProvision: formatNumber(data.annualProvision) }, (_value, key) => _.snakeCase(key)) } catch (error) { - timeStamp(chain.path, 'Update failed', error.message) + timeStamp(chain.path, 'Params update failed', error.message) } } diff --git a/chains/chainsController.js b/chains/chainsController.js index 0717558..12d9a88 100644 --- a/chains/chainsController.js +++ b/chains/chainsController.js @@ -3,10 +3,10 @@ import { renderJson } from '../utils.js'; function ChainsController(registry) { async function chainResponse(chain, summarize) { - const { chain_name, network_type, pretty_name, chain_id, status, explorers } = chain.chain; + const { chain_name, network_type, pretty_name, chain_id, status, explorers, keywords, codebase } = chain.chain; const baseAsset = chain.baseAsset const apis = await chain.apis() - const { params, services, prices, assets } = chain + const { params, versions, services, prices, assets } = chain const response = { name: chain_name, path: chain.path, @@ -30,11 +30,20 @@ function ChainsController(registry) { rest: !!apis.bestAddress('rest'), rpc: !!apis.bestAddress('rpc') }, + versions: { + ...versions, + application_version: versions?.application_version || codebase?.recommended_version, + cosmos_sdk_version: versions?.cosmos_sdk_version || codebase?.cosmos_sdk_version, + tendermint_version: versions?.tendermint_version || codebase?.tendermint_version, + cosmwasm_version: codebase?.cosmwasm_version + }, + cosmwasm_enabled: codebase?.cosmwasm_enabled, explorers, params, services, prices, - assets + assets, + keywords }; if (summarize) { return response diff --git a/package-lock.json b/package-lock.json index 7154bcc..74701cd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,7 @@ "@koa/cors": "^3.1.0", "agentkeepalive": "^4.2.1", "bytes": "^3.1.0", + "compare-versions": "^5.0.1", "compressible": "^2.0.18", "fast-safe-stringify": "^2.0.7", "get-stream": "^5.1.0", @@ -219,11 +220,11 @@ } }, "node_modules/@sindresorhus/is": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", - "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.3.0.tgz", + "integrity": "sha512-CX6t4SYQ37lzxicAqsBtxA3OseeoVrh9cSJ5PFYam0GksYlupRfy1A+Q4aYD3zvcfECLc0zO2u+ZnR2UYKvCrw==", "engines": { - "node": ">=10" + "node": ">=14.16" }, "funding": { "url": "https://github.com/sindresorhus/is?sponsor=1" @@ -240,43 +241,11 @@ "node": ">=14.16" } }, - "node_modules/@types/cacheable-request": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", - "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==", - "dependencies": { - "@types/http-cache-semantics": "*", - "@types/keyv": "*", - "@types/node": "*", - "@types/responselike": "*" - } - }, "node_modules/@types/http-cache-semantics": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==" }, - "node_modules/@types/keyv": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", - "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/node": { - "version": "17.0.23", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", - "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==" - }, - "node_modules/@types/responselike": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", - "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", - "dependencies": { - "@types/node": "*" - } - }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -391,36 +360,39 @@ } }, "node_modules/cacheable-lookup": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-6.0.4.tgz", - "integrity": "sha512-mbcDEZCkv2CZF4G01kr8eBd/5agkt9oCqz75tJMSIsquvRZ2sL6Hi5zGVKi/0OSC9oO1GHfJ2AV0ZIOY9vye0A==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", + "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", "engines": { - "node": ">=10.6.0" + "node": ">=14.16" } }, "node_modules/cacheable-request": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", - "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.1.tgz", + "integrity": "sha512-3tLJyBjGuXw1s5gpKFSG3iS4kaKT4id04dZi98wzHQp/8cqZNweBnrF9J+rrlvrf4M53OdtDGNctNHFias8BEA==", "dependencies": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^4.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^6.0.1", - "responselike": "^2.0.0" + "@types/http-cache-semantics": "^4.0.1", + "get-stream": "^6.0.1", + "http-cache-semantics": "^4.1.0", + "keyv": "^4.5.0", + "mimic-response": "^4.0.0", + "normalize-url": "^7.1.0", + "responselike": "^3.0.0" }, "engines": { - "node": ">=8" + "node": ">=14.16" } }, - "node_modules/cacheable-request/node_modules/lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "node_modules/cacheable-request/node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/clean-git-ref": { @@ -428,14 +400,6 @@ "resolved": "https://registry.npmjs.org/clean-git-ref/-/clean-git-ref-2.0.1.tgz", "integrity": "sha512-bLSptAy2P0s6hU4PzuIMKmMJJSE6gLXGH1cntDu7bWJUksvuM+7ReOK61mozULErYvP6a15rnYl0zFDef+pyPw==" }, - "node_modules/clone-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", - "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", - "dependencies": { - "mimic-response": "^1.0.0" - } - }, "node_modules/cluster-key-slot": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.0.tgz", @@ -453,6 +417,11 @@ "node": ">= 0.12.0" } }, + "node_modules/compare-versions": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-5.0.1.tgz", + "integrity": "sha512-v8Au3l0b+Nwkp4G142JcgJFh1/TUhdxut7wzD1Nq1dyp5oa3tXaqb03EXOAB6jS4gMlalkjAUPZBMiAfKUixHQ==" + }, "node_modules/complex.js": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/complex.js/-/complex.js-2.1.1.tgz", @@ -704,9 +673,12 @@ } }, "node_modules/form-data-encoder": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.1.tgz", - "integrity": "sha512-EFRDrsMm/kyqbTQocNvRXMLjc7Es2Vk+IQFx/YW7hkUH1eBl4J1fqiP34l74Yt0pFLCNpc06fkbVk00008mzjg==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.3.tgz", + "integrity": "sha512-KqU0nnPMgIJcCOFTNJFEA8epcseEaoox4XZffTgy8jlI6pL/5EFyR54NRG7CnCJN0biY7q52DO3MH6/sJ/TKlQ==", + "engines": { + "node": ">= 14.17" + } }, "node_modules/fraction.js": { "version": "4.2.0", @@ -751,23 +723,21 @@ } }, "node_modules/got": { - "version": "12.0.2", - "resolved": "https://registry.npmjs.org/got/-/got-12.0.2.tgz", - "integrity": "sha512-Zi4yHiqCgaorUbknr/RHFBsC3XqjSodaw0F3qxlqAqyj+OGYZl37/uy01R0qz++KANKQYdY5FHJ0okXZpEzwWQ==", + "version": "12.5.1", + "resolved": "https://registry.npmjs.org/got/-/got-12.5.1.tgz", + "integrity": "sha512-sD16AK8cCyUoPtKr/NMvLTFFa+T3i3S+zoiuvhq0HP2YiqBZA9AtlBjAdsQBsLBK7slPuvmfE0OxhGi7N5dD4w==", "dependencies": { - "@sindresorhus/is": "^4.6.0", + "@sindresorhus/is": "^5.2.0", "@szmarczak/http-timer": "^5.0.1", - "@types/cacheable-request": "^6.0.2", - "@types/responselike": "^1.0.0", - "cacheable-lookup": "^6.0.4", - "cacheable-request": "^7.0.2", + "cacheable-lookup": "^7.0.0", + "cacheable-request": "^10.2.1", "decompress-response": "^6.0.0", - "form-data-encoder": "1.7.1", + "form-data-encoder": "^2.1.2", "get-stream": "^6.0.1", "http2-wrapper": "^2.1.10", "lowercase-keys": "^3.0.0", "p-cancelable": "^3.0.0", - "responselike": "^2.0.0" + "responselike": "^3.0.0" }, "engines": { "node": ">=14.16" @@ -1011,9 +981,9 @@ } }, "node_modules/keyv": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.1.1.tgz", - "integrity": "sha512-tGv1yP6snQVDSM4X6yxrv2zzq/EvpW+oYiUz6aueW1u9CtS8RzUQYxxmFwgZlO2jSgCxQbchhxaqXXp2hnKGpQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.0.tgz", + "integrity": "sha512-2YvuMsA+jnFGtBareKqgANOEKe1mk3HKiXu2fRmAfyxG0MJAywNhi5ttWA3PMjl4NmpyjZNbFifR2vNjW1znfA==", "dependencies": { "json-buffer": "3.0.1" } @@ -1189,11 +1159,14 @@ } }, "node_modules/mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", + "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", "engines": { - "node": ">=4" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/minimalistic-assert": { @@ -1244,11 +1217,11 @@ } }, "node_modules/normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-7.2.0.tgz", + "integrity": "sha512-uhXOdZry0L6M2UIo9BTt7FdpBDiAGN/7oItedQwPKh8jh31ZlvC8U9Xl/EJ3aijDHaywXTW3QbZ6LuCocur1YA==", "engines": { - "node": ">=10" + "node": ">=12.20" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -1469,19 +1442,17 @@ "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==" }, "node_modules/responselike": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz", - "integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", + "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", "dependencies": { - "lowercase-keys": "^2.0.0" - } - }, - "node_modules/responselike/node_modules/lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "lowercase-keys": "^3.0.0" + }, "engines": { - "node": ">=8" + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/ripemd160": { @@ -1900,9 +1871,9 @@ "requires": {} }, "@sindresorhus/is": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", - "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==" + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.3.0.tgz", + "integrity": "sha512-CX6t4SYQ37lzxicAqsBtxA3OseeoVrh9cSJ5PFYam0GksYlupRfy1A+Q4aYD3zvcfECLc0zO2u+ZnR2UYKvCrw==" }, "@szmarczak/http-timer": { "version": "5.0.1", @@ -1912,43 +1883,11 @@ "defer-to-connect": "^2.0.1" } }, - "@types/cacheable-request": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", - "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==", - "requires": { - "@types/http-cache-semantics": "*", - "@types/keyv": "*", - "@types/node": "*", - "@types/responselike": "*" - } - }, "@types/http-cache-semantics": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==" }, - "@types/keyv": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", - "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", - "requires": { - "@types/node": "*" - } - }, - "@types/node": { - "version": "17.0.23", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", - "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==" - }, - "@types/responselike": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", - "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", - "requires": { - "@types/node": "*" - } - }, "accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -2029,28 +1968,28 @@ } }, "cacheable-lookup": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-6.0.4.tgz", - "integrity": "sha512-mbcDEZCkv2CZF4G01kr8eBd/5agkt9oCqz75tJMSIsquvRZ2sL6Hi5zGVKi/0OSC9oO1GHfJ2AV0ZIOY9vye0A==" + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", + "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==" }, "cacheable-request": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", - "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.1.tgz", + "integrity": "sha512-3tLJyBjGuXw1s5gpKFSG3iS4kaKT4id04dZi98wzHQp/8cqZNweBnrF9J+rrlvrf4M53OdtDGNctNHFias8BEA==", "requires": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^4.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^6.0.1", - "responselike": "^2.0.0" + "@types/http-cache-semantics": "^4.0.1", + "get-stream": "^6.0.1", + "http-cache-semantics": "^4.1.0", + "keyv": "^4.5.0", + "mimic-response": "^4.0.0", + "normalize-url": "^7.1.0", + "responselike": "^3.0.0" }, "dependencies": { - "lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==" + "get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==" } } }, @@ -2059,14 +1998,6 @@ "resolved": "https://registry.npmjs.org/clean-git-ref/-/clean-git-ref-2.0.1.tgz", "integrity": "sha512-bLSptAy2P0s6hU4PzuIMKmMJJSE6gLXGH1cntDu7bWJUksvuM+7ReOK61mozULErYvP6a15rnYl0zFDef+pyPw==" }, - "clone-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", - "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", - "requires": { - "mimic-response": "^1.0.0" - } - }, "cluster-key-slot": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.1.0.tgz", @@ -2077,6 +2008,11 @@ "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" }, + "compare-versions": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-5.0.1.tgz", + "integrity": "sha512-v8Au3l0b+Nwkp4G142JcgJFh1/TUhdxut7wzD1Nq1dyp5oa3tXaqb03EXOAB6jS4gMlalkjAUPZBMiAfKUixHQ==" + }, "complex.js": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/complex.js/-/complex.js-2.1.1.tgz", @@ -2257,9 +2193,9 @@ "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==" }, "form-data-encoder": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.1.tgz", - "integrity": "sha512-EFRDrsMm/kyqbTQocNvRXMLjc7Es2Vk+IQFx/YW7hkUH1eBl4J1fqiP34l74Yt0pFLCNpc06fkbVk00008mzjg==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.3.tgz", + "integrity": "sha512-KqU0nnPMgIJcCOFTNJFEA8epcseEaoox4XZffTgy8jlI6pL/5EFyR54NRG7CnCJN0biY7q52DO3MH6/sJ/TKlQ==" }, "fraction.js": { "version": "4.2.0", @@ -2285,23 +2221,21 @@ } }, "got": { - "version": "12.0.2", - "resolved": "https://registry.npmjs.org/got/-/got-12.0.2.tgz", - "integrity": "sha512-Zi4yHiqCgaorUbknr/RHFBsC3XqjSodaw0F3qxlqAqyj+OGYZl37/uy01R0qz++KANKQYdY5FHJ0okXZpEzwWQ==", + "version": "12.5.1", + "resolved": "https://registry.npmjs.org/got/-/got-12.5.1.tgz", + "integrity": "sha512-sD16AK8cCyUoPtKr/NMvLTFFa+T3i3S+zoiuvhq0HP2YiqBZA9AtlBjAdsQBsLBK7slPuvmfE0OxhGi7N5dD4w==", "requires": { - "@sindresorhus/is": "^4.6.0", + "@sindresorhus/is": "^5.2.0", "@szmarczak/http-timer": "^5.0.1", - "@types/cacheable-request": "^6.0.2", - "@types/responselike": "^1.0.0", - "cacheable-lookup": "^6.0.4", - "cacheable-request": "^7.0.2", + "cacheable-lookup": "^7.0.0", + "cacheable-request": "^10.2.1", "decompress-response": "^6.0.0", - "form-data-encoder": "1.7.1", + "form-data-encoder": "^2.1.2", "get-stream": "^6.0.1", "http2-wrapper": "^2.1.10", "lowercase-keys": "^3.0.0", "p-cancelable": "^3.0.0", - "responselike": "^2.0.0" + "responselike": "^3.0.0" }, "dependencies": { "get-stream": { @@ -2483,9 +2417,9 @@ } }, "keyv": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.1.1.tgz", - "integrity": "sha512-tGv1yP6snQVDSM4X6yxrv2zzq/EvpW+oYiUz6aueW1u9CtS8RzUQYxxmFwgZlO2jSgCxQbchhxaqXXp2hnKGpQ==", + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.0.tgz", + "integrity": "sha512-2YvuMsA+jnFGtBareKqgANOEKe1mk3HKiXu2fRmAfyxG0MJAywNhi5ttWA3PMjl4NmpyjZNbFifR2vNjW1znfA==", "requires": { "json-buffer": "3.0.1" } @@ -2622,9 +2556,9 @@ } }, "mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", + "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==" }, "minimalistic-assert": { "version": "1.0.1", @@ -2666,9 +2600,9 @@ "optional": true }, "normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==" + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-7.2.0.tgz", + "integrity": "sha512-uhXOdZry0L6M2UIo9BTt7FdpBDiAGN/7oItedQwPKh8jh31ZlvC8U9Xl/EJ3aijDHaywXTW3QbZ6LuCocur1YA==" }, "on-finished": { "version": "2.4.1", @@ -2839,18 +2773,11 @@ "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==" }, "responselike": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.0.tgz", - "integrity": "sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", + "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", "requires": { - "lowercase-keys": "^2.0.0" - }, - "dependencies": { - "lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==" - } + "lowercase-keys": "^3.0.0" } }, "ripemd160": { diff --git a/package.json b/package.json index a38b5b2..8172e45 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "@koa/cors": "^3.1.0", "agentkeepalive": "^4.2.1", "bytes": "^3.1.0", + "compare-versions": "^5.0.1", "compressible": "^2.0.18", "fast-safe-stringify": "^2.0.7", "get-stream": "^5.1.0", diff --git a/services/servicesMonitor.js b/services/servicesMonitor.js index 6e27f5a..c0b4eaa 100644 --- a/services/servicesMonitor.js +++ b/services/servicesMonitor.js @@ -104,7 +104,6 @@ function ServicesMonitor() { async function refreshCoingecko(client, chains) { try { - await Promise.all([...chains].map((chain) => { const request = async () => { try { diff --git a/status/healthMonitor.js b/status/healthMonitor.js index dd89cbf..de2240d 100644 --- a/status/healthMonitor.js +++ b/status/healthMonitor.js @@ -15,9 +15,9 @@ function HealthMonitor() { async function refreshApis(client, chains) { timeStamp('Running health checks'); await Promise.all([...chains].map(async (chain) => { - const apis = await chain.apis() await Promise.all(['rpc', 'rest', 'private-rpc', 'private-rest', 'service'].map(async (type) => { - const urls = getUrls(chain, type) + const urls = chain.apiUrls(type) + const apis = await chain.apis() const health = apis.health[type] || {}; const updated = await Promise.all([...urls].map(async (url) => { const urlHealth = health[url.address] || {}; @@ -35,18 +35,6 @@ function HealthMonitor() { debugLog('Health checks complete') } - function getUrls(chain, type){ - switch (type) { - case 'service': - return chain.serviceApis() || [] - case 'private-rpc': - case 'private-rest': - return chain.privateApis(type.replace('private-', '')) || [] - default: - return chain.apiUrls(type) || [] - } - } - function checkUrl(url, type, chain, urlHealth) { const request = async () => { try {