Finish validator detail

This commit is contained in:
liangping
2021-08-03 00:13:53 +08:00
parent 18e0d933b0
commit e4fca8f41b
22 changed files with 1326 additions and 7 deletions
+137
View File
@@ -0,0 +1,137 @@
export const codeDirective = `
<template>
<div class="d-flex">
<!-- form input -->
<b-form-group class="mb-0 mr-1">
<b-form-input
v-model="message"
/>
</b-form-group>
<!-- button -->
<b-button
v-clipboard:copy="message"
v-clipboard:success="onCopy"
v-clipboard:error="onError"
v-ripple.400="'rgba(186, 191, 199, 0.15)'"
variant="primary"
>
Copy!
</b-button>
</div>
</template>
<script>
import { BFormInput, BFormGroup, BButton } from 'bootstrap-vue'
import ToastificationContent from '@core/components/toastification/ToastificationContent.vue'
import Ripple from 'vue-ripple-directive'
export default {
components: {
BFormInput,
BFormGroup,
BButton,
// eslint-disable-next-line vue/no-unused-components
ToastificationContent,
},
directives: {
Ripple,
},
data() {
return {
message: 'Copy Me!',
}
},
methods: {
onCopy() {
this.$toast({
component: ToastificationContent,
props: {
title: 'Text copied',
icon: 'BellIcon',
},
})
},
onError() {
this.$toast({
component: ToastificationContent,
props: {
title: 'Failed to copy texts!',
icon: 'BellIcon',
},
})
},
},
}
</script>
`
export const codeWithoutDirective = `
<template>
<div class="d-flex">
<!-- input -->
<b-form-group class="mb-0 mr-1">
<b-form-input
v-model="message1"
/>
</b-form-group>
<!-- button -->
<b-button
v-ripple.400="'rgba(186, 191, 199, 0.15)'"
variant="primary"
@click="doCopy"
>
Copy!
</b-button>
</div>
</template>
<script>
import {BFormInput, BFormGroup, BButton, BCardText} from 'bootstrap-vue'
import ToastificationContent from '@core/components/toastification/ToastificationContent.vue'
import Ripple from 'vue-ripple-directive'
export default {
components: {
BFormInput,
BFormGroup,
BButton,
BCardText,
// eslint-disable-next-line vue/no-unused-components
ToastificationContent,
},
directives: {
Ripple,
},
data() {
return {
message1: 'Copy Me Without Directive',
}
},
methods: {
doCopy() {
this.$copyText(this.message1).then(() => {
this.$toast({
component: ToastificationContent,
props: {
title: 'Text copied',
icon: 'BellIcon',
},
})
}, e => {
this.$toast({
component: ToastificationContent,
props: {
title: 'Can not copy!',
icon: 'BellIcon',
},
})
})
},
},
}
</script>
`
+11
View File
@@ -0,0 +1,11 @@
export default class BlockData {
constructor() {
this.txs = []
}
static create(element) {
const self = new BlockData()
self.txs = element.txs
return self
}
}
+41
View File
@@ -0,0 +1,41 @@
import BlockId from './block-id'
export default class BlockHeader {
constructor() {
this.version = {
block: '0',
}
this.chain_id = ''
this.height = 0
this.time = '2021-08-02T01:12:43.42506492Z'
this.last_block_id = new BlockId()
this.last_commit_hash = ''
this.data_hash = ''
this.validators_hash = ''
this.next_validators_hash = ''
this.consensus_hash = ''
this.app_hash = ''
this.last_results_hash = ''
this.evidence_hash = ''
this.proposer_address = ''
}
static create(element) {
const self = new BlockHeader()
self.version = element.version
self.chain_id = element.chain_id
self.height = element.height
self.time = element.time
self.last_block_id = element.last_block_id
self.last_commit_hash = element.last_commit_hash
self.data_hash = element.data_hash
self.validators_hash = element.validators_hash
self.next_validators_hash = element.next_validators_hash
self.consensus_hash = element.consensus_hash
self.app_hash = element.app_hash
self.last_results_hash = element.last_results_hash
self.evidence_hash = element.evidence_hash
self.proposer_address = element.proposer_address
return self
}
}
+13
View File
@@ -0,0 +1,13 @@
export default class BlockId {
constructor() {
this.hash = ''
this.parts = { total: 0, hash: '' }
}
static create(element) {
const self = new BlockId()
self.hash = element.hash
self.parts = element.parts
return self
}
}
+21
View File
@@ -0,0 +1,21 @@
import BlockData from './block-data'
import BlockHeader from './block-header'
import BlockLastCommit from './block-last-commit'
export default class BlockInner {
constructor() {
this.header = new BlockHeader()
this.data = new BlockData()
this.evidence = { evidence: [] }
this.last_commit = new BlockLastCommit()
}
static create(element) {
const self = new BlockInner()
self.header = BlockHeader.create(element.header)
self.data = BlockData.create(element.data)
self.evidence = element.evidence
self.last_commit = BlockLastCommit.create(element.last_commit)
return self
}
}
+20
View File
@@ -0,0 +1,20 @@
import BlockId from './block-id'
import Signature from './signature'
export default class BlockLastCommit {
constructor() {
this.height = 0
this.round = 0
this.block_id = new BlockId()
this.signatures = []
}
static create(element) {
const self = new BlockLastCommit()
self.height = Number(element.height)
self.round = Number(element.round)
self.block_id = element.block_id
self.signatures = element.signatures.map(x => Signature.create(x))
return self
}
}
+16
View File
@@ -0,0 +1,16 @@
import BlockId from './block-id'
import BlockInner from './block-inner'
export default class Block {
constructor() {
this.block_id = new BlockId()
this.block = new BlockInner()
}
static create(element) {
const self = new Block()
self.block_id = BlockId.create(element.block_id)
self.block = BlockInner.create(element.block)
return self
}
}
+20
View File
@@ -1,4 +1,8 @@
import dayjs from 'dayjs'
import {
Bech32, fromBase64, fromHex, toHex,
} from '@cosmjs/encoding'
import { sha256 } from '@cosmjs/crypto'
export function toDay(time) {
return dayjs(time).format('YYYY-MM-DD HH:mm')
@@ -23,6 +27,22 @@ export function tokenFormatter(tokens) {
return formatToken(tokens)
}
export function operatorAddressToAccount(operAddress) {
const { prefix, data } = Bech32.decode(operAddress)
return Bech32.encode(prefix.replace('valoper', ''), data)
}
export function consensusPubkeyToHexAddress(consensusPubkey) {
let raw = null
if (typeof consensusPubkey === 'object') {
raw = toHex(fromBase64(consensusPubkey.value))
} else {
raw = toHex(Bech32.decode(consensusPubkey).data).toUpperCase().replace('1624DE6420', '')
}
const address = toHex(sha256(fromHex(raw))).slice(0, 40).toUpperCase()
return address
}
export * from 'compare-versions'
export class Data {
+3
View File
@@ -6,6 +6,9 @@ export { default as Votes } from './votes'
export { default as Deposit } from './deposit'
export { default as Validator } from './validator'
export { default as StakingParameters } from './staking-parameters'
export { default as Block } from './block'
export { default as ValidatorDistribution } from './validator-distribution'
export { default as StakingDelegation } from './staking-delegation'
export * from './data'
export default class Test {}
+17
View File
@@ -0,0 +1,17 @@
export default class Signature {
constructor() {
this.block_id_flag = 2
this.validator_address = ''
this.timestamp = ''
this.signature = ''
}
static create(element) {
const self = new Signature()
self.block_id_flag = element.block_id_flag
self.validator_address = element.validator_address
self.timestamp = element.timestamp
self.signature = element.signature
return self
}
}
+13
View File
@@ -0,0 +1,13 @@
export default class StakingDelegation {
constructor() {
this.delegation = {}
this.balance = {}
}
static create(element) {
const self = new StakingDelegation()
self.delegation = element.delegation
self.balance = element.balance
return self
}
}
+25
View File
@@ -0,0 +1,25 @@
import compareVersions from 'compare-versions'
export default class ValidatorDistribution {
constructor() {
this.element = {}
this.operator_address = ''
this.self_bond_rewards = []
this.val_commission = []
}
static create(element) {
const self = new ValidatorDistribution()
self.element = element
self.operator_address = element.operator_address
self.self_bond_rewards = element.self_bond_rewards
self.val_commission = element.val_commission
return self
}
versionFixed(ver) {
if (compareVersions(ver, '0.40') >= 0) {
this.val_commission = this.element.val_commission.commission
}
}
}
+2
View File
@@ -15,6 +15,7 @@ export default class Validator {
this.unbonding_height = 0
this.unbonding_time = '1970-01-01T00:00:00Z'
this.commission = new ValidatorCommission()
this.min_self_delegation = 1
}
init(element) {
@@ -30,6 +31,7 @@ export default class Validator {
this.unbonding_height = element.unbonding_height
this.unbonding_time = element.unbonding_time
this.commission = new ValidatorCommission().init(element.commission)
this.min_self_delegation = element.min_self_delegation
return this
}
}
+25 -1
View File
@@ -2,7 +2,7 @@ import fetch from 'node-fetch'
import store from '@/store'
import {
Proposal, ProposalTally, Proposer, StakingPool, Votes, Deposit,
Validator, StakingParameters,
Validator, StakingParameters, Block, ValidatorDistribution, StakingDelegation,
} from './data'
function commonProcess(res) {
@@ -21,6 +21,26 @@ const chainAPI = class ChainFetch {
return this.config
}
async getLatestBlock() {
return this.get('/blocks/latest').then(data => Block.create(data))
}
async getBlockByHeight(height) {
return this.get(`/blocks/${height}`).then(data => Block.create(data))
}
async getValidatorDistribution(address) {
return this.get(`/distribution/validators/${address}`).then(data => {
const ret = ValidatorDistribution.create(commonProcess(data))
ret.versionFixed(this.config.sdk_version)
return ret
})
}
async getStakingDelegatorDelegation(delegatorAddr, validatorAddr) {
return this.get(`/staking/delegators/${delegatorAddr}/delegations/${validatorAddr}`).then(data => StakingDelegation.create(commonProcess(data)))
}
async getStakingPool() {
return this.get('/staking/pool').then(data => new StakingPool().init(commonProcess(data)))
}
@@ -37,6 +57,10 @@ const chainAPI = class ChainFetch {
return this.get('/staking/validators').then(data => commonProcess(data).map(i => new Validator().init(i)))
}
async getStakingValidator(address) {
return this.get(`/staking/validators/${address}`).then(data => new Validator().init(commonProcess(data)))
}
async getGovernanceTally(pid, total) {
return this.get(`/gov/proposals/${pid}/tally`).then(data => new ProposalTally().init(commonProcess(data), total))
}