Merge branch 'master' of https://github.com/donne1226/explorer
This commit is contained in:
commit
be0224eb67
17
src/chains/mainnet/celestia.json
Normal file
17
src/chains/mainnet/celestia.json
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"chain_name": "celestia",
|
||||||
|
"coingecko": "",
|
||||||
|
"api": "https://celestia-api.skynetvalidators.com",
|
||||||
|
"sdk_version": "0.44.0",
|
||||||
|
"coin_type": "118",
|
||||||
|
"min_tx_fee": "800",
|
||||||
|
"addr_prefix": "celestia",
|
||||||
|
"logo": "https://explorer-images.s3.filebase.com/celestia-logo.png",
|
||||||
|
"assets": [{
|
||||||
|
"base": "celes",
|
||||||
|
"symbol": "CELES",
|
||||||
|
"exponent": "0",
|
||||||
|
"coingecko_id": "",
|
||||||
|
"logo": "https://explorer-images.s3.filebase.com/celestia-logo.png"
|
||||||
|
}]
|
||||||
|
}
|
23
src/chains/mainnet/cht.json
Normal file
23
src/chains/mainnet/cht.json
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"chain_name": "chronic-token",
|
||||||
|
"coingecko": "",
|
||||||
|
"api": "https://chtd-api.skynetvalidators.com",
|
||||||
|
"sdk_version": "0.44.5",
|
||||||
|
"coin_type": "118",
|
||||||
|
"min_tx_fee": "800",
|
||||||
|
"addr_prefix": "chronic",
|
||||||
|
"logo": "https://explorer-images.s3.filebase.com/cht-logo.jpg",
|
||||||
|
"assets": [{
|
||||||
|
"base": "ucgas",
|
||||||
|
"symbol": "CGAS",
|
||||||
|
"exponent": "6",
|
||||||
|
"coingecko_id": "",
|
||||||
|
"logo": "https://explorer-images.s3.filebase.com/cht-logo.jpg"
|
||||||
|
},{
|
||||||
|
"base": "ucht",
|
||||||
|
"symbol": "CHT",
|
||||||
|
"exponent": "6",
|
||||||
|
"coingecko_id": "ion",
|
||||||
|
"logo": "https://explorer-images.s3.filebase.com/cht-logo.jpg"
|
||||||
|
}]
|
||||||
|
}
|
16
src/chains/mainnet/coho.json
Normal file
16
src/chains/mainnet/coho.json
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"chain_name": "cosmic-horizon",
|
||||||
|
"api": ["https://coho-api.skynetvalidators.com"],
|
||||||
|
"sdk_version": "0.44.5",
|
||||||
|
"coin_type": "118",
|
||||||
|
"min_tx_fee": "300",
|
||||||
|
"assets": [{
|
||||||
|
"base": "ucoho",
|
||||||
|
"symbol": "COHO",
|
||||||
|
"exponent": "6",
|
||||||
|
"coingecko_id": "",
|
||||||
|
"logo": "https://coho-images.s3.filebase.com/red_logo.png"
|
||||||
|
}],
|
||||||
|
"addr_prefix": "coho",
|
||||||
|
"logo": "https://coho-images.s3.filebase.com/red_logo.png"
|
||||||
|
}
|
17
src/chains/mainnet/dws.json
Normal file
17
src/chains/mainnet/dws.json
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"chain_name": "DWS",
|
||||||
|
"coingecko": "",
|
||||||
|
"api": "https://dws-api.skynetvalidators.com",
|
||||||
|
"sdk_version": "0.44.3",
|
||||||
|
"coin_type": "118",
|
||||||
|
"min_tx_fee": "200",
|
||||||
|
"addr_prefix": "deweb",
|
||||||
|
"logo": "https://dws-images.s3.filebase.com/logo.png",
|
||||||
|
"assets": [{
|
||||||
|
"base": "udws",
|
||||||
|
"symbol": "DWS",
|
||||||
|
"exponent": "6",
|
||||||
|
"coingecko_id": "",
|
||||||
|
"logo": "https://dws-images.s3.filebase.com/logo.png"
|
||||||
|
}]
|
||||||
|
}
|
17
src/chains/mainnet/omniflix.json
Normal file
17
src/chains/mainnet/omniflix.json
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"chain_name": "omniflix",
|
||||||
|
"coingecko": "",
|
||||||
|
"api": "https://omniflixhub-api.skynetvalidators.com",
|
||||||
|
"sdk_version": "0.45.1",
|
||||||
|
"coin_type": "118",
|
||||||
|
"min_tx_fee": "3000",
|
||||||
|
"addr_prefix": "omniflix",
|
||||||
|
"logo": "https://explorer-images.s3.filebase.com/omniflix-alpha-logo.png",
|
||||||
|
"assets": [{
|
||||||
|
"base": "uflix",
|
||||||
|
"symbol": "FLIX",
|
||||||
|
"exponent": "6",
|
||||||
|
"coingecko_id": "",
|
||||||
|
"logo": "https://explorer-images.s3.filebase.com/omniflix-alpha-logo.png"
|
||||||
|
}]
|
||||||
|
}
|
@ -71,8 +71,8 @@ export default class ChainFetch {
|
|||||||
return this.get(`/blocks/${height}`, config).then(data => Block.create(data))
|
return this.get(`/blocks/${height}`, config).then(data => Block.create(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
async getSlashingSigningInfo() {
|
async getSlashingSigningInfo(config = null) {
|
||||||
return this.get('/cosmos/slashing/v1beta1/signing_infos')
|
return this.get('/cosmos/slashing/v1beta1/signing_infos?pagination.limit=500', config)
|
||||||
}
|
}
|
||||||
|
|
||||||
async getTxs(hash) {
|
async getTxs(hash) {
|
||||||
@ -140,8 +140,8 @@ export default class ChainFetch {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async getValidatorList() {
|
async getValidatorList(config = null) {
|
||||||
return this.get('/staking/validators').then(data => {
|
return this.get('/staking/validators', config).then(data => {
|
||||||
const vals = commonProcess(data).map(i => new Validator().init(i))
|
const vals = commonProcess(data).map(i => new Validator().init(i))
|
||||||
localStorage.setItem(`validators-${this.config.chain_name}`, JSON.stringify(vals))
|
localStorage.setItem(`validators-${this.config.chain_name}`, JSON.stringify(vals))
|
||||||
return vals
|
return vals
|
||||||
@ -157,15 +157,15 @@ export default class ChainFetch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getValidatorListByStatus(status) {
|
async getValidatorListByStatus(status) {
|
||||||
return this.get(`/cosmos/staking/v1beta1/validators?status=${status}`).then(data => {
|
return this.get(`/cosmos/staking/v1beta1/validators?status=${status}&pagination.limit=500`).then(data => {
|
||||||
const result = commonProcess(data)
|
const result = commonProcess(data)
|
||||||
const vals = result.validators ? result.validators : result
|
const vals = result.validators ? result.validators : result
|
||||||
return vals.map(i => new Validator().init(i))
|
return vals.map(i => new Validator().init(i))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async getValidatorListByHeight(height) {
|
async getValidatorListByHeight(height, offset) {
|
||||||
return this.get(`/validatorsets/${height}`).then(data => commonProcess(data))
|
return this.get(`/cosmos/base/tendermint/v1beta1/validatorsets/${height}?pagination.limit=100&pagination.offset=${offset}`).then(data => commonProcess(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
async getStakingValidator(address) {
|
async getStakingValidator(address) {
|
||||||
|
@ -93,7 +93,7 @@
|
|||||||
no-body
|
no-body
|
||||||
>
|
>
|
||||||
<b-card-header class="d-flex justify-content-between">
|
<b-card-header class="d-flex justify-content-between">
|
||||||
<b-form-group>
|
<b-form-group class="mb-0">
|
||||||
<b-form-radio-group
|
<b-form-radio-group
|
||||||
id="btn-radios-1"
|
id="btn-radios-1"
|
||||||
v-model="selectedStatus"
|
v-model="selectedStatus"
|
||||||
@ -108,8 +108,9 @@
|
|||||||
<span>Validators {{ validators.length }}/{{ stakingParameters.max_validators }} </span>
|
<span>Validators {{ validators.length }}/{{ stakingParameters.max_validators }} </span>
|
||||||
</b-card-title>
|
</b-card-title>
|
||||||
</b-card-header>
|
</b-card-header>
|
||||||
<b-card-body class="pl-0 pr-0">
|
<b-card-body class="pl-0 pr-0 pb-0">
|
||||||
<b-table
|
<b-table
|
||||||
|
class="mb-0"
|
||||||
:items="list"
|
:items="list"
|
||||||
:fields="validator_fields"
|
:fields="validator_fields"
|
||||||
:sort-desc="true"
|
:sort-desc="true"
|
||||||
@ -317,7 +318,7 @@ export default {
|
|||||||
list() {
|
list() {
|
||||||
return this.validators.map(x => {
|
return this.validators.map(x => {
|
||||||
const xh = x
|
const xh = x
|
||||||
const change = this.changes[x.consensus_pubkey.value]
|
const change = this.changes[x.consensus_pubkey.key]
|
||||||
if (change) {
|
if (change) {
|
||||||
xh.changes = change.latest - change.previous
|
xh.changes = change.latest - change.previous
|
||||||
}
|
}
|
||||||
@ -326,28 +327,7 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.$http.getValidatorListByHeight('latest').then(data => {
|
this.getValidatorListByHeight()
|
||||||
let height = Number(data.block_height)
|
|
||||||
if (height > 14400) {
|
|
||||||
height -= 14400
|
|
||||||
} else {
|
|
||||||
height = 1
|
|
||||||
}
|
|
||||||
const changes = []
|
|
||||||
data.validators.forEach(x => {
|
|
||||||
changes[x.pub_key.value] = { latest: Number(x.voting_power), previous: 0 }
|
|
||||||
})
|
|
||||||
this.$http.getValidatorListByHeight(height).then(previous => {
|
|
||||||
previous.validators.forEach(x => {
|
|
||||||
if (changes[x.pub_key.value]) {
|
|
||||||
changes[x.pub_key.value].previous = Number(x.voting_power)
|
|
||||||
} else {
|
|
||||||
changes[x.pub_key.value] = { latest: 0, previous: Number(x.voting_power) }
|
|
||||||
}
|
|
||||||
})
|
|
||||||
this.$set(this, 'changes', changes)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
this.$http.getStakingParameters().then(res => {
|
this.$http.getStakingParameters().then(res => {
|
||||||
this.stakingParameters = res
|
this.stakingParameters = res
|
||||||
})
|
})
|
||||||
@ -357,6 +337,30 @@ export default {
|
|||||||
this.islive = false
|
this.islive = false
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
getValidatorListByHeight(offset = 0) {
|
||||||
|
this.$http.getValidatorListByHeight('latest', offset).then(data => {
|
||||||
|
let height = Number(data.block_height)
|
||||||
|
if (height > 14400) {
|
||||||
|
height -= 14400
|
||||||
|
} else {
|
||||||
|
height = 1
|
||||||
|
}
|
||||||
|
const { changes } = this
|
||||||
|
data.validators.forEach(x => {
|
||||||
|
changes[x.pub_key.key] = { latest: Number(x.voting_power), previous: 0 }
|
||||||
|
})
|
||||||
|
this.$http.getValidatorListByHeight(height, offset).then(previous => {
|
||||||
|
previous.validators.forEach(x => {
|
||||||
|
if (changes[x.pub_key.key]) {
|
||||||
|
changes[x.pub_key.key].previous = Number(x.voting_power)
|
||||||
|
} else {
|
||||||
|
changes[x.pub_key.key] = { latest: 0, previous: Number(x.voting_power) }
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.$set(this, 'changes', changes)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
getValidatorListByStatus(statusList) {
|
getValidatorListByStatus(statusList) {
|
||||||
this.validators = []
|
this.validators = []
|
||||||
statusList.forEach(status => {
|
statusList.forEach(status => {
|
||||||
@ -375,6 +379,9 @@ export default {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.stakingPool = total
|
this.stakingPool = total
|
||||||
|
if (total > 100) {
|
||||||
|
this.getValidatorListByHeight(100)
|
||||||
|
}
|
||||||
this.validators.push(...temp)
|
this.validators.push(...temp)
|
||||||
|
|
||||||
// fetch avatar from keybase
|
// fetch avatar from keybase
|
||||||
|
@ -19,10 +19,20 @@
|
|||||||
>
|
>
|
||||||
Browse favorite only
|
Browse favorite only
|
||||||
</b-button>
|
</b-button>
|
||||||
<b-form-input
|
<b-input-group>
|
||||||
v-model="query"
|
<b-input-group-prepend is-text>
|
||||||
placeholder="Keywords to filter validators"
|
<b-form-checkbox
|
||||||
/>
|
v-model="missedFilter"
|
||||||
|
v-b-tooltip.hover
|
||||||
|
title="Only missed blocks"
|
||||||
|
name="viewMissed"
|
||||||
|
/>
|
||||||
|
</b-input-group-prepend>
|
||||||
|
<b-form-input
|
||||||
|
v-model="query"
|
||||||
|
placeholder="Keywords to filter validators"
|
||||||
|
/>
|
||||||
|
</b-input-group>
|
||||||
</b-card>
|
</b-card>
|
||||||
<b-row>
|
<b-row>
|
||||||
<b-col
|
<b-col
|
||||||
@ -32,13 +42,36 @@
|
|||||||
md="4"
|
md="4"
|
||||||
class="text-truncate"
|
class="text-truncate"
|
||||||
>
|
>
|
||||||
<b-form-checkbox
|
<div class="d-flex justify-content-between">
|
||||||
v-model="pinned"
|
<b-form-checkbox
|
||||||
:value="`${chain}#${x.address}`"
|
v-model="pinned"
|
||||||
class="custom-control-warning"
|
:value="`${chain}#${x.address}`"
|
||||||
@change="pinValidator(`${chain}#${x.address}`)"
|
class="custom-control-warning text-truncate"
|
||||||
><span class="d-inline-block text-truncate font-weight-bold align-bottom">{{ index+1 }} {{ x.validator.moniker }}</span>
|
@change="pinValidator(`${chain}#${x.address}`)"
|
||||||
</b-form-checkbox>
|
><span class="d-inline-block text-truncate font-weight-bold align-bottom">{{ index+1 }} {{ x.validator.moniker }}</span>
|
||||||
|
</b-form-checkbox>
|
||||||
|
<span
|
||||||
|
v-if="missing[x.address]"
|
||||||
|
>
|
||||||
|
<b-badge
|
||||||
|
v-if="missing[x.address].missed_blocks_counter > 0"
|
||||||
|
v-b-tooltip.hover.v-danger
|
||||||
|
variant="light-danger"
|
||||||
|
:title="`${missing[x.address].missed_blocks_counter} missed blocks`"
|
||||||
|
class="text-danger text-bolder"
|
||||||
|
>
|
||||||
|
{{ missing[x.address].missed_blocks_counter }}
|
||||||
|
</b-badge>
|
||||||
|
<b-badge
|
||||||
|
v-else
|
||||||
|
v-b-tooltip.hover.v-success
|
||||||
|
variant="light-success"
|
||||||
|
title="Perfect! No missed blocks"
|
||||||
|
>
|
||||||
|
0
|
||||||
|
</b-badge>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
<div class="d-flex justify-content-between align-self-stretch flex-wrap">
|
<div class="d-flex justify-content-between align-self-stretch flex-wrap">
|
||||||
<div
|
<div
|
||||||
v-for="(b,i) in blocks"
|
v-for="(b,i) in blocks"
|
||||||
@ -62,12 +95,13 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {
|
import {
|
||||||
BRow, BCol, VBTooltip, BFormInput, BCard, BAlert, BFormCheckbox, BButton,
|
BRow, BCol, VBTooltip, BFormInput, BCard, BAlert, BFormCheckbox, BButton, BBadge, BInputGroup, BInputGroupPrepend,
|
||||||
} from 'bootstrap-vue'
|
} from 'bootstrap-vue'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
consensusPubkeyToHexAddress, getCachedValidators, timeIn, toDay,
|
consensusPubkeyToHexAddress, getCachedValidators, timeIn, toDay,
|
||||||
} from '@/libs/utils'
|
} from '@/libs/utils'
|
||||||
|
import { Bech32, toHex } from '@cosmjs/encoding'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
@ -77,7 +111,10 @@ export default {
|
|||||||
BCard,
|
BCard,
|
||||||
BAlert,
|
BAlert,
|
||||||
BButton,
|
BButton,
|
||||||
|
BBadge,
|
||||||
BFormCheckbox,
|
BFormCheckbox,
|
||||||
|
BInputGroup,
|
||||||
|
BInputGroupPrepend,
|
||||||
},
|
},
|
||||||
directives: {
|
directives: {
|
||||||
'b-tooltip': VBTooltip,
|
'b-tooltip': VBTooltip,
|
||||||
@ -86,6 +123,7 @@ export default {
|
|||||||
const { chain } = this.$route.params
|
const { chain } = this.$route.params
|
||||||
const pinned = localStorage.getItem('pinned') ? localStorage.getItem('pinned').split(',') : ''
|
const pinned = localStorage.getItem('pinned') ? localStorage.getItem('pinned').split(',') : ''
|
||||||
return {
|
return {
|
||||||
|
missedFilter: false,
|
||||||
pinned,
|
pinned,
|
||||||
chain,
|
chain,
|
||||||
query: '',
|
query: '',
|
||||||
@ -100,10 +138,14 @@ export default {
|
|||||||
uptime() {
|
uptime() {
|
||||||
const vals = this.query ? this.validators.filter(x => String(x.description.moniker).indexOf(this.query) > -1) : this.validators
|
const vals = this.query ? this.validators.filter(x => String(x.description.moniker).indexOf(this.query) > -1) : this.validators
|
||||||
vals.sort((a, b) => b.delegator_shares - a.delegator_shares)
|
vals.sort((a, b) => b.delegator_shares - a.delegator_shares)
|
||||||
return vals.map(x => ({
|
const rets = vals.map(x => ({
|
||||||
validator: x.description,
|
validator: x.description,
|
||||||
address: consensusPubkeyToHexAddress(x.consensus_pubkey),
|
address: consensusPubkeyToHexAddress(x.consensus_pubkey),
|
||||||
}))
|
}))
|
||||||
|
if (this.missedFilter) {
|
||||||
|
return rets.filter(x => this.missing[x.address].missed_blocks_counter > 0)
|
||||||
|
}
|
||||||
|
return rets
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
@ -115,6 +157,16 @@ export default {
|
|||||||
this.$http.getValidatorList().then(res => {
|
this.$http.getValidatorList().then(res => {
|
||||||
this.validators = res
|
this.validators = res
|
||||||
})
|
})
|
||||||
|
this.$http.getSlashingSigningInfo().then(res => {
|
||||||
|
if (res.info) {
|
||||||
|
res.info.forEach(x => {
|
||||||
|
if (x.address) {
|
||||||
|
const hex = toHex(Bech32.decode(x.address).data).toUpperCase()
|
||||||
|
this.missing[hex] = x
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
this.initBlocks()
|
this.initBlocks()
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
|
@ -23,14 +23,37 @@
|
|||||||
sm="12"
|
sm="12"
|
||||||
class="text-truncate"
|
class="text-truncate"
|
||||||
>
|
>
|
||||||
<b-form-checkbox
|
<div class="d-flex justify-content-between">
|
||||||
v-model="pinned"
|
<b-form-checkbox
|
||||||
:value="`${chain}#${x.address}`"
|
v-model="pinned"
|
||||||
class="custom-control-warning"
|
:value="`${chain}#${x.address}`"
|
||||||
@change="pinValidator(`${chain}#${x.address}`)"
|
class="custom-control-warning"
|
||||||
>
|
@change="pinValidator(`${chain}#${x.address}`)"
|
||||||
<span class="d-inline-block text-truncate font-weight-bold align-bottom"> {{ x.validator.moniker }} </span>
|
>
|
||||||
</b-form-checkbox>
|
<span class="d-inline-block text-truncate font-weight-bold align-bottom"> {{ x.validator.moniker }} </span>
|
||||||
|
</b-form-checkbox>
|
||||||
|
<span
|
||||||
|
v-if="missing[x.address]"
|
||||||
|
>
|
||||||
|
<b-badge
|
||||||
|
v-if="missing[x.address].missed_blocks_counter > 0"
|
||||||
|
v-b-tooltip.hover.v-danger
|
||||||
|
variant="light-danger"
|
||||||
|
:title="`${missing[x.address].missed_blocks_counter} missed blocks`"
|
||||||
|
class="text-danger text-bolder"
|
||||||
|
>
|
||||||
|
{{ missing[x.address].missed_blocks_counter }}
|
||||||
|
</b-badge>
|
||||||
|
<b-badge
|
||||||
|
v-else
|
||||||
|
v-b-tooltip.hover.v-success
|
||||||
|
variant="light-success"
|
||||||
|
title="Perfect! No missed blocks"
|
||||||
|
>
|
||||||
|
0
|
||||||
|
</b-badge>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
<div class="d-flex justify-content-between align-self-stretch flex-wrap">
|
<div class="d-flex justify-content-between align-self-stretch flex-wrap">
|
||||||
<div
|
<div
|
||||||
v-for="(b,i) in blocks"
|
v-for="(b,i) in blocks"
|
||||||
@ -54,16 +77,18 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {
|
import {
|
||||||
BRow, BCol, VBTooltip, BCard, BAlert, BCardTitle, BFormCheckbox,
|
BRow, BCol, VBTooltip, BCard, BAlert, BCardTitle, BFormCheckbox, BBadge,
|
||||||
} from 'bootstrap-vue'
|
} from 'bootstrap-vue'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getLocalChains, timeIn, toDay,
|
getLocalChains, timeIn, toDay,
|
||||||
} from '@/libs/utils'
|
} from '@/libs/utils'
|
||||||
|
import { Bech32, toHex } from '@cosmjs/encoding'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'Blocks',
|
name: 'Blocks',
|
||||||
components: {
|
components: {
|
||||||
|
BBadge,
|
||||||
BRow,
|
BRow,
|
||||||
BCol,
|
BCol,
|
||||||
BCard,
|
BCard,
|
||||||
@ -105,6 +130,16 @@ export default {
|
|||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.initBlocks()
|
this.initBlocks()
|
||||||
|
this.$http.getSlashingSigningInfo(this.config).then(res => {
|
||||||
|
if (res.info) {
|
||||||
|
res.info.forEach(x => {
|
||||||
|
if (x.address) {
|
||||||
|
const hex = toHex(Bech32.decode(x.address).data).toUpperCase()
|
||||||
|
this.missing[hex] = x
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
this.blocks = [] // clear running tasks if it is not finish
|
this.blocks = [] // clear running tasks if it is not finish
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="container-md px-0">
|
<div class="container-md px-0">
|
||||||
<b-row>
|
<b-row v-if="chainVals">
|
||||||
<b-col
|
<b-col
|
||||||
v-for="(x,index) in Object.keys(chainVals)"
|
v-for="(x,index) in Object.keys(chainVals)"
|
||||||
:key="index"
|
:key="index"
|
||||||
@ -15,27 +15,42 @@
|
|||||||
|
|
||||||
</b-col>
|
</b-col>
|
||||||
</b-row>
|
</b-row>
|
||||||
|
<b-alert
|
||||||
|
class="mt-2"
|
||||||
|
variant="success"
|
||||||
|
show
|
||||||
|
>
|
||||||
|
<div class="alert-heading">
|
||||||
|
Note
|
||||||
|
</div>
|
||||||
|
<div class="alert-body">
|
||||||
|
There are two ways to monitor your validators:
|
||||||
|
<li> Pin a validator on Uptime pages.</li>
|
||||||
|
<li> Specify parameters like following: <pre>https://ping.pub/cosmos/uptime/my?validators={"sifchain":["FBADE9A30473BB9ED6DFA16BFB3838E028F33650"],"chain_name":["hexAddress"]}</pre></li>
|
||||||
|
</div>
|
||||||
|
</b-alert>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {
|
import {
|
||||||
BRow, BCol, VBTooltip,
|
BRow, BCol, VBTooltip, BAlert,
|
||||||
} from 'bootstrap-vue'
|
} from 'bootstrap-vue'
|
||||||
import { consensusPubkeyToHexAddress, getCachedValidators } from '@/libs/utils'
|
import { consensusPubkeyToHexAddress, getCachedValidators, getLocalChains } from '@/libs/utils'
|
||||||
import UptimeMyChainBlocks from './UptimeMyChainBlocks.vue'
|
import UptimeMyChainBlocks from './UptimeMyChainBlocks.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
BRow,
|
BRow,
|
||||||
BCol,
|
BCol,
|
||||||
|
BAlert,
|
||||||
UptimeMyChainBlocks,
|
UptimeMyChainBlocks,
|
||||||
},
|
},
|
||||||
directives: {
|
directives: {
|
||||||
'b-tooltip': VBTooltip,
|
'b-tooltip': VBTooltip,
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
const pinned = (localStorage.getItem('pinned') || '').split(',').map(x => x.split('#')).reduce((a1, b) => {
|
let pinned = (localStorage.getItem('pinned') || '').split(',').map(x => x.split('#')).reduce((a1, b) => {
|
||||||
const a = a1
|
const a = a1
|
||||||
if (a[b[0]]) {
|
if (a[b[0]]) {
|
||||||
a[b[0]].push(b[1])
|
a[b[0]].push(b[1])
|
||||||
@ -44,17 +59,34 @@ export default {
|
|||||||
}
|
}
|
||||||
return a
|
return a
|
||||||
}, {})
|
}, {})
|
||||||
|
if (this.$route.query.validators) {
|
||||||
|
pinned = (JSON.parse(this.$route.query.validators))
|
||||||
|
}
|
||||||
|
|
||||||
const chainVals = {}
|
const chainVals = {}
|
||||||
Object.keys(pinned).forEach(x => {
|
if (pinned) {
|
||||||
const cached = JSON.parse(getCachedValidators(x))
|
const configs = getLocalChains()
|
||||||
const validators = []
|
Object.keys(pinned).forEach(x => {
|
||||||
pinned[x].forEach(address => {
|
const cached = JSON.parse(getCachedValidators(x))
|
||||||
const val = cached.find(v => address === consensusPubkeyToHexAddress(v.consensus_pubkey))
|
if (cached) {
|
||||||
if (val) validators.push({ address, validator: val.description })
|
const validators = []
|
||||||
|
pinned[x].forEach(address => {
|
||||||
|
const val = cached.find(v => address === consensusPubkeyToHexAddress(v.consensus_pubkey))
|
||||||
|
if (val) validators.push({ address, validator: val.description })
|
||||||
|
})
|
||||||
|
chainVals[x] = validators
|
||||||
|
} else {
|
||||||
|
this.$http.getValidatorList(configs[x]).then((vals => {
|
||||||
|
const validators = []
|
||||||
|
pinned[x].forEach(address => {
|
||||||
|
const val = vals.find(v => address === consensusPubkeyToHexAddress(v.consensus_pubkey))
|
||||||
|
if (val) validators.push({ address, validator: val.description })
|
||||||
|
})
|
||||||
|
this.$set(this.chainVals, x, validators)
|
||||||
|
}))
|
||||||
|
}
|
||||||
})
|
})
|
||||||
chainVals[x] = validators
|
}
|
||||||
})
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
chainVals,
|
chainVals,
|
||||||
|
Loading…
Reference in New Issue
Block a user